From 98cef5e9a772602d42acfcf233838c760424db9a Mon Sep 17 00:00:00 2001 From: Nicolas James Date: Thu, 13 Feb 2025 18:00:17 +1100 Subject: initial commit --- comp2041/tigger/test00.sh | 58 +++++++++++++++++++++++ comp2041/tigger/test01.sh | 53 +++++++++++++++++++++ comp2041/tigger/test02.sh | 73 +++++++++++++++++++++++++++++ comp2041/tigger/test03.sh | 56 ++++++++++++++++++++++ comp2041/tigger/test04.sh | 45 ++++++++++++++++++ comp2041/tigger/test05.sh | 46 ++++++++++++++++++ comp2041/tigger/test06.sh | 62 +++++++++++++++++++++++++ comp2041/tigger/test07.sh | 51 ++++++++++++++++++++ comp2041/tigger/test08.sh | 70 ++++++++++++++++++++++++++++ comp2041/tigger/test09.sh | 61 ++++++++++++++++++++++++ comp2041/tigger/tigger-add | 42 +++++++++++++++++ comp2041/tigger/tigger-branch | 68 +++++++++++++++++++++++++++ comp2041/tigger/tigger-checkout | 84 +++++++++++++++++++++++++++++++++ comp2041/tigger/tigger-commit | 88 +++++++++++++++++++++++++++++++++++ comp2041/tigger/tigger-init | 39 ++++++++++++++++ comp2041/tigger/tigger-log | 24 ++++++++++ comp2041/tigger/tigger-rm | 66 ++++++++++++++++++++++++++ comp2041/tigger/tigger-show | 63 +++++++++++++++++++++++++ comp2041/tigger/tigger-status | 100 ++++++++++++++++++++++++++++++++++++++++ 19 files changed, 1149 insertions(+) create mode 100755 comp2041/tigger/test00.sh create mode 100755 comp2041/tigger/test01.sh create mode 100755 comp2041/tigger/test02.sh create mode 100755 comp2041/tigger/test03.sh create mode 100755 comp2041/tigger/test04.sh create mode 100755 comp2041/tigger/test05.sh create mode 100755 comp2041/tigger/test06.sh create mode 100755 comp2041/tigger/test07.sh create mode 100755 comp2041/tigger/test08.sh create mode 100755 comp2041/tigger/test09.sh create mode 100755 comp2041/tigger/tigger-add create mode 100755 comp2041/tigger/tigger-branch create mode 100755 comp2041/tigger/tigger-checkout create mode 100755 comp2041/tigger/tigger-commit create mode 100755 comp2041/tigger/tigger-init create mode 100755 comp2041/tigger/tigger-log create mode 100755 comp2041/tigger/tigger-rm create mode 100755 comp2041/tigger/tigger-show create mode 100755 comp2041/tigger/tigger-status (limited to 'comp2041/tigger') diff --git a/comp2041/tigger/test00.sh b/comp2041/tigger/test00.sh new file mode 100755 index 0000000..b76f4a3 --- /dev/null +++ b/comp2041/tigger/test00.sh @@ -0,0 +1,58 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that removing the expected .tigger +# folder does reset the state of tigger. In addition, there should be NO extra +# files at the end of this operation, even if it fails. We are only allowed to +# edit/create .tigger and what is inside .tigger! + +num_files_before=$(find ./ | wc -l) +assert_good_exec "./tigger-init" +num_files_after=$(find ./ | wc -l) +assert_bad_exec "./tigger-init" # should make no more files +if [ "$(find ./ | wc -l)" -ne "$num_files_after" ]; then + printf "the amount of files should be equal to before when tigger-init was called previously!\n" >&2 + exit 1 +fi +rm -rf ./.tigger +if [ "$(find ./ | wc -l)" -ne "$num_files_before" ]; then + printf "there should be the same amount as files as before any commands were run!\n" >&2 + exit 1 +fi +assert_good_exec "./tigger-init" + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test01.sh b/comp2041/tigger/test01.sh new file mode 100755 index 0000000..246ed2a --- /dev/null +++ b/comp2041/tigger/test01.sh @@ -0,0 +1,53 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that all commands fail if a valid +# repository is not present (naturally aside from tigger-init). + +#assert_bad_exec "./tigger-init" +assert_bad_exec "./tigger-add" +assert_bad_exec "./tigger-commit" +assert_bad_exec "./tigger-log" +assert_bad_exec "./tigger-show" +assert_bad_exec "./tigger-commit" +assert_bad_exec "./tigger-rm" +assert_bad_exec "./tigger-status" +assert_bad_exec "./tigger-branch" +assert_bad_exec "./tigger-checkout" +assert_bad_exec "./tigger-merge" + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test02.sh b/comp2041/tigger/test02.sh new file mode 100755 index 0000000..461da82 --- /dev/null +++ b/comp2041/tigger/test02.sh @@ -0,0 +1,73 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that there are no arbitrary limits on +# the amount of times a command may be performed, and that file +# creation/deletion and increment logic is handled correctly between commits. +# It's possible that this fails due to bad increment handling at the radix +# point (if a program is implemented incorrectly). This test might also expose +# complexity issues if they are present. + +# Specifically we might use sort as opposed to sort -n, which works until 10. +# ... i did :( + +assert_good_exec "./tigger-init" +printf "adding and committing large number of files...\n" +for _ in $(seq 25); do + echo "repeated\n" >> repeated + assert_good_exec "./tigger-add repeated" > /dev/null + assert_good_exec "./tigger-commit -m placeholder" > /dev/null +done + +# Commit count should be 50 here! +printf "testing commit count string result\n" +printf "repeated\n" >> repeated +assert_good_exec "./tigger-add repeated" > /dev/null +if [ "$(./tigger-commit -m placeholder)" != "Committed as commit 25" ]; then + printf "bad commit count string\n" >&2 + exit 0 +fi + +# New one added so 26 now. +printf "testing tigger-log line count\n" +assert_good_exec "./tigger-log" > /dev/null +if [ "$(./tigger-log | wc --line)" -ne 26 ]; then + printf "bad tigger log string length\n" >&2 + exit 0 +fi + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test03.sh b/comp2041/tigger/test03.sh new file mode 100755 index 0000000..6ce8559 --- /dev/null +++ b/comp2041/tigger/test03.sh @@ -0,0 +1,56 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to test whether tigger-add handles a large number +# of filenames. Also tests tigger-status against a new, uncommitted repo. + +assert_good_exec "./tigger-init" +filenames=$(seq 20) +printf "adding large number of files...\n" +for filename in $filenames; do + touch "$filename" > /dev/null + assert_good_exec "./tigger-add $filename" > /dev/null +done + +# Test the length of tigger-status. +printf "testing tigger-status line count\n" +if [ "$(./tigger-status | wc --line)" -ge 100 ]; then + printf "bad tigger status line count\n" >&2 + exit 1 +fi + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test04.sh b/comp2041/tigger/test04.sh new file mode 100755 index 0000000..80f7b2e --- /dev/null +++ b/comp2041/tigger/test04.sh @@ -0,0 +1,45 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that it isn't possible to commit a +# binary file. (as specified, all files should be string-representable). + +assert_good_exec "./tigger-init" +dd if=/dev/zero of=zero bs=1c count=1 status=none # stack overflow make binary file +assert_bad_exec "./tigger-add a" >&2 + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test05.sh b/comp2041/tigger/test05.sh new file mode 100755 index 0000000..cc49cd1 --- /dev/null +++ b/comp2041/tigger/test05.sh @@ -0,0 +1,46 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that adding a file with spacebars +# results in an error. This is specified to not occur in the spec, but it should +# still be handled correctly. + +assert_good_exec "./tigger-init" +printf "placeholder contents" > "file name" +assert_bad_exec "./tigger-add "file name"" + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test06.sh b/comp2041/tigger/test06.sh new file mode 100755 index 0000000..33c93f6 --- /dev/null +++ b/comp2041/tigger/test06.sh @@ -0,0 +1,62 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that deleting a .tigger folder, and then +# restoring the folder, results in the same state that occurred before deletion. +# This implies that the metadata is held only in the .tigger directory. + +assert_good_exec "./tigger-init" +touch a +touch b +touch c +assert_good_exec "./tigger-add a b c" +echo a >> a +assert_good_exec "./tigger-add a" +touch d +assert_good_exec "./tigger-commit -m commit_message" +status=$(./tigger-status) +mv ./.tigger ./.tigger.old +assert_good_exec "./tigger-init" +rm -r ./.tigger +mv ./.tigger.old ./.tigger +printf "testing previous status is the same as the current status\n" +if [ "$(./tigger-status)" != "$status" ]; then + printf "tigger-status was not the same between copies\n" >&2 + exit 1 +fi + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test07.sh b/comp2041/tigger/test07.sh new file mode 100755 index 0000000..fdffb7c --- /dev/null +++ b/comp2041/tigger/test07.sh @@ -0,0 +1,51 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that calling ./tigger-status and +# tigger-log in an empty directory is not considered an error and results in +# empty output. + +assert_good_exec "./tigger-init" +assert_good_exec "./tigger-status" +assert_good_exec "./tigger-log" +printf "testing tigger status in an empty dir\n" +if [ "$(./tigger-status | grep -E -v "^tigger-*")" != "" ]; then # remove tigger-* files from output + printf "tigger-status was not empty in an empty dir\n" >&2 + exit 1 +fi + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test08.sh b/comp2041/tigger/test08.sh new file mode 100755 index 0000000..6d9116f --- /dev/null +++ b/comp2041/tigger/test08.sh @@ -0,0 +1,70 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that creating a new branch from an empty +# branch branches with multiple files with multiple commits and then deleting +# the branch results in the same status as an empty branch. + +# TODO CURRENTLY DOESNT FUNCTION BECAUSE CHECKOUT IS WRONG IN MY IMPLEMENTATION! + +printf "WARNING: DOESN'T FUNCTION DUE TO NON FULLY IMPLEMENTED CHECKOUT\n\n" + +assert_good_exec "./tigger-init" +touch z +assert_good_exec "./tigger-add z" +assert_good_exec "./tigger-commit -m commitmessage" +before_status=$(./tigger-status) +assert_good_exec "./tigger-branch new" +assert_good_exec "./tigger-checkout new" +touch a +touch b +assert_good_exec "./tigger-add a b" +assert_good_exec "./tigger-commit -m commitmessage" +touch c +touch d +assert_good_exec "./tigger-add c d" +assert_good_exec "./tigger-commit -m commitmessage" +assert_good_exec "./tigger-checkout master" +assert_good_exec "./tigger-branch -d new" + +printf "testing tigger status is the same as before the branch was created\n" +if [ "$(./tigger-status)" != "$before_status" ]; then + printf "tigger-status was not empty in an empty dir\n" >&2 + exit 1 +fi + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/test09.sh b/comp2041/tigger/test09.sh new file mode 100755 index 0000000..6931de6 --- /dev/null +++ b/comp2041/tigger/test09.sh @@ -0,0 +1,61 @@ +#!/bin/dash + +# Test startup, create a temporary directory and cd into it with files. +tmp_dir=$(mktemp --directory --quiet --tmpdir=./) +if [ "$(find tigger-* | wc -l)" -le 0 ]; then + printf "error: no tigger commands found, cannot run tests\n" >&2 + exit 1 +fi +cp tigger-* "$tmp_dir"/ +cd "$tmp_dir" || exit + +# Functions to test if the return value was 0 or non-zero. +assert_good_exec () { + printf "%s: " "$1" + if $1; then + return + fi + printf "test failed, previous command expected zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +# Functions to test if the return value was 0 or non-zero. +assert_bad_exec () { + printf "%s: " "$1" + if ! $1; then + return + fi + printf "test failed, previous command expected non-zero output code\n" >&2 + rm -rf ../"$tmp_dir" + exit 1 +} +printf "starting tests: output and order will be printed\n\n" +# End of test startup + +# The purpose of this test is to ensure that tigger-rm'ing a file can still be +# retrieved later (provided it was in a different commit). +assert_good_exec "./tigger-init" +printf "contents" > a +assert_good_exec "./tigger-add a" +assert_good_exec "./tigger-commit -m commitmessage" +assert_good_exec "./tigger-rm a" +assert_good_exec "./tigger-commit -m commitmessage" + +# Ensure it was deleted. +if [ -e a ]; then + printf "error: file was not deleted after git rm\n" >&2 + exit 1 +fi + +# Ensure it can be later retrieved. +assert_good_exec "./tigger-show 0:a" +if [ "$(./tigger-show 0:a)" = "" ]; then + printf "error: file was not retrievable after git rm\n" >&2 + exit 1 +fi + + +# Test teardown/cleanup +printf "\ntest completed successfully\n" +rm -rf ../"$tmp_dir" +exit 0 diff --git a/comp2041/tigger/tigger-add b/comp2041/tigger/tigger-add new file mode 100755 index 0000000..4ec51bb --- /dev/null +++ b/comp2041/tigger/tigger-add @@ -0,0 +1,42 @@ +#!/bin/dash + +# Test if we have a valid repo before doing anything. +if ! [ -d ".tigger/" ]; then + printf "tigger-add: error: tigger repository directory .tigger not found\n" + exit 1 +fi + +# Get current branch, then current commit (default 0). +branch=$(cat .tigger/branch.tig) +mkdir --parents ".tigger/$branch/" + + +# Grabs the latest commit +commit=$(find .tigger/"$branch"/ -maxdepth 1 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -n -r | head -n 1) +if [ "$commit" = "" ]; then + commit="0" + mkdir --parents ".tigger/$branch/$commit/" +fi + + +staged_dir=".tigger/$branch/$commit/staged/" +mkdir --parents "$staged_dir" +for filename in "$@"; do + + if ! [ -f "$filename" ]; then + + # If it doesn't exist in the dir, but does exist in staged, delete staged. + if [ -f .tigger/"$branch"/"$commit"/staged/"$filename" ]; then + rm --force .tigger/"$branch"/"$commit"/staged/"$filename" + continue + fi + + printf "tigger-add: error: can not open '%s'\n" "$filename" + exit 1 + fi + + + cp "$filename" "$staged_dir" +done + +exit 0 diff --git a/comp2041/tigger/tigger-branch b/comp2041/tigger/tigger-branch new file mode 100755 index 0000000..f4a5472 --- /dev/null +++ b/comp2041/tigger/tigger-branch @@ -0,0 +1,68 @@ +#!/bin/dash + +# Test if we have a valid repo before doing anything. +if ! [ -d ".tigger/" ]; then + printf "tigger-add: error: tigger repository directory .tigger not found\n" >&2 + exit 1 +fi + + +# For some reason we have to make it so that we can only run this if we're after +# the first commit, even though this isn't a part of git and our program can do +# it without issues. +if ! [ -e ".tigger/branch.unlock" ]; then + printf "tigger-branch: error: this command can not be run until after the first commit\n" >&2 + exit 1 +fi + +# Case where we give it no arguments -> list the branches. +if [ "$(echo "$@" | tr -d " \n")" = "" ]; then + printf "%s\n" "$(find .tigger/* -maxdepth 0 -type d | sort | grep -o -E "[\/][^\/]*$" | tr -d "/")" + exit 0 +fi + +target_branch=$(echo "$@" | sed "s|-d||g" | tr -d " "); +if [ "$target_branch" = "" ]; then + # no branch provided + printf "tigger-branch: error: no branch provided\n" >&2 + exit 1 +fi + +# Delete a branch, again taking care that we remove the target branch string +# before testing if it contains -d. +if [ "$(echo "$@" | sed "s|$target_branch||g" | grep -o -E "\-d" | tr -d " ")" != "" ]; then + + if [ "$target_branch" = master ]; then + printf "tigger-branch: error: can not delete branch '%s'\n" "$target_branch" >&2 + exit 1 + fi + + if ! [ -d .tigger/"$target_branch"/ ]; then + printf "tigger-branch: error: branch '%s' doesn't exist\n" "$target_branch" >&2 + exit 1 + fi + + rm -r .tigger/"$target_branch" + printf "Deleted branch '%s'\n" "$target_branch" + exit 0 +fi + +# Adding branch logic should test if a branch exists before adding it. +if [ -d .tigger/"$target_branch"/ ]; then + printf "tigger-branch: error: branch '%s' already exists\n" "$target_branch" >&2 + exit 1 +fi + +# We have to copy our current commit to the target branch. +current_branch=$(cat .tigger/branch.tig) +current_commit=$(find .tigger/"$current_branch"/ -maxdepth 1 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -n -r | head -n 1) +if [ "$current_commit" = "" ]; then + current_commit="0" + mkdir --parents ".tigger/$current_branch/$current_commit/" +fi + +mkdir --parents .tigger/"$target_branch"/ +mkdir --parents .tigger/"$target_branch"/0/staged +cp -r .tigger/"$current_branch"/"$current_commit"/commit .tigger/"$target_branch"/0/ + +exit 0 diff --git a/comp2041/tigger/tigger-checkout b/comp2041/tigger/tigger-checkout new file mode 100755 index 0000000..a1a5a21 --- /dev/null +++ b/comp2041/tigger/tigger-checkout @@ -0,0 +1,84 @@ +#!/bin/dash + +# Test if we have a valid repo before doing anything. +if ! [ -d ".tigger/" ]; then + printf "tigger-add: error: tigger repository directory .tigger not found\n" >&2 + exit 1 +fi + +# Case where we give it no arguments -> early out (without error?) +target_branch=$(echo "$@" | tr -d " "); +if [ "$target_branch" = "" ]; then + # no branch provided, idk if we should print anything so just early out + exit 1 +fi + +if ! [ -d .tigger/"$target_branch" ]; then + printf "tigger-checkout: error: unknown branch '%s'\n" "$target_branch" >&2 + exit 1 +fi + + +current_branch=$(cat .tigger/branch.tig) +current_commit=$(find .tigger/"$current_branch"/ -maxdepth 1 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -n -r | head -n 1) +if [ "$current_commit" = "" ]; then + current_commit="0" + mkdir --parents ".tigger/$current_branch/$current_commit/" +fi + +target_commit=$(find .tigger/"$target_branch"/ -maxdepth 1 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -n -r | head -n 1) +if [ "$target_commit" = "" ]; then + target_commit="0" + mkdir --parents ".tigger/$target_branch/$target_commit/" +fi + +for filename in *; do + basename=$(basename "$filename") + + # nothing in dir, just exit (should exit) + if ! [ -e "$filename" ]; then + continue + fi + + # if it's in staging, do not remove + #if [ -e .tigger/"$current_branch"/"$current_commit"/staged/"$basename" ]; then + # continue + #fi + + # if it doesn't exist in the target commit, remove + if ! [ -e .tigger/"$target_branch"/"$target_commit"/commit/"$basename" ]; then + rm "$basename" + continue + fi +done + +for filename in .tigger/"$target_branch"/"$target_commit"/commit/*; do + basename=$(basename "$filename") + + # nothing in dir, just exit (should exit) + if ! [ -e "$filename" ]; then + continue + fi + + # if it's in the current dir, do nothing TODO fix if different + if [ -e "$basename" ]; then + + # If it's the same AND not different to current staging, don't copy. + if [ "$(diff .tigger/"$target_branch"/"$target_commit"/commit/"$basename" "$basename")" = "" ]; then + if [ "$(diff .tigger/"$current_branch"/"$current_commit"/staged/"$basename" "$basename")" != "" ]; then + continue + fi + fi + + fi + + cp "$filename" ./ +done + +# Non-compliant tigger vs git behaviour: copy our staged to theirs. +rm -rf .tigger/"$target_branch"/"$target_commit"/staged +cp -r .tigger/"$current_branch"/"$current_commit"/staged .tigger/"$target_branch"/"$target_commit"/staged + +echo "$target_branch" > .tigger/branch.tig +printf "Switched to branch '%s'\n" "$target_branch" +exit 0 diff --git a/comp2041/tigger/tigger-commit b/comp2041/tigger/tigger-commit new file mode 100755 index 0000000..b2c7573 --- /dev/null +++ b/comp2041/tigger/tigger-commit @@ -0,0 +1,88 @@ +#!/bin/dash + +# Test if we have a valid repo before doing anything. +if ! [ -d ".tigger/" ]; then + printf "tigger-add: error: tigger repository directory .tigger not found\n" >&2 + exit 1 +fi + + +# Get current branch, then current commit (default 0). +branch=$(cat .tigger/branch.tig) +mkdir --parents ".tigger/$branch/" +commit=$(find .tigger/"$branch"/ -maxdepth 1 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -n -r | head -n 1) +if [ "$commit" = "" ]; then + commit="0" + mkdir --parents ".tigger/$branch/$commit/" +fi + + +commit_files=".tigger/$branch/$commit/" +file_dir="$commit_files/commit/" +mkdir --parents "$file_dir" +mkdir --parents "$commit_files/staged/" + + +# -a causes all files already in the index to have their contents from the +# current directory added to the index before the commit. We have to remove +# the message arg before testing the regex here. +message=$(echo "$@" | grep -o -E "\-m\s?.*" | cut -d' ' -f2- | tr -d \"\') +if [ "$(echo "$@" | sed "s|$message||g" | grep -o -E "\-a")" != "" ]; then + for filename in "$commit_files"/staged/*; do + basename=$(basename "$filename") + if ! [ -e "$basename" ]; then + continue + fi + cp "$basename" "$commit_files"/staged/ + done +fi + + +# If all files in staging are equal to those in commit, we have nothing to commit. +different="" +for filename in "$commit_files"/staged/*; do + basename=$(basename "$filename") + + EXISTS="$(cmp --silent .tigger/"$branch"/"$commit"/commit/"$basename" "$filename"; echo $?)" + if [ "$EXISTS" -ne 0 ]; then + different="true" + break + fi +done +for filename in "$commit_files"/commit/*; do + basename=$(basename "$filename") + + EXISTS="$(cmp --silent .tigger/"$branch"/"$commit"/staged/"$basename" "$filename"; echo $?)" + if [ "$EXISTS" -ne 0 ]; then + different="true" + break + fi +done +if [ "$different" = "" ] || [ -z "$(find .tigger/"$branch"/"$commit"/staged/ .tigger/"$branch"/"$commit"/commit/ -maxdepth 1 -type f)" ] ; then + printf "nothing to commit\n" + exit 0 +fi + + +# Copy all from staged into commit. +#for filename in "$commit_files"/staged/*; do +# cp "$filename" "$file_dir" +#done +rm -r --force "$commit_files"/commit/ +cp -r "$commit_files"/staged "$commit_files"/commit/ + + +# Copy our commit message and setup our new commit (n + 1). +#printf "%s > .tigger/%s/%s/message.tig\n" "$branch" "$commit" +printf "%s" "$message" > .tigger/"$branch"/"$commit"/message.tig +new_commit="$((($(cat .tigger/commit_count.tig) + 1)))" +mkdir --parents ".tigger/$branch/$new_commit/commit" +cp -r ".tigger/$branch/$commit/commit" ".tigger/$branch/$new_commit/" +cp -r ".tigger/$branch/$commit/commit" ".tigger/$branch/$new_commit/staged" +touch .tigger/branch.unlock + +# Increment our commit count value (which isn't used outside of printing). +echo "$new_commit" > .tigger/commit_count.tig + +printf "Committed as commit %s\n" "$((($(printf "%s" "$new_commit") - 1)))" +exit 0 diff --git a/comp2041/tigger/tigger-init b/comp2041/tigger/tigger-init new file mode 100755 index 0000000..cee1a77 --- /dev/null +++ b/comp2041/tigger/tigger-init @@ -0,0 +1,39 @@ +#!/bin/dash + +# We will create a new file in .tigger called "branch.tig" with our current +# branch. By default this should be master. All future ops should read this. + +# Commits will be contained in files starting at 0...n inside our branch dir. +# Our directory heirarchy might look like: +# .tigger/ +# branch.tig // current branch +# commit_count.tig // see the below comment @ echo "0"... +# master/ +# 0/ +# commit/ +# staged/ +# message.tig // because we have a message, it's a finished commit +# 1/ +# commit/ +# staged/ + +if [ -d ".tigger/" ]; then + printf "tigger-init: error: .tigger already exists\n" >&2 + exit 1 +fi + +branch="master" # in future should be ~ branch=$(cat ./.tigger/branch.tig) +mkdir --parents ".tigger/$branch" +echo "$branch" > ".tigger/branch.tig" + +# This is necessary because their implementation of git branch considers a +# global commit count as opposed to a (more logical) per branch commit count. +# Whenever we do any commit we have to increment this value (which is only +# used for printing so that we are compliant with their autotests). +echo "0" > .tigger/commit_count.tig + +mkdir --parents ".tigger/$branch/0/commit" +mkdir --parents ".tigger/$branch/0/staged" + +printf "Initialized empty tigger repository in .tigger\n" +exit 0 diff --git a/comp2041/tigger/tigger-log b/comp2041/tigger/tigger-log new file mode 100755 index 0000000..5e269c2 --- /dev/null +++ b/comp2041/tigger/tigger-log @@ -0,0 +1,24 @@ +#!/bin/dash + +# Test if we have a valid repo before doing anything. +if ! [ -d ".tigger/" ]; then + printf "tigger-add: error: tigger repository directory .tigger not found\n" >&2 + exit 1 +fi + +# Get current branch. +branch=$(cat .tigger/branch.tig) +mkdir --parents ".tigger/$branch/" + +# Iterate through commits and print their message. +for commit in $(find .tigger/"$branch"/* -maxdepth 0 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -r -n); do + + # No message = we're working on it, so it's not considered here. + if ! [ -e .tigger/"$branch"/"$commit"/message.tig ]; then + continue + fi + + printf "%s %s\n" "$commit" "$(cat .tigger/"$branch"/"$commit"/message.tig)" +done + +exit 0 diff --git a/comp2041/tigger/tigger-rm b/comp2041/tigger/tigger-rm new file mode 100755 index 0000000..e50420a --- /dev/null +++ b/comp2041/tigger/tigger-rm @@ -0,0 +1,66 @@ +#!/bin/dash + +# Test if we have a valid repo before doing anything. +if ! [ -d ".tigger/" ]; then + printf "tigger-add: error: tigger repository directory .tigger not found\n" >&2 + exit 1 +fi + +# Get current branch, then current commit (default 0). +branch=$(cat .tigger/branch.tig) +mkdir --parents ".tigger/$branch/" +commit=$(find .tigger/"$branch"/ -maxdepth 1 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -n -r | head -n 1) +if [ "$commit" = "" ]; then + commit="0" + mkdir --parents ".tigger/$branch/$commit/" +fi + +commit_files=".tigger/$branch/$commit/" +mkdir --parents "$commit_files/commit/" +mkdir --parents "$commit_files/staged/" + +for filename in $(echo "$@" | sed "s|--force||g" | sed "s|--cached||g"); do + + basename=$(basename "$filename") + if ! [ -e .tigger/"$branch"/"$commit"/staged/"$basename" ]; then + printf "tigger-rm: error: '%s' is not in the tigger repository\n" "$basename" >&2 + exit 1 + fi + + # Accidental deletion checking, should be non-cached and non-forced. + if [ "$(echo "$@" | grep -o -E "\-\-force")" = "" ]; then + + if [ "$(cmp --silent .tigger/"$branch"/"$commit"/staged/"$basename" "$basename"; echo $?)" -ne 0 ]; then + + if [ "$(cmp --silent .tigger/"$branch"/"$commit"/staged/"$basename" .tigger/"$branch"/"$commit"/commit/"$basename"; echo $?)" -ne 0 ]; then + printf "tigger-rm: error: '%s' in index is different to both the working file and the repository\n" "$basename" >&2 + exit 1 + fi + + if ! [ "$(echo "$@" | grep -o -E "\-\-cached")" != "" ]; then + printf "tigger-rm: error: '%s' in the repository is different to the working file\n" "$basename" >&2 + exit 1 + fi + + fi + + + if ! [ "$(echo "$@" | grep -o -E "\-\-cached")" != "" ]; then + if [ "$(cmp --silent .tigger/"$branch"/"$commit"/staged/"$basename" .tigger/"$branch"/"$commit"/commit/"$basename"; echo $?)" -ne 0 ]; then + printf "tigger-rm: error: '%s' has staged changes in the index\n" "$basename" >&2 + exit 1 + fi + fi + fi + + rm --force .tigger/"$branch"/"$commit"/staged/"$basename" + # If the cached option is specified the files are removed only from the index. + if [ "$(echo "$@" | grep -o -E "\-\-cached")" != "" ]; then + continue + fi + + rm --force "$basename" + +done + +exit 0 diff --git a/comp2041/tigger/tigger-show b/comp2041/tigger/tigger-show new file mode 100755 index 0000000..05d8405 --- /dev/null +++ b/comp2041/tigger/tigger-show @@ -0,0 +1,63 @@ +#!/bin/dash + +# Test if we have a valid repo before doing anything. +if ! [ -d ".tigger/" ]; then + printf "tigger-add: error: tigger repository directory .tigger not found\n" >&2 + exit 1 +fi + +if [ "$(printf "%s" "$@")" = "" ]; then + printf "tigger-show: error: no arguments provided\n" >&2 + exit 1 +fi + +branch=$(cat .tigger/branch.tig) +filename=$(echo "$@" | cut -d':' -f2-2) +commit=$(echo "$@" | cut -d':' -f1-1) + +# Lots of error checking here and unnecessarily distinct printing per error. + +target="" # LAMBDA CAPTURE +if [ "$commit" != "" ]; then + target=".tigger/$branch/$commit/commit/$filename" + + if ! [ -e ".tigger/$branch/$commit/message.tig" ]; then + printf "tigger-show: error: unknown commit '%s'\n" "$commit" >&2 + exit 1 + fi + + if ! [ -e "$target" ]; then + printf "tigger-show: error: '%s' not found in commit %s\n" "$filename" "$commit" >&2 + exit 1 + fi + + printf "%s\n" "$(cat "$target")" + exit 0 + +else + commit=$(find .tigger/"$branch"/ -maxdepth 1 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -n -r | head -n 1) + if [ "$commit" = "" ]; then + commit="0" + mkdir --parents ".tigger/$branch/$commit/" + fi + + if ! [ -e ".tigger/$branch/$commit/staged/$filename" ]; then + printf "tigger-show: error: '%s' not found in index\n" "$filename" >&2 + exit 1 + fi + + target=".tigger/$branch/$commit/staged/$filename" +fi + +if ! [ -e ".tigger/$branch/$commit/" ]; then + printf "tigger-show: error: unknown commit '%s'\n" "$commit" >&2 + exit 1 +fi + +if ! [ -e "$target" ]; then + printf "tigger-show: error: '%s' not found in commit %s\n" "$filename" "$commit" >&2 + exit 1 +fi + +printf "%s\n" "$(cat "$target")" +exit 0 diff --git a/comp2041/tigger/tigger-status b/comp2041/tigger/tigger-status new file mode 100755 index 0000000..b623432 --- /dev/null +++ b/comp2041/tigger/tigger-status @@ -0,0 +1,100 @@ +#!/bin/dash + +# Test if we have a valid repo before doing anything. +if ! [ -d ".tigger/" ]; then + printf "tigger-add: error: tigger repository directory .tigger not found\n" >&2 + exit 1 +fi + +# Get current branch + commit as usual. +branch=$(cat .tigger/branch.tig) +mkdir --parents ".tigger/$branch/" +commit=$(find .tigger/"$branch"/ -maxdepth 1 -type d | grep -o -E "[\/][^\/]*$" | tr -d "/" | sort -n -r | head -n 1) +if [ "$commit" = "" ]; then + commit="0" + mkdir --parents ".tigger/$branch/$commit/" +fi + +# Grabs regular files from our working dir, staging and commit. +files=$(find .tigger/"$branch"/"$commit"/commit/ .tigger/"$branch"/"$commit"/staged/ ./ -maxdepth 1 -type f -printf "%P\n" | sort | uniq | grep -v -E "^\." 2>/dev/null) +for filename in $files; do + + c_dir=".tigger/$branch/$commit/commit/$filename"; + s_dir=".tigger/$branch/$commit/staged/$filename"; + + is_c=0 + is_s=0 + is_w=0 + if [ -e "$c_dir" ]; then + is_c=1 + fi + if [ -e "$s_dir" ]; then + is_s=1 + fi + if [ -e "$filename" ]; then + is_w=1 + fi + + # There are a LOT of very specific cases here. + + if [ $is_w -eq 0 ] && [ $is_s -eq 0 ] && [ $is_c -eq 1 ]; then + printf "%s - deleted\n" "$filename" + continue + fi + + if [ $is_w -eq 1 ] && [ $is_s -eq 0 ] && [ $is_c -eq 0 ]; then + printf "%s - untracked\n" "$filename" + continue; + fi + + if [ $is_w -eq 1 ] && [ $is_s -eq 1 ] && [ $is_c -eq 1 ]; then + c="$(cat "$c_dir")" + s="$(cat "$s_dir")" + w="$(cat "$filename")" + + if [ "$w" != "$s" ] && [ "$s" != "$c" ] && [ "$c" != "$w" ]; then + printf "%s - file changed, different changes staged for commit\n" "$filename" + continue + fi + + if [ "$w" = "$s" ] && [ "$s" != "$c" ]; then + printf "%s - file changed, changes staged for commit\n" "$filename" + continue + fi + + if [ "$w" != "$s" ] && [ "$s" = "$c" ]; then + printf "%s - file changed, changes not staged for commit\n" "$filename" + continue + fi + + if [ "$w" = "$s" ] && [ "$s" = "$c" ]; then + printf "%s - same as repo\n" "$filename" + continue + fi + fi + + if [ $is_w -eq 0 ] && [ $is_s -eq 1 ] && [ $is_c -eq 1 ] && [ "$(diff "$s_dir" "$c_dir")" = "" ]; then + printf "%s - file deleted\n" "$filename" + continue + fi + + if [ $is_w -eq 1 ] && [ $is_s -eq 1 ] && [ $is_c -eq 0 ] && [ "$(diff "$filename" "$s_dir")" = "" ]; then + printf "%s - added to index\n" "$filename" + continue + fi + + if [ $is_w -eq 1 ] && [ $is_s -eq 1 ] && [ $is_c -eq 0 ] && [ "$(diff "$filename" "$s_dir")" != "" ]; then + printf "%s - added to index, file changed\n" "$filename" + continue; + fi + + if [ $is_w -eq 0 ] && [ $is_s -eq 1 ] && [ $is_c -eq 0 ]; then + printf "%s - added to index, file deleted\n" "$filename" + continue; + fi + + printf "%s - untracked\n" "$filename" + +done + +exit 0 -- cgit v1.2.3