diff --git a/.wf/tests-execution.bash b/.wf/tests-execution.bash new file mode 100755 index 0000000..fc34d5b --- /dev/null +++ b/.wf/tests-execution.bash @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -e +# Runs bats tests +# usage: ./script [command name] + +if [[ -n "${1}" ]]; then + bats --tap $(find tests -type f -name "*${1}*") +else + bats --tap tests +fi diff --git a/libexec/git-elegant b/libexec/git-elegant index da783dc..fdb2f1a 100755 --- a/libexec/git-elegant +++ b/libexec/git-elegant @@ -6,6 +6,7 @@ set -e # It registers all "libexec" scripts. BINS=$(dirname ${0}) export PATH=${BINS}:${PATH} +source ${BINS}/plugins/pipe source ${BINS}/plugins/text __site="https://elegant-git.bees-hive.org" @@ -28,12 +29,6 @@ _error-if-empty() { fi } -__branches() { - local branch_command="$1"; shift - local b=$(eval "$branch_command" | sed -e 's|[* ]||g') - echo ${b[@]} -} - __loop_ask() { local c="$1"; shift local m="$1"; shift diff --git a/libexec/git-elegant-amend-work b/libexec/git-elegant-amend-work index 2ceffac..bedf5fc 100644 --- a/libexec/git-elegant-amend-work +++ b/libexec/git-elegant-amend-work @@ -29,7 +29,7 @@ MESSAGE } default(){ - local BRANCH=$(__branches 'git branch | grep \*') + local BRANCH=$(git rev-parse --abbrev-ref HEAD) if [[ "$BRANCH" == "master" ]]; then error-box "No commits to 'master' branch. Please read more on ${__site}" error-box "Try 'git elegant start-work' prior to retrying this command." diff --git a/libexec/git-elegant-deliver-work b/libexec/git-elegant-deliver-work index 176d427..37d09f5 100644 --- a/libexec/git-elegant-deliver-work +++ b/libexec/git-elegant-deliver-work @@ -31,7 +31,7 @@ MESSAGE } default() { - local BRANCH=$(__branches 'git branch | grep \*') + local BRANCH=$(git rev-parse --abbrev-ref HEAD) if [[ "$BRANCH" == "master" ]]; then error-box "No pushes to 'master' branch. Please read more on ${__site}" exit 42 diff --git a/libexec/git-elegant-save-work b/libexec/git-elegant-save-work index 55da651..9e1ee06 100644 --- a/libexec/git-elegant-save-work +++ b/libexec/git-elegant-save-work @@ -30,7 +30,7 @@ MESSAGE } default(){ - local BRANCH=$(__branches 'git branch | grep \*') + local BRANCH=$(git rev-parse --abbrev-ref HEAD) if [[ "$BRANCH" == "master" ]]; then error-box "No commits to 'master' branch. Please read more on ${__site}" error-box "Try 'git elegant start-work' prior to retrying this command." diff --git a/libexec/git-elegant-start-work b/libexec/git-elegant-start-work index 3ca1977..64d81cb 100644 --- a/libexec/git-elegant-start-work +++ b/libexec/git-elegant-start-work @@ -32,15 +32,13 @@ git stash drop stash@{0} MESSAGE } -default() { - _error-if-empty "$1" "Please give a name for the new branch." - status=$(git-verbose stash save elegant-git) +--start-work-logic(){ git-verbose checkout ${MASTER} git-verbose pull git-verbose checkout -b "$1" +} - if [[ "$status" =~ "Saved working directory" ]]; then - git-verbose stash apply stash^{/elegant-git} - git-verbose stash drop stash@{0} - fi +default() { + _error-if-empty "$1" "Please give a name for the new branch." + stash-pipe --start-work-logic "${@}" } diff --git a/libexec/plugins/pipe b/libexec/plugins/pipe new file mode 100644 index 0000000..571187d --- /dev/null +++ b/libexec/plugins/pipe @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# The plugin which allows running a given functions through different types +# (aka pre- and post-conditions). + +stash-pipe() { + # Makes automatic stash and unstash if possible + # usage: stash-pipe [args]... + + git update-index -q --refresh + if ! git diff-index --quiet HEAD --; then + local message="Elegant Git auto-stash: " + message+="WIP in '$(git rev-parse --abbrev-ref HEAD)' branch " + message+="on $(date "+%Y-%m-%dT%H:%M:%S")" + git-verbose stash push --message "${message}" + fi + + "${@}" + + if [[ -n "${message}" ]]; then + git update-index -q --refresh + git-verbose stash pop $(git stash list --grep="${message}" --format="%gd") + fi +} diff --git a/tests/addons-fake.bash b/tests/addons-fake.bash index b38c6ad..aca8850 100644 --- a/tests/addons-fake.bash +++ b/tests/addons-fake.bash @@ -45,7 +45,7 @@ if [[ -e "\${FIXTURE_HOME}" ]]; then cat "\${FIXTURE_HOME}/stderr" >&2 exit \$(cat "\${FIXTURE_HOME}/exit_code") else - ${ORIGIN_BINARY} \$@ + ${ORIGIN_BINARY} "\$@" fi MOCK fi diff --git a/tests/addons-git.bash b/tests/addons-git.bash index 2bde4f2..10f454c 100644 --- a/tests/addons-git.bash +++ b/tests/addons-git.bash @@ -33,7 +33,7 @@ gitrepo() { # execute given arguments on real git repo # usage: gitrepo testtee cd ${GIT_REPO_DIR} - testtee $@ + testtee "${@}" testtee cd - } diff --git a/tests/git-elegant-deliver-work.bats b/tests/git-elegant-deliver-work.bats index d424792..2bd1433 100644 --- a/tests/git-elegant-deliver-work.bats +++ b/tests/git-elegant-deliver-work.bats @@ -9,7 +9,7 @@ teardown() { } @test "'deliver-work': by default, a name of remote branch is equal to local branch" { - fake-pass git branch *feature1 + fake-pass git "rev-parse --abbrev-ref HEAD" feature1 fake-pass git "fetch" fake-pass git "rebase origin/master" fake-pass git "push --set-upstream --force origin feature1:feature1" @@ -19,7 +19,7 @@ teardown() { } @test "'deliver-work': if branch name passed, a name of remote branch is different to local branch" { - fake-pass git branch *feature1 + fake-pass git "rev-parse --abbrev-ref HEAD" feature1 fake-pass git "fetch" fake-pass git "rebase origin/master" fake-pass git "push --set-upstream --force origin feature1:feature2" @@ -29,7 +29,7 @@ teardown() { } @test "'deliver-work': exit code is 42 when current local branch is master" { - fake-pass git branch *master + fake-pass git "rev-parse --abbrev-ref HEAD" master fake-pass git "fetch" fake-pass git "rebase origin/master" fake-pass git "push --set-upstream --force origin master:master" diff --git a/tests/git-elegant-start-work.bats b/tests/git-elegant-start-work.bats index 468fd97..890e264 100644 --- a/tests/git-elegant-start-work.bats +++ b/tests/git-elegant-start-work.bats @@ -16,12 +16,12 @@ teardown() { @test "'start-work': branch with given name is created successfully" { check git-elegant start-work test-feature - [ "$status" -eq 0 ] + [[ "$status" -eq 0 ]] } @test "'start-work': exit code is 45 when branch name isn't set" { check git-elegant start-work - [ "$status" -eq 45 ] + [[ "$status" -eq 45 ]] } @test "'start-work': print error message when branch name isn't set" { @@ -29,24 +29,23 @@ teardown() { [[ "${lines[0]}" =~ "Please give a name for the new branch." ]] } -@test "'start-work': use stash for available changes" { - fake-pass git "stash save elegant-git" "Saved working directory" - fake-pass git "stash apply stash^{/elegant-git}" - fake-pass git "stash drop stash@{0}" +@test "'start-work': use stash pipe if there are uncommitted changes" { + gitrepo "echo stash >> ${FILE_TO_MODIFY}" check git-elegant start-work test-feature - [ "$status" -eq 0 ] + [[ "$status" -eq 0 ]] + [[ "${lines[@]}" =~ "stash push" ]] + [[ "${lines[@]}" =~ "stash pop" ]] } -@test "'start-work': ignore stash if there are no changes" { +@test "'start-work': ignore stash pipe if there are uncommitted changes" { fake-pass git "stash save elegant-git" "No local changes to save" check git-elegant start-work test-feature [ "$status" -eq 0 ] } -@test "'start-work': exit code is 100 when stash wasn't applied" { - fake-pass git "stash save elegant-git" "Saved working directory" - fake-pass git "stash apply stash^{/elegant-git}" - fake-fail git "stash drop stash@{0}" +@test "'start-work': exit code is 100 when stash pipe wasn't applied" { + gitrepo "echo stash >> ${FILE_TO_MODIFY}" + fake-fail git "stash pop stash@{0}" check git-elegant start-work test-feature - [ "$status" -eq 100 ] + [[ "$status" -eq 100 ]] } diff --git a/workflows b/workflows new file mode 100755 index 0000000..d5e7c29 --- /dev/null +++ b/workflows @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -ex + +testing() { + docker run -it --rm -v $PWD:/eg beeshive/elegant-git-ci:3 ./.wf/tests-execution.bash $@ +} + +repository() { + docker run -idt --rm --name repository --workdir /tmp/elegant-git-repo -v $PWD:/eg beeshive/elegant-git-ci:3 bash + docker exec -it repository bash -c "source /eg/tests/addons-git.bash;source /eg/tests/addons-common.bash; init-repo" + docker attach repository +} + +commands=( + testing + repository +) + +main() { + local command=${1} + if [[ -z "${command}" ]]; then + select any in ${commands[@]}; do + command=${any} + break + done + else + shift + fi + ${command} ${@} +} + +main ${@}