Skip to content

Commit

Permalink
Merge pull request #1148 from dra27/git-precommit-hook
Browse files Browse the repository at this point in the history
Supply a Git pre-commit hook for tools/check-typo
  • Loading branch information
dra27 committed Jun 30, 2018
2 parents 18bba74 + 38caf1c commit 3522037
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 11 deletions.
7 changes: 4 additions & 3 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,16 @@ README* ocaml-typo=missing-header
asmcomp/*/emit.mlp ocaml-typo=tab,long-line,unused-prop
asmcomp/power/NOTES.md ocaml-typo=missing-header

config/gnu ocaml-typo=prune
/config/gnu ocaml-typo=prune

emacs/*.el ocaml-typo=long-line,unused-prop
emacs/caml.el ocaml-typo=long-line,unused-prop,missing-header
emacs/COPYING ocaml-typo=tab,non-printing,missing-header
emacs/ocamltags.in ocaml-typo=non-printing

experimental ocaml-typo=prune
/experimental ocaml-typo=prune

manual ocaml-typo=prune
/manual ocaml-typo=prune

ocamldoc/Changes.txt ocaml-typo=missing-header
ocamldoc/ocamldoc.sty ocaml-typo=missing-header
Expand Down Expand Up @@ -135,6 +135,7 @@ tools/make-package-macosx text eol=lf
tools/ocaml-objcopy-macosx text eol=lf
tools/ocamlmktop.tpl text eol=lf
tools/ocamlsize text eol=lf
tools/pre-commit-githook text eol=lf

# These two are cat scripts, so may not actually require this
config/auto-aux/sharpbang text eol=lf
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ matrix:
- env: CI_KIND=build XARCH=x64 CONFIG_ARG=-flambda OCAMLRUNPARAM=b,v=0
- env: CI_KIND=changes
- env: CI_KIND=manual
- env: CI_KIND=check-typo
- env: CI_KIND=tests
allow_failures:
- env: CI_KIND=tests
Expand Down
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ columns, not use tab characters (spaces only), and not use non-ASCII
characters. These typographical rules can be checked with the script
`tools/check-typo`.

If you are working from a Git clone, you can automate this process by
copying the file `tools/pre-commit-githook` to `.git/hooks/pre-commit`.

Otherwise, there are no strongly enforced guidelines specific to the
compiler -- and, as a result, the style may differ in the different
parts of the compiler. The general [OCaml Programming
Expand Down
30 changes: 22 additions & 8 deletions tools/check-typo
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ export LC_ALL=C
# Special case for recursive call from the find command (see IGNORE_DIRS).
case "$1" in
--check-prune)
case `git check-attr ocaml-typo "$2" 2>/dev/null` in
case `env $OCAML_CT_GIT_INDEX git check-attr $OCAML_CT_CA_FLAG \
ocaml-typo "$2" 2>/dev/null` in
*prune*) echo "INFO: pruned directory $2 (ocaml-typo=prune)" >&2; exit 0;;
*) exit 3;;
esac;;
Expand All @@ -113,6 +114,16 @@ while : ; do
esac
done

OCAML_CT_CAT=${OCAML_CT_CAT:-cat}
OCAML_CT_LS_FILES=${OCAML_CT_LS_FILES:-git ls-files}
OCAML_CT_HEAD=${OCAML_CT_HEAD:-HEAD}
OCAML_CT_AWK=${OCAML_CT_AWK:-awk}
if [ -z "${OCAML_CT_GIT_INDEX+x}" ] ; then
OCAML_CT_GIT_INDEX=
else
OCAML_CT_GIT_INDEX="GIT_INDEX_FILE=$OCAML_CT_GIT_INDEX"
fi

IGNORE_DIRS="
-name .git -prune -o
-type d -exec $0 --check-prune {} ; -prune -o
Expand All @@ -124,7 +135,7 @@ IGNORE_DIRS="
esac
) | (
while read f; do
case `git ls-files "$f" 2>&1` in
case `$OCAML_CT_LS_FILES "$f" 2>&1` in
"") is_svn=false;;
*) is_svn=true;;
esac
Expand All @@ -147,9 +158,11 @@ IGNORE_DIRS="
# the documentation for the --numstat option. Commands designated as
# "plumbing" commands in git have stable output intended for parsing)
EMPTY=`git hash-object -t tree /dev/null`
git diff-tree --numstat $EMPTY HEAD -- "$f" | grep -q "^-[[:blank:]]-" \
&& continue
svnrules=`git check-attr ocaml-typo "$f" | sed -e 's/.*: //'`
git diff-tree --numstat $EMPTY $OCAML_CT_HEAD -- "$f" \
| grep -q "^-[[:blank:]]-" && continue
svnrules=`env $OCAML_CT_GIT_INDEX git check-attr $OCAML_CT_CA_FLAG \
ocaml-typo "$f" \
| sed -e 's/.*: //'`
case $svnrules in unspecified) svnrules= ;; esac
fi
rules="$userrules"
Expand All @@ -169,15 +182,16 @@ IGNORE_DIRS="
# requires the entire line to match. This specifically detects the
# presence of lines containing malformed UTF-8. It may be tested using
# https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
if LC_ALL=en_US.UTF8 grep -qaxv '.*' "$f" ; then
if $OCAML_CT_CAT "$OCAML_CT_PREFIX$f" \
| LC_ALL=en_US.UTF8 grep -qaxv '.*' ; then
echo File "$f" is not correctly encoded in UTF-8
exit 2
fi
;;
esac

(cat "$f" | tr -d '\r'; echo) \
| awk -v rules="$rules" -v svnrules="$svnrules" -v file="$f" \
($OCAML_CT_CAT "$OCAML_CT_PREFIX$f" | tr -d '\r'; echo) \
| $OCAML_CT_AWK -v rules="$rules" -v svnrules="$svnrules" -v file="$f" \
'
function is_err(name) {
return (("," rules svnrules ",") !~ ("[, ]" name "[, ]"));
Expand Down
8 changes: 8 additions & 0 deletions tools/ci/inria/extra-checks
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,11 @@ TSAN_OPTIONS="die_after_fork=0" $run_testsuite
# # Build the system (bytecode only) and test
# make $jobs world
# $run_testsuite

#########################################################################

# Ensure that the repo still passes the check-typo script
if [ ! -x tools/check-typo ] ; then
error "tools/check-typo does not appear to be executable?"
fi
tools/check-typo
77 changes: 77 additions & 0 deletions tools/ci/travis/travis-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,80 @@ EOF
testsuite > /dev/null && exit 1 || echo pass
}

# Test to see if any part of the directory name has been marked prune
not_pruned () {
DIR=$(dirname "$1")
if [ "$DIR" = "." ] ; then
return 0
else
case ",$(git check-attr ocaml-typo "$DIR" | sed -e 's/.*: //')," in
,prune,)
return 1
;;
*)

not_pruned $DIR
return $?
esac
fi
}

CheckTypoTree () {
export OCAML_CT_HEAD=$1
export OCAML_CT_LS_FILES="git diff-tree --no-commit-id --name-only -r $2 --"
export OCAML_CT_CAT="git cat-file --textconv"
export OCAML_CT_PREFIX="$1:"
GIT_INDEX_FILE=tmp-index git read-tree --reset -i $1
git diff-tree --diff-filter=d --no-commit-id --name-only -r $1 \
| (while IFS= read -r path
do
if not_pruned $path ; then
echo "Checking $1: $path"
if ! tools/check-typo ./$path ; then
touch check-typo-failed
fi
else
echo "NOT checking $1: $path (ocaml-typo=prune)"
fi
done)
rm -f tmp-index
}

CHECK_ALL_COMMITS=0

CheckTypo () {
export OCAML_CT_GIT_INDEX="tmp-index"
export OCAML_CT_CA_FLAG="--cached"
# Work around an apparent bug in Ubuntu 12.4.5
# See https://bugs.launchpad.net/ubuntu/+source/gawk/+bug/1647879
export OCAML_CT_AWK="awk --re-interval"
rm -f check-typo-failed
if test -z "$TRAVIS_COMMIT_RANGE"
then CheckTypoTree $TRAVIS_COMMIT $TRAVIS_COMMIT
else
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]
then TRAVIS_COMMIT_RANGE=$TRAVIS_BRANCH..$TRAVIS_PULL_REQUEST_SHA
fi
if [ $CHECK_ALL_COMMITS -eq 1 ]
then
for commit in $(git rev-list $TRAVIS_COMMIT_RANGE --reverse)
do
CheckTypoTree $commit $commit
done
else
if [ -z "$TRAVIS_PULL_REQUEST_SHA" ]
then CheckTypoTree $TRAVIS_COMMIT $TRAVIS_COMMIT
else CheckTypoTree $TRAVIS_PULL_REQUEST_SHA $TRAVIS_COMMIT_RANGE
fi
fi
fi
echo complete
if [ -e check-typo-failed ]
then exit 1
fi
}


case $CI_KIND in
build) BuildAndTest;;
changes)
Expand All @@ -169,6 +243,9 @@ tests)
case $TRAVIS_EVENT_TYPE in
pull_request) CheckTestsuiteModified;;
esac;;
check-typo)
set +x
CheckTypo;;
*) echo unknown CI kind
exit 1
;;
Expand Down
76 changes: 76 additions & 0 deletions tools/pre-commit-githook
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
#**************************************************************************
#* *
#* OCaml *
#* *
#* David Allsopp, MetaStack Solutions Ltd. *
#* *
#* Copyright 2017 MetaStack Solutions Ltd. *
#* *
#* All rights reserved. This file is distributed under the terms of *
#* the GNU Lesser General Public License version 2.1, with the *
#* special exception on linking described in the file LICENSE. *
#* *
#**************************************************************************

# For what it's worth, allow for empty trees!
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# Redirect output to stderr.
exec 1>&2

# Check to see if the script's been updated
if git ls-files --error-unmatch tools/pre-commit-githook >/dev/null 2>&1 ; then
if ! diff -q <(git cat-file --textconv HEAD:tools/pre-commit-githook) "$0" \
>/dev/null 2>&1 ; then
echo "Note: tools/pre-commit-githook differs from .git/hooks/pre-commit"
echo "You may wish to upgrade your local githook"
fi
fi

# Git's built-in mechanism for whitespace is neater than ours, so do it first.
# The strange construction below creates a list of files which have either
# white-at-eol or white-at-eof included in ocaml-typo in .gitattributes and by
# prefixing the names with :! causes git diff-index to skip over them.
FILES=$(git diff-index --cached --name-only $against \
| xargs git check-attr --cached ocaml-typo \
| sed -ne 's/\(.*\): ocaml-typo:.*[ ,]white-at-eo[fl]\(,\|$\)/:!\1/p')
if ! git diff-index --check --cached $against -- $FILES ; then
exit 1
fi

# Test to see if any part of the directory name has been marked prune
not_pruned () {
DIR=$(dirname "$1")
if [ "$DIR" = "." ] ; then
return 0
else
case ",$(git check-attr ocaml-typo "$DIR" | sed -e 's/.*: //')," in
,prune,)
return 1
;;
*)

not_pruned $DIR
return $?
esac
fi
}

# Now run check-typo over all the files in the index
ERRORS=0
export OCAML_CT_PREFIX=:
export OCAML_CT_CAT="git cat-file --textconv"
export OCAML_CT_CA_FLAG=--cached
git diff --diff-filter=d --staged --name-only | (while IFS= read -r path
do
if not_pruned $path && ! tools/check-typo ./$path ; then
ERRORS=1
fi
done; exit $ERRORS)

0 comments on commit 3522037

Please sign in to comment.