├── .travis.yml ├── AUTHORS ├── Dockerfile ├── LICENCE ├── README.md ├── bin └── argsh ├── docs └── README.md ├── install.sh ├── libexec └── argsh │ ├── arg.sh │ ├── libs │ ├── arguments.awk │ ├── declare.awk │ ├── getopt.awk │ ├── parse.awk │ ├── settings.awk │ ├── usage.awk │ └── validators.awk │ └── validator.sh ├── man └── README.md ├── package.json ├── test.bats └── tests ├── argsh.bats ├── fixtures └── argsh │ ├── bin │ ├── example │ └── no-argsh │ └── vals │ └── shared.sh └── helper.bash /.travis.yml: -------------------------------------------------------------------------------- 1 | language: bash 2 | 3 | os: 4 | - linux 5 | 6 | env: 7 | - BASHVER=3.2 8 | - BASHVER=4.0 9 | - BASHVER=4.1 10 | - BASHVER=4.2 11 | - BASHVER=4.3 12 | - BASHVER=4.4 13 | - BASHVER=5.0 14 | 15 | matrix: 16 | include: 17 | - os: osx 18 | 19 | services: 20 | - docker 21 | 22 | script: 23 | - | 24 | cat < (https://thingylabs.io) -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.9 2 | 3 | RUN apk add --no-cache \ 4 | bats \ 5 | git \ 6 | bash \ 7 | gawk 8 | 9 | WORKDIR /argsh 10 | COPY . . 11 | RUN ln -s $(pwd)/bin/argsh /bin/ 12 | 13 | ENTRYPOINT ["bats", "tests/argsh.bats"] -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2019 Jan Guth and contributors 3 | 4 | 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: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 🗃️ archived for https://github.com/arg-sh/argsh 2 | 3 | --- 4 | 5 | # argsh 6 | [![Latest release](https://img.shields.io/github/release/fentas/argsh.svg)](https://github.com/fentas/argsh/releases/latest) 7 | [![npm package](https://img.shields.io/npm/v/argsh.svg)](https://www.npmjs.com/package/argsh) 8 | [![License](https://img.shields.io/github/license/fentas/argsh.svg)](https://github.com/fentas/argsh/blob/master/LICENSE) 9 | [![Continuous integration status for Linux and macOS](https://img.shields.io/travis/fentas/argsh/master.svg?label=travis%20build)](https://travis-ci.org/fentas/argsh) 10 | 11 | Create simple and short shell (bash) scripts with ease. `argsh` takes away the 12 | tedious work to create your own argument parser and keeps your shell usage at bay. 13 | 14 | ## Install argsh 15 | * to be able to use argsh scripts on your system, it makes sense to install it globally 16 | ```sh 17 | # manually 18 | git clone https://github.com/fentas/argsh.git 19 | cd argsh/bin 20 | suod ln -sf argsh /usr/local/bin 21 | ``` 22 | 23 | ## Quick start 24 | * Describe your arguments and `argsh` does the rest. 25 | 26 | ### script template 27 | ```sh 28 | touch 29 | sudo chmod +x 30 | ``` 31 | 32 | ### create argsh script from template 33 | ```sh 34 | #!/usr/bin/env argsh 35 | set -eu -o pipefail 36 | 37 | # OPTIONS 38 | # argsh(t|test-option): env(TEST_OPTION) def(false) des(A test option.) val() 39 | 40 | # ACTIONS 41 | 42 | # PATHS 43 | 44 | # VARIABLES 45 | 46 | # IMPORTS 47 | 48 | # MAIN 49 | main() { 50 | # dependencies 51 | 52 | # actions 53 | for ACTION in ${ARGSH_ACTIONS}; do case "${ACTION}" in 54 | T|test-action) test_action ;; 55 | esac; done 56 | } 57 | 58 | # FUNCTIONS 59 | test_action() { 60 | echo "$TEST_OPTION" 61 | } 62 | 63 | # VALIDATORS 64 | 65 | # RUN 66 | [[ "${0}" != "${BASH_SOURCE[0]}" ]] || main "${@}" 67 | ``` 68 | 69 | ## Include `argsh` into your tests 70 | 71 | Follow up. 72 | 73 | ## Honorable Mentions 74 | 75 | Folder structure is right out copied from https://github.com/bats-core/bats-core. Also is bats used for testing. Big thanks for that. 76 | -------------------------------------------------------------------------------- /bin/argsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC1090 3 | set -eu -o pipefail 4 | 5 | [ -f "${1:-}" ] || { 6 | echo "Help is comming. 🤕" 7 | exit 1 8 | } 9 | 10 | ARGSH_READLINK='true' 11 | if command -v 'greadlink' >/dev/null; then 12 | ARGSH_READLINK='greadlink' 13 | elif command -v 'readlink' >/dev/null; then 14 | ARGSH_READLINK='readlink' 15 | fi 16 | 17 | _argsh_resolve_absolute_root_dir() { 18 | local -r cwd="${PWD}" 19 | local -r result="${2}" 20 | local -r original_shell_options="${-}" 21 | local path="${1}" 22 | local target_dir 23 | local target_name 24 | 25 | # Resolve the parent directory, e.g. /bin => /usr/bin on CentOS (https://github.com/bats-core/bats-core/issues/113). 26 | set -P 27 | 28 | while true; do 29 | target_dir="${path%/*}" 30 | target_name="${path##*/}" 31 | 32 | if [[ "${target_dir}" != "${path}" ]]; then 33 | cd "${target_dir}" 34 | fi 35 | 36 | if [[ -L "${target_name}" ]]; then 37 | path="$("${ARGSH_READLINK}" "${target_name}")" 38 | else 39 | printf -v "${result}" -- '%s' "${PWD%/*}" 40 | set +P "-${original_shell_options}" 41 | cd "${cwd}" 42 | return 43 | fi 44 | done 45 | } 46 | 47 | export ARGSH_ROOT 48 | _argsh_resolve_absolute_root_dir "${0}" 'ARGSH_ROOT' 49 | export ARGSH_SHELL 50 | ARGSH_SHELL="bash" 51 | export ARGSH_SOURCE 52 | ARGSH_SOURCE="${1}" 53 | export ARGSH_ROOT_SOURCE 54 | ARGSH_ROOT_SOURCE="$(realpath "$(dirname "${ARGSH_SOURCE}")")" 55 | 56 | export ARGSH_LIBEXEC="${ARGSH_ROOT}/libexec/argsh" 57 | source "${ARGSH_LIBEXEC}/arg.sh" 58 | source "${ARGSH_LIBEXEC}/validator.sh" 59 | 60 | args=("${@}") 61 | 62 | while IFS= read -r setting; do case "${setting}" in 63 | shell=*) 64 | ARGSH_SHELL="${setting:6}" 65 | command -v "${ARGSH_SHELL}" &>/dev/null || { 66 | echo "wanted argsh shell not found: ${ARGSH_SHELL}" >&2 67 | exit 1 68 | } 69 | ;; 70 | source=*) 71 | path="$(realpath "${ARGSH_ROOT_SOURCE}/${setting:7}")" 72 | [ -f "${path}" ] || { 73 | echo "source path does not exist: ${path}" >&2 74 | exit 1 75 | } 76 | source "${path}" 77 | ;; 78 | pass=*) 79 | case "${setting:5}" in 80 | "file") args=("${1}") ;; 81 | "args") args=("${@:2}") ;; 82 | "none") args=() ;; 83 | esac 84 | ;; 85 | esac; done < <(_argsh_settings "${ARGSH_SOURCE}") 86 | 87 | # remove first argument (script path) 88 | _argsh "${@:2}" 89 | exec "${ARGSH_SHELL}" "${args[@]}" -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fentas/argsh/6e8c4d17560ae540dad8867a64e9f7951a204564/docs/README.md -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/usr/bin/env bash 3 | 4 | set -e 5 | 6 | ARGSH_ROOT="${0%/*}" 7 | PREFIX="$1" 8 | 9 | if [[ -z "$PREFIX" ]]; then 10 | printf '%s\n' \ 11 | "usage: $0 " \ 12 | " e.g. $0 /usr/local" >&2 13 | exit 1 14 | fi 15 | 16 | install -d -m 755 "$PREFIX"/{bin,libexec/argsh,share/man/man{1,7}} 17 | install -m 755 "$ARGSH_ROOT/bin"/* "$PREFIX/bin" 18 | install -m 755 "$ARGSH_ROOT/libexec/argsh"/* "$PREFIX/libexec/argsh" 19 | 20 | echo "Installed Bats to $PREFIX/bin/argsh" -------------------------------------------------------------------------------- /libexec/argsh/arg.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # shellcheck disable=SC2064 3 | set -eu -o pipefail 4 | 5 | export ARGSH_SOURCE 6 | export ARGSH_FIELD_SEPERATOR 7 | export ARGSH_ACTIONS 8 | : "${ARGSH_SOURCE:="${BASH_SOURCE[-1]}"}" 9 | : "${ARGSH_FIELD_SEPERATOR:=""}" # \u001E - Record Separator 10 | 11 | _argsh_error() { 12 | [ -n "${1-}" ] || { 13 | file="$(mktemp)"; trap "rm $file" EXIT; echo "${file}" 14 | return 15 | } 16 | local -r msg="$(sed 's/^getopt: //' "${1:?}")" 17 | [ -z "${msg}" ] || { 18 | _usage "${msg}" >&2 19 | exit 2 20 | } 21 | } 22 | 23 | _argsh_settings() { 24 | awk -f "${ARGSH_LIBEXEC}"/libs/settings.awk "${1}" 25 | } 26 | 27 | _argsh_parse() { 28 | awk -f "${ARGSH_LIBEXEC}"/libs/parse.awk "${1}" 29 | } 30 | 31 | _argsh_declare() { 32 | eval "$(awk -f "${ARGSH_LIBEXEC}"/libs/declare.awk)" 33 | } 34 | 35 | _argsh_usage() { 36 | source /dev/stdin < <(awk -f "${ARGSH_LIBEXEC}/libs/usage.awk") 37 | } 38 | 39 | # shellcheck disable=SC2034,SC2154 40 | _argsh_arguments() { 41 | local -r args="$(cat)" 42 | local file_error 43 | 44 | local params getopt error; error="$(_argsh_error)" 45 | getopt="$(awk -f "${ARGSH_LIBEXEC}"/libs/getopt.awk <<<"${args}")" 46 | params="$($getopt -- "$@" 2>"${error}" || _argsh_error "${error}")" 47 | 48 | eval set -- "${params}" 49 | local cmd opt val 50 | until [ "${1}" = '--' ]; do 51 | eval "$(awk -v arg="${1}" -f "${ARGSH_LIBEXEC}"/libs/arguments.awk <<<"${args}")" 52 | shift 53 | 54 | if [ "${cmd}" == "h" ] || [ "${cmd}" == "help" ]; then 55 | _usage 56 | exit 57 | fi 58 | 59 | if [ -n "${opt}" ]; then 60 | declare -n ref="${opt}" 61 | ref=true 62 | [ -n "${val}" ] || continue 63 | ref="${1}" 64 | shift; continue 65 | fi 66 | 67 | ARGSH_ACTIONS+="${cmd}"$'\n' 68 | done 69 | 70 | ARGSH_ACTIONS="${ARGSH_ACTIONS-%$'\n'}" 71 | } 72 | 73 | _argsh_validators() { 74 | local val cmd opt error; error="$(_argsh_error)" 75 | while IFS= read -r variables; do 76 | eval "${variables}" 77 | 78 | declare -f "${val}" &>/dev/null || { 79 | [ "${val}" == "" ] || echo -e "[argsh][warning]\tfunction does not exists '${val}'" 1>&2 80 | continue 81 | } 82 | "${val}" "${cmd}" "${opt}" 2>"${error}" || _argsh_error "${error}" 83 | done < <(awk -f "${ARGSH_LIBEXEC}"/libs/validators.awk) 84 | } 85 | 86 | _argsh() { 87 | # TODO: do not fail of there is no argsh comment 88 | local -r args="$(_argsh_parse "${ARGSH_SOURCE}")" 89 | 90 | _argsh_declare \ 91 | <<<"${args}" 92 | _argsh_usage \ 93 | <<<"${args}" 94 | [ -n "${*}" ] || { 95 | _usage 96 | exit 1 97 | } 98 | _argsh_arguments "${@}" \ 99 | <<<"${args}" 100 | _argsh_validators \ 101 | <<<"${args}" 102 | } 103 | -------------------------------------------------------------------------------- /libexec/argsh/libs/arguments.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk -f 2 | 3 | function options(cmd) { 4 | print "cmd=\"" cmd "\" opt=\"" $3 "\" val=\"" $5 "\"" 5 | exit 6 | } 7 | 8 | BEGIN { 9 | FS=ENVIRON["ARGSH_FIELD_SEPERATOR"] 10 | } 11 | arg ~ /^-[^-]/ && arg == "-" $1 { options($1); } 12 | arg ~ /^--[^-]/ && arg == "--" $2 { options($2); } 13 | -------------------------------------------------------------------------------- /libexec/argsh/libs/declare.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk -f 2 | 3 | BEGIN { 4 | FS=ENVIRON["ARGSH_FIELD_SEPERATOR"] 5 | } 6 | $3 { 7 | printf "export %s\n", $3 8 | if ($4 && $4 != "") { 9 | printf ": \"${%s:=\"%s\"}\"\n", $3, $4 10 | } 11 | } 12 | $4 ~ /^!!/ { 13 | $4 = substr($4, 3) 14 | call = call sprintf("! command -v \"%s\" &>/dev/null || \"%s\" \"%s\" \"%s\"\n", $4, $4, $2, $3) 15 | } 16 | END { 17 | print call 18 | } 19 | -------------------------------------------------------------------------------- /libexec/argsh/libs/getopt.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk -f 2 | 3 | BEGIN { 4 | FS=ENVIRON["ARGSH_FIELD_SEPERATOR"] 5 | o = "" 6 | } 7 | $1 { o = o (o ? "," $1 : $1) ($5 ? ":" : "") } 8 | $2 { l = l (l ? "," $2 : $2) ($5 ? ":" : "") } 9 | END { 10 | print "getopt -o \"" o "\" -l \"" l "\"" 11 | } 12 | -------------------------------------------------------------------------------- /libexec/argsh/libs/parse.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk -f 2 | 3 | BEGIN { 4 | OFS=ENVIRON["ARGSH_FIELD_SEPERATOR"] 5 | } 6 | { 7 | match($0, /# argsh\(([^)|]+)?\|?([^)]+)?\)/, args) 8 | if (args[0]) { 9 | $0 = substr($0, RSTART + RLENGTH) 10 | while(match($0, /[:)] +(env|def|val|des)\(([^)]*)/, opt)) { 11 | args[opt[1]] = opt[2] ? opt[2] : "" # \u0000 - NULL 12 | $0 = substr($0, RSTART + RLENGTH) 13 | } 14 | if (length(args[1]) > 1) { 15 | args[2] = args[1] 16 | args[1] = "" 17 | } 18 | print args[1], args[2], args["env"], args["def"], args["val"], args["des"] 19 | } 20 | } 21 | END { 22 | print "h", "help", "", "", "", "", "Print help." 23 | } 24 | -------------------------------------------------------------------------------- /libexec/argsh/libs/settings.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk -f 2 | 3 | BEGIN { 4 | OFS="\n" 5 | } 6 | $0 ~ "# argsh " { 7 | $0 = substr($0, 7) 8 | for (i=2; i <= NF; i++) { 9 | print $i 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /libexec/argsh/libs/usage.awk: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env awk -f 2 | 3 | function format() { 4 | opt = sprintf(" %-23s %s", ($1 ? "-"$1 : "") ($1 && $2 ? ", " : "") ($2 ? "--"$2 : ""), $6) 5 | if ($4) { 6 | opt = opt sprintf("\n%-24s ➜ ${%s-}", "", $3) 7 | } 8 | return opt 9 | } 10 | 11 | BEGIN { 12 | FS=ENVIRON["ARGSH_FIELD_SEPERATOR"]; OFS="\n" 13 | cmd=sprintf("basename %s", ENVIRON["ARGSH_SOURCE"]) 14 | cmd | getline filename; close(cmd) 15 | 16 | print \ 17 | "_usage() {", 18 | "local -r message=\"${1:-}\"", 19 | "[ -z \"${message}\" ] || echo -e \"\n\033[31m■■\033[0m \033[1m${message}\033[0m\n\"", 20 | "cat <<-EOTXT", 21 | "Usage:" 22 | printf " %s [options]\n", filename 23 | 24 | len_options=0 25 | len_actions=0 26 | } 27 | 28 | $3 { options[len_options++]=format(); } 29 | ! $3 { actions[len_actions++]=format(); } 30 | 31 | END { 32 | if (len_options) { 33 | print "\nOptions:" 34 | for (i=0; i&2 8 | return 127 9 | } 10 | } 11 | 12 | _argsh_is_directory() { 13 | local -n opt="${2}" 14 | [ -d "${opt}" ] || { 15 | echo "[ ${1} ] needs to be a directory." 1>&2 16 | return 127 17 | } 18 | } 19 | 20 | _argsh_is_executable() { 21 | local -n opt="${2}" 22 | command -v "${opt}" &>/dev/null || { 23 | echo "[ ${1} ] needs to be executable." 1>&2 24 | return 1 25 | } 26 | } -------------------------------------------------------------------------------- /man/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fentas/argsh/6e8c4d17560ae540dad8867a64e9f7951a204564/man/README.md -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "argsh", 3 | "version": "0.3.1", 4 | "description": "Bash arguments manager", 5 | "homepage": "https://github.com/fentas/argsh#readme", 6 | "license": "MIT", 7 | "author": "Jan Guth ", 8 | "repository": "github:fentas/argsh", 9 | "bugs": "https://github.com/fentas/argsh/issues", 10 | "files": [ 11 | "bin", 12 | "libexec", 13 | "man" 14 | ], 15 | "directories": { 16 | "bin": "bin", 17 | "doc": "docs", 18 | "tests": "tests" 19 | }, 20 | "scripts": { 21 | "test": "time docker run -it -v $(pwd):/opt/argsh bats/bats:latest --tap /opt/argsh/tests/argsh.bats" 22 | }, 23 | "keywords": [ 24 | "argsh", 25 | "bash", 26 | "shell", 27 | "arguments", 28 | "getopt" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /test.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env argsh 2 | # shellcheck shell=bats disable=SC2154 3 | # argsh shell=bats pass=file 4 | 5 | # argsh(e|executable): env(ARGSH_TEST) def(./tests/fixtures/argsh/bin/example) des(executable for argsh integration test.) val(_argsh_is_executable) 6 | # argsh(run): des(test executable for argsh integration.) 7 | 8 | load tests/helper 9 | 10 | @test "${ARGSH_TEST}: is executable" { 11 | run command -v "${ARGSH_TEST}" 12 | [ "${status}" -eq 0 ] 13 | } 14 | 15 | @test "no arguments prints message and usage instructions" { 16 | run "${ARGSH_TEST}" 17 | log_on_failure 18 | [ "${status}" -eq 1 ] 19 | [ "${lines[0]%% *}" == 'Usage:' ] 20 | } 21 | 22 | @test "-h and --help print help" { 23 | run "${ARGSH_TEST}" -h 24 | [ "${status}" -eq 0 ] 25 | [ "${#lines[@]}" -gt 3 ] 26 | [ "${lines[0]%% *}" == 'Usage:' ] 27 | } 28 | 29 | @test "invalid option prints message and usage instructions" { 30 | run filter_control_sequences "${ARGSH_TEST}" --invalid-option 31 | log_on_failure 32 | [ "${status}" -eq 2 ] 33 | [ "${lines[0]}" == "■■ unrecognized option '--invalid-option'" ] 34 | [ "${lines[1]%% *}" == 'Usage:' ] 35 | } 36 | -------------------------------------------------------------------------------- /tests/argsh.bats: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load helper 4 | fixtures argsh 5 | 6 | @test "check args integration" { 7 | run "${PATH_BASE}/test.bats" -e "${FIXTURE_ROOT}"/bin/example 8 | log_on_failure 9 | [ $status -eq 0 ] 10 | } 11 | 12 | @test "check no args integration" { 13 | ARGSH_TEST="${FIXTURE_ROOT}"/bin/no-argsh \ 14 | run bats "${BATS_TEST_DIRNAME}"/source.bats 15 | log_on_failure 16 | [ $status -eq 1 ] 17 | } 18 | 19 | @test "execute action" { 20 | run "${FIXTURE_ROOT}"/bin/example --simple-output 21 | log_on_failure 22 | [ $status -eq 0 ] 23 | [ "${lines[0]}" == "wubba lubba dub dub" ] 24 | } 25 | 26 | @test "check if default value is set" { 27 | run "${FIXTURE_ROOT}"/bin/example --print 28 | log_on_failure 29 | [ $status -eq 0 ] 30 | [ "${lines[0]}" == "default value" ] 31 | } 32 | 33 | @test "overwrite default value" { 34 | local -r s="$(date '+%s')" 35 | run "${FIXTURE_ROOT}"/bin/example -i "${s}" --print 36 | log_on_failure 37 | [ $status -eq 0 ] 38 | [ "${lines[0]}" == "${s}" ] 39 | } 40 | 41 | @test "print environment variable" { 42 | export NON_EMPTY="Lorem Ipsum" 43 | run "${FIXTURE_ROOT}"/bin/example -v NON_EMPTY --print 44 | log_on_failure 45 | [ $status -eq 0 ] 46 | [ "${lines[0]}" == "Lorem Ipsum" ] 47 | } 48 | 49 | @test "do not overwrite env with empty default value" { 50 | export EMPTY="Lorem Ipsum" 51 | run "${FIXTURE_ROOT}"/bin/example -v EMPTY --print 52 | log_on_failure 53 | [ $status -eq 0 ] 54 | [ "${lines[0]}" == "Lorem Ipsum" ] 55 | } 56 | -------------------------------------------------------------------------------- /tests/fixtures/argsh/bin/example: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env argsh 2 | # shellcheck shell=bash 3 | # argsh shell=bash source=../vals/shared.sh 4 | 5 | # some globals 6 | : "${PATH_BASE:="$(git rev-parse --show-toplevel)"}" 7 | 8 | # setup args 9 | # argsh(i|input): env(INPUT) def(default value) des(set INPUT) val() 10 | # argsh(v|variable): env(VARIABLE) def(INPUT) val() 11 | # argsh(simple-output): des(test output.) 12 | # argsh(empty-default): env(EMPTY) def() 13 | # argsh(print): des(prints variable) 14 | 15 | 16 | main() { 17 | # given actions 18 | for ACTION in ${ARGSH_ACTIONS}; do case "${ACTION}" in 19 | simple-output) wubba ;; 20 | print) print ;; 21 | esac; done 22 | } 23 | 24 | wubba() { 25 | echo "wubba lubba dub dub" 26 | } 27 | 28 | print() { 29 | local -n ref="${VARIABLE}" 30 | echo "${ref}" 31 | } 32 | 33 | has_default() { 34 | : 35 | } 36 | 37 | has_value() { 38 | : 39 | } 40 | 41 | is_exported() { 42 | : 43 | } 44 | 45 | [[ "${0}" != "${BASH_SOURCE[0]}" ]] || main "${@}" -------------------------------------------------------------------------------- /tests/fixtures/argsh/bin/no-argsh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "nothing to do here! 🧪" -------------------------------------------------------------------------------- /tests/fixtures/argsh/vals/shared.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | _example_validator() { 4 | : 5 | } -------------------------------------------------------------------------------- /tests/helper.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | : "${PATH_BASE:="$(git rev-parse --show-toplevel)"}" 4 | 5 | fixtures() { 6 | FIXTURE_ROOT="${BATS_TEST_DIRNAME}/fixtures/${1}" 7 | RELATIVE_FIXTURE_ROOT="${FIXTURE_ROOT#${BATS_CWD}/}" 8 | } 9 | 10 | filter_control_sequences() { 11 | "${@}" 2>&1 | sed $'s,\x1b\\[[0-9;]*[a-zA-Z],,g' 12 | exit "${PIPESTATUS[0]}" 13 | } 14 | 15 | log_on_failure() { 16 | echo Failed with status "${status}" and output: 17 | echo "${output}" 18 | } --------------------------------------------------------------------------------