Skip to content

Commit

Permalink
[ci] Add a lint script to detect code that has not been formatted.
Browse files Browse the repository at this point in the history
The script `support/ci/lint.sh` has 4 detection modes to trigger
slightly different behavior depending on the context or use case:

* If a `LINT_ALL` environment variable is set, all `*.rs` under the
  `components/` directory will be checked with `rustfmt`. This may only
  be useful when upgrading the version of `rustfmt` as it will also flag
  any currently vendored crates also under `./components/`.
* If there are unstaged files, check all Rust files that are unstaged.
  This is most useful when actively developing a commit or feature.
* If there are staged files, check all Rust files that are staged (also
  known as cached). This is most useful as a pre-commit activity before
  writing a commit.
* Otherwise, use the last commit (i.e. `HEAD`) to select the files to
  check. This is most useful in a CI environment where the last commit
  is assumed to contain most of the work. If a `TRAVIS_COMMIT_RANGE`
  environment varible is present, this will be used instead to get all
  files for the pull request under review.

Signed-off-by: Fletcher Nichol <[email protected]>
  • Loading branch information
fnichol committed Jun 1, 2016
1 parent 7f934dc commit 02db112
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ matrix:
before_install:
- ./support/ci/compile_libsodium.sh
- ./support/ci/compile_libarchive.sh
- ./support/ci/install_rustfmt.sh
script:
- ./support/ci/rust_tests.sh
- ./support/ci/lint.sh
- language: rust
env:
- COMPONENTS=lib LIBSODIUM=$HOME/pkgs/libsodium/1.0.8 LIBARCHIVE=$HOME/pkgs/libarchive/3.2.0 PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$LIBARCHIVE/lib/pkgconfig:$LIBSODIUM/lib/pkgconfig" LD_LIBRARY_PATH="LD_LIBRARY_PATH:$LIBARCHIVE/lib:$LIBSODIUM/lib"
Expand Down Expand Up @@ -72,8 +74,10 @@ matrix:
before_install:
- ./support/ci/compile_libsodium.sh
- ./support/ci/compile_libarchive.sh
- ./support/ci/install_rustfmt.sh
script:
- ./support/ci/rust_tests.sh
- ./support/ci/lint.sh
- language: rust
env:
- COMPONENTS=srv LIBSODIUM=$HOME/pkgs/libsodium/1.0.8 LIBARCHIVE=$HOME/pkgs/libarchive/3.2.0 PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$LIBARCHIVE/lib/pkgconfig:$LIBSODIUM/lib/pkgconfig" LD_LIBRARY_PATH="LD_LIBRARY_PATH:$LIBARCHIVE/lib:$LIBSODIUM/lib"
Expand Down Expand Up @@ -106,8 +110,10 @@ matrix:
before_install:
- ./support/ci/compile_libsodium.sh
- ./support/ci/compile_libarchive.sh
- ./support/ci/install_rustfmt.sh
script:
- ./support/ci/rust_tests.sh
- ./support/ci/lint.sh
- language: node_js
node_js: 4.2.6
sudo: required
Expand Down
13 changes: 13 additions & 0 deletions support/ci/install_rustfmt.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu

version=0.5.0

if command -v rustfmt >/dev/null; then
if [[ $(rustfmt --version) = "$version" ]]; then
echo "--> Detected rustfmt version $version, skipping install"
exit 0
fi
fi

cargo install --vers $version rustfmt
126 changes: 126 additions & 0 deletions support/ci/lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/bin/bash

# Fail if there are any unset variables and whenever a command returns a
# non-zero exit code.
set -eu

# If the variable `$DEBUG` is set, then print the shell commands as we execute.
if [ -n "${DEBUG:-}" ]; then
set -x
export DEBUG
fi

info() {
case "${TERM:-}" in
*term | xterm-* | rxvt | screen | screen-*)
printf -- " \033[1;32m${program}: \033[1;37m$1\033[0m\n"
;;
*)
printf -- " ${program}: $1\n"
;;
esac
return 0
}

warn() {
case "${TERM:-}" in
*term | xterm-* | rxvt | screen | screen-*)
>&2 echo -e " \033[1;32m${program}: \033[1;33mWARN \033[1;37m$1\033[0m"
;;
*)
>&2 echo " ${pkg_name}: WARN $1"
;;
esac
return 0
}

exit_with() {
case "${TERM:-}" in
*term | xterm-* | rxvt | screen | screen-*)
>&2 printf -- "\033[1;31mERROR: \033[1;37m$1\033[0m\n"
;;
*)
>&2 printf -- "ERROR: $1\n"
;;
esac
exit $2
}

program=$(basename $0)
rf_version="0.5.0"

info "Checking for rustfmt"
if ! command -v rustfmt >/dev/null; then
exit_with "Program \`rustfmt' not found on PATH, aborting" 1
fi

info "Checking for version $rf_version of rustfmt"
actual="$(rustfmt --version)"
if [[ "$actual" != "0.5.0" ]]; then
exit_with "\`rustfmt' version $actual doesn't match expected: $rf_version" 2
fi

failed="$(mktemp -t "$(basename $0)-failed-XXXX")"
trap 'rm -f $failed; exit $?' INT TERM EXIT

if [[ -n "${LINT_ALL:-}" ]]; then
cmd="find components -type f -name '*.rs'"
info "Linting all files, selecting files via: '$cmd'"
elif [[ $(git diff --name-only | wc -l) -gt 0 ]]; then
cmd="git diff --name-only"
info "Unstaged changes detected, selecting files via: '$cmd'"
elif [[ $(git diff --name-only --cached | wc -l) -gt 0 ]]; then
cmd="git diff --name-only --cached"
info "Staged changes detected, selecting files via: '$cmd'"
else
treeish="${1:-${TRAVIS_COMMIT_RANGE:-${TRAVIS_COMMIT:-HEAD}}}"
cmd="git diff-tree --no-commit-id --name-only -r $treeish"
info "Selecting files from Git via: '$cmd'"
fi

eval "$cmd" | while read file; do
case "${file##*.}" in
rs)
info "Running rustfmt on $file"
set +e
output="$(rustfmt --skip-children --write-mode diff "$file" 2>&1)"
rf_exit="$?"
set -e
case $rf_exit in
0|3)
if echo "$output" | grep -q "Diff at line " >/dev/null; then
warn "File $file generates a diff after running rustfmt $rf_version"
warn "Perhaps you forgot to run \`rustfmt' or \`cargo fmt'?"
warn "Diff for $file:"
echo "$output"
echo "$file" >> "$failed"
fi
;;
101)
warn "File $file exited with $rf_exit"
warn "Error output:"
echo "$output"
warn "Skipping this failure until next release of rustfmt"
;;
*)
warn "File $file exited with $rf_exit"
warn "Error output:"
echo "$output"
echo "$file" >> "$failed"
;;
esac
;;
esac
done

if [[ $(cat "$failed" | wc -l) -gt 0 ]]; then
echo
echo
warn "Summary: One or more files failed linting:"
cat "$failed" | while read file; do
warn " * $file"
done
exit_with "File(s) failed linting" 10
else
info "Summary: All checked files passed their lints."
fi

0 comments on commit 02db112

Please sign in to comment.