Home | History | Annotate | Download | only in ci_build
      1 #!/usr/bin/env bash
      2 # Copyright 2016 The TensorFlow Authors. All Rights Reserved.
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #     http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 # ==============================================================================
     16 #
     17 # Usage: ci_sanity.sh [--pep8] [--incremental] [bazel flags]
     18 #
     19 # Options:
     20 #           run sanity checks: python 2&3 pylint checks and bazel nobuild
     21 #  --pep8   run pep8 test only
     22 #  --incremental  Performs checks incrementally, by using the files changed in
     23 #                 the latest commit
     24 
     25 # Current script directory
     26 SCRIPT_DIR=$( cd ${0%/*} && pwd -P )
     27 source "${SCRIPT_DIR}/builds/builds_common.sh"
     28 
     29 ROOT_DIR=$( cd "$SCRIPT_DIR/../../.." && pwd -P )
     30 
     31 # Helper functions
     32 die() {
     33   echo $@
     34   exit 1
     35 }
     36 
     37 num_cpus() {
     38   # Get the number of CPUs
     39   N_CPUS=$(grep -c ^processor /proc/cpuinfo)
     40   if [[ -z ${N_CPUS} ]]; then
     41     die "ERROR: Unable to determine the number of CPUs"
     42   fi
     43 
     44   echo ${N_CPUS}
     45 }
     46 
     47 # Helper functions for examining changed files in the last non-merge git
     48 # commit.
     49 
     50 # Get the hash of the last non-merge git commit on the current branch.
     51 # Usage: get_last_non_merge_git_commit
     52 get_last_non_merge_git_commit() {
     53   git rev-list --no-merges -n 1 HEAD
     54 }
     55 
     56 # List files changed (i.e., added, removed or revised) in the last non-merge
     57 # git commit.
     58 # Usage: get_changed_files_in_last_non_merge_git_commit
     59 get_changed_files_in_last_non_merge_git_commit() {
     60   git diff-tree --no-commit-id --name-only -r $(get_last_non_merge_git_commit)
     61 }
     62 
     63 # List Python files changed in the last non-merge git commit that still exist,
     64 # i.e., not removed.
     65 # Usage: get_py_files_to_check [--incremental]
     66 get_py_files_to_check() {
     67   if [[ "$1" == "--incremental" ]]; then
     68     CHANGED_PY_FILES=$(get_changed_files_in_last_non_merge_git_commit | \
     69                        grep '.*\.py$')
     70 
     71     # Do not include files removed in the last non-merge commit.
     72     PY_FILES=""
     73     for PY_FILE in ${CHANGED_PY_FILES}; do
     74       if [[ -f "${PY_FILE}" ]]; then
     75         PY_FILES="${PY_FILES} ${PY_FILE}"
     76       fi
     77     done
     78 
     79     echo "${PY_FILES}"
     80   else
     81     find tensorflow -name '*.py'
     82   fi
     83 }
     84 
     85 # Subfunctions for substeps
     86 # Run pylint
     87 do_pylint() {
     88   # Usage: do_pylint (PYTHON2 | PYTHON3) [--incremental]
     89   #
     90   # Options:
     91   #   --incremental  Performs check on only the python files changed in the
     92   #                  last non-merge git commit.
     93 
     94   # Use this list to whitelist pylint errors
     95   ERROR_WHITELIST="^tensorflow/python/framework/function_test\.py.*\[E1123.*noinline "\
     96 "^tensorflow/python/platform/default/_gfile\.py.*\[E0301.*non-iterator "\
     97 "^tensorflow/python/platform/default/_googletest\.py.*\[E0102.*function\salready\sdefined "\
     98 "^tensorflow/python/feature_column/feature_column_test\.py.*\[E0110.*abstract-class-instantiated "\
     99 "^tensorflow/contrib/layers/python/layers/feature_column\.py.*\[E0110.*abstract-class-instantiated "\
    100 "^tensorflow/contrib/eager/python/evaluator\.py.*\[E0202.*method-hidden "\
    101 "^tensorflow/contrib/eager/python/metrics_impl\.py.*\[E0202.*method-hidden "\
    102 "^tensorflow/python/platform/gfile\.py.*\[E0301.*non-iterator "\
    103 "^tensorflow/python/keras/_impl/keras/callbacks\.py.*\[E1133.*not-an-iterable "\
    104 "^tensorflow/python/keras/_impl/keras/layers/recurrent\.py.*\[E0203.*access-member-before-definition "\
    105 "^tensorflow/python/kernel_tests/constant_op_eager_test.py.*\[E0303.*invalid-length-returned"
    106 
    107   echo "ERROR_WHITELIST=\"${ERROR_WHITELIST}\""
    108 
    109   if [[ $# != "1" ]] && [[ $# != "2" ]]; then
    110     echo "Invalid syntax when invoking do_pylint"
    111     echo "Usage: do_pylint (PYTHON2 | PYTHON3) [--incremental]"
    112     return 1
    113   fi
    114 
    115   if [[ $1 == "PYTHON2" ]]; then
    116     PYLINT_BIN="python -m pylint"
    117   elif [[ $1 == "PYTHON3" ]]; then
    118     PYLINT_BIN="python3 -m pylint"
    119   else
    120     echo "Unrecognized python version (PYTHON2 | PYTHON3): $1"
    121     return 1
    122   fi
    123 
    124   if [[ "$2" == "--incremental" ]]; then
    125     PYTHON_SRC_FILES=$(get_py_files_to_check --incremental)
    126 
    127     if [[ -z "${PYTHON_SRC_FILES}" ]]; then
    128       echo "do_pylint will NOT run due to --incremental flag and due to the "\
    129 "absence of Python code changes in the last commit."
    130       return 0
    131     else
    132       # For incremental builds, we still check all Python files in cases there
    133       # are function signature changes that affect unchanged Python files.
    134       PYTHON_SRC_FILES=$(get_py_files_to_check)
    135     fi
    136   elif [[ -z "$2" ]]; then
    137     PYTHON_SRC_FILES=$(get_py_files_to_check)
    138   else
    139     echo "Invalid syntax for invoking do_pylint"
    140     echo "Usage: do_pylint (PYTHON2 | PYTHON3) [--incremental]"
    141     return 1
    142   fi
    143 
    144   if [[ -z ${PYTHON_SRC_FILES} ]]; then
    145     echo "do_pylint found no Python files to check. Returning."
    146     return 0
    147   fi
    148 
    149   PYLINTRC_FILE="${SCRIPT_DIR}/pylintrc"
    150 
    151   if [[ ! -f "${PYLINTRC_FILE}" ]]; then
    152     die "ERROR: Cannot find pylint rc file at ${PYLINTRC_FILE}"
    153   fi
    154 
    155   NUM_SRC_FILES=$(echo ${PYTHON_SRC_FILES} | wc -w)
    156   NUM_CPUS=$(num_cpus)
    157 
    158   echo "Running pylint on ${NUM_SRC_FILES} files with ${NUM_CPUS} "\
    159 "parallel jobs..."
    160   echo ""
    161 
    162   PYLINT_START_TIME=$(date +'%s')
    163   OUTPUT_FILE="$(mktemp)_pylint_output.log"
    164   ERRORS_FILE="$(mktemp)_pylint_errors.log"
    165   NONWL_ERRORS_FILE="$(mktemp)_pylint_nonwl_errors.log"
    166 
    167   rm -rf ${OUTPUT_FILE}
    168   rm -rf ${ERRORS_FILE}
    169   rm -rf ${NONWL_ERRORS_FILE}
    170   touch ${NONWL_ERRORS_FILE}
    171 
    172   ${PYLINT_BIN} --rcfile="${PYLINTRC_FILE}" --output-format=parseable \
    173       --jobs=${NUM_CPUS} ${PYTHON_SRC_FILES} > ${OUTPUT_FILE} 2>&1
    174   PYLINT_END_TIME=$(date +'%s')
    175 
    176   echo ""
    177   echo "pylint took $((PYLINT_END_TIME - PYLINT_START_TIME)) s"
    178   echo ""
    179 
    180   # Report only what we care about
    181   # Ref https://pylint.readthedocs.io/en/latest/technical_reference/features.html
    182   # E: all errors
    183   # W0311 bad-indentation
    184   # W0312 mixed-indentation
    185   # C0330 bad-continuation
    186   # C0301 line-too-long
    187   # C0326 bad-whitespace
    188   # W0611 unused-import
    189   # W0622 redefined-builtin
    190   grep -E '(\[E|\[W0311|\[W0312|\[C0330|\[C0301|\[C0326|\[W0611|\[W0622)' ${OUTPUT_FILE} > ${ERRORS_FILE}
    191 
    192   N_ERRORS=0
    193   while read -r LINE; do
    194     IS_WHITELISTED=0
    195     for WL_REGEX in ${ERROR_WHITELIST}; do
    196       if echo ${LINE} | grep -q "${WL_REGEX}"; then
    197         echo "Found a whitelisted error:"
    198         echo "  ${LINE}"
    199         IS_WHITELISTED=1
    200       fi
    201     done
    202 
    203     if [[ ${IS_WHITELISTED} == "0" ]]; then
    204       echo "${LINE}" >> ${NONWL_ERRORS_FILE}
    205       echo "" >> ${NONWL_ERRORS_FILE}
    206       ((N_ERRORS++))
    207     fi
    208   done <${ERRORS_FILE}
    209 
    210   echo ""
    211   if [[ ${N_ERRORS} != 0 ]]; then
    212     echo "FAIL: Found ${N_ERRORS} non-whitelited pylint errors:"
    213     cat "${NONWL_ERRORS_FILE}"
    214     return 1
    215   else
    216     echo "PASS: No non-whitelisted pylint errors were found."
    217     return 0
    218   fi
    219 }
    220 
    221 # Run pep8 check
    222 do_pep8() {
    223   # Usage: do_pep8 [--incremental]
    224   # Options:
    225   #   --incremental  Performs check on only the python files changed in the
    226   #                  last non-merge git commit.
    227 
    228   PEP8_BIN="/usr/local/bin/pep8"
    229   PEP8_CONFIG_FILE="${SCRIPT_DIR}/pep8"
    230 
    231   if [[ "$1" == "--incremental" ]]; then
    232     PYTHON_SRC_FILES=$(get_py_files_to_check --incremental)
    233     NUM_PYTHON_SRC_FILES=$(echo ${PYTHON_SRC_FILES} | wc -w)
    234 
    235     echo "do_pep8 will perform checks on only the ${NUM_PYTHON_SRC_FILES} "\
    236 "Python file(s) changed in the last non-merge git commit due to the "\
    237 "--incremental flag:"
    238     echo "${PYTHON_SRC_FILES}"
    239     echo ""
    240   else
    241     PYTHON_SRC_FILES=$(get_py_files_to_check)
    242   fi
    243 
    244   if [[ -z ${PYTHON_SRC_FILES} ]]; then
    245     echo "do_pep8 found no Python files to check. Returning."
    246     return 0
    247   fi
    248 
    249   if [[ ! -f "${PEP8_CONFIG_FILE}" ]]; then
    250     die "ERROR: Cannot find pep8 config file at ${PEP8_CONFIG_FILE}"
    251   fi
    252   echo "See \"${PEP8_CONFIG_FILE}\" for pep8 config( e.g., ignored errors)"
    253 
    254   NUM_SRC_FILES=$(echo ${PYTHON_SRC_FILES} | wc -w)
    255 
    256   echo "Running pep8 on ${NUM_SRC_FILES} files"
    257   echo ""
    258 
    259   PEP8_START_TIME=$(date +'%s')
    260   PEP8_OUTPUT_FILE="$(mktemp)_pep8_output.log"
    261 
    262   rm -rf ${PEP8_OUTPUT_FILE}
    263 
    264   ${PEP8_BIN} --config="${PEP8_CONFIG_FILE}" --statistics \
    265       ${PYTHON_SRC_FILES} 2>&1 | tee ${PEP8_OUTPUT_FILE}
    266   PEP8_END_TIME=$(date +'%s')
    267 
    268   echo ""
    269   echo "pep8 took $((PEP8_END_TIME - PEP8_START_TIME)) s"
    270   echo ""
    271 
    272   if [[ -s ${PEP8_OUTPUT_FILE} ]]; then
    273     echo "FAIL: pep8 found above errors and/or warnings."
    274     return 1
    275   else
    276     echo "PASS: No pep8 errors or warnings were found"
    277     return 0
    278   fi
    279 }
    280 
    281 
    282 do_buildifier(){
    283   BUILD_FILES=$(find tensorflow -name 'BUILD*')
    284   NUM_BUILD_FILES=$(echo ${BUILD_FILES} | wc -w)
    285 
    286   echo "Running do_buildifier on ${NUM_BUILD_FILES} files"
    287   echo ""
    288 
    289   BUILDIFIER_START_TIME=$(date +'%s')
    290   BUILDIFIER_OUTPUT_FILE="$(mktemp)_buildifier_output.log"
    291 
    292   rm -rf ${BUILDIFIER_OUTPUT_FILE}
    293 
    294   buildifier -showlog -v -mode=check \
    295     ${BUILD_FILES} 2>&1 | tee ${BUILDIFIER_OUTPUT_FILE}
    296   BUILDIFIER_END_TIME=$(date +'%s')
    297 
    298   echo ""
    299   echo "buildifier took $((BUILDIFIER_END_TIME - BUILDIFIER_START_TIME)) s"
    300   echo ""
    301 
    302   if [[ -s ${BUILDIFIER_OUTPUT_FILE} ]]; then
    303     echo "FAIL: buildifier found errors and/or warnings in above BUILD files."
    304     echo "buildifier suggested the following changes:"
    305     buildifier -showlog -v -mode=diff ${BUILD_FILES}
    306     echo "Please fix manually or run buildifier <file> to auto-fix."
    307     return 1
    308   else
    309     echo "PASS: No buildifier errors or warnings were found"
    310     return 0
    311   fi
    312 }
    313 
    314 do_external_licenses_check(){
    315   BUILD_TARGET="$1"
    316   LICENSES_TARGET="$2"
    317 
    318   EXTERNAL_LICENSES_CHECK_START_TIME=$(date +'%s')
    319 
    320   EXTERNAL_DEPENDENCIES_FILE="$(mktemp)_external_dependencies.log"
    321   LICENSES_FILE="$(mktemp)_licenses.log"
    322   MISSING_LICENSES_FILE="$(mktemp)_missing_licenses.log"
    323   EXTRA_LICENSES_FILE="$(mktemp)_extra_licenses.log"
    324 
    325   echo "Getting external dependencies for ${BUILD_TARGET}"
    326  bazel query "attr('licenses', 'notice', deps(${BUILD_TARGET}))" --keep_going \
    327   | grep -E -v "^//tensorflow" \
    328   | sed -e 's|:.*||' \
    329   | sort \
    330   | uniq 2>&1 \
    331   | tee ${EXTERNAL_DEPENDENCIES_FILE}
    332 
    333   echo
    334   echo "Getting list of external licenses mentioned in ${LICENSES_TARGET}."
    335   bazel query "deps(${LICENSES_TARGET})" --keep_going \
    336   | grep -E -v "^//tensorflow" \
    337   | sed -e 's|:.*||' \
    338   | sort \
    339   | uniq 2>&1 \
    340   | tee ${LICENSES_FILE}
    341 
    342   echo
    343   comm -1 -3 ${EXTERNAL_DEPENDENCIES_FILE}  ${LICENSES_FILE} 2>&1 | tee ${EXTRA_LICENSES_FILE}
    344   echo
    345   comm -2 -3 ${EXTERNAL_DEPENDENCIES_FILE}  ${LICENSES_FILE} 2>&1 | tee ${MISSING_LICENSES_FILE}
    346 
    347   EXTERNAL_LICENSES_CHECK_END_TIME=$(date +'%s')
    348 
    349   # Blacklist
    350   echo ${MISSING_LICENSES_FILE}
    351   grep -e "@bazel_tools//third_party/" -e "@com_google_absl//absl" -e "@org_tensorflow//" -v ${MISSING_LICENSES_FILE} > temp.txt
    352   mv temp.txt ${MISSING_LICENSES_FILE}
    353 
    354   # Whitelist
    355   echo ${EXTRA_LICENSE_FILE}
    356   grep -e "@bazel_tools//src" -e "@bazel_tools//tools/" -e "@com_google_absl//" -e "//external" -e "@local" -v ${EXTRA_LICENSES_FILE} > temp.txt
    357   mv temp.txt ${EXTRA_LICENSES_FILE}
    358 
    359 
    360 
    361   echo
    362   echo "do_external_licenses_check took $((EXTERNAL_LICENSES_CHECK_END_TIME - EXTERNAL_LICENSES_CHECK_START_TIME)) s"
    363   echo
    364 
    365   if [[ -s ${MISSING_LICENSES_FILE} ]] || [[ -s ${EXTRA_LICENSES_FILE} ]] ; then
    366     echo "FAIL: mismatch in packaged licenses and external dependencies"
    367     if [[ -s ${MISSING_LICENSES_FILE} ]] ; then
    368       echo "Missing the licenses for the following external dependencies:"
    369       cat ${MISSING_LICENSES_FILE}
    370     fi
    371     if [[ -s ${EXTRA_LICENSES_FILE} ]] ; then
    372       echo "Please remove the licenses for the following external dependencies:"
    373       cat ${EXTRA_LICENSES_FILE}
    374     fi
    375     rm -rf ${EXTERNAL_DEPENDENCIES_FILE}
    376     rm -rf ${LICENSES_FILE}
    377     rm -rf ${MISSING_LICENSES_FILE}
    378     rm -rf ${EXTRA_LICENSES_FILE}
    379     return 1
    380   else
    381     echo "PASS: all external licenses included."
    382     rm -rf ${EXTERNAL_DEPENDENCIES_FILE}
    383     rm -rf ${LICENSES_FILE}
    384     rm -rf ${MISSING_LICENSES_FILE}
    385     rm -rf ${EXTRA_LICENSES_FILE}
    386     return 0
    387   fi
    388 }
    389 
    390 do_pip_package_licenses_check() {
    391   echo "Running do_pip_package_licenses_check"
    392   echo ""
    393   do_external_licenses_check \
    394     "//tensorflow/tools/pip_package:build_pip_package" \
    395     "//tensorflow/tools/pip_package:licenses"
    396 }
    397 
    398 do_lib_package_licenses_check() {
    399   echo "Running do_lib_package_licenses_check"
    400   echo ""
    401   do_external_licenses_check \
    402     "//tensorflow:libtensorflow.so" \
    403     "//tensorflow/tools/lib_package:clicenses_generate"
    404 }
    405 
    406 do_java_package_licenses_check() {
    407   echo "Running do_java_package_licenses_check"
    408   echo ""
    409   do_external_licenses_check \
    410     "//tensorflow/java:libtensorflow_jni.so" \
    411     "//tensorflow/tools/lib_package:jnilicenses_generate"
    412 }
    413 
    414 #Check for the bazel cmd status (First arg is error message)
    415 cmd_status(){
    416   if [[ $? != 0 ]]; then
    417     echo ""
    418     echo "FAIL: ${BUILD_CMD}"
    419     echo "  $1 See lines above for details."
    420     return 1
    421   else
    422     echo ""
    423     echo "PASS: ${BUILD_CMD}"
    424     return 0
    425   fi
    426 }
    427 
    428 # Run bazel build --nobuild to test the validity of the BUILD files
    429 # TODO(mikecase): Remove TF Lite exclusion from this list. Exclusion is
    430 # necessary since the @androidsdk WORKSPACE dependency is commented
    431 # out by default in TF WORKSPACE file.
    432 do_bazel_nobuild() {
    433   BUILD_TARGET="//tensorflow/..."
    434   BUILD_TARGET="${BUILD_TARGET} -//tensorflow/contrib/lite/java/demo/app/src/main/..."
    435   BUILD_TARGET="${BUILD_TARGET} -//tensorflow/contrib/lite/schema/..."
    436   BUILD_CMD="bazel build --nobuild ${BAZEL_FLAGS} -- ${BUILD_TARGET}"
    437 
    438   ${BUILD_CMD}
    439 
    440   cmd_status \
    441     "This is due to invalid BUILD files."
    442 }
    443 
    444 do_pip_smoke_test() {
    445   cd "$ROOT_DIR/tensorflow/tools/pip_package"
    446   python pip_smoke_test.py
    447 }
    448 
    449 do_code_link_check() {
    450   tensorflow/tools/ci_build/code_link_check.sh
    451 }
    452 
    453 # List .h|.cc files changed in the last non-merge git commit that still exist,
    454 # i.e., not removed.
    455 # Usage: get_clang_files_to_check [--incremental]
    456 get_clang_files_to_check() {
    457   if [[ "$1" == "--incremental" ]]; then
    458     CHANGED_CLANG_FILES=$(get_changed_files_in_last_non_merge_git_commit | \
    459                        grep '.*\.h$\|.*\.cc$')
    460 
    461     # Do not include files removed in the last non-merge commit.
    462     CLANG_FILES=""
    463     for CLANG_FILE in ${CHANGED_CLANG_FILES}; do
    464       if [[ -f "${CLANG_FILE}" ]]; then
    465         CLANG_FILES="${CLANG_FILES} ${CLANG_FILE}"
    466       fi
    467     done
    468 
    469     echo "${CLANG_FILES}"
    470   else
    471     find tensorflow -name '*.h' -o -name '*.cc'
    472   fi
    473 }
    474 
    475 do_clang_format_check() {
    476   if [[ $# != "0" ]] && [[ $# != "1" ]]; then
    477     echo "Invalid syntax when invoking do_clang_format_check"
    478     echo "Usage: do_clang_format_check [--incremental]"
    479     return 1
    480   fi
    481 
    482   if [[ "$1" == "--incremental" ]]; then
    483     CLANG_SRC_FILES=$(get_clang_files_to_check --incremental)
    484 
    485     if [[ -z "${CLANG_SRC_FILES}" ]]; then
    486       echo "do_clang_format_check will NOT run due to --incremental flag and "\
    487 "due to the absence of .h or .cc code changes in the last commit."
    488       return 0
    489     fi
    490   elif [[ -z "$1" ]]; then
    491     # TODO (yongtang): Always pass --incremental until all files have
    492     # been sanitized gradually. Then this --incremental could be removed.
    493     CLANG_SRC_FILES=$(get_clang_files_to_check --incremental)
    494   else
    495     echo "Invalid syntax for invoking do_clang_format_check"
    496     echo "Usage: do_clang_format_check [--incremental]"
    497     return 1
    498   fi
    499 
    500   CLANG_FORMAT=${CLANG_FORMAT:-clang-format-3.8}
    501 
    502   success=1
    503   for filename in $CLANG_SRC_FILES; do
    504     $CLANG_FORMAT --style=google $filename | diff $filename - > /dev/null
    505     if [ ! $? -eq 0 ]; then
    506       success=0
    507       echo File $filename is not properly formatted with "clang-format "\
    508 "--style=google"
    509     fi
    510   done
    511 
    512   if [ $success == 0 ]; then
    513     echo Clang format check fails.
    514     exit 1
    515   fi
    516   echo Clang format check success.
    517 }
    518 
    519 do_check_load_py_test() {
    520   cd "$ROOT_DIR/tensorflow/tools/pip_package"
    521   python check_load_py_test.py
    522 }
    523 
    524 do_cmake_python_sanity() {
    525   cd "$ROOT_DIR/tensorflow/contrib/cmake"
    526   python -m unittest -v python_sanity_test
    527 }
    528 
    529 do_check_futures_test() {
    530   cd "$ROOT_DIR/tensorflow/tools/test"
    531   python check_futures_test.py
    532 }
    533 
    534 do_check_file_name_test() {
    535   cd "$ROOT_DIR/tensorflow/tools/test"
    536   python file_name_test.py
    537 }
    538 
    539 # Supply all sanity step commands and descriptions
    540 SANITY_STEPS=("do_pylint PYTHON2" "do_pylint PYTHON3" "do_check_futures_test" "do_buildifier" "do_bazel_nobuild" "do_pip_package_licenses_check" "do_lib_package_licenses_check" "do_java_package_licenses_check" "do_pip_smoke_test" "do_check_load_py_test" "do_code_link_check" "do_cmake_python_sanity" "do_check_file_name_test")
    541 SANITY_STEPS_DESC=("Python 2 pylint" "Python 3 pylint" "Check that python files have certain __future__ imports" "buildifier check" "bazel nobuild" "pip: license check for external dependencies" "C library: license check for external dependencies" "Java Native Library: license check for external dependencies" "Pip Smoke Test: Checking py_test dependencies exist in pip package" "Check load py_test: Check that BUILD files with py_test target properly load py_test" "Code Link Check: Check there are no broken links" "Test entries in /tensorflow/contrib/cmake/python_{modules|protos|protos_cc}.txt for validity and consistency" "Check file names for cases")
    542 
    543 INCREMENTAL_FLAG=""
    544 DEFAULT_BAZEL_CONFIGS="--config=hdfs --config=gcp"
    545 
    546 # Parse command-line arguments
    547 BAZEL_FLAGS=${DEFAULT_BAZEL_CONFIGS}
    548 for arg in "$@"; do
    549   if [[ "${arg}" == "--pep8" ]]; then
    550     # Only run pep8 test if "--pep8" option supplied
    551     SANITY_STEPS=("do_pep8")
    552     SANITY_STEPS_DESC=("pep8 test")
    553   elif [[ "${arg}" == "--incremental" ]]; then
    554     INCREMENTAL_FLAG="--incremental"
    555   else
    556     BAZEL_FLAGS="${BAZEL_FLAGS} ${arg}"
    557   fi
    558 done
    559 
    560 
    561 FAIL_COUNTER=0
    562 PASS_COUNTER=0
    563 STEP_EXIT_CODES=()
    564 
    565 # Execute all the sanity build steps
    566 COUNTER=0
    567 while [[ ${COUNTER} -lt "${#SANITY_STEPS[@]}" ]]; do
    568   INDEX=COUNTER
    569   ((INDEX++))
    570 
    571   echo ""
    572   echo "=== Sanity check step ${INDEX} of ${#SANITY_STEPS[@]}: "\
    573 "${SANITY_STEPS[COUNTER]} (${SANITY_STEPS_DESC[COUNTER]}) ==="
    574   echo ""
    575 
    576   # subshell: don't leak variables or changes of working directory
    577   (
    578   ${SANITY_STEPS[COUNTER]} ${INCREMENTAL_FLAG}
    579   )
    580   RESULT=$?
    581 
    582   if [[ ${RESULT} != "0" ]]; then
    583     ((FAIL_COUNTER++))
    584   else
    585     ((PASS_COUNTER++))
    586   fi
    587 
    588   STEP_EXIT_CODES+=(${RESULT})
    589 
    590   echo ""
    591   ((COUNTER++))
    592 done
    593 
    594 # Print summary of build results
    595 COUNTER=0
    596 echo "==== Summary of sanity check results ===="
    597 while [[ ${COUNTER} -lt "${#SANITY_STEPS[@]}" ]]; do
    598   INDEX=COUNTER
    599   ((INDEX++))
    600 
    601   echo "${INDEX}. ${SANITY_STEPS[COUNTER]}: ${SANITY_STEPS_DESC[COUNTER]}"
    602   if [[ ${STEP_EXIT_CODES[COUNTER]} == "0" ]]; then
    603     printf "  ${COLOR_GREEN}PASS${COLOR_NC}\n"
    604   else
    605     printf "  ${COLOR_RED}FAIL${COLOR_NC}\n"
    606   fi
    607 
    608   ((COUNTER++))
    609 done
    610 
    611 echo
    612 echo "${FAIL_COUNTER} failed; ${PASS_COUNTER} passed."
    613 
    614 echo
    615 if [[ ${FAIL_COUNTER} == "0" ]]; then
    616   printf "Sanity checks ${COLOR_GREEN}PASSED${COLOR_NC}\n"
    617 else
    618   printf "Sanity checks ${COLOR_RED}FAILED${COLOR_NC}\n"
    619   exit 1
    620 fi
    621