diff --git a/build.sh b/build.sh index 2d9461d..abd9736 100755 --- a/build.sh +++ b/build.sh @@ -60,9 +60,9 @@ ALMOST_CREDITS_HASH="$(git hash-object -w "$DOCDIR/almost_credits.txt")" FINAL_CREDITS_HASH="$(tr 'A-Za-z' 'N-ZA-Mn-za-m' < "$DOCDIR/credits.txt" | git hash-object -w --stdin)" CREDITS_TREE="$(printf "100644 blob %s almost\n100644 blob %s final\n" "$ALMOST_CREDITS_HASH" "$FINAL_CREDITS_HASH" | git mktree)" -NUMBER_OF_NUGGITS="$(wc -l <"$DOCDIR/nuggits")" +NUMBER_OF_NUGGITS="$(($(wc -l <"$DOCDIR/nuggits.tsv")))" -replace NUMBER_OF_NUGGITS CREDITS_TREE NUGGIT_DESCRIPTION_TREE "$DOCDIR/redeem-nuggit.sh" > ./.git/redeem.nuggit +replace NUMBER_OF_NUGGITS CREDITS_TREE NUGGIT_DESCRIPTION_TREE "$DOCDIR/redeem-nuggit.sh" | sed -e 's/\s*# .*$//' -e '/^[[:space:]]*$/d' > ./.git/redeem.nuggit chmod a=rx ./.git/redeem.nuggit # ------------------------------------------------------------------------------------------- # diff --git a/lib.sh b/lib.sh index 240ac37..c51ef20 100644 --- a/lib.sh +++ b/lib.sh @@ -122,7 +122,7 @@ store_nuggits() { fi # piped into mktree, this creates a sub-folder in general one with the name of the hashed nuggit to avoid easy discovery printf "40000 tree %s %s\n" "$description_tree_hash" "$nuggit_folder_name" - done < "$DOCDIR/nuggits"))" + done < "$DOCDIR/nuggits.tsv"))" LOCAL_CODE_EXECUTION_HASH="$(cat tmp)" rm tmp } diff --git a/src/nuggits b/src/nuggits.tsv similarity index 100% rename from src/nuggits rename to src/nuggits.tsv diff --git a/src/redeem-nuggit.sh b/src/redeem-nuggit.sh index d21ae9f..ccc1727 100755 --- a/src/redeem-nuggit.sh +++ b/src/redeem-nuggit.sh @@ -1,12 +1,14 @@ #!/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 +#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: +#nuggit: CuriosityKilledTheCat +# +#Note for developers: comments starting with "#" and empty lines are +#stripped from the build version to make reverse engineering this just a tiny +#bit harder ;) nuggit="$1" -already_redeemed() { - echo "'$1' already redeemed" -} - if [ -z "$nuggit" ]; then echo "no nuggit passed in..." >&2 echo "Usage: \`$0 TestNuggit\`" >&2 @@ -18,41 +20,65 @@ if [ "$nuggit" = TestNuggit ]; then exit fi -already_redeemed=0 -git cat-file -e "$(already_redeemed "$nuggit" | git hash-object --stdin)" 2>/dev/null && already_redeemed=1 -redeemed_nuggits="$(git rev-list --count nuggits)" -redeemed_nuggits=$((redeemed_nuggits - already_redeemed)) +already_redeemed="'$nuggit' already redeemed" +tried_before="You tried '$nuggit' before. It still isn't a valid answer... 🙄" + +redeemed=0 +# check if this nuggit was already_redeemed +git cat-file -e "$(echo "$already_redeemed" | git hash-object --stdin)" 2>/dev/null && redeemed=1 +# The total number of nuggits is one bigger than the already committed ones +# because of the root commit, so we have to subtract 1 if this one was already +# redeemed +redeemed_nuggits="$(($(git rev-list --count nuggits) - redeemed))" -[ "$redeemed_nuggits" -ne $((NUMBER_OF_NUGGITS - 1 )) ] || git cat-file -p CREDITS_TREE:almost; +# For the second last nuggit we want to show a hint that one is still missing +# to give a hint that LocalCodeExecution is self-deleting. +# CREDITS_TREE is a tree-object and CREDITS_TREE:almost means the blob with the +# name "almost" inside of it +[ "$redeemed_nuggits" -ne $((NUMBER_OF_NUGGITS - 1)) ] || git cat-file -p CREDITS_TREE:almost; -[ "$redeemed_nuggits" -ne $(( NUMBER_OF_NUGGITS + 0 )) ] || { - git cat-file -e "$(git hash-object --stdin <<< "$((NUMBER_OF_NUGGITS - 1))" | git hash-object --stdin)" 2>/dev/null || { echo Noughty boy!; exit 1; } +# shellcheck disable=2170 # NUMBER_OF_NUGGITS will be replaced by an integer, once we "build" it. +[ "$redeemed_nuggits" -ne NUMBER_OF_NUGGITS ] || { + # check if the player did not just add a commit to our "nuggits" + # pseudobranch by looking up if we wrote the last number of redeemed + # nuggits to the objects. This is just a very basic "cheat-detection"... + git cat-file -e "$(git hash-object --stdin <<< "$((NUMBER_OF_NUGGITS - 1))" | git hash-object --stdin)" 2>/dev/null || { echo Naughty boy!; exit 1; } + # print the final credits. See "almost" above for syntax description + # Also do rot13 on the result in order to make it just a bit harder to just + # find the blob and read it git cat-file -p CREDITS_TREE:final | tr 'A-Za-z' 'N-ZA-Mn-za-m'; } -git cat-file -p "$(already_redeemed "$nuggit" | 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 +# if we already have redeemed this nuggit, print that it was already redeemed and exit +git cat-file -p "$(echo "$already_redeemed" | git hash-object --stdin)" 2>/dev/null && exit +# if the user already tried to submit this wrong string, print the error and exit +git cat-file -p "$(echo "$tried_before" | git hash-object --stdin)" 2>/dev/null && exit 1 +# Print the success message for this nuggit if it exists git cat-file -p "NUGGIT_DESCRIPTION_TREE:$(echo "$nuggit" | git hash-object --stdin)/success" 2>/dev/null || { + # if it does not exist, then this is not a valid nuggit (or it was + # LocalCodeExecution and that was deleted) 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 + echo "$tried_before" | 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 rev-parse "nuggits^{tree}")" - description="$(git cat-file -p "NUGGIT_DESCRIPTION_TREE:$(echo "$1" | git hash-object --stdin)/description")" - # 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 - -$description" > .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" +# Manage our own little "branch" manually + +# get the tree object from the last commit in nuggits +tree="$(git rev-parse "nuggits^{tree}")" +# get the description from our "nuggit tree object" from the folder with +# the hash of the nuggit and inside of that the description file +description="$(git cat-file -p "NUGGIT_DESCRIPTION_TREE:$(echo "$nuggit" | git hash-object --stdin)/description")" +# 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 "$(printf "%s\n\n" "$nuggit" "$description")" > .git/nuggits.bak +# We can't directly pipe it into the file, because it will empty it before we read it... +# Therefore write it into a backup file and then replace it +mv .git/nuggits.bak .git/nuggits # update our "branch" -echo "Number of redeemed nuggits: $redeemed_nuggits of $((NUMBER_OF_NUGGITS))" -already_redeemed "$nuggit" | git hash-object --stdin -w >/dev/null 2>&1 +# Print some stats for the player, so they know if they still need to look for other nuggits +echo "Number of redeemed nuggits: $redeemed_nuggits of NUMBER_OF_NUGGITS" +# Write to our database, that this nuggit is now redeemed +echo "$already_redeemed" | git hash-object --stdin -w >/dev/null 2>&1 +# Write as a "cheat-detection" for the final credits how many we have redeemed git hash-object --stdin <<< "$redeemed_nuggits"| git hash-object --stdin -w >/dev/null 2>&1 diff --git a/test.sh b/test.sh index 7b81cf7..ac1beff 100755 --- a/test.sh +++ b/test.sh @@ -24,7 +24,7 @@ check_redeem_without_local_code_execution() { [ "$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 "git redeem-nuggit '$nuggit'" not to contain "You almost got it" - done < "$DOCDIR/nuggits" + done < "$DOCDIR/nuggits.tsv" # the second last nuggit should show the "Almost got it" text and resubmitting should show the same expect "git redeem-nuggit WorkInProgress" to contain "You almost got it! There is only a single nuggit left to redeem..." expect "git redeem-nuggit WorkInProgress" to contain "You almost got it! There is only a single nuggit left to redeem..." @@ -174,7 +174,7 @@ check_redeem() { expect "git redeem-nuggit '$nuggit'" to contain "already redeemed" expect "git redeem-nuggit '$nuggit'" not to contain Success expect "git log nuggits" to contain "$nuggit" - done < "$DOCDIR/nuggits" + done < "$DOCDIR/nuggits.tsv" } it 'All nuggits should be redeemed at the end of the test' check_redeem