This commit is contained in:
ptt-homme 2020-08-31 18:56:21 +00:00 committed by GitHub
commit fe0acf1bf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 139 additions and 38 deletions

View File

@ -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() {
<<SH
Usage: has [OPTION] <command-names>...
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 <<SH
Usage: has [OPTION] <command-names>...
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 <<SH
Usage: has [OPTION] <command-names>...
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] <command-names>...' ]
[ "${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}" ]
}

73
has
View File

@ -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 <<EOF
Usage: ${BINARY_NAME} [OPTION] <command-names>...
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}
@ -250,15 +268,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"
@ -266,11 +321,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] <command-names>..\n' "${BINARY_NAME}" > "$OUTPUT"
printf 'EXAMPLE: %s git curl node\n' "${BINARY_NAME}" > "$OUTPUT"
_usage
else
# for each cli-arg
for cmd in "$@"; do