-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #24 from aaronjameslang/setup
Add `proofr setup` subcommand for end user ease
- Loading branch information
Showing
6 changed files
with
265 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#! /bin/sh --version | ||
set -eu | ||
|
||
if test 0 -eq "$#" | ||
then | ||
echo 'Read the README' | ||
exit 1 | ||
fi | ||
|
||
if test 'setup' = "$1" | ||
then | ||
setup | ||
exit | ||
fi | ||
|
||
commit_message_file="$1" | ||
|
||
cleanup_commit_message () { | ||
commit_message_file="$1" | ||
while read -r line | ||
do | ||
if test "$line" = '# ------------------------ >8 ------------------------' | ||
then | ||
return | ||
fi | ||
if test "$( echo "$line" | cut -c 1)" = '#' | ||
then | ||
continue | ||
fi | ||
echo "$line" | ||
done < "$commit_message_file" | ||
} | ||
|
||
commit_message="$(cleanup_commit_message "$commit_message_file")" | ||
commit_message_subject="$(echo "$commit_message" | head -n 1 )" | ||
commit_message_body="$(echo "$commit_message" | tail -n +2)" | ||
|
||
# Pass if message is empty, exit early | ||
test -z "$commit_message" && exit | ||
|
||
grep_subject() { | ||
echo "$commit_message_subject" | grep --quiet "$1" | ||
} | ||
|
||
if grep_subject '^Merge ' | ||
then | ||
is_merge=true | ||
else | ||
is_merge=false | ||
fi | ||
|
||
rule() { | ||
case $1 in | ||
1) echo Separate subject from body with a blank line ;; | ||
2) echo Limit the subject line to 50 characters ;; | ||
3) echo Capitalize the subject line ;; | ||
4) echo Do not end the subject line with a period ;; | ||
5) echo Use the imperative mood in the subject line ;; | ||
6) echo Wrap the body at 72 characters ;; | ||
7) echo Use the body to explain _what_ and _why_ vs. _how_ ;; | ||
esac | ||
} | ||
|
||
validate() { | ||
case $1 in | ||
1) # Message has one line, or second line is blank | ||
test -z "$(echo "$commit_message_body" | head -n 1)" ;; | ||
2) # Subject is no more than 51 characters (50 + newline) | ||
test 51 -ge ${#commit_message_subject} || | ||
$is_merge ;; | ||
3) # Subject does not begin with lowercase letter | ||
! grep_subject '^[a-z]' ;; | ||
4) # Subject does not end with a period | ||
$is_merge || ! grep_subject '\.\s*$' ;; | ||
5) # Subject does not begin with past tense | ||
! grep_subject '^\w*ed\s' ;; | ||
6) # Body does not contain line longer than 73 characters | ||
echo "$commit_message_body" | while read -r line | ||
do | ||
test 73 -ge "${#line}" || return 1 # TODO this return shouldn't be required | ||
done ;; | ||
esac | ||
} | ||
|
||
calc_error_code() { | ||
echo $((1<<$1)) | ||
} | ||
|
||
exit_code=0 | ||
|
||
for index in $(seq 6) | ||
do | ||
validate "$index" && continue | ||
rule "$index" | ||
error_code=$(calc_error_code "$index") | ||
exit_code=$(( exit_code + error_code )) | ||
done | ||
|
||
exit "$exit_code" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#! /bin/sh --version | ||
set -eu | ||
|
||
setup() { | ||
file='.git/hooks/commit-msg' | ||
if ( test -f "$file" && grep_for_proofr "$file" ) | ||
then | ||
echo 'proofr already setup' | ||
else | ||
echo "$0" '"$@" || exit $?' >> "$file" | ||
chmod u+x "$file" | ||
fi | ||
} | ||
|
||
grep_for_proofr () { | ||
grep --quiet '\bproofr\b' "$@" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#! /bin/sh --version | ||
set -eu | ||
|
||
# shellcheck source=lib/setup.sh | ||
. ../lib/setup.sh | ||
|
||
it_does_not_match_no_hook () { | ||
input='some-other-command --abc proofrun' | ||
actual="$(! echo "$input" | grep_for_proofr)" | ||
test -z "$actual" | ||
} | ||
|
||
it_matches_hook () { | ||
input='proofr "$@" || exit $?' | ||
actual="$(echo "$input" | grep_for_proofr)" | ||
test -z "$actual" | ||
} | ||
|
||
it_matches_other_hook () { | ||
# shellcheck disable=SC2016 | ||
input='command proofr "$1"' | ||
actual="$(echo "$input" | grep_for_proofr)" | ||
test -z "$actual" | ||
} | ||
|
||
it_sets_up_hook () { | ||
cd "$(mktemp -d proofr-test-XXXX)" | ||
git init | ||
file=".git/hooks/commit-msg" | ||
echo banana > "$file" | ||
../../bin/proofr setup | ||
actual="$(cat "$file")" | ||
expected='banana | ||
../../bin/proofr "$@" || exit $?' | ||
rm -rf "$PWD" | ||
cd - | ||
test "$expected" = "$actual" | ||
} | ||
|
||
it_sets_up_missing_hook () { | ||
cd "$(mktemp -d proofr-test-XXXX)" | ||
git init | ||
file=".git/hooks/commit-msg" | ||
rm -f "$file" | ||
test -d "$(dirname "$file")" | ||
! test -f "$file" | ||
../../bin/proofr setup | ||
test -x "$file" | ||
actual="$(cat "$file")" | ||
expected='../../bin/proofr "$@" || exit $?' | ||
rm -rf "$PWD" | ||
cd - | ||
test "$expected" = "$actual" | ||
} | ||
|
||
it_sets_up_exisiting_hook () { | ||
cd "$(mktemp -d proofr-test-XXXX)" | ||
git init | ||
file=".git/hooks/commit-msg" | ||
echo banana proofr > "$file" | ||
../../bin/proofr setup | ||
actual="$(cat "$file")" | ||
expected='banana proofr' | ||
rm -rf "$PWD" | ||
cd - | ||
test "$expected" = "$actual" | ||
} | ||
|
||
it_sets_up_hook_and_hook_works () { | ||
cd "$(mktemp -d proofr-test-XXXX)" | ||
git init | ||
PATH="$PWD/../../bin/:$PATH" | ||
rm -f .git/hooks/commit-msg | ||
proofr setup | ||
test -x .git/hooks/commit-msg | ||
git config user.name 'proofr test' | ||
git config user.email '[email protected]' | ||
actual="$(git commit --allow-empty --message 'Fix it')" | ||
echo "$actual" | grep --quiet '\[master (root-commit) [0-9a-f]\{7\}\] Fix it' | ||
actual="$(! git commit --allow-empty --message 'fixed it.' 2>&1)" | ||
test 'Capitalize the subject line | ||
Do not end the subject line with a period | ||
Use the imperative mood in the subject line' = "$actual" | ||
# test from a subdirectory | ||
mkdir fig | ||
cd fig | ||
git commit --allow-empty --message 'Fix it again' | ||
! git commit --allow-empty --message 'Fixed it again' | ||
cd ../.. | ||
rm -rf "proofr-test-*" | ||
} | ||
|
||
if echo "$0" | grep --quiet -v 'roundup' | ||
then | ||
it_matches_hook | ||
it_sets_up_hook | ||
it_matches_other_hook | ||
it_sets_up_missing_hook | ||
it_sets_up_exisiting_hook | ||
it_does_not_match_no_hook | ||
it_sets_up_hook_and_hook_works | ||
fi |