Skip to content

Commit

Permalink
Make tool installation more user-friendly
Browse files Browse the repository at this point in the history
We still support 2 types of installations using `install.bash`:
1. using remote git - a production installation which installs latest
   master branch by default.
2. using local sources - an installation type which is provided for
   development purposes. It is a part of testing procedure also.
By default, a tool is installed into ``${HOME}/.elegant-git` directory.
Meanwhile, the installation path can be customized. See `install.bash`
for further details.

Uninstall process is removed from `install.bash` as it has to be
managed separately.

New project layout:
.
├── bin          - production scripts only
├── completions  - completions for different shells
├── docs         - WEB site with documentation
├── libexec      - auxiliary scripts needed for production scripts
└── tests        - unit tests

Also, `run-tests` is working only from a docker environment as it may
install 'bad' code into `/usr/local`.
  • Loading branch information
extsoft committed Jun 25, 2019
1 parent 6dd45d6 commit 12aac20
Show file tree
Hide file tree
Showing 41 changed files with 125 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .rultor.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
architect: extsoft
docker:
image: extsoft/elegant-git-ci:1
image: extsoft/elegant-git-ci:2
as_root: true
merge:
fast-forward: only
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
sudo: required
language: bash
services: docker
script: docker run -t --rm -v $PWD:/eg extsoft/elegant-git-ci:1 ./run-tests
script: docker run -t --rm -v $PWD:/eg extsoft/elegant-git-ci:2 ./run-tests
notifications:
email: false
56 changes: 30 additions & 26 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
# 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

# Usage
## Installation
Use `./install.bash dev` to get an installation from the current sources.
# Debug mode
You can enable debug mode by running `export GED=1` (the equivalent of `set -x` for `bash`).
Run `unset GED` to switch debug off.

## Debug mode
Use `export GED=1` to switch on the debug of `git elegant` or `unset GED` to switch off.
# Testing procedure
A testing procedure consists of 3 steps:
1. unit testing using [bats](https://github.com/sstephenson/bats)
2. installation testing
3. validation of todo' correctness (for [0pdd](http://www.0pdd.com/p?name=bees-hive/elegant-git))

# Unit tests
[bats](https://github.com/sstephenson/bats) is used for unit testing.
All these steps can be executed by
`docker run -it --rm -v $PWD:/eg extsoft/elegant-git-ci:2 ./run-tests`.

`extsoft/elegant-git-ci` Docker image is also used on CI. If the image requires modifications,
it has to be updated manually by the following instructions:
1. update `Dockerfile` (including `version` and `description`)
2. `docker build -t extsoft/elegant-git-ci:<version> .`
3. `docker push extsoft/elegant-git-ci:<version>`

# Unit testing
## Addons
Add the following line to the test file if the extension is required:
- `load addons-common` to have the working test (**mandatory**)
- `load addons-git` to interact with real git repository (**optional**)
- `load addons-fake` to fake a Linux command (**optional**)
- `load addons-cd` to fake `cd` command (**optional**)
- `load addons-read` to fake `read` command (**optional**)
In order to have a working unit tests, you need to add `load addons-common` line to each `.bats`
file. This addon configures right access to executables (`libexec` directory) and defines mandatory
functions.

Also, there are several optional addons which can be useful in some circumstances:
- add `load addons-git` to interact with real git repository
- add `load addons-fake` to fake a Linux command
- add `load addons-cd` to fake `cd` command
- add `load addons-read` to fake `read` command

## Writing tests
1. **Use `setup()` or `teardown()`** bats methods only in the tests.
Expand All @@ -30,16 +45,5 @@ Add the following line to the test file if the extension is required:
- `[ "${#lines[@]}" -eq 0 ]` for an empty command output

## Test name template
Use the following test name template - `'<command args>': <describe what will be tested>` like `'check -s': trailing spaces in the staged changes`.

## Run
Use one of the following commands to run the unit tests:
- `bats src/test`
- `./run-tests`
- `docker run -t --rm -v $PWD:/eg extsoft/elegant-git-ci:1 ./run-tests`

# CI
CI execution is automated using Docker. If some changes are required to the CI docker image, please follow next:
- update `Dockerfile` (including `version` and and `description`)
- `docker build -t extsoft/elegant-git-ci:<version> .`
- `docker push extsoft/elegant-git-ci:<version>`
Use the following test name template - `'<command args>': <describe what will be tested>` like
`'acquire-repository': raise an error if cloneable URL isn't set`.
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ RUN apk update && \
gem install pdd
LABEL maintainer="Dmytro Serdiuk <dmytro.serdiuk@gmail.com>" \
description="ruby:2.4.1 git:2.13.5 0pdd:0.20.3" \
version=1
version=2
WORKDIR /eg
ENV EG_ENABLE_TESTING true
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ Allows easy handle git tasks.

Installation
============
Manual
------
`curl https://raw.githubusercontent.com/bees-hive/elegant-git/master/install.bash | $(which bash)`
bash
----
Run `curl https://raw.githubusercontent.com/bees-hive/elegant-git/master/install.bash | $(which bash)`
to install the tool.

Run `rm -r ${HOME}/.elegant-git` if you need to remove the installation.

Homebrew
--------
On macOS, you can install [Homebrew](https://brew.sh/) if you haven't already, then run:
`brew install bees-hive/hive/elegant-git`

To find out more [click here](https://github.com/bees-hive/homebrew-hive).
Expand Down
14 changes: 14 additions & 0 deletions bin/git-elegant
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
# The entry script which should parse its location and run
# original "elegant git".

# https://stackoverflow.com/a/246128/10418734
SOURCE="${BASH_SOURCE[0]}"
while [[ -h "$SOURCE" ]]; do
INSTALLATION="$(cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd)"
SOURCE="$(readlink "$SOURCE")"
[[ ${SOURCE} != /* ]] && SOURCE="$INSTALLATION/$SOURCE"
done
INSTALLATION="$(cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd)"

exec "${INSTALLATION}/../libexec/git-elegant"
File renamed without changes.
94 changes: 43 additions & 51 deletions install.bash
Original file line number Diff line number Diff line change
@@ -1,62 +1,54 @@
#!/usr/bin/env bash
# Usage:
# ./install.bash installs to "${HOME}/.elegant-git" from remote git
# ./install.bash /installation/path installs to "/installation/path" from remote git
# ./install.bash /installation/path src installs to "installation/path" from local sources
set -e

[ -z "$INSTALL_PATH" ] && INSTALL_PATH="$HOME/.git-elegant"
[ -z "$REPO_HOME" ] && REPO_HOME="https://github.com/extsoft/elegant-git.git"

man() {
echo "Usage: ./install.bash [remote|dev|uninstall]"
echo " - remote - install from GitHub (default)"
echo " - dev - install from local copy"
echo " - uninstall - remove current installation"
echo ""
echo "Configuration:"
echo " INSTALL_PATH=$INSTALL_PATH"
echo " REPO_HOME=$REPO_HOME"
REPO_HOME="https://github.com/extsoft/elegant-git.git"

copy(){
local FROM=${1}
local INTO=${2}
install -d -m 755 ${INTO}/{bin,libexec,completions}
install -m 755 ${FROM}/bin/* ${INTO}/bin
install -m 755 ${FROM}/libexec/* ${INTO}/libexec
install -m 644 ${FROM}/completions/* ${INTO}/completions
install -m 644 ${FROM}/LICENSE ${INTO}
install -m 644 ${FROM}/README.md ${INTO}
}

run() {
echo "$1"
eval "$1"
next-steps() {
local INSTALL_PATH=${1}
local COMPLETION_FILE="${INSTALL_PATH}/completions/git-elegant.bash"
cat <<TEXT >&1
Please add 3 highlighted lines to your "~/.bashrc" (or "~/.bash_profile"):
--------------------------------------------------------------------------
# elegant git: ${REPO_HOME}
export PATH=${INSTALL_PATH}/bin:\$PATH
[ -f ${COMPLETION_FILE} ] && . ${COMPLETION_FILE}
--------------------------------------------------------------------------
Then, please restart the terminal and enjoy the 'elegant git'!
TEXT
}

install() {
echo "Installing 'elegant git' to $INSTALL_PATH"
run "rm -rfv $INSTALL_PATH"
run "mkdir -p $INSTALL_PATH"
if [ $1 = 'remote' ]; then
run "git clone --depth 1 $REPO_HOME $INSTALL_PATH"
cd "$INSTALL_PATH"
rm -rf .git
elif [ $1 = 'dev' ]; then
cp -rv $(dirname "$0")/* $INSTALL_PATH
main() {
if [[ -n ${1} ]]; then
INSTALL_PATH="${1}"
shift
fi
: ${INSTALL_PATH:="${HOME}/.elegant-git"}
# mode selection
if [[ -z ${1} ]]; then
local CODE="/tmp/elegant-git"
git clone --quiet --depth 1 ${REPO_HOME} ${CODE}
copy ${CODE} ${INSTALL_PATH}
rm -r ${CODE}
else
echo "Unexpected mode: $1"
copy ${0%/*} ${INSTALL_PATH}
fi

run "mkdir -p $INSTALL_PATH/bin"
run "mkdir -p $INSTALL_PATH/completion"
run "mv $INSTALL_PATH/src/main/git-elegant-completion $INSTALL_PATH/completion"
run "mv $INSTALL_PATH/src/main/git-elegant* $INSTALL_PATH/bin"

echo ""
echo "Add the following to your .bash_profile to allow:"
echo "# extend 'git' with 'elegant git' commands"
echo "export PATH=$INSTALL_PATH/bin:\$PATH"
echo "#'elegant git' completion"
echo "[ -f $INSTALL_PATH/completion/git-elegant-completion ] && . $INSTALL_PATH/completion/git-elegant-completion"
echo ""
echo "Then please restart the terminal and enjoy the 'elegant git'!"
}

uninstall() {
echo "Uninstalling 'elegant git' from $INSTALL_PATH"
run "rm -rfv $INSTALL_PATH"
echo "'elegant git' is installed to '${INSTALL_PATH}/bin/git-elegant'."
command -v git-elegant 1>/dev/null 2>&1 || next-steps ${INSTALL_PATH}
}

case "$1" in
uninstall) uninstall ;;
help) man ;;
dev) uninstall && install dev ;;
*) uninstall && install remote ;;
esac
main $@
15 changes: 8 additions & 7 deletions src/main/git-elegant → libexec/git-elegant
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
set -e
[ -n "$GED" ] && set -x

BINS=$(dirname "$0")
# Update PATH for a round of command execution.
# It registers all "libexec" scripts.
BINS=$(dirname ${0})
export PATH=${BINS}:${PATH}

__red=`tput setaf 1`
__green=`tput setaf 2`
Expand Down Expand Up @@ -92,12 +95,10 @@ usage() {
}

main() {
local COMMAND
if [ -n "$1" ]; then
COMMAND="$1"; shift
fi
[ -z "$COMMAND" ] || [ "$COMMAND" = "help" ] && usage && exit 10
[ ! -e "$BINS/git-elegant-$COMMAND" ] && echo "Unknown command: git elegant $COMMAND" && usage && exit 2
local COMMAND="help"
[[ -n "$1" ]] && COMMAND="$1" && shift
[[ "$COMMAND" = "help" ]] && usage && exit 0
[[ ! -e "$BINS/git-elegant-$COMMAND" ]] && echo "Unknown command: git elegant $COMMAND" && usage && exit 2
. "$BINS/git-elegant-$COMMAND"

default "$@"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 17 additions & 3 deletions run-tests
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
#!/bin/bash -e
#!/usr/bin/env bash
# This script is destructive! That's why it will work only if a specific variable is set.
# It's recommended to run it within a docker container only.
set -e

bats --tap src/test
pdd --source=$(pwd) --verbose --file=/dev/null
if [[ -z $EG_ENABLE_TESTING ]]; then
echo "Testing is disabled!"
exit 1
fi

fail() {
echo $@
exit 1
}

bats --tap tests || fail "Unit tests are failed."
./install.bash /usr/local src && git elegant help || fail "Installation test is failed."
pdd --source=$(pwd) --verbose --file=/dev/null || fail "Unreadable todo is identified."
File renamed without changes.
4 changes: 2 additions & 2 deletions src/test/addons-common.bash → tests/addons-common.bash
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
set -e

THIS="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BIN_DIR="$THIS/../../src/main"
export PATH=$BIN_DIR:$PATH
BIN_DIR="$THIS/../libexec"
export PATH=${BIN_DIR}:$PATH

check(){
run "$@"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit 12aac20

Please sign in to comment.