Merge pull request 'Add support for multiple git-check-assertions blocks in one commit message' (#16) from multiple-blocks into main
Reviewed-on: https://codeberg.org/svenvanheugten/git-check-assertions/pulls/16
This commit is contained in:
commit
ac6000d1ee
5 changed files with 77 additions and 11 deletions
|
|
@ -65,7 +65,7 @@ dotnet test --no-build
|
||||||
```
|
```
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
This script will be run with `set -euo pipefail`, and the commit will be considered correct if the script exits successfully.
|
This script will be run with `set -euo pipefail` on the version of the code that is in the commit, and the commit will be considered correct if the script exits successfully.
|
||||||
|
|
||||||
You can technically assert that a command fails by writing `! ... || exit 1`, or write assertions about a command's output by piping it to `grep`, but doing so won't lead to very useful error messages when things go wrong. To make those things easier, there are some helper functions included, which are inspired by [bats](https://github.com/bats-core/bats-core) and [bats-assert](https://github.com/bats-core/bats-assert):
|
You can technically assert that a command fails by writing `! ... || exit 1`, or write assertions about a command's output by piping it to `grep`, but doing so won't lead to very useful error messages when things go wrong. To make those things easier, there are some helper functions included, which are inspired by [bats](https://github.com/bats-core/bats-core) and [bats-assert](https://github.com/bats-core/bats-assert):
|
||||||
|
|
||||||
|
|
@ -77,6 +77,10 @@ You can technically assert that a command fails by writing `! ... || exit 1`, or
|
||||||
|
|
||||||
I'm considering taking `bats-assert` as a dependency, but for now, this very minimal set of functions with a similar interface should get you on your way.
|
I'm considering taking `bats-assert` as a dependency, but for now, this very minimal set of functions with a similar interface should get you on your way.
|
||||||
|
|
||||||
|
## Multiple blocks in one commit message
|
||||||
|
|
||||||
|
You can include multiple `git-check-assertions` blocks in a single commit message. When you do, each individual block will run with a 'fresh' version of the commit, in which all changes that you made in the previous block have been undone.
|
||||||
|
|
||||||
## Cache of successful commits
|
## Cache of successful commits
|
||||||
|
|
||||||
After a commit's assertions run successfully, `git-check-assertions` appends the commit hash to `.git-check-assertions-cache` in the repo root. On the next run, any commit listed there is skipped.
|
After a commit's assertions run successfully, `git-check-assertions` appends the commit hash to `.git-check-assertions-cache` in the repo root. On the next run, any commit listed there is skipped.
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,12 @@ set -euo pipefail
|
||||||
# helper functions inspired by bats/bats-assert
|
# helper functions inspired by bats/bats-assert
|
||||||
run() {
|
run() {
|
||||||
set +e
|
set +e
|
||||||
output="$("$@" 2>&1)"
|
tmp_output="$(mktemp)"
|
||||||
status=$?
|
"$@" 2>&1 | tee "$tmp_output"
|
||||||
|
status=${PIPESTATUS[0]}
|
||||||
set -e
|
set -e
|
||||||
|
output="$(cat "$tmp_output")"
|
||||||
|
rm -f "$tmp_output"
|
||||||
printf '%s\n' "$output"
|
printf '%s\n' "$output"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
@ -106,13 +109,15 @@ for commit_hash in "${commits[@]}"; do
|
||||||
echo "Checking out $commit_hash"
|
echo "Checking out $commit_hash"
|
||||||
git -c advice.detachedHead=false checkout -q "$commit_hash"
|
git -c advice.detachedHead=false checkout -q "$commit_hash"
|
||||||
commit_msg="$(git log -1 --format=%B "$commit_hash")"
|
commit_msg="$(git log -1 --format=%B "$commit_hash")"
|
||||||
# shellcheck disable=SC2016
|
mapfile -d '' -t blocks < <(
|
||||||
block="$(printf '%s\n' "$commit_msg" |
|
printf '%s\n' "$commit_msg" |
|
||||||
sed -n '/^```git-check-assertions[[:space:]]*$/,/^```[[:space:]]*$/p' |
|
perl -0777 -ne 'while (/^```git-check-assertions\s*\n(.*?)^```\s*$/msg){ print $1, "\0" }'
|
||||||
sed '1d;$d')"
|
)
|
||||||
if [ -n "$block" ]; then
|
block_num=0
|
||||||
echo "git-check-assertions block in $commit_hash:"
|
for block in "${blocks[@]}"; do
|
||||||
printf '%s\n' "$block" | sed 's/^/> /'
|
block_num=$((block_num + 1))
|
||||||
|
echo "git-check-assertions block $block_num:"
|
||||||
|
printf '%s' "$block" | sed 's/^/> /'
|
||||||
if ! bash -euo pipefail -c "$block"; then
|
if ! bash -euo pipefail -c "$block"; then
|
||||||
echo "git-check-assertions block failed in $commit_hash" >&2
|
echo "git-check-assertions block failed in $commit_hash" >&2
|
||||||
restore
|
restore
|
||||||
|
|
@ -121,7 +126,8 @@ for commit_hash in "${commits[@]}"; do
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
restore
|
restore
|
||||||
fi
|
git -c advice.detachedHead=false checkout -q "$commit_hash"
|
||||||
|
done
|
||||||
printf '%s\n' "$commit_hash" >>.git-check-assertions-cache
|
printf '%s\n' "$commit_hash" >>.git-check-assertions-cache
|
||||||
echo
|
echo
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
gitMinimal,
|
gitMinimal,
|
||||||
resholve,
|
resholve,
|
||||||
shfmt,
|
shfmt,
|
||||||
|
perl,
|
||||||
|
coreutils,
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
@ -40,6 +42,8 @@ resholve.mkDerivation {
|
||||||
]))
|
]))
|
||||||
gitMinimal
|
gitMinimal
|
||||||
shfmt
|
shfmt
|
||||||
|
perl
|
||||||
|
coreutils
|
||||||
];
|
];
|
||||||
|
|
||||||
checkPhase = ''
|
checkPhase = ''
|
||||||
|
|
@ -66,6 +70,8 @@ resholve.mkDerivation {
|
||||||
gitMinimal
|
gitMinimal
|
||||||
gnused
|
gnused
|
||||||
bash
|
bash
|
||||||
|
perl
|
||||||
|
coreutils
|
||||||
];
|
];
|
||||||
execer = [
|
execer = [
|
||||||
# Not true at all, but ¯\_(ツ)_/¯
|
# Not true at all, but ¯\_(ツ)_/¯
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@
|
||||||
p.bats-support
|
p.bats-support
|
||||||
p.bats-file
|
p.bats-file
|
||||||
]))
|
]))
|
||||||
|
pkgs.perl
|
||||||
pkgs.shfmt
|
pkgs.shfmt
|
||||||
|
pkgs.coreutils
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,54 @@ commit_with_assertion() {
|
||||||
assert_output "feature"
|
assert_output "feature"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "multiple git-check-assertions blocks in one commit message run in order" {
|
||||||
|
git checkout -b feature
|
||||||
|
git commit --allow-empty -F - <<-EOF
|
||||||
|
test
|
||||||
|
|
||||||
|
\`\`\`git-check-assertions
|
||||||
|
touch ../test1
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`git-check-assertions
|
||||||
|
touch ../test2
|
||||||
|
\`\`\`
|
||||||
|
EOF
|
||||||
|
|
||||||
|
run git-check-assertions
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
assert_output --partial "git-check-assertions block 1:"
|
||||||
|
assert_output --partial "git-check-assertions block 2:"
|
||||||
|
assert_file_exists ../test1
|
||||||
|
assert_file_exists ../test2
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "should restore the commit between assertion blocks in one commit message" {
|
||||||
|
git checkout -b feature
|
||||||
|
echo old >readme
|
||||||
|
git add readme
|
||||||
|
git commit -m "old"
|
||||||
|
|
||||||
|
echo new >readme
|
||||||
|
git add readme
|
||||||
|
git commit -F - <<-EOF
|
||||||
|
update
|
||||||
|
|
||||||
|
\`\`\`git-check-assertions
|
||||||
|
git checkout HEAD~
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
\`\`\`git-check-assertions
|
||||||
|
grep new readme
|
||||||
|
\`\`\`
|
||||||
|
EOF
|
||||||
|
|
||||||
|
run git-check-assertions
|
||||||
|
|
||||||
|
assert_success
|
||||||
|
}
|
||||||
|
|
||||||
@test "should stop at the first failing assertion block and return to the original branch" {
|
@test "should stop at the first failing assertion block and return to the original branch" {
|
||||||
git checkout -b feature
|
git checkout -b feature
|
||||||
commit_with_assertion "touch ../test1 && exit 3"
|
commit_with_assertion "touch ../test1 && exit 3"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue