diff --git a/bin/git-check-assertions b/bin/git-check-assertions index 24bbfdf..11e0b44 100755 --- a/bin/git-check-assertions +++ b/bin/git-check-assertions @@ -106,11 +106,11 @@ for commit_hash in "${commits[@]}"; do echo "Checking out $commit_hash" git -c advice.detachedHead=false checkout -q "$commit_hash" commit_msg="$(git log -1 --format=%B "$commit_hash")" - # shellcheck disable=SC2016 - block="$(printf '%s\n' "$commit_msg" | - sed -n '/^```git-check-assertions[[:space:]]*$/,/^```[[:space:]]*$/p' | - sed '1d;$d')" - if [ -n "$block" ]; then + mapfile -d '' -t blocks < <( + printf '%s\n' "$commit_msg" | + perl -0777 -ne 'while (/^```git-check-assertions\s*\n(.*?)^```\s*$/msg){ print $1, "\0" }' + ) + for block in "${blocks[@]}"; do echo "git-check-assertions block in $commit_hash:" printf '%s\n' "$block" | sed 's/^/> /' if ! bash -euo pipefail -c "$block"; then @@ -121,7 +121,7 @@ for commit_hash in "${commits[@]}"; do exit 1 fi restore - fi + done printf '%s\n' "$commit_hash" >>.git-check-assertions-cache echo done diff --git a/default.nix b/default.nix index 12dcadf..4f9f1bd 100644 --- a/default.nix +++ b/default.nix @@ -9,6 +9,7 @@ gitMinimal, resholve, shfmt, + perl, }: let @@ -40,6 +41,7 @@ resholve.mkDerivation { ])) gitMinimal shfmt + perl ]; checkPhase = '' @@ -66,6 +68,7 @@ resholve.mkDerivation { gitMinimal gnused bash + perl ]; execer = [ # Not true at all, but ¯\_(ツ)_/¯ diff --git a/flake.nix b/flake.nix index e82af69..06dda90 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,7 @@ p.bats-support p.bats-file ])) + pkgs.perl pkgs.shfmt ]; }; diff --git a/test/git-check-assertions.bats b/test/git-check-assertions.bats index e706f41..8805d2f 100755 --- a/test/git-check-assertions.bats +++ b/test/git-check-assertions.bats @@ -124,6 +124,27 @@ commit_with_assertion() { 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_file_exists ../test1 + assert_file_exists ../test2 +} + @test "should stop at the first failing assertion block and return to the original branch" { git checkout -b feature commit_with_assertion "touch ../test1 && exit 3"