268 lines
6.4 KiB
Bash
Executable File
268 lines
6.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
|
||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
main_script="git-repo-watcher"
|
||
shunit_git="https://github.com/kward/shunit2"
|
||
|
||
# The tests use the temp folder to store the test framework
|
||
# and all generated git repositories
|
||
temp_dir="/tmp/git-repo-watcher"
|
||
stdout="$temp_dir/stdout.txt"
|
||
shunit2_dir="$temp_dir/shunit2/"
|
||
|
||
remote_repo="remote"
|
||
remote_repo_clone="remote-clone"
|
||
watched_clone="watched-clone"
|
||
|
||
test_file_name="test-file"
|
||
test_commit_message="Test commit message"
|
||
|
||
# A verbose-flag can be passed ("-v")
|
||
[[ "$1" == "-v" ]] && verbose=true && shift
|
||
|
||
# Redirecting output
|
||
if [[ "$verbose" ]]; then
|
||
exec 3>&1
|
||
exec 4>&2
|
||
else
|
||
exec 3>/dev/null
|
||
exec 4>/dev/null
|
||
fi
|
||
|
||
# Create temp directory
|
||
[[ ! -d "$temp_dir" ]] && mkdir "$temp_dir"
|
||
|
||
# Checkout shunit2 unit test framework
|
||
if [[ ! -d "$shunit2_dir" ]]; then
|
||
git clone --depth 1 "$shunit_git" "$shunit2_dir"
|
||
fi
|
||
|
||
# Prints a seperator. It helps to make the output more readable.
|
||
printSeparator() {
|
||
local sep="$1"
|
||
[[ -z "$sep" ]] && sep="-"
|
||
|
||
# shellcheck disable=SC2034
|
||
for i in {1..75}; do local x=$x"$sep"; done && echo "$x"
|
||
}
|
||
|
||
# Removes created temp files and directories
|
||
cleanupTempFiles() {
|
||
[[ -f "$stdout" ]] && rm "$stdout"
|
||
[[ -d "$temp_dir/$remote_repo" ]] && rm -rf "${temp_dir:?}/$remote_repo"
|
||
[[ -d "$temp_dir/$watched_clone" ]] && rm -rf "${temp_dir:?}/$watched_clone"
|
||
[[ -d "$temp_dir/$remote_repo_clone" ]] && rm -rf "${temp_dir:?}/$remote_repo_clone"
|
||
# I don't know why, but the following tests seem to start,
|
||
# before all temp files are deleted, so we pause a little
|
||
sleep 0.05
|
||
}
|
||
|
||
# Will be executed before each test
|
||
# https://github.com/kward/shunit2#-setupteardown
|
||
setUp() {
|
||
cd "$script_dir" || exit 1
|
||
|
||
# Create a fresh 'remote' git repository
|
||
git init --bare "$temp_dir/$remote_repo" 1>&3 2>&4
|
||
git clone "$temp_dir/$remote_repo" "$temp_dir/$remote_repo_clone" 1>&3 2>&4
|
||
pushOneFile 'README.md'
|
||
git clone "$temp_dir/$remote_repo" "$temp_dir/$watched_clone" 1>&3 2>&4
|
||
}
|
||
|
||
# Will be executed after each test
|
||
tearDown() {
|
||
cleanupTempFiles
|
||
printSeparator
|
||
return 0
|
||
}
|
||
|
||
# Commiting and pushing file to remote repository
|
||
#
|
||
# $1 - File name
|
||
# $2 - Commit message
|
||
pushOneFile() {
|
||
local file="$1"
|
||
[[ -z "$file" ]] && file="$test_file_name"
|
||
|
||
local message="$2"
|
||
[[ -z "$message" ]] && message="$test_commit_message"
|
||
|
||
cd "$temp_dir/$remote_repo_clone" || exit 1
|
||
touch "$file"
|
||
git add . 1>&3 2>&4
|
||
git commit -m "$message" 1>&3 2>&4
|
||
git push 1>&3 2>&4
|
||
}
|
||
|
||
printBashVersion() {
|
||
echo && printSeparator "#"
|
||
echo "Testing on bash-version: '$BASH_VERSION'"
|
||
printSeparator "#" && echo && printSeparator
|
||
}
|
||
|
||
# Start the main git-repo-watcher-script
|
||
#
|
||
# $1 - override options
|
||
startWatcher() {
|
||
local options=" -d $temp_dir/$watched_clone"
|
||
[[ -n "$1" ]] && options="$1"
|
||
|
||
# A short interval is used to guarantee multiple iterations
|
||
options="$options -i 0.1" # 0.1 seconds
|
||
eval "$script_dir/$main_script $options" &>$stdout &
|
||
watcher_pid=$!
|
||
}
|
||
|
||
# $1 - time to collect output
|
||
collectOutput() {
|
||
local sleep_time=1
|
||
[[ -n "$1" ]] && sleep_time="$1"
|
||
|
||
# We wait one second to collect stdout of multiple
|
||
# iterations of the main watch loop.
|
||
sleep "$sleep_time"
|
||
|
||
# Killing the watcher script
|
||
disown "$watcher_pid"
|
||
kill "$watcher_pid" 2>/dev/null
|
||
|
||
# Reading the logfile
|
||
result=$(cat "$stdout")
|
||
|
||
[[ "$verbose" ]] && echo "$result"
|
||
}
|
||
|
||
# $1 - branch name
|
||
createNewBranch() {
|
||
cd "$temp_dir/$remote_repo_clone" || exit 1
|
||
git checkout -b "$1" 1>&3 2>&4
|
||
git push --set-upstream origin "$1" 1>&3 2>&4
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
# Should print the help screen, if no arguments given
|
||
testHelpScreen() {
|
||
startWatcher " " # no arguments
|
||
collectOutput 0.1
|
||
|
||
assertContains "$result" "ERROR: Git directory (-d) not given!"
|
||
assertContains "$result" "The following options are available:"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testNewCommitBeforeStart() {
|
||
pushOneFile
|
||
startWatcher
|
||
collectOutput
|
||
|
||
assertContains "$result" "1 file changed"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testNewCommitAfterStart() {
|
||
startWatcher
|
||
pushOneFile
|
||
collectOutput
|
||
|
||
assertContains "$result" "1 file changed"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testPulledHook() {
|
||
pushOneFile
|
||
startWatcher
|
||
collectOutput
|
||
|
||
assertContains "$result" "Changes pulled"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testSpecialCharactersInCommitMessage() {
|
||
local message="!$%&/()=?{[]}#<>§|;:_,.-*+~'\"´\`"
|
||
|
||
pushOneFile "$test_file_name" "$message"
|
||
startWatcher
|
||
collectOutput
|
||
|
||
assertContains "$result" "$message"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testNothingChangedHook() {
|
||
startWatcher
|
||
collectOutput 0.2
|
||
|
||
assertContains "$result" "Nothing changed"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testStartupHook() {
|
||
startWatcher
|
||
collectOutput
|
||
|
||
assertContains "$result" "Watch started"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testBranchChangedHook() {
|
||
local branch="new_branch"
|
||
createNewBranch "$branch"
|
||
|
||
startWatcher
|
||
|
||
sleep 0.5
|
||
cd "$temp_dir/$watched_clone" || exit 1
|
||
git checkout -t "origin/$branch" 1>&3 2>&4
|
||
|
||
collectOutput
|
||
|
||
assertContains "$result" "Branch changed"
|
||
assertContains "$result" "$branch"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testNoUpstreamHook() {
|
||
startWatcher
|
||
|
||
sleep 0.5
|
||
cd "$temp_dir/$watched_clone" || exit 1
|
||
git checkout -b "new_branch" 1>&3 2>&4
|
||
|
||
collectOutput
|
||
|
||
assertContains "$result" "Upstream not set"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
testRelativePath() {
|
||
pushOneFile
|
||
|
||
# Use a relative path for the git directory
|
||
cd "$temp_dir" || exit 1
|
||
startWatcher "-d $watched_clone"
|
||
|
||
collectOutput
|
||
|
||
assertNotContains "$result" "No such file or directory"
|
||
assertContains "$result" "Changes pulled"
|
||
}
|
||
|
||
# -------------------------------------------------------------------- #
|
||
|
||
printBashVersion
|
||
|
||
# shellcheck source=/tmp/git-repo-watcher/shunit2
|
||
. $shunit2_dir/shunit2
|
||
|
||
# -------------------------------------------------------------------- #
|