| #!/bin/bash | |
| # | |
| # Copyright 2018-present the Material Components for iOS authors. All Rights Reserved. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # | |
| # Finds all newly-added files that are missing BUILD targets | |
| # Unique identifier for GitHub comments posted by this script. | |
| COMMENT_IDENTIFIER='bazel-rule-coverage' | |
| ## Import Github Comment library script | |
| if [ -n "$KOKORO_BUILD_NUMBER" ]; then | |
| # Import source methods for managing GitHub comments | |
| scripts_dir='github/repo/scripts/lib' | |
| else | |
| scripts_dir="$(dirname $0)/lib" | |
| fi | |
| source "${scripts_dir}/github_comments.sh" | |
| # Required for posting and deleting comments | |
| source "${scripts_dir}/select_xcode.sh" | |
| if [ -n "$XCODE_VERSION" ]; then | |
| select_xcode "$XCODE_VERSION" | |
| fi | |
| # Generates a list of files that were modified since the target branch | |
| modified_files() { | |
| # Move to our cloned repository | |
| if [ -n "$KOKORO_BUILD_NUMBER" ]; then | |
| pushd github/repo >> /dev/null | |
| fi | |
| # `target_branch` is either the Pull Request destination branch (where it will be merged) or if | |
| # none can be determined, defaults to `develop`. | |
| if [ -n "$KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH" ]; then | |
| target_branch="origin/${KOKORO_GITHUB_PULL_REQUEST_TARGET_BRANCH}" | |
| else | |
| target_branch=develop | |
| fi | |
| # `base_sha` is the merge base of `target_branch` and the current HEAD. | |
| base_sha=$(git merge-base "${target_branch}" HEAD) | |
| # `TARGET` is then all bazel targets affected by changes in the commit range between `base_sha` | |
| # and `HEAD`. By default, that becomes all changes between the `develop` branch and the latest | |
| # commit. | |
| range="${base_sha}...HEAD" | |
| git diff --name-status "${range}" \ | |
| | grep -v -E '^D' \ | |
| | grep -E '(\.swift|\.h|\.m)$' \ | |
| | while read LINE; do \ | |
| echo "$LINE" | sed -nE 's/.*[[:blank:]]+([[:alnum:]_\-\.\/+]+)$/\1/p'; \ | |
| done \ | |
| | sort \ | |
| | uniq | |
| if [ -n "$KOKORO_BUILD_NUMBER" ]; then | |
| popd >> /dev/null | |
| fi | |
| } | |
| # Deletes any previously-posted comment and posts a comment to GitHub with | |
| # the list of source files not in a bazel target. | |
| update_comment() { | |
| if [ -n "$GITHUB_API_TOKEN" ]; then | |
| delete_comment "$COMMENT_IDENTIFIER" | |
| fi | |
| if [ -n "$1" ]; then | |
| comment_tmp_path=$(mktemp -d) | |
| comment_tmp_file="${comment_tmp_path}/comment.tmp" | |
| echo -e "The following files are not in any BUILD targets:\n" >> "$comment_tmp_file" | |
| echo -e "\`\`\`\n${1}\n\`\`\`\n" >> "$comment_tmp_file" | |
| cat "$comment_tmp_file" | |
| if [ -n "$GITHUB_API_TOKEN" ]; then | |
| post_comment "$COMMENT_IDENTIFIER" "$comment_tmp_file" | |
| fi | |
| fi | |
| } | |
| # Determines if any of the modified files are not included in a bazel rule. | |
| check_files_covered() { | |
| update_comment # Deletes any previously-posted comment | |
| files=$(modified_files) | |
| SAVEIFS=$IFS | |
| IFS=$'\n' | |
| files=($files) | |
| IFS=$SAVEIFS | |
| if [ -z "$files" ]; then | |
| echo "No source files were modified" | |
| exit 0 | |
| fi | |
| if [ -n "$KOKORO_BUILD_NUMBER" ]; then | |
| pushd github/repo >> /dev/null | |
| # We must upgrade bazel prior to running bazel query because we rely on features in bazel | |
| # 0.20. | |
| bazel version | |
| use_bazel.sh 0.20.0 | |
| bazel version | |
| fi | |
| num_files="${#files[@]}" | |
| current_index=0 | |
| for file in "${files[@]}"; do | |
| targets=$(bazel query "'$file'" --output=package 2>/dev/null) | |
| if [ -z "$targets" ]; then | |
| if [ -z "$missing_targets" ]; then | |
| missing_targets="$file" | |
| else | |
| missing_targets="${missing_targets}\n${file}" | |
| fi | |
| exit_status=1 | |
| fi | |
| ((current_index++)) | |
| if (( current_index % 25==0 )); then | |
| echo "Processing file $current_index / $num_files" | |
| fi | |
| done | |
| if [ -n "$KOKORO_BUILD_NUMBER" ]; then | |
| popd >> /dev/null | |
| fi | |
| if (( exit_status != 0 )); then | |
| missing_targets=$(echo -e "$missing_targets" | sort | uniq) | |
| update_comment "$missing_targets" | |
| fi | |
| exit $exit_status | |
| } | |
| check_files_covered | |