Skip to content

Instantly share code, notes, and snippets.

@subtleGradient
Last active December 27, 2023 01:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save subtleGradient/dd50e1a89b6abf4bd131472f28caefae to your computer and use it in GitHub Desktop.
Save subtleGradient/dd50e1a89b6abf4bd131472f28caefae to your computer and use it in GitHub Desktop.
Test && Commit || Revert
#!/bin/bash
set -e # exit on error
set -u # exit on undefined variable
# set -o pipefail # exit on failure in pipe
# set -x # print commands as they are run
# if DEBUG is set, print commands as they are run
set +u # allow undefined variables for this check
if [ ! -z "$DEBUG" ]; then
set -x
fi
set -u # throw on undefined variables
# TCR -- Test && Commit || Revert
{
ANSI_RESET="\033[0m"
ANSI_FG_WHITE="\033[37m"
ANSI_BG_RED="\033[41m"
ANSI_BG_WHITE="\033[47m"
ANSI_FG_BLACK="\033[30m"
}
tcr_confirm() {
echo -en "${ANSI_BG_WHITE}${ANSI_FG_BLACK}"
echo "TCR -- Test && Commit || Revert"
echo -en "${ANSI_RESET}"
echo -en "${ANSI_BG_RED}${ANSI_FG_WHITE}"
echo "WARNING: This script is destructive."
echo -en "${ANSI_RESET}"
echo "It will add all local changes, run the tests, and either commit or revert."
# force the user to type "DOIT" to continue
echo -en "Type \"${ANSI_BG_RED}${ANSI_FG_WHITE}YOLO${ANSI_RESET}\" to continue: "
echo -en "${ANSI_BG_RED}${ANSI_FG_WHITE}"
read -r REPLY # -r means don't interpret backslashes
echo -en "${ANSI_RESET}"
if [[ "$REPLY" =~ ^YOLO$ ]]; then
echo "Ok, you seem to know what you're doing I guess"
else
echo "Aborting. You didn't really want to do this, did you?"
exit 1
fi
}
function tcr_once() {
echo "Running TCR once at $(date)..."
make_sure_we_are_in_a_git_repo
# get ready to run the tests
clear
# add all the changes
git add .
git status
# return if there are no changes
if [ -z "$(git status --porcelain)" ]; then
echo "No changes to commit"
return
fi
set +e # unset exit on error
TEST_ERRORS=0
# run the tests
bun test
if [ $? -eq 0 ]; then
echo -en "${ANSI_BG_WHITE}${ANSI_FG_BLACK}"
echo "Tests passed"
echo -en "${ANSI_RESET}"
else
echo -en "${ANSI_BG_RED}${ANSI_FG_WHITE}"
echo "Tests failed"
echo -en "${ANSI_RESET}"
TEST_ERRORS=1
fi
# exclude any file named openapi-spec.ts
bun run eslint --fix . --ext .ts,.tsx,.js,.jsx --ignore-path .gitignore --ignore-pattern openapi-spec.ts
if [ $? -eq 0 ]; then
echo -en "${ANSI_BG_WHITE}${ANSI_FG_BLACK}"
echo "Linting passed"
echo -en "${ANSI_RESET}"
else
echo -en "${ANSI_BG_RED}${ANSI_FG_WHITE}"
echo "Linting failed"
echo -en "${ANSI_RESET}"
TEST_ERRORS=1
fi
set -e # exit on error
# if the tests pass, commit
if [ $TEST_ERRORS -eq 0 ]; then
git status
set +e # unset exit on error
git commit -am "TCR; tests pass"
TEST_ERRORS=$?
set -e # exit on error
fi
# if the tests fail, revert
if [ $TEST_ERRORS -ne 0 ]; then
# if it hasn't been very long, abort reverting
local TIME_SINCE_LAST_COMMIT=$(tcr_time_since_last_commit)
if [ $TIME_SINCE_LAST_COMMIT -lt 60 ]; then
echo -en "${ANSI_BG_RED}${ANSI_FG_WHITE}"
echo "Tests failed, but it hasn't been very long since the last commit."
echo "Not reverting."
echo -en "${ANSI_RESET}"
return
fi
echo "Tests failed, reverting..."
echo -en "\007" # BEEP!
echo -en "${ANSI_BG_RED}${ANSI_FG_WHITE}"
git reset --hard
echo -en "${ANSI_RESET}"
fi
}
make_sure_we_are_in_a_git_repo() {
# is the script being run from inside a git repo?
set +e # unset exit on error
GIT_ROOT="$(git rev-parse --show-toplevel)"
set -e # exit on error
# if GIT_ROOT is not a folder, cd to the git root of the project that contains this script
if [ -d "$GIT_ROOT" ]; then
echo -n "Already in a git repo, assuming you want to focus on this subfolder: "
# echo the PWD, but remove the git root from the beginning
echo "${PWD#$GIT_ROOT}"
else
cd "$(dirname "$0")"
GIT_ROOT="$(git rev-parse --show-toplevel)"
cd "$GIT_ROOT"
fi
}
tcr_time_since_last_commit() {
# get the time since the last commit
local TIME_SINCE_LAST_COMMIT=$(git log -1 --format=%ct)
TIME_SINCE_LAST_COMMIT=$(($(date +%s) - $TIME_SINCE_LAST_COMMIT))
echo $TIME_SINCE_LAST_COMMIT
}
# watch for changes
tcr_watch() {
# verify that fswatch is installed
if ! command -v fswatch &>/dev/null; then
echo "fswatch could not be found, installing with homebrew..."
brew install fswatch
fi
echo "Watching for changes..."
fswatch -r -e Created,Updated,Removed,Renamed . | while read -r FILE; do
echo "File changed: $FILE"
# only run the script if the file ends with .js,.ts,.tsx,.jsx
if [[ "$FILE" =~ \.(js|ts|tsx|jsx)$ ]]; then
tcr_once
else
echo "Ignoring"
fi
done
echo "Done watching for changes."
exit 0
}
tcr_confirm "$@"
# run the script once
tcr_once
# watch for changes
tcr_watch "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment