Skip to content

Commit

Permalink
Add help messages for each Elegant Git command
Browse files Browse the repository at this point in the history
`-h`, `--help`, `help` are allowed options to get a help message for any
command. The `libexec/git-elegant` is responsible for building and
printing help. The commands scripts are responsible for providing the
messages. It is described on "Architecture" section of README.md.

Also, there are new tests which allow checking of the availability of the
help messages.

#118
  • Loading branch information
extsoft committed Sep 11, 2019
1 parent c20aa82 commit 10594a7
Show file tree
Hide file tree
Showing 14 changed files with 451 additions and 11 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ something which should be quickly available, please propose changes here.

**Table of contents**

- [Architecture](#architecture)
- [Coding rules](#coding-rules)
- [Debug mode](#debug-mode)
- [Testing procedure](#testing-procedure)
Expand All @@ -55,10 +56,32 @@ something which should be quickly available, please propose changes here.
- [Test name template](#test-name-template)
- [Documentation preview](#documentation-preview)

### Architecture

The structure of directories:
```text
.
├── bin <- stores executable which is entry point
├── completions <- stores completion files
├── docs <- stores user documentation
├── libexec <- contains all commands
└── tests <- stores all tests along with additional test libraries
```

When you run `git elegant ...`, it initiates `bin/git-elegant` entry-point script. It calls
`libexec/git-elegant` which is responsible for the execution of a given command by loading the code
of a desired command (using a command file like `libexec/git-elegant-<command>`) and executing
it. Each command file has to provide the following BASH functions:
- `command-name` prints a command name (line length is limited to 50 characters)
- `command-synopsis` prints a `usage` statement (line length is limited to 80 characters)
- `command-description` prints a command description (line length is limited to 80 characters)
- `default` executes given command

### Coding rules
We enforce having a consistent implementation by following the next strict rules:
- add `#!/usr/bin/env bash` at the beginning of each script
- use `boxtee` to execute each original `git` command
- use `boxtee` to execute each original `git` command
- a private function (a usage in the scope of current script) should be prefixed with `--`

### Debug mode
You can enable debug mode by running `export GED=1` (the equivalent of `set -x` for `bash`).
Expand Down
74 changes: 64 additions & 10 deletions libexec/git-elegant
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,74 @@ branch-from-remote-reference() {
echo ${1} | sed "s|^[a-zA-Z0-9_-]*/||g"
}

usage() {
echo "git elegant <command>"
git elegant commands
# @todo #6 Describe usage of git elegant
--print-command-in-usage() { (
source "${BINS}/git-elegant-${1}"
printf " %-20s %s\n" "${1}" "$(command-purpose)"

) }

--usage() {
cat <<MESSAGE
An assistant who carefully makes routine work with Git.
usage: git elegant [-h|--help|help]
or: git elegant <command> [args]
or: git elegant <command> [-h|--help|help]
There are commands used in various situations such as
act with a repository
$(--print-command-in-usage clone-repository)
$(--print-command-in-usage init-repository)
$(--print-command-in-usage acquire-repository)
$(--print-command-in-usage clear-local)
manage a personal work
$(--print-command-in-usage start-work)
$(--print-command-in-usage save-work)
$(--print-command-in-usage amend-work)
$(--print-command-in-usage deliver-work)
operate a flow of work management
$(--print-command-in-usage obtain-work)
$(--print-command-in-usage accept-work)
and others
$(--print-command-in-usage commands)
Please visit ${__site} to find out more.
MESSAGE
}

--run-command() {
# usage: <command name> [arg]...
local COMMAND=${1}; shift
. "${BINS}/git-elegant-${COMMAND}" 2>/dev/null || {
echo "Unknown command: git elegant $COMMAND" && --usage && exit 46
}
case "${1}" in
-h|--help|help)
echo ""
command-synopsis
echo ""
command-description
echo ""
;;
*) default "$@" ;;
esac
}

main() {
local COMMAND="help"
local COMMAND="none"
[[ -n "$1" ]] && COMMAND="$1" && shift
[[ "$COMMAND" = "help" ]] && usage && exit 0
[[ ! -e "$BINS/git-elegant-$COMMAND" ]] && echo "Unknown command: git elegant $COMMAND" && usage && exit 46
. "$BINS/git-elegant-$COMMAND"

default "$@"
case "${COMMAND}" in
none|-h|--help|help) --usage ;;
*) --run-command ${COMMAND} "$@" ;;
esac
}

main "$@"
35 changes: 35 additions & 0 deletions libexec/git-elegant-accept-work
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
#!/usr/bin/env bash
set -e

command-purpose() {
cat <<MESSAGE
Applies a branch on top of upstream branch.
MESSAGE
}

command-synopsis() {
cat <<MESSAGE
usage: git elegant accept-work <remote branch>
MESSAGE
}

command-description() {
cat<<MESSAGE
Checkouts given branch using \`git elegant obtain-work\` into a temporary one.
Then, it makes a rebase of the latest version of default upstream branch with
current changes. The final index merges using fast-forward strategy into the
default local branch and pushes into the default upstream branch. After a
successful push, the given and temporary branches are removed.
Approximate commands flow is
\`\`\`bash
==> git elegant accept-work task-123
git fetch --all --tags
git checkout --force -B __eg origin/task-123
git status
git rebase origin/master
git checkout master
git merge --ff-only __eg
git push origin master:master
git branch --delete --force __eg
git push origin --delete task-123
\`\`\`
MESSAGE
}

default() {
local WORK_BRANCH="__eg"
Expand Down
61 changes: 61 additions & 0 deletions libexec/git-elegant-acquire-repository
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,67 @@ _rebase_autoStash=("rebase.autoStash" "false")
## Credentials, MAC only
_credential_helper_darwin=("credential.helper" "osxkeychain")

command-purpose() {
cat <<MESSAGE
Configures current repository.
MESSAGE
}

command-synopsis() {
cat <<MESSAGE
usage: git elegant acquire-repository
MESSAGE
}

command-description() {
cat<<MESSAGE
A bunch of git configuration applies to current repository using
\`git config --local\`. The first part is an interactive configuration which
aims to set all user-specific options (identity, editor, etc.). The second batch
applies all options which are required for successful using of Elegant Git.
Finally, the last part is aliasing Elegant Git commands by making them available
as regular Git commands.
Approximate commands flow is
\`\`\`bash
==> git elegant acquire-repository
################ Part 1 ################
git config --local user.name "Dmytro Serdiuk"
git config --local user.email "[email protected]"
git config --local core.editor vim
################ Part 2 ################
# "|" char starts non-message lines while writing commit message
git config --local core.commentChar |
# Remove whitespaces when apply a patch
git config --local apply.whitespace fix
# Aliasing Elegant Git commands by making them available as Git commands
git config --local "alias.<command>" "elegant <command>"
# Keeping up-to-date with both branches and tags on the remote
git config --local fetch.prune true
git config --local fetch.pruneTags true
# Rebase local changes while puling remotes refs
git config --local fetch.prune true
git config --local fetch.pruneTags
# Line ending configuration
## on MAC or Linux
git config --local core.autocrlf input
## on Windows
git config --local core.autocrlf true
# Always rebase when pull
git config --local pull.rebase true
# Never autostash if rebase
git config --local rebase.autoStash false
# Specify an external helper to be called when a username
# or password credential is needed (MAC only)
git config --local credential.helper osxkeychain
################ Part 3 ################
# Remove local aliases which contain Elegant Git commands
git config --local --unset <alias>
# Add aliases for current commands
git config --local alias.<command> "elegant <command>"
\`\`\`
MESSAGE
}

__ask_question() {
# usage: __ask_options <prefix>
Expand Down
27 changes: 27 additions & 0 deletions libexec/git-elegant-amend-work
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
#!/usr/bin/env bash
set -e

command-purpose() {
cat <<MESSAGE
Amends some changes to the most recent commit.
MESSAGE
}

command-synopsis() {
cat <<MESSAGE
usage: git elegant amend-work
MESSAGE
}

command-description() {
cat<<MESSAGE
Updates the most recent commit by adding some changes. The command will fail if
you'll try to modify history of the default local branch.
Approximate commands flow is
\`\`\`bash
==> git elegant amend-work
git add --interactive
git diff --cached --check
git commit --amend
\`\`\`
MESSAGE
}

default(){
local BRANCH=$(__branches 'git branch | grep \*')
if [[ "$BRANCH" == "master" ]]; then
Expand Down
29 changes: 29 additions & 0 deletions libexec/git-elegant-clear-local
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
#!/usr/bin/env bash
set -e

command-purpose() {
cat <<MESSAGE
Removes obsolete local branches.
MESSAGE
}

command-synopsis() {
cat <<MESSAGE
usage: git elegant clear-local
MESSAGE
}

command-description() {
cat<<MESSAGE
Identifies local branches for which remote branches were removed. Then, it
removes them by invoking \`git branch -d\`. If there are unmerged branches, you
have to choose either batch or one-by-one deletion procedure using
\`git branch -D\`.
Approximate commands flow is
\`\`\`bash
==> git elegant clear-local
git branch -d task-24
git branch -d 2349
git branch -D task-1
\`\`\`
MESSAGE
}

default() {
git elegant obtain-work ${MASTER}
local cmd="git branch -lvv | grep gone | awk {'print \$1'}"
Expand Down
26 changes: 26 additions & 0 deletions libexec/git-elegant-clone-repository
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
#!/usr/bin/env bash
set -e

command-purpose() {
cat <<MESSAGE
Clones a repository and configures it.
MESSAGE
}

command-synopsis() {
cat <<MESSAGE
usage: git elegant clone-repository <repository>
MESSAGE
}

command-description() {
cat<<MESSAGE
Clones a repository into a new directory and runs its configuration.
Approximate commands flow is
\`\`\`bash
==> git elegant clone-repository [email protected]:bees-hive/elegant-git.git
git clone [email protected]:bees-hive/elegant-git.git
cd elegant-git
git elegant acquire-repository
\`\`\`
MESSAGE
}

default() {
_error-if-empty "$1" "Cloneable URL is not set."
boxtee git clone "$1"
Expand Down
26 changes: 26 additions & 0 deletions libexec/git-elegant-commands
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
#!/usr/bin/env bash
set -e

command-purpose() {
cat <<MESSAGE
Prints available Elegant Git commands.
MESSAGE
}

command-synopsis() {
cat <<MESSAGE
usage: git elegant commands
MESSAGE
}

command-description() {
cat<<MESSAGE
Displays all available commands. This is useful for completion functions as well
as for other cases when you need iteration over the available commands.
Approximate commands flow is
\`\`\`bash
==> git elegant commands
echo <command>
echo ...
\`\`\`
MESSAGE
}

default() {
echo "acquire-repository"
echo "clone-repository"
Expand Down
Loading

0 comments on commit 10594a7

Please sign in to comment.