diff --git a/.hastest.bats b/.hastest.bats index 76d3cf8..f46511a 100644 --- a/.hastest.bats +++ b/.hastest.bats @@ -1,5 +1,8 @@ #!/usr/bin/env bats +load 'tests/libs/bats-support/load' +load 'tests/libs/bats-assert/load' + INSTALL_DIR= BATS_TMPDIR="${BATS_TMPDIR:-/tmp}" fancyx='✗' @@ -19,30 +22,63 @@ teardown() { fi } +_usage() { +<... +Has checks the presence of various command line tools on the PATH and reports their installed version. + +Options: + -q Silent mode + -h, --help Display this help text and quit + -V, --version Show version number and quit + +Examples: has git curl node + +SH +} + @test "invoking 'has' without arguments prints usage" { run $has - [ "$status" -eq 0 ] - [ "${lines[0]%% *}" = 'has' ] - [ "${lines[1]%%:*}" = 'USAGE' ] - [ "${lines[2]}" = 'EXAMPLE: has git curl node' ] + assert_success + assert_output <... +Has checks the presence of various command line tools on the PATH and reports their installed version. + +Options: + -q Silent mode + -h, --help Display this help text and quit + -V, --version Show version number and quit + +Examples: has git curl node + +SH } @test "make install creates a valid installation" { INSTALL_DIR="${HAS_TMPDIR}/.local" cd "${BATS_TEST_DIRNAME}" run make PREFIX="${INSTALL_DIR}" install - [ "$status" -eq 0 ] + + assert_success [ -x "${INSTALL_DIR}/bin/has" ] # has reads .hasrc from $PWD, so change anywhere else. cd "${INSTALL_DIR}" run "${INSTALL_DIR}/bin/has" - [ "$status" -eq 0 ] - [ "${lines[0]%% *}" = 'has' ] - [ "${lines[1]%%:*}" = 'USAGE' ] - [ "${lines[2]}" = 'EXAMPLE: has git curl node' ] - # [ "${lines[2]%%:*}" = 'EXAMPLE' ] + + assert_output <... +Has checks the presence of various command line tools on the PATH and reports their installed version. + +Options: + -q Silent mode + -h, --help Display this help text and quit + -V, --version Show version number and quit + +Examples: has git curl node + +SH } @test "..even if 'has' is missing from directory" { @@ -72,35 +108,35 @@ teardown() { run make update - [ "$status" -eq 0 ] + assert_success [ "$(echo "${output}" | grep "git fetch --verbose")" ] } @test "works with single command check" { run $has git - [ "$status" -eq 0 ] + assert_success [ "$(echo "${lines[0]}" | grep "git")" ] } @test "'has' warns about tools not configured" { run $has foobar - [ "$status" -eq 1 ] + assert_failure 1 [ "$(echo "${output}" | grep ${fancyx} | grep "foobar not understood")" ] } @test "env var 'HAS_ALLOW_UNSAFE' overrides safety check" { HAS_ALLOW_UNSAFE=y run $has foobar - [ "$status" -eq 1 ] + assert_failure 1 [ "$(echo "${output}" | grep ${fancyx} | grep "foobar")" ] } @test "status code reflects number of failed commands" { HAS_ALLOW_UNSAFE=y run $has foobar bc git barbaz - [ "$status" -eq 2 ] + assert_failure 2 [ "$(echo "${output}" | grep ${fancyx} | grep "foobar")" ] [ "$(echo "${output}" | grep ${fancyx} | grep "barbaz")" ] } @@ -108,7 +144,7 @@ teardown() { @test "status code reflects number of failed commands up to 126" { run $has $(for i in {1..256}; do echo foo; done) - [ "$status" -eq 126 ] + assert_failure 126 } @test "loads commands from .hasrc file and excludes comments" { @@ -116,7 +152,7 @@ teardown() { run $has - [ "$status" -eq 0 ] + assert_success [ "$(echo "${output}" | grep ${checkmark} | grep "bash")" ] [ "$(echo "${output}" | grep ${checkmark} | grep "make")" ] } @@ -125,7 +161,7 @@ teardown() { printf "bash\nmake\ngit" >> .hasrc HAS_ALLOW_UNSAFE=y run $has git bc - [ "$status" -eq 0 ] + assert_success [ "$(echo "${output}" | grep ${checkmark} | grep "bash")" ] [ "$(echo "${output}" | grep ${checkmark} | grep "make")" ] [ "$(echo "${output}" | grep ${checkmark} | grep "git")" ] @@ -135,21 +171,21 @@ teardown() { @test "testing PASS output with unicode" { run $has git - [ "$status" -eq 0 ] + assert_success [[ "printf '%b\n' ${lines[0]}" =~ '✓' ]] } @test "testing FAIL output with unicode" { run $has foobar - [ "$status" -eq 1 ] + assert_failure 1 [[ "printf '%b\n' ${lines[0]}" =~ '✗' ]] } @test "fail count 3: testing output with and without unicode" { run $has git foobar barbaz barfoo - [ "$status" -eq 3 ] + assert_failure 3 [[ "printf '%b\n' ${lines[0]}" =~ "${checkmark}" ]] [[ "printf '%b\n' ${lines[2]}" =~ '✗' ]] } @@ -157,7 +193,7 @@ teardown() { @test "testing archiving commands" { run $has tar unzip gzip xz unar pv zip - [ "$status" -eq 0 ] + assert_success [ "$(echo "${lines[0]}" | grep "tar")" ] [ "$(echo "${lines[1]}" | grep "unzip")" ] [ "$(echo "${lines[2]}" | grep "gzip")" ] @@ -170,7 +206,7 @@ teardown() { @test "testing coreutils commands" { run $has coreutils sed awk grep sudo file linuxutils - [ "$status" -eq 0 ] + assert_success [ "$(echo "${lines[0]}" | grep "gnu_coreutils")" ] [ "$(echo "${lines[5]}" | grep "file")" ] [ "$(echo "${lines[6]}" | grep "gnu_coreutils")" ] @@ -182,21 +218,35 @@ teardown() { fi run $has hub git - [ "$status" -eq 0 ] + assert_success [ "$(echo "${lines[0]}" | grep "hub")" ] [ "$(echo "${lines[1]}" | grep "git")" ] [ ! "${lines[0]##*\ }" = "${lines[1]##*\ }" ] } @test "quiet mode" { - run $has -q - [ "$status" -eq 0 ] + run $has -q git + + assert_success [ -z "${output}" ] } +@test "quiet mode should print usage when no commands or .hasrc file" { + run $has -q + + assert_success + [ "${lines[0]}" = 'Usage: has [OPTION] ...' ] + [ "${lines[1]}" = 'Has checks the presence of various command line tools on the PATH and reports their installed version.' ] + [ "${lines[2]}" = 'Options:' ] + [ "${lines[3]}" = ' -q Silent mode' ] + [ "${lines[4]}" = ' -h, --help Display this help text and quit' ] + [ "${lines[5]}" = ' -V, --version Show version number and quit' ] + [ "${lines[6]}" = 'Examples: has git curl node' ] +} + @test "status code in quiet mode still equal to number of failed commands" { HAS_ALLOW_UNSAFE=y run $has -q foobar bc git barbaz - [ "$status" -eq 2 ] + assert_failure 2 [ -z "${output}" ] } diff --git a/has b/has index 86ab1aa..cd0d578 100755 --- a/has +++ b/has @@ -42,6 +42,24 @@ REGEX_SIMPLE_VERSION="([[:digit:]]+\.?){2,3}" ## name of RC file that can contain list of tools to be checked RC_FILE=".hasrc" +_usage() { + cat <... +Has checks the presence of various command line tools on the PATH and reports their installed version. + +Options: + -q Silent mode + -h, --help Display this help text and quit + -V, --version Show version number and quit + +Examples: ${BINARY_NAME} git curl node +EOF +} + +_version() { + printf '%s\n' "${VERSION}" +} + # try to extract version by executing "${1}" with "${2}" arg # command name to be executed is dynamically passed to this function as ${1} # arg to ${1} is passed in ${2} @@ -247,15 +265,52 @@ __detect(){ OPTIND=1 OUTPUT=/dev/stdout -while getopts "q" opt; do - case "$opt" in - q) QUIET="true" - OUTPUT=/dev/null - ;; +while getopts ":qhV-" OPTION; do + case "$OPTION" in + q) + QUIET="true" + OUTPUT=/dev/null + ;; + h) + _usage + exit 0 + ;; + V) + _version + exit 0 + ;; + -) + [ $OPTIND -ge 1 ] && optind=$(expr $OPTIND - 1) || optind=$OPTIND + eval OPTION="\$$optind" + OPTARG=$(echo $OPTION | cut -d'=' -f2) + OPTION=$(echo $OPTION | cut -d'=' -f1) + case $OPTION in + --version) + _version + exit 0 + ;; + --help) + _usage + exit 0 + ;; + *) + printf '%s: unrecognized option '%s'\n' "${BINARY_NAME}" "${OPTARG}" + _usage + exit 2 + ;; esac + OPTIND=1 + shift + ;; + ?) + printf '%s: unrecognized option '%s'\n' "${BINARY_NAME}" "${OPTARG}" + _usage + exit 2 + ;; + esac done -shift $((OPTIND-1)) +shift $((OPTIND - 1)) if [ -s "${RC_FILE}" ]; then HASRC="true" @@ -263,11 +318,7 @@ fi # if HASRC is not set AND no arguments passed to script if [[ -z "${HASRC}" ]] && [ "$#" -eq 0 ]; then - # print help - printf '%s %s\n' "${BINARY_NAME}" "${VERSION}" > "$OUTPUT" - printf 'USAGE:\t %s [-q] ..\n' "${BINARY_NAME}" > "$OUTPUT" - printf 'EXAMPLE: %s git curl node\n' "${BINARY_NAME}" > "$OUTPUT" - + _usage else # for each cli-arg for cmd in "$@"; do