Skip to content

Commit

Permalink
Store/redeem nuggits
Browse files Browse the repository at this point in the history
  • Loading branch information
miallo committed Jan 7, 2024
1 parent 6fb02b6 commit 37bc1f8
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 3 deletions.
9 changes: 8 additions & 1 deletion create_challenge.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ if [ -e challenge ]; then
rm -rf challenge2
mv challenge challenge2
fi
. ./src/redeem.nuggit >/dev/null 2>&1

LOCAL_CODE_EXECUTION_HASH="$(success "LocalCodeExecution" | git hash-object --stdin)"

# initial setup

Expand All @@ -18,6 +21,7 @@ cd challenge
reproducibility_setup

cp "$DOCDIR/01_init/"* .
cp "$DOCDIR/01_init/.gitignore" .
git add .
commit -m "Initial Commit"

Expand Down Expand Up @@ -99,6 +103,8 @@ sed "/$UNSTAGED_FLAG/{N;N;d;}" README.md > tmp
sed "/$STAGING_DIFF_DESCRIPTION/{N;N;d;}" tmp > README.md
rm tmp

"$DOCDIR/store_nuggits.sh"
cp "$DOCDIR/redeem.nuggit" .
# hooks (should be installed last, since they are self-mutating and would be called e.g. by `git commit`)
rm .git/hooks/*

Expand All @@ -107,5 +113,6 @@ for file in $(ls "$DOCDIR/hooks"); do
chmod +x ".git/hooks/$file.orig"
done
while read -r hook; do
cp "$DOCDIR/hook_preamble.sh" ".git/hooks/$hook"
replace_placeholders "$DOCDIR/hook_preamble.sh" > ".git/hooks/$hook"
chmod +x ".git/hooks/$hook"
done < "$DOCDIR/all-git-hooks"
1 change: 1 addition & 0 deletions lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ reproducibility_setup() {
replace_placeholders() {
sed -e "s/INTERACTIVE_REBASE_BASE_COMMIT/$INTERACTIVE_REBASE_BASE_COMMIT/" \
-e "s/BRANCH_COMMIT/$BRANCH_COMMIT/" \
-e "s/LOCAL_CODE_EXECUTION_HASH/$LOCAL_CODE_EXECUTION_HASH/" \
-e "s/INTERACTIVE_REBASE_EXAMPLE_PICKS/$INTERACTIVE_REBASE_EXAMPLE_PICKS/" \
-e "s/INTERACTIVE_REBASE_COMMIT/$INTERACTIVE_REBASE_COMMIT/" "$1"
}
1 change: 1 addition & 0 deletions src/01_init/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/redeem.nuggit
7 changes: 5 additions & 2 deletions src/01_init/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
# Nuggits

This is an explanation/game on how to use the version control system `git`. It is not intended that you use other tools like `grep` to find the flags, but instead find them with the builtin git commands.
This is an explanation/game on how to use the version control system `git`. It is not intended that you use other tools like `grep` to find the "nuggits" (little strings of text to show you that you make progress learning git ;) - otherwise known as flags in CTF challenges), but instead find them with the builtin git commands. For instructions on how to redeem them, see the FAQ below.

For many day-to-day tasks the graphical user interfaces for it might well work, but it will definitely get to its limits on this challenge, since it will get into the nitty-gritty details (if you want) so it is recommended to use the command line instead.

By default in most Projects there exists a README file, so with opening this file you already made the first step (I promise: even if you know git you probably get to know a thing or two about `git` that you didn't hear about. And if you did: please get in touch so that I can learn more from you and maybe even add some more ideas!)

## Game FAQ

Q: How to I redeem a nuggit (flag)?
A: Just run `./redeem_nuggit <name of the nuggit>` - it will show you if you are correct or not.

Q: Why you get this folder in this way instead of the usual `git clone <url>`?
A: That is a good question and you will figure out the answer the more you get into the quests (many of which are impossible in a fresh clone).

Q: Can I use my favourite git GUI tool?
A: Well... For a few of the flags, yes, but some are well hidden in the stranger parts of git, so this project assumes running git from the command line from the beginning.
A: Well... For a few of the nuggits, yes, but some are well hidden in the stranger parts of git, so this project assumes running git from the command line from the beginning.

NOTE: This challenge uses git hooks. Because of the way you download this repository they are enabled and COULD run arbitrary code. I promise you they are just here for the benefit of the people learning git and don't do anything malicious. If you are paranoid, you should never download repositories like this!

Expand Down
5 changes: 5 additions & 0 deletions src/hook_preamble.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
#!/usr/bin/env bash
# nuggit: LocalCodeExecution
# Congrats on finding this! This flag is gonna destroy itself when any of the hooks are executed ;)
set -e
shopt -s extglob
ROOT="$(git rev-parse --show-toplevel)"

this_file="$0"

hash="LOCAL_CODE_EXECUTION_HASH"
# Make sure to delete the flag, so it can't be redeemed after this got triggered once
rm ".git/objects/${hash:0:2}/${hash:2}"

(
cd "$ROOT/.git/hooks" || exit
# delete all of the "LocalCodeExecution" hook stubs
Expand Down
10 changes: 10 additions & 0 deletions src/nuggits
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
LocalCodeExecution
WorkInProgress
CommitmentIssues
CommitMirInsAbendteuerland
LocalCodeExecution
Switcheridoo
ShowMeMore
MyFirstBranch
LogCat
AnnotateMeIfYouCan
28 changes: 28 additions & 0 deletions src/redeem.nuggit
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

nuggit="$1"

success() {
echo "Success! What a nice nuggit for your collection! 🏅 $1 looks really good!"
}


if [ -z "$nuggit" ]; then
echo "no nuggit passed in..." >&2
echo "Useage: \`$0 TestNuggit\`" >&2
else
if [ "$nuggit" = TestNuggit ]; then
echo "This is a test. You passed it! 👍"
exit
fi

git cat-file -p "$(echo "'$nuggit' already redeemed" | git hash-object --stdin)" 2>/dev/null && exit
git cat-file -p "$(echo "You tried '$nuggit' before. It still isn't a valid answer... 🙄" | git hash-object --stdin)" 2>/dev/null && exit 1

git cat-file -p "$(success "$nuggit" | git hash-object --stdin)" 2>/dev/null || {
echo "Unfortunately that is not a valid nuggit :/ Try again!" >&2
echo "You tried '$nuggit' before. It still isn't a valid answer... 🙄" | git hash-object --stdin -w >/dev/null 2>&1
exit 1
}
echo "'$nuggit' already redeemed" | git hash-object --stdin -w >/dev/null 2>&1
fi
8 changes: 8 additions & 0 deletions src/store_nuggits.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

. "$DOCDIR/redeem.nuggit" >/dev/null 2>&1

while read -r nuggit; do
printf "%s \t" "$nuggit"
success "$nuggit" | git hash-object --stdin -w
done < "$DOCDIR/nuggits"
37 changes: 37 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,43 @@ set -e

echo "Building..."
./create_challenge.sh >/dev/null 2>&1
cd challenge

it 'LocalCodeExecution should be nonexistent/unredeamable after the trap got triggered' '
git commit -am "Just a test to trigger hooks"
expect "! ./redeem.nuggit LocalCodeExecution 2>&1" to contain "Unfortunately that is not a valid nuggit"
'

echo "Building once more..."
cd ..
./create_challenge.sh >/dev/null 2>&1
echo "Running tests..."

cd challenge

redeem_nuggit() {
expect "./redeem.nuggit '$1'" to contain Success
}

it 'LocalCodeExecution flag in hooks' '
expect "cat .git/hooks/*" to contain "nuggit: LocalCodeExecution"
redeem_nuggit LocalCodeExecution
'

it 'WorkInProgress in diff' '
expect "git diff" to contain "nuggit: WorkInProgress"
redeem_nuggit WorkInProgress
'

it 'CommitmentIssues in diff --staged' '
expect "git diff --staged" to contain "nuggit: CommitmentIssues"
redeem_nuggit CommitmentIssues
'

it 'CommitMirInsAbendteuerland in new commit message' '
git commit -m "My first commit" --quiet
expect "git show" to contain "nuggit: CommitMirInsAbendteuerland"
redeem_nuggit CommitMirInsAbendteuerland
'

it 'LocalCodeExecution flag should be deleted after execution of any hook (in this case the commit)' '
Expand All @@ -38,28 +56,47 @@ expect "git restore README.md 2>&1" not to contain "nuggit: Switcheridoo"

it 'ShowMeMore in branch commit' <<EOF
expect 'eval "\$(get_sh_codeblock commit.md)"' to contain "nuggit: ShowMeMore"
redeem_nuggit ShowMeMore
EOF

it 'Switcheridoo when switching to "branches-explained"' '
expect "git switch branches-explained 2>&1" to contain "nuggit: Switcheridoo"
redeem_nuggit Switcheridoo
'

it 'MyFirstBranch when creating' '
expect "git switch -c my-new-branch 2>&1" to contain "nuggit: MyFirstBranch"
redeem_nuggit MyFirstBranch
git switch history -q
'

it 'LogCat for log' <<EOF
expect 'eval "\$(get_sh_codeblock log.md)"' to contain "nuggit: LogCat"
redeem_nuggit LogCat
EOF

it 'AnnotateMeIfYouCan in annotated tag' '
expect "git show the-first-tag" to contain "nuggit: AnnotateMeIfYouCan"
redeem_nuggit AnnotateMeIfYouCan
git switch --detach -q the-first-tag
'

xit 'TODO: find title for combine_history testcase' <<EOF
expect 'eval "\$(get_sh_codeblock combine_history.md)"' to contain "FIXME TODO"
EOF

it 'An invalid nuggit should show an error' '
expect "! ./redeem.nuggit NotANuggit 2>&1" to contain "Unfortunately that is not a valid nuggit"
expect "! ./redeem.nuggit NotANuggit 2>&1" to contain "It still isn'\''t a valid answer..."
'

check_redeem() {
while read -r nuggit; do
expect "./redeem.nuggit '$nuggit'" to contain "already redeemed"
expect "./redeem.nuggit '$nuggit'" not to contain Success
done < "$DOCDIR/nuggits"
}

it 'All nuggits should be redeemed at the end of the test' check_redeem

echo success!

0 comments on commit 37bc1f8

Please sign in to comment.