hooks: change from post- to pre-commit

Avoid erroneous commits. The pre-commit can be skipped with the
`--no-verify` option, which is not available with the post-commit.
Note that `pre-commit` doesn't run when rebase while post-commit did.

This allows to have a single script which is run by both hooks. This
scripts can also be used independently to run the CI setup locally.
This commit is contained in:
Ana María Martínez Gómez
2020-07-29 18:14:26 +02:00
parent 8ff9e339f5
commit f9abbbe9ba
5 changed files with 32 additions and 80 deletions

2
.gitignore vendored
View File

@@ -110,7 +110,7 @@ venv.bak/
*.i64 *.i64
!rules/lib !rules/lib
# hooks output # hooks/ci.sh output
isort-output.log isort-output.log
black-output.log black-output.log
rule-linter-output.log rule-linter-output.log

View File

@@ -68,10 +68,17 @@ To install these development dependencies, run:
Note that some development dependencies (including the black code formatter) require Python 3. Note that some development dependencies (including the black code formatter) require Python 3.
To check the code style, formatting and run the tests you can run the script `scripts/ci.sh`.
You can run it with the argument `no_tests` to skip the tests and only run the code style and formatting: `scripts/ci.sh no_tests`
### 3. Setup hooks [optional] ### 3. Setup hooks [optional]
If you plan to contribute to capa, you may want to setup the hooks. If you plan to contribute to capa, you may want to setup the hooks.
Run `scripts/setup-hooks.sh` to set the following hooks up: Run `scripts/setup-hooks.sh` to set the following hooks up:
- The `post-commit` hook runs checks after every `git commit`, letting you know if there are code style or rule linter offenses you need to fix. - The `pre-commit` hook runs checks before every `git commit`.
- The `pre-push` hook runs various style and lint checks as well as the tests. If they do not succeed `git push` is blocked. It runs `scripts/ci.sh no_tests` aborting the commit if there are code style or rule linter offenses you need to fix.
You can skip this check by using the `--no-verify` git option.
- The `pre-push` hook runs checks before every `git push`.
It runs `scripts/ci.sh` aborting the push if there are code style or rule linter offenses or if the tests fail.
This way you can ensure everything is alright before sending a pull request. This way you can ensure everything is alright before sending a pull request.

View File

@@ -1,3 +1,5 @@
#!/usr/bin/env bash
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved. # Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -37,7 +39,7 @@ python_3 'isort --profile black --length-sort --line-width 120 -c .' 'isort-outp
if [ $? == 0 ]; then if [ $? == 0 ]; then
echo 'isort succeeded!! 💖'; echo 'isort succeeded!! 💖';
else else
echo 'isort failed 😭'; echo 'isort FAILED! 😭';
echo 'Check isort-output.log for details'; echo 'Check isort-output.log for details';
restore_stashed; restore_stashed;
exit 1; exit 1;
@@ -48,7 +50,7 @@ python_3 'black -l 120 --check .' 'black-output.log';
if [ $? == 0 ]; then if [ $? == 0 ]; then
echo 'black succeeded!! 💝'; echo 'black succeeded!! 💝';
else else
echo 'black failed 😭'; echo 'black FAILED! 😭';
echo 'Check black-output.log for details'; echo 'Check black-output.log for details';
restore_stashed; restore_stashed;
exit 2; exit 2;
@@ -59,24 +61,26 @@ python ./scripts/lint.py ./rules/ > rule-linter-output.log 2>&1;
if [ $? == 0 ]; then if [ $? == 0 ]; then
echo 'Rule linter succeeded!! 💘'; echo 'Rule linter succeeded!! 💘';
else else
echo 'Rule linter failed 😭'; echo 'Rule linter FAILED! 😭';
echo 'Check rule-linter-output.log for details'; echo 'Check rule-linter-output.log for details';
restore_stashed; restore_stashed;
exit 3; exit 3;
fi fi
# Run tests # Run tests except if first argument is no_tests
echo 'Running tests, please wait ⌛'; if [ "$1" != 'no_tests' ]; then
pytest tests/ --maxfail=1; echo 'Running tests, please wait ⌛';
if [ $? == 0 ]; then pytest tests/ --maxfail=1;
echo 'Tests succeed!! 🎉'; if [ $? == 0 ]; then
else echo 'Tests succeed!! 🎉';
echo 'Tests failed 😓 PUSH ABORTED'; else
echo 'Run `pytest -v --cov=capa test/` if you need more details'; echo 'Tests FAILED! 😓';
restore_stashed; echo 'Run `pytest -v --cov=capa test/` if you need more details';
exit 4; restore_stashed;
exit 4;
fi
fi fi
echo 'PUSH SUCCEEDED 🎉🎉';
restore_stashed; restore_stashed;
echo 'SUCCEEDED 🎉🎉';

View File

@@ -1,59 +0,0 @@
# Copyright (C) 2020 FireEye, Inc. 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: [package root]/LICENSE.txt
# 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.
# Use a console with emojis support for a better experience
# Stash uncommited changes
MSG="post-commit-$(date +%s)";
git stash push -kum "$MSG" &>/dev/null ;
STASH_LIST=$(git stash list);
if [[ "$STASH_LIST" == *"$MSG"* ]]; then
echo "Uncommited changes stashed with message '$MSG', if you abort before they are restored run \`git stash pop\`";
fi
python_3() {
case "$(uname -s)" in
CYGWIN*|MINGW32*|MSYS*|MINGW*)
py -3 -m $1 > $2 2>&1;;
*)
python3 -m $1 > $2 2>&1;;
esac
}
# Run isort and print state (it doesn't block the commit)
python_3 'isort --profile black --length-sort --line-width 120 -c .' 'isort-output.log';
if [ $? == 0 ]; then
echo 'isort succeeded!! 💖';
else
echo 'isort failed 😭';
echo 'Check isort-output.log for details';
fi
# Run black and print state (it doesn't block the commit)
python_3 'black -l 120 --check .' 'black-output.log';
if [ $? == 0 ]; then
echo 'black succeeded!! 💝';
else
echo 'black failed 😭';
echo 'Check black-output.log for details';
fi
# Run rule linter and print state (it doesn't block the commit)
python ./scripts/lint.py ./rules/ > rule-linter-output.log 2>&1;
if [ $? == 0 ]; then
echo 'Rule linter succeeded!! 💘';
else
echo 'Rule linter failed 😭';
echo 'Check rule-linter-output.log for details';
fi
# Restore stashed changes
if [[ "$STASH_LIST" == *"$MSG"* ]]; then
git stash pop --index &>/dev/null ;
echo "Stashed changes '$MSG' restored";
fi

View File

@@ -19,10 +19,10 @@ create_hook() {
if [[ ! -e .git/hooks/$1 ]]; then if [[ ! -e .git/hooks/$1 ]]; then
echo "#!/usr/bin/env bash" > ".git/hooks/$1"; echo "#!/usr/bin/env bash" > ".git/hooks/$1";
fi fi
cat scripts/hooks/"$1" >> ".git/hooks/$1"; echo "scripts/ci.sh ${2:-}" >> ".git/hooks/$1";
chmod +x .git/hooks/"$1"; chmod +x .git/hooks/"$1";
} }
printf 'Copying hooks into .git/hooks'; printf 'Adding scripts/ci.sh to .git/hooks/';
create_hook 'post-commit'; create_hook 'pre-commit' 'no_tests';
create_hook 'pre-push'; create_hook 'pre-push';