Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

All flags redeemed #20

Merged
merged 11 commits into from
Jan 8, 2024
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# What is this?

This is the (WIP) script for creating a `git` challenge. To create a local "playable" copy run `./create_challenge.sh`. The challenge itself is only in the then created folder "challenge" and NOT in this repository. Do NOT look around in this repository unless you want to develop this challenge, because otherwise you will be spoiled with the solutions ;)
This is the (WIP) script for creating an interactive `git` repo that is a completely self-contained `git` tutorial. To create a local "playable" copy run `./create_challenge.sh`. The challenge itself is only in the then created folder "challenge" and NOT in this repository. Do NOT look around in this repository unless you want to develop this challenge, because otherwise you will be spoiled with the solutions ;)


## testing
Expand Down
26 changes: 22 additions & 4 deletions create_challenge.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,25 @@ fi
. ./src/redeem.nuggit >/dev/null 2>&1

LOCAL_CODE_EXECUTION_HASH="$(success "LocalCodeExecution" | git hash-object --stdin)"
NUMBER_OF_NUGGITS="$(wc -l <"$DOCDIR/nuggits")"

# initial setup

# TODO: figure out how to use --template="$DOCDIR/01_init"
git init --initial-branch=main challenge
initial_branch=main
git init --initial-branch="$initial_branch" challenge
cd challenge
reproducibility_setup

cp "$DOCDIR/01_init/"* .
# Create an empty commit and delete it, so that our own nuggits "branch" can reference the empty tree
# TODO: figure out how to create a tree object without interacting with the index
commit --allow-empty -m "RootOfAllNuggits

Have a free nuggit!"
# pretend this was done in our manually managed nuggits "branch" instead
mv ".git/refs/heads/$initial_branch" ".git/nuggits"

cp -r "$DOCDIR/01_init/"* .
cp "$DOCDIR/01_init/.gitignore" .
git add .
commit -m "Initial Commit"
Expand Down Expand Up @@ -103,8 +113,16 @@ 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" .
# nuggits
# TODO: once we have the origin and another "clone" in the .git folder, we should store the blobs in there, because it is trivial to list all of them with `git fsck --dangling | cut -d " " -f3 | xargs -n 1 git cat-file -p`
eval "$DOCDIR/store_nuggits.sh" # register the nuggits in our "git database" (aka some loose objects)
ALMOST_CREDITS_HASH="$(git hash-object -w "$DOCDIR/almost_credits.txt")"
# for the final credits do a little rot13, just to make life a bit harder if anyone e.g. greps through the loose objects...
CREDITS_HASH="$(tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$DOCDIR/credits.txt" | git hash-object -w --stdin)"

replace_placeholders "$DOCDIR/redeem.nuggit" > ./redeem.nuggit
chmod +x ./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 Down
3 changes: 3 additions & 0 deletions lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ reproducibility_setup() {
replace_placeholders() {
sed -e "s/INTERACTIVE_REBASE_BASE_COMMIT/$INTERACTIVE_REBASE_BASE_COMMIT/" \
-e "s/BRANCH_COMMIT/$BRANCH_COMMIT/" \
-e "s/NUMBER_OF_NUGGITS/$NUMBER_OF_NUGGITS"/ \
-e "s/ALMOST_CREDITS_HASH/$ALMOST_CREDITS_HASH"/ \
-e "s/CREDITS_HASH/$CREDITS_HASH"/ \
-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"
Expand Down
3 changes: 3 additions & 0 deletions src/01_init/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ By default in most Projects there exists a README file, so with opening this fil
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: Where do I see all my redeemed nuggits?
A: Just run `git log nuggits` :)

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).

Expand Down
3 changes: 3 additions & 0 deletions src/almost_credits.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
You almost got it! There is only a single flag left to redeem...

Try to find it and you are sure you looked everywhere without success: sometimes even the very first steps you take can put you on a path that is already lost... 😉
7 changes: 7 additions & 0 deletions src/credits.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
You have found all the little nuggits?! Very impressive!!! 🥳

I mean most of them where quite findable, but if you solved it you know that one flag that was indeed a bit "slippery" and hard to get a grip on, right!? You have to tell me: did you get it first try? And how did it came to your mind to look there? Generally: I would like to hear from you!

Thanks to everyone who taught me about git - especially 🐢 who taught me about the workflows and gave me a solid understanding of the core concepts of it. You seem to have that, too, so go for it! The sky is the limit!

Are you interested in how this was created? Then take a look at https://github.com/miallo/nuggit and maybe even contribute a bit with your awesome skills 😉
2 changes: 1 addition & 1 deletion src/nuggits
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ LocalCodeExecution
WorkInProgress
CommitmentIssues
CommitMirInsAbendteuerland
LocalCodeExecution
Switcheridoo
ShowMeMore
MyFirstBranch
LogCat
AnnotateMeIfYouCan
CuriosityKilledTheCat
27 changes: 27 additions & 0 deletions src/redeem.nuggit
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
# This file is not really intended for you to look into too much - but I like how curious you are, so here is a nuggit for you: CuriosityKilledTheCat

nuggit="$1"

Expand All @@ -16,6 +17,18 @@ else
exit
fi

already_redeemed=0
git cat-file -e "$(echo "'$nuggit' already redeemed" | git hash-object --stdin)" 2>/dev/null && already_redeemed=1
redeemed_nuggits="$(git rev-list --count nuggits)"
redeemed_nuggits=$((redeemed_nuggits - already_redeemed))

[ "$redeemed_nuggits" -ne $((NUMBER_OF_NUGGITS - 1 )) ] || git cat-file -p ALMOST_CREDITS_HASH;

[ "$redeemed_nuggits" -ne $(( NUMBER_OF_NUGGITS + 0 )) ] || {
git cat-file -e "$(echo "# Redeemed nuggits: $((NUMBER_OF_NUGGITS - 1))" | git hash-object --stdin)" 2>/dev/null || { echo Noughty boy!; exit 1; }
git cat-file -p CREDITS_HASH | tr 'A-Za-z' 'N-ZA-Mn-za-m';
}

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

Expand All @@ -24,5 +37,19 @@ else
echo "You tried '$nuggit' before. It still isn't a valid answer... 🙄" | git hash-object --stdin -w >/dev/null 2>&1
exit 1
}

commit_nuggit() { # Manage our own little "branch" manually
local tree
# get the tree object from the last commit in nuggits
tree="$(git show --format="%T" nuggits)"
# add an empty commit with the parent being nuggits and "reset nuggits to that new commit"
git commit-tree "$tree" -p "$(cat .git/nuggits)" -m "$1" > .git/nuggits.bak
# We can't directly pipe it into the file, because it will empty it before we read it...
mv .git/nuggits.bak .git/nuggits
}
commit_nuggit "$nuggit"

echo "Number of redeemed nuggits: $redeemed_nuggits"
echo "# Redeemed nuggits: $redeemed_nuggits" | git hash-object --stdin -w >/dev/null 2>&1
echo "'$nuggit' already redeemed" | git hash-object --stdin -w >/dev/null 2>&1
fi
17 changes: 17 additions & 0 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,20 @@ echo "Building..."
./create_challenge.sh >/dev/null 2>&1
cd challenge

check_redeem_without_local_code_execution() {
while read -r nuggit; do
[ "$nuggit" != LocalCodeExecution ] || continue
[ "$nuggit" != WorkInProgress ] || continue # we want to do this after all the others, so we see that this is the first time that the "You almost got it" text is shown
expect "./redeem.nuggit '$nuggit'" not to contain "You almost got it"
done < "$DOCDIR/nuggits"
expect "./redeem.nuggit WorkInProgress" to contain "You almost got it! There is only a single flag left to redeem..."
expect "./redeem.nuggit WorkInProgress" to contain "You almost got it! There is only a single flag left to redeem..."
}

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"
check_redeem_without_local_code_execution
'

echo "Building once more..."
Expand Down Expand Up @@ -90,8 +101,14 @@ expect "! ./redeem.nuggit NotANuggit 2>&1" to contain "Unfortunately that is not
expect "! ./redeem.nuggit NotANuggit 2>&1" to contain "It still isn'\''t a valid answer..."
'

it 'CuriosityKilledTheCat in redeem script' '
expect "cat redeem.nuggit" to contain CuriosityKilledTheCat
redeem_nuggit CuriosityKilledTheCat
'

check_redeem() {
while read -r nuggit; do
expect "./redeem.nuggit '$nuggit'" to contain "You have found all the little nuggits?! Very impressive!"
expect "./redeem.nuggit '$nuggit'" to contain "already redeemed"
expect "./redeem.nuggit '$nuggit'" not to contain Success
done < "$DOCDIR/nuggits"
Expand Down