diff --git a/.gitignore b/.gitignore index ff9450490..f50859de4 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ htmlcov/ nosetests.xml coverage.xml *.cover +*,cover .hypothesis/ # Sphinx documentation diff --git a/check/all b/check/all new file mode 100755 index 000000000..76a03c436 --- /dev/null +++ b/check/all @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +# +# Copyright 2025 Google LLC +# +# 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 +# +# https://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. + +# This script is modeled in part on Cirq's check/all script. + +declare -r usage="\ +Usage: ${0##*/} [--help] [--only-changed-files] [--apply-format-changes] [BASE_REV] + +If the first argument given on the command line is the option --help or -h, +this program prints usage information and then exits. + +With no arguments, this runs multiple checks on the code base. These tests +are based on the programs in the checks/ subdirectory. + +If --apply-format-changes is specified, the flag --apply will be passed to +check/format-incremental to apply the format changes suggested by the +formatter. + +You can specify a base git revision to compare against (i.e., to use when +determining whether or not a file is considered to have changed). If given, +the argument BASE_REV is passed on to tests that can use it, such as +check/pytest-and-incremental-coverage." + +set -eo pipefail -o errtrace +shopt -s inherit_errexit + +# Get the working directory to the repo root. +thisdir=$(dirname "${BASH_SOURCE[0]:?}") +repo_dir=$(git -C "${thisdir}" rev-parse --show-toplevel) +cd "${repo_dir}" + +function error() { + echo >&2 "ERROR: ${*}" +} + +# ~~~~ Parse the CLI arguments and gather some data ~~~~ + +declare -a rev=() +declare -a apply_arg=() +declare only_changed="" +for arg in "$@"; do + case "${arg}" in + -h | --help) + echo "${usage}" + exit 0 + ;; + --apply-format-changes) + apply_arg=( "--apply" ) + shift + ;; + --only-changed-files) + only_changed="true" + shift + ;; + -*) + error "Invalid option '${arg}'" + error "See '$0 --help' for the list of supported options." + exit 1 + ;; + *) + if ! rev=( "$(git rev-parse --verify --end-of-options "${arg}^{commit}")" ); then + error "No revision '${arg}'" + exit 1 + fi + ;; + esac +done + +# ~~~~ Run the tests ~~~~ + +declare -a errors=() + +function run() { + echo "Running $* ..." + "$@" || errors+=( "$* failed" ) + echo +} + +if [[ -n "${only_changed}" ]]; then + run check/format-incremental "${rev[@]}" "${apply_arg[@]}" + run check/pylint-changed-files "${rev[@]}" +else + run check/format-incremental "${rev[@]}" "${apply_arg[@]}" --all + run check/pylint "${rev[@]}" +fi +run check/mypy +run check/pytest-and-incremental-coverage "${rev[@]}" +run check/shellcheck + +# ~~~~ Summarize the results and exit with a status code ~~~~ + +declare exit_code=0 +echo +echo "Done." +if [[ "${#errors[@]}" == 0 ]]; then + echo "All checks passed." +else + error "Some checks failed." + printf " %s\n" "${errors[@]}" + exit_code=1 +fi + +exit "${exit_code}" diff --git a/check/shellcheck b/check/shellcheck index 58a2215ff..f5d36bfdf 100755 --- a/check/shellcheck +++ b/check/shellcheck @@ -54,10 +54,13 @@ IFS=$'\n' read -r -d "" -a our_shell_scripts < <( declare -a required_shell_scripts required_shell_scripts=( # items below must be sorted + check/all check/format-incremental check/mypy check/pylint + check/pylint-changed-files check/pytest + check/pytest-and-incremental-coverage ) scripts_not_found=$(comm -13 \