First Commit
This commit is contained in:
21
LICENSE.md
Normal file
21
LICENSE.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Michael Jedich
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
115
README.md
Normal file
115
README.md
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# Git Repo Watcher
|
||||||
|
|
||||||
|
A simple bash script to watch a git repository and pull upstream changes if available.
|
||||||
|
|
||||||
|
### Requirements
|
||||||
|
|
||||||
|
* Bash with Version > 3
|
||||||
|
* Tested on Ubuntu, Debian, MacOS, [Windows Git Shell](https://git-scm.com/download/win), [Windows Subsystem for Linux (WSL)](https://www.microsoft.com/en-us/p/ubuntu/9nblggh4msv6)
|
||||||
|
|
||||||
|
Basically, it will work anywhere you can install Bash.
|
||||||
|
|
||||||
|
If something doesn't work, please [let me know](https://github.com/kolbasa/git-repo-watcher/issues).
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
You only need the path to your git repository to start.
|
||||||
|
Make sure your local repository is tracking a remote branch, otherwise the script will fail.
|
||||||
|
|
||||||
|
This will start a watcher that looks for changes every 10 seconds:
|
||||||
|
```bash
|
||||||
|
./git-repo-watcher -d "/path/to/your/repository"
|
||||||
|
```
|
||||||
|
|
||||||
|
The time interval can be changed by passing it to `-i` (seconds):
|
||||||
|
```bash
|
||||||
|
./git-repo-watcher -d "/path/to/your/repository" -i 60
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also turn off the watcher by passing `-o`.
|
||||||
|
This will execute the script only once.
|
||||||
|
```bash
|
||||||
|
./git-repo-watcher -d "/path/to/your/repository" -o
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customizations
|
||||||
|
|
||||||
|
You can add your own logic to the file: [`git-repo-watcher-hooks`](https://github.com/kolbasa/git-repo-watcher/blob/master/git-repo-watcher-hooks)
|
||||||
|
|
||||||
|
For example, you can start your build process in case of changes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
# $3 - Commit details
|
||||||
|
change_pulled() {
|
||||||
|
echo "Starting build for commit: $@"
|
||||||
|
./your-build-script.sh
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have more than one repository you can pass a copy of the `git-repo-watcher-hooks` file like so:
|
||||||
|
```bash
|
||||||
|
./git-repo-watcher -d "/path/to/your/repository" -h "/path/to/your/hooks-file"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Private repositories
|
||||||
|
|
||||||
|
The script works with private repositories.
|
||||||
|
|
||||||
|
First configure a password cache with `git config --global credential.helper "cache --timeout=60"`.
|
||||||
|
Make sure the `timeout` is greater than the time interval given to the script. Both are given as seconds.
|
||||||
|
The program will execute `git fetch` and ask for your login data. The script itself **does not** store passwords!
|
||||||
|
|
||||||
|
If you want it to run in the background as a daemon process, you have to execute `git fetch` beforehand.
|
||||||
|
|
||||||
|
Example code:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd "/path/to/your/repository"
|
||||||
|
git config --global credential.helper "cache --timeout=60"
|
||||||
|
git fetch
|
||||||
|
|
||||||
|
# Checking exit code
|
||||||
|
if [[ $? -eq 1 ]]; then
|
||||||
|
echo "Wrong password!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disown process
|
||||||
|
./git-repo-watcher -d "/path/to/your/repository" > "/path/to/your/logfile.log" & disown
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows 10
|
||||||
|
|
||||||
|
The easiest way is to install [Git Shell](https://git-scm.com/download/win), which also comes with bash.
|
||||||
|
The only thing you have to consider are the file separators. The Unix format should be used here:
|
||||||
|
|
||||||
|
`C:\YourGitRepository` → `/C/YourGitRepository`
|
||||||
|
|
||||||
|
It is a little more difficult with [WSL](https://www.microsoft.com/en-us/p/ubuntu/9nblggh4msv6).
|
||||||
|
This must first be installed and configured via the Windows Store.
|
||||||
|
The file structure is also slightly different:
|
||||||
|
|
||||||
|
`C:\YourGitRepository` → `/mnt/c/YourGitRepository`
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
The test suite [`git-repo-watcher-tests`](https://github.com/kolbasa/git-repo-watcher/blob/master/git-repo-watcher-tests) is using the test framework [shunit2](https://github.com/kward/shunit2), it will be downloaded automatically to your `/tmp` folder.
|
||||||
|
The script has no other dependencies and requires no internet connection.
|
||||||
|
|
||||||
|
The tests create several test git repositories in the folder: `/tmp/git-repo-watcher`.
|
||||||
|
|
||||||
|
A git user should be configured, otherwise the tests will fail.
|
||||||
|
With the following line you can check if this is the case:
|
||||||
|
```bash
|
||||||
|
git config --list
|
||||||
|
```
|
||||||
|
|
||||||
|
You can configure it as follows:
|
||||||
|
```bash
|
||||||
|
git config --global user.email "your@email.com"
|
||||||
|
git config --global user.name "Your Name"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
181
git-repo-watcher
Executable file
181
git-repo-watcher
Executable file
@@ -0,0 +1,181 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
default_interval_in_seconds=10
|
||||||
|
default_hooks_file="$script_dir""/git-repo-watcher-hooks"
|
||||||
|
|
||||||
|
print_usage() {
|
||||||
|
echo ""
|
||||||
|
echo "NAME"
|
||||||
|
echo " git-repo-watcher -- keeps a git repository in sync with its origin"
|
||||||
|
echo "SYNOPSIS"
|
||||||
|
echo " git-repo-watcher -d <directory> [-h <hooks-file>] [-i <interval>] [-o]"
|
||||||
|
echo "DESCRIPTION"
|
||||||
|
echo " The following options are available:"
|
||||||
|
echo " -d The path to the git repository"
|
||||||
|
echo " -i Watch interval time in seconds (defaults to 10 seconds)"
|
||||||
|
echo " -o Run once"
|
||||||
|
echo " -h Custom hooks file"
|
||||||
|
echo ""
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
while getopts ":d:i:h:o" options; do
|
||||||
|
case "${options}" in
|
||||||
|
d)
|
||||||
|
git_repository_dir=${OPTARG}
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
hooks_file=${OPTARG}
|
||||||
|
;;
|
||||||
|
i)
|
||||||
|
interval_in_seconds=${OPTARG}
|
||||||
|
;;
|
||||||
|
o)
|
||||||
|
run_once=true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print_usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
# Validating given git directory
|
||||||
|
if [[ -z "$git_repository_dir" ]]; then
|
||||||
|
echo -e "\nERROR: Git directory (-d) not given!" >&2
|
||||||
|
print_usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "$git_repository_dir/.git" ]] || [[ ! -r "$git_repository_dir/.git" ]]; then
|
||||||
|
echo "ERROR: Git directory (-d) not found: '$git_repository_dir/.git'!" >&2
|
||||||
|
print_usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -w "$git_repository_dir/.git" ]]; then
|
||||||
|
echo "ERROR: Missing write permissions for the git directory (-d): '$git_repository_dir/.git'!" >&2
|
||||||
|
print_usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Convert to absolute file path if necessary
|
||||||
|
if [[ "$git_repository_dir" != /* ]]; then
|
||||||
|
git_repository_dir="$PWD/$git_repository_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validating given hook file
|
||||||
|
[[ -z "${hooks_file}" ]] && hooks_file="$default_hooks_file"
|
||||||
|
|
||||||
|
if [[ -f "${hooks_file}" ]] && [[ -r "${hooks_file}" ]]; then
|
||||||
|
# shellcheck source=git-repo-watcher-hooks
|
||||||
|
source "${hooks_file}"
|
||||||
|
else
|
||||||
|
echo "ERROR: Hooks (-h) file not found: '$hooks_file'" >&2
|
||||||
|
print_usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validating given interval
|
||||||
|
if [[ -z "$interval_in_seconds" ]]; then
|
||||||
|
interval_in_seconds="$default_interval_in_seconds"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Executes user hooks
|
||||||
|
#
|
||||||
|
# $1 - Hook name
|
||||||
|
# $2-$4 - Hook arguments
|
||||||
|
hook() {
|
||||||
|
hook_name="$1"
|
||||||
|
shift
|
||||||
|
if [[ "$(type -t "$hook_name")" == "function" ]]; then
|
||||||
|
eval "$hook_name $*"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pulls commit from remote git repository
|
||||||
|
#
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
pull_change() {
|
||||||
|
git pull
|
||||||
|
exit_code=$?
|
||||||
|
|
||||||
|
commit_message=$(git log -1 --pretty=format:"%h | %an | %ad | %s")
|
||||||
|
|
||||||
|
if [[ $exit_code -eq 1 ]]; then
|
||||||
|
hook "pull_failed" "$1" "$2" "$commit_message"
|
||||||
|
else
|
||||||
|
hook "change_pulled" "$1" "$2" "$(printf '%q\n' "$commit_message")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
|
||||||
|
cd "$git_repository_dir" || exit 1
|
||||||
|
|
||||||
|
if [[ -f ".git/index.lock" ]]; then
|
||||||
|
echo "ERROR: Git repository is locked, waiting to unlock" >&2
|
||||||
|
|
||||||
|
if [[ $run_once ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep $interval_in_seconds
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
git fetch
|
||||||
|
|
||||||
|
repo_name=$(basename -s .git "$(git config --get remote.origin.url)")
|
||||||
|
|
||||||
|
previous_branch="$branch"
|
||||||
|
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
|
||||||
|
|
||||||
|
if [[ -z $branch ]]; then
|
||||||
|
echo "ERROR: Unable to get branch" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $previous_branch ]] && [[ "$previous_branch" != "$branch" ]]; then
|
||||||
|
hook "branch_changed" "$repo_name" "$branch" "$previous_branch"
|
||||||
|
fi
|
||||||
|
|
||||||
|
upstream="$(git rev-parse --abbrev-ref --symbolic-full-name "@{u}" 2>/dev/null)"
|
||||||
|
|
||||||
|
# upstream was not configured
|
||||||
|
if [[ -z "$upstream" ]]; then
|
||||||
|
hook "upstream_not_set" "$repo_name" "$branch"
|
||||||
|
|
||||||
|
if [[ $run_once ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep $interval_in_seconds
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
git_local=$(git rev-parse @)
|
||||||
|
git_remote=$(git rev-parse "$upstream")
|
||||||
|
git_base=$(git merge-base @ "$upstream")
|
||||||
|
|
||||||
|
if [[ -z $started ]]; then
|
||||||
|
started=true
|
||||||
|
hook "startup" "$repo_name" "$branch"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$git_local" == "$git_remote" ]]; then
|
||||||
|
hook "no_changes" "$repo_name" "$branch"
|
||||||
|
elif [[ "$git_local" == "$git_base" ]]; then
|
||||||
|
hook "pull_change" "$repo_name" "$branch"
|
||||||
|
elif [[ "$git_remote" == "$git_base" ]]; then
|
||||||
|
hook "local_change" "$repo_name" "$branch"
|
||||||
|
else
|
||||||
|
hook "diverged" "$repo_name" "$branch"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $run_once ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep $interval_in_seconds
|
||||||
|
|
||||||
|
done
|
||||||
55
git-repo-watcher-hooks
Executable file
55
git-repo-watcher-hooks
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
startup() {
|
||||||
|
echo "Watch started: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
no_changes() {
|
||||||
|
printf "."
|
||||||
|
#echo "Nothing changed: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
# $3 - Commit details
|
||||||
|
change_pulled() {
|
||||||
|
echo "Changes pulled: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
# $3 - Commit details
|
||||||
|
pull_failed() {
|
||||||
|
echo "Pull failed --> Exiting: $*"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - New branch name
|
||||||
|
# $3 - Old branch name
|
||||||
|
branch_changed() {
|
||||||
|
echo "Branch changed: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
upstream_not_set() {
|
||||||
|
echo "Upstream not set: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
local_change() {
|
||||||
|
echo "local file changed: $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# $1 - Git repository name
|
||||||
|
# $2 - Branch name
|
||||||
|
diverged() {
|
||||||
|
echo "Diverged --> Exiting: $*"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
267
git-repo-watcher-tests
Executable file
267
git-repo-watcher-tests
Executable file
@@ -0,0 +1,267 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------- #
|
||||||
Reference in New Issue
Block a user