Initial commit

This commit is contained in:
Sven van Heugten 2026-02-20 15:55:21 +01:00
commit f87d6bd4c8
No known key found for this signature in database
GPG key ID: D612F88666F4F660
3 changed files with 134 additions and 0 deletions

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Sven van Heugten
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

51
README.md Normal file
View file

@ -0,0 +1,51 @@
# git-check-assertions
🚧 Merely a proof-of-concept right now.
I recently wrote two blogs posts arguing that there might be some value in writing verifiable claims, i.e. assertions, inside of our commit messages:
* [Should we start writing verifiable claims in commit message?](https://sven.memcmp.org/2026-02-19-should-we-start-writing-verifiable-claims-in-commit-messages/)
* [Writing the steps to validate a test in the commit message](https://sven.memcmp.org/2026-02-20-writing-the-steps-to-validate-a-test-in-the-commit-message/)
This is a simple verifier for such assertions.
You include a small bash script inside your commit messages, and `git-check-assertions` will then check out every commit (from the point that your branch diverged from `main`), and verify that the script in the commit message runs successfully.
⚠️ Only run this on repositories and branches that you trust, since the `bash` scripts in the commit messages can do whatever they want.
## Examples of commit messages
Assert that a commit builds:
~~~
```git-check-assertions
dotnet build
```
~~~
Assert that a commit builds and that the tests succeed:
~~~
```git-check-assertions
dotnet build
dotnet test --no-build
```
~~~
Assert that a commit builds, but that the tests do not succeed (`assert_fails` is a helper function included in `git-check-assertions`):
~~~
```git-check-assertions
dotnet build
assert_fails dotnet test --no-build
```
~~~
Assert that a commit builds, and that the tests fail with exactly the error that you expect:
~~~
```git-check-assertions
dotnet build
(assert_fails dotnet test --no-build) | grep "Invalid URL"
```
~~~

62
git-check-assertions.sh Executable file
View file

@ -0,0 +1,62 @@
#!/usr/bin/env bash
# Copyright (c) 2026 Sven van Heugten
#
# Repository: https://codeberg.org/svenvanheugten/git-check-assertions
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
set -euo pipefail
assert_fails() {
! "$@" || { echo "Expected command to fail, but it succeeded."; exit 1; }
}
export -f assert_fails
orig_ref="$(git symbolic-ref --quiet --short HEAD || git rev-parse HEAD)"
base="$(git merge-base main HEAD)"
mapfile -t commits < <(git rev-list --reverse "${base}..HEAD")
echo "Base: $base"
echo "Commits to visit: ${#commits[@]}"
echo
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")"
block="$(printf '%s\n' "$commit_msg" \
| sed -n '/^```git-check-assertions[[:space:]]*$/,/^```[[:space:]]*$/p' \
| sed '1d;$d')"
if [ -n "$block" ]; then
echo "git-check-assertions block in $commit_hash:"
printf '%s\n' "$block" | sed 's/^/> /'
if ! bash -euo pipefail -c "$block"; then
echo "git-check-assertions block failed in $commit_hash" >&2
echo "Returning to $orig_ref"
git checkout -q "$orig_ref"
exit 1
fi
fi
echo
done
echo
echo "Returning to $orig_ref"
git checkout -q "$orig_ref"