Skip to content

Commit

Permalink
Add release-work command
Browse files Browse the repository at this point in the history
The command automates tags creation.

Also, `addons-read.bash` supports custom answers for the questions. This
gives more flexibility on manipulation with input parameters during the
testing.
  • Loading branch information
extsoft committed Oct 4, 2019
1 parent 64b9b88 commit 98edb89
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ Also, there are several optional addons which can be useful in some circumstance
1. **Use `setup()` or `teardown()`** bats methods only in the tests.
2. Use **`check` instead of bats `run`** to execute a command to be tested.
3. Use **`perform-verbose`** to execute any real command within a test which should not be tested.
4. If `addons-fake` or `addons-repo` is used, call `fake-clean` or `repo-clean` within a `teardown()` method.
4. Use appropriate `*-clean` function within a `teardown()` method if the addon provides it.
5. Do not fake `git-elegant` commands within the tests.

#### Assertions
Expand Down
27 changes: 27 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ There are commands used in various situations such as

release new versions
show-release-notes Prints a release log between two references.
release-work Releases available work as a new annotated tag.

and others
commands Prints available Elegant Git commands.
Expand Down Expand Up @@ -246,6 +247,32 @@ git fetch --all
git checkout -B task-133 custom-remote/new-feature
```

# `release-work`

```bash
usage: git elegant release-work [tag name]
```

Annotates the latest commit of `master` branch with a given tag and publishes
it. The tag's message will be prepopulated using commits subjects (from oldest
to newest) between the last available tag and HEAD. The release notes will be
either copied to clipboard (if `pbcopy` or `xclip` is available) or printed
to standard output using `git elegant show-release-notes`.

Prior to the execution, a current state is saved (a branch with modifications).
After the successful command execution, the state will be restored. In the case
of a failure, you need to go to the desired branch and apply a stash if needed.

Approximate commands flow is
```bash
==>> git elegant release-work 1.2.0
git checkout master
git pull --tags
git tag --annotate --file tag-message --edit 1.2.0
git push --tags
git elegant show-release-notes smart 1.1.12 1.2.0
```

# `save-work`

```bash
Expand Down
1 change: 1 addition & 0 deletions libexec/git-elegant
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ $(--print-command-in-usage accept-work)
release new versions
$(--print-command-in-usage show-release-notes)
$(--print-command-in-usage release-work)
and others
$(--print-command-in-usage commands)
Expand Down
76 changes: 76 additions & 0 deletions libexec/git-elegant-release-work
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash

command-purpose() {
cat <<MESSAGE
Releases available work as a new annotated tag.
MESSAGE
}

command-synopsis() {
cat <<MESSAGE
usage: git elegant release-work [tag name]
MESSAGE
}

command-description() {
cat<<MESSAGE
Annotates the latest commit of \`master\` branch with a given tag and publishes
it. The tag's message will be prepopulated using commits subjects (from oldest
to newest) between the last available tag and HEAD. The release notes will be
either copied to clipboard (if \`pbcopy\` or \`xclip\` is available) or printed
to standard output using \`git elegant show-release-notes\`.
Prior to the execution, a current state is saved (a branch with modifications).
After the successful command execution, the state will be restored. In the case
of a failure, you need to go to the desired branch and apply a stash if needed.
Approximate commands flow is
\`\`\`bash
==>> git elegant release-work 1.2.0
git checkout master
git pull --tags
git tag --annotate --file tag-message --edit 1.2.0
git push --tags
git elegant show-release-notes smart 1.1.12 1.2.0
\`\`\`
MESSAGE
}

--release-work() {
git-verbose checkout ${MASTER}
git-verbose pull --tags
local new_tag="${1}"
local last_tag=$(git for-each-ref --sort "-version:refname" --format "%(refname:short)" refs/tags --count 1)
if [[ -z ${new_tag} ]]; then
question-text "'${last_tag}' is the last tag. Which one will be next? "
read new_tag
fi
local message="tag-message"
echo "Release ${new_tag}" >> ${message}
echo "" >> ${message}
git log ${last_tag}...@ --pretty=format:'- %s' --reverse >> ${message}
echo "" >> ${message}
echo "" >> ${message}
git-verbose tag --annotate --file ${message} --edit ${new_tag}
remove-file ${message}
git-verbose push --tags


local default_tool="cat"
local copy_tool=${default_tool}
# mac
which pbcopy >/dev/null && copy_tool="pbcopy"
# linux
which xclip >/dev/null && copy_tool="xclip -selection clipboard"
(
git-verbose elegant show-release-notes smart ${last_tag} ${new_tag}
) | ${copy_tool}
if [[ ! "${default_tool}" == "${copy_tool}" ]]; then
info-text "The release notes are copied to clipboard."
fi

}

default() {
stash-pipe branch-pipe --release-work "${@}"
}
2 changes: 1 addition & 1 deletion libexec/plugins/pipe
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ branch-pipe() {
local to=$(git rev-parse --abbrev-ref HEAD)
"${@}"
local now=$(git rev-parse --abbrev-ref HEAD)
if ! ${to} == ${now}; then
if [[ ! "${to}" == "${now}" ]]; then
git-verbose checkout ${to}
fi
}
34 changes: 33 additions & 1 deletion tests/addons-read.bash
Original file line number Diff line number Diff line change
@@ -1,8 +1,40 @@
# This is a mock for system function 'read'
#!/usr/bin/env bash
# The addon allows manipulating what is returned by a system function `read`.
#
# In order to use it, you have to add `load addons-read` to your tests file.
#
# After, you can record answers by calling `read-answer <the answer>`. It
# records a queen of answers. And they will be read by the sequence of adding.
#
# If you didn't record any answers, and an empty string will be used.
#
# Don't forget to call `read-clean` to clean the recorded answers.
set -e

export next_write=0
export next_read=0
export answers_directory="/tmp/read-answers"

read-answer() {
if [[ ! -d "${answers_directory}" ]]; then
mkdir -pv ${answers_directory}
fi
export next_write=$(($next_write + 1))
echo "==>> Register replay on 'read' function call #${next_write}"
echo "${1}" | tee -i ${answers_directory}/${next_write}
}

read-clean() {
if [[ -d "${answers_directory}" ]]; then
rm -vr ${answers_directory}
fi
}

read() {
export next_read=$((next_read + 1))
if [[ -f "${answers_directory}/${next_read}" ]]; then
eval "export ${1}=$(cat ${answers_directory}/${next_read})"
fi
echo ""
}

Expand Down
1 change: 1 addition & 0 deletions tests/git-elegant-commands.bats
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ teardown() {
"commands"
"amend-work"
"show-release-notes"
"release-work"
)
check git-elegant commands
[ ${#lines[@]} -eq ${#COMMANDS[@]} ]
Expand Down
47 changes: 47 additions & 0 deletions tests/git-elegant-release-work.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bats -ex

load addons-common
load addons-fake
load addons-repo
load addons-read

first=first.txt
second=second.txt
third=third.txt
new_tag=3.0.0

setup() {
repo-new
repo-commit-file ${first}
repo "git tag -a -m ${first} 1"
repo-commit-file ${second}
repo "git tag -a -m ${second} 2"
repo-commit-file ${third}
repo "git tag -a -m ${third} ${new_tag}"
repo "git tag && git log --oneline"
fake-pass "git pull --tags"
fake-pass "git push --tags"
fake-pass "git tag --annotate --file tag-message --edit ${new_tag}"
fake-fail "which pbcopy"
fake-fail "which xclip"
fake-pass "git remote get-url origin" "https://fake-repo.git"
read-answer ${new_tag}
}

teardown() {
fake-clean
repo-clean
read-clean
}

@test "'release-work': release work when a new tag is provided as argument" {
check git-elegant release-work ${new_tag}
[[ "${status}" -eq 0 ]]
[[ "${lines[@]}" =~ "Release notes" ]]
}

@test "'release-work': release work when a new tag is provided via question" {
check git-elegant release-work
[[ "${status}" -eq 0 ]]
[[ "${lines[@]}" =~ "Release notes" ]]
}

0 comments on commit 98edb89

Please sign in to comment.