Fix the coverage tests
This fixes a bug where `make cover` was missing packages. The target now covers all code except for code placed in the top level package (such as main.go) and anything placed in the testutils directory. This also fixes minor issues with the Dockerfile and the coverage_check script Note that this commit also strives to increase code coverage beyond the 80% margin Change-Id: I9e1cbcf841cc869345a00f05e39774cb3da10065
This commit is contained in:
parent
08cc716de5
commit
dc9c78b210
@ -10,11 +10,7 @@ ENV GO111MODULE=on
|
||||
RUN make get-modules
|
||||
|
||||
ARG MAKE_TARGET=build
|
||||
RUN make ${MAKE_TARGET} && \
|
||||
if [[ "${MAKE_TARGET}" == 'lint' ]]; then \
|
||||
mkdir -p /usr/src/airshipctl/bin; \
|
||||
touch /usr/src/airshipctl/bin/airshipctl; \
|
||||
fi
|
||||
RUN make ${MAKE_TARGET}
|
||||
|
||||
FROM ${RELEASE_IMAGE} as release
|
||||
COPY --from=builder /usr/src/airshipctl/bin/airshipctl /usr/local/bin/airshipctl
|
||||
|
18
Makefile
18
Makefile
@ -18,11 +18,15 @@ DOCKER_IMAGE_NAME ?= airshipctl
|
||||
DOCKER_IMAGE_PREFIX ?= airshipit
|
||||
DOCKER_IMAGE_TAG ?= dev
|
||||
DOCKER_IMAGE ?= $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_PREFIX)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)
|
||||
DOCKER_TARGET_STAGE ?= release
|
||||
|
||||
# go options
|
||||
PKG := ./...
|
||||
TESTS := .
|
||||
TEST_FLAGS :=
|
||||
COVER_FLAGS :=
|
||||
COVER_PROFILE := cover.out
|
||||
COVER_PKG := $(shell go list ./... | tail -n+2 | grep -v "opendev.org/airship/airshipctl/testutil" | paste -sd"," -)
|
||||
|
||||
.PHONY: get-modules
|
||||
get-modules:
|
||||
@ -34,17 +38,17 @@ build: get-modules
|
||||
|
||||
.PHONY: test
|
||||
test: lint
|
||||
test: TESTFLAGS += -race -v
|
||||
test: unit-tests
|
||||
test: cover
|
||||
|
||||
.PHONY: unit-tests
|
||||
unit-tests: build
|
||||
unit-tests: TESTFLAGS += -race -v
|
||||
unit-tests:
|
||||
@echo "Performing unit test step..."
|
||||
@GO111MODULE=on go test -run $(TESTS) $(PKG) $(TESTFLAGS) -covermode=atomic -coverprofile=$(COVER_PROFILE)
|
||||
@GO111MODULE=on go test -run $(TESTS) $(PKG) $(TESTFLAGS) $(COVER_FLAGS)
|
||||
@echo "All unit tests passed"
|
||||
|
||||
.PHONY: cover
|
||||
cover: COVER_FLAGS = -covermode=atomic -coverprofile=$(COVER_PROFILE) -coverpkg=$(COVER_PKG)
|
||||
cover: unit-tests
|
||||
@./tools/coverage_check $(COVER_PROFILE)
|
||||
|
||||
@ -56,7 +60,7 @@ lint:
|
||||
|
||||
.PHONY: docker-image
|
||||
docker-image:
|
||||
@docker build . --build-arg MAKE_TARGET=$(DOCKER_MAKE_TARGET) --tag $(DOCKER_IMAGE)
|
||||
@docker build . --build-arg MAKE_TARGET=$(DOCKER_MAKE_TARGET) --tag $(DOCKER_IMAGE) --target $(DOCKER_TARGET_STAGE)
|
||||
|
||||
.PHONY: print-docker-image-tag
|
||||
print-docker-image-tag:
|
||||
@ -64,10 +68,12 @@ print-docker-image-tag:
|
||||
|
||||
.PHONY: docker-image-unit-tests
|
||||
docker-image-unit-tests: DOCKER_MAKE_TARGET = cover
|
||||
docker-image-unit-tests: DOCKER_TARGET_STAGE = builder
|
||||
docker-image-unit-tests: docker-image
|
||||
|
||||
.PHONY: docker-image-lint
|
||||
docker-image-lint: DOCKER_MAKE_TARGET = lint
|
||||
docker-image-lint: DOCKER_TARGET_STAGE = builder
|
||||
docker-image-lint: docker-image
|
||||
|
||||
.PHONY: clean
|
||||
@ -81,7 +87,7 @@ docs:
|
||||
|
||||
.PHONY: update-golden
|
||||
update-golden: delete-golden
|
||||
update-golden: TESTFLAGS += -update -v
|
||||
update-golden: TESTFLAGS += -update
|
||||
update-golden: PKG = opendev.org/airship/airshipctl/cmd/...
|
||||
update-golden: unit-tests
|
||||
|
||||
|
48
cmd/completion/completion_test.go
Normal file
48
cmd/completion/completion_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
package completion_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"opendev.org/airship/airshipctl/cmd/completion"
|
||||
"opendev.org/airship/airshipctl/testutil"
|
||||
)
|
||||
|
||||
func TestCompletion(t *testing.T) {
|
||||
cmd := completion.NewCompletionCommand()
|
||||
|
||||
cmdTests := []*testutil.CmdTest{
|
||||
{
|
||||
Name: "completion-bash",
|
||||
CmdLine: "bash",
|
||||
Cmd: cmd,
|
||||
},
|
||||
{
|
||||
Name: "completion-zsh",
|
||||
CmdLine: "zsh",
|
||||
Cmd: cmd,
|
||||
},
|
||||
{
|
||||
Name: "completion-no-args",
|
||||
CmdLine: "",
|
||||
Cmd: cmd,
|
||||
Error: errors.New("shell not specified"),
|
||||
},
|
||||
{
|
||||
Name: "completion-too-many-args",
|
||||
CmdLine: "bash zsh",
|
||||
Cmd: cmd,
|
||||
Error: errors.New("too many arguments, expected only the shell type"),
|
||||
},
|
||||
{
|
||||
Name: "completion-unknown-shell",
|
||||
CmdLine: "fish",
|
||||
Cmd: cmd,
|
||||
Error: errors.New("unsupported shell type \"fish\""),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range cmdTests {
|
||||
testutil.RunTest(t, tt)
|
||||
}
|
||||
}
|
303
cmd/completion/testdata/TestCompletionGoldenOutput/completion-bash.golden
vendored
Normal file
303
cmd/completion/testdata/TestCompletionGoldenOutput/completion-bash.golden
vendored
Normal file
@ -0,0 +1,303 @@
|
||||
# bash completion for completion -*- shell-script -*-
|
||||
|
||||
__completion_debug()
|
||||
{
|
||||
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
|
||||
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
|
||||
# _init_completion. This is a very minimal version of that function.
|
||||
__completion_init_completion()
|
||||
{
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref "$@" cur prev words cword
|
||||
}
|
||||
|
||||
__completion_index_of_word()
|
||||
{
|
||||
local w word=$1
|
||||
shift
|
||||
index=0
|
||||
for w in "$@"; do
|
||||
[[ $w = "$word" ]] && return
|
||||
index=$((index+1))
|
||||
done
|
||||
index=-1
|
||||
}
|
||||
|
||||
__completion_contains_word()
|
||||
{
|
||||
local w word=$1; shift
|
||||
for w in "$@"; do
|
||||
[[ $w = "$word" ]] && return
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
__completion_handle_reply()
|
||||
{
|
||||
__completion_debug "${FUNCNAME[0]}"
|
||||
case $cur in
|
||||
-*)
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
compopt -o nospace
|
||||
fi
|
||||
local allflags
|
||||
if [ ${#must_have_one_flag[@]} -ne 0 ]; then
|
||||
allflags=("${must_have_one_flag[@]}")
|
||||
else
|
||||
allflags=("${flags[*]} ${two_word_flags[*]}")
|
||||
fi
|
||||
COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
[[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
|
||||
fi
|
||||
|
||||
# complete after --flag=abc
|
||||
if [[ $cur == *=* ]]; then
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
compopt +o nospace
|
||||
fi
|
||||
|
||||
local index flag
|
||||
flag="${cur%=*}"
|
||||
__completion_index_of_word "${flag}" "${flags_with_completion[@]}"
|
||||
COMPREPLY=()
|
||||
if [[ ${index} -ge 0 ]]; then
|
||||
PREFIX=""
|
||||
cur="${cur#*=}"
|
||||
${flags_completion[${index}]}
|
||||
if [ -n "${ZSH_VERSION}" ]; then
|
||||
# zsh completion needs --flag= prefix
|
||||
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
return 0;
|
||||
;;
|
||||
esac
|
||||
|
||||
# check if we are handling a flag with special work handling
|
||||
local index
|
||||
__completion_index_of_word "${prev}" "${flags_with_completion[@]}"
|
||||
if [[ ${index} -ge 0 ]]; then
|
||||
${flags_completion[${index}]}
|
||||
return
|
||||
fi
|
||||
|
||||
# we are parsing a flag and don't have a special handler, no completion
|
||||
if [[ ${cur} != "${words[cword]}" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local completions
|
||||
completions=("${commands[@]}")
|
||||
if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
|
||||
completions=("${must_have_one_noun[@]}")
|
||||
fi
|
||||
if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
|
||||
completions+=("${must_have_one_flag[@]}")
|
||||
fi
|
||||
COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
|
||||
|
||||
if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
|
||||
COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
|
||||
fi
|
||||
|
||||
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
|
||||
declare -F __custom_func >/dev/null && __custom_func
|
||||
fi
|
||||
|
||||
# available in bash-completion >= 2, not always present on macOS
|
||||
if declare -F __ltrim_colon_completions >/dev/null; then
|
||||
__ltrim_colon_completions "$cur"
|
||||
fi
|
||||
|
||||
# If there is only 1 completion and it is a flag with an = it will be completed
|
||||
# but we don't want a space after the =
|
||||
if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then
|
||||
compopt -o nospace
|
||||
fi
|
||||
}
|
||||
|
||||
# The arguments should be in the form "ext1|ext2|extn"
|
||||
__completion_handle_filename_extension_flag()
|
||||
{
|
||||
local ext="$1"
|
||||
_filedir "@(${ext})"
|
||||
}
|
||||
|
||||
__completion_handle_subdirs_in_dir_flag()
|
||||
{
|
||||
local dir="$1"
|
||||
pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
|
||||
}
|
||||
|
||||
__completion_handle_flag()
|
||||
{
|
||||
__completion_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
# if a command required a flag, and we found it, unset must_have_one_flag()
|
||||
local flagname=${words[c]}
|
||||
local flagvalue
|
||||
# if the word contained an =
|
||||
if [[ ${words[c]} == *"="* ]]; then
|
||||
flagvalue=${flagname#*=} # take in as flagvalue after the =
|
||||
flagname=${flagname%=*} # strip everything after the =
|
||||
flagname="${flagname}=" # but put the = back
|
||||
fi
|
||||
__completion_debug "${FUNCNAME[0]}: looking for ${flagname}"
|
||||
if __completion_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
|
||||
must_have_one_flag=()
|
||||
fi
|
||||
|
||||
# if you set a flag which only applies to this command, don't show subcommands
|
||||
if __completion_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
|
||||
commands=()
|
||||
fi
|
||||
|
||||
# keep flag value with flagname as flaghash
|
||||
# flaghash variable is an associative array which is only supported in bash > 3.
|
||||
if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
|
||||
if [ -n "${flagvalue}" ] ; then
|
||||
flaghash[${flagname}]=${flagvalue}
|
||||
elif [ -n "${words[ $((c+1)) ]}" ] ; then
|
||||
flaghash[${flagname}]=${words[ $((c+1)) ]}
|
||||
else
|
||||
flaghash[${flagname}]="true" # pad "true" for bool flag
|
||||
fi
|
||||
fi
|
||||
|
||||
# skip the argument to a two word flag
|
||||
if __completion_contains_word "${words[c]}" "${two_word_flags[@]}"; then
|
||||
c=$((c+1))
|
||||
# if we are looking for a flags value, don't show commands
|
||||
if [[ $c -eq $cword ]]; then
|
||||
commands=()
|
||||
fi
|
||||
fi
|
||||
|
||||
c=$((c+1))
|
||||
|
||||
}
|
||||
|
||||
__completion_handle_noun()
|
||||
{
|
||||
__completion_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
if __completion_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
|
||||
must_have_one_noun=()
|
||||
elif __completion_contains_word "${words[c]}" "${noun_aliases[@]}"; then
|
||||
must_have_one_noun=()
|
||||
fi
|
||||
|
||||
nouns+=("${words[c]}")
|
||||
c=$((c+1))
|
||||
}
|
||||
|
||||
__completion_handle_command()
|
||||
{
|
||||
__completion_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
local next_command
|
||||
if [[ -n ${last_command} ]]; then
|
||||
next_command="_${last_command}_${words[c]//:/__}"
|
||||
else
|
||||
if [[ $c -eq 0 ]]; then
|
||||
next_command="_completion_root_command"
|
||||
else
|
||||
next_command="_${words[c]//:/__}"
|
||||
fi
|
||||
fi
|
||||
c=$((c+1))
|
||||
__completion_debug "${FUNCNAME[0]}: looking for ${next_command}"
|
||||
declare -F "$next_command" >/dev/null && $next_command
|
||||
}
|
||||
|
||||
__completion_handle_word()
|
||||
{
|
||||
if [[ $c -ge $cword ]]; then
|
||||
__completion_handle_reply
|
||||
return
|
||||
fi
|
||||
__completion_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
if [[ "${words[c]}" == -* ]]; then
|
||||
__completion_handle_flag
|
||||
elif __completion_contains_word "${words[c]}" "${commands[@]}"; then
|
||||
__completion_handle_command
|
||||
elif [[ $c -eq 0 ]]; then
|
||||
__completion_handle_command
|
||||
elif __completion_contains_word "${words[c]}" "${command_aliases[@]}"; then
|
||||
# aliashash variable is an associative array which is only supported in bash > 3.
|
||||
if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
|
||||
words[c]=${aliashash[${words[c]}]}
|
||||
__completion_handle_command
|
||||
else
|
||||
__completion_handle_noun
|
||||
fi
|
||||
else
|
||||
__completion_handle_noun
|
||||
fi
|
||||
__completion_handle_word
|
||||
}
|
||||
|
||||
_completion_root_command()
|
||||
{
|
||||
last_command="completion"
|
||||
|
||||
command_aliases=()
|
||||
|
||||
commands=()
|
||||
|
||||
flags=()
|
||||
two_word_flags=()
|
||||
local_nonpersistent_flags=()
|
||||
flags_with_completion=()
|
||||
flags_completion=()
|
||||
|
||||
flags+=("--help")
|
||||
flags+=("-h")
|
||||
local_nonpersistent_flags+=("--help")
|
||||
|
||||
must_have_one_flag=()
|
||||
must_have_one_noun=()
|
||||
must_have_one_noun+=("bash")
|
||||
must_have_one_noun+=("zsh")
|
||||
noun_aliases=()
|
||||
}
|
||||
|
||||
__start_completion()
|
||||
{
|
||||
local cur prev words cword
|
||||
declare -A flaghash 2>/dev/null || :
|
||||
declare -A aliashash 2>/dev/null || :
|
||||
if declare -F _init_completion >/dev/null 2>&1; then
|
||||
_init_completion -s || return
|
||||
else
|
||||
__completion_init_completion -n "=" || return
|
||||
fi
|
||||
|
||||
local c=0
|
||||
local flags=()
|
||||
local two_word_flags=()
|
||||
local local_nonpersistent_flags=()
|
||||
local flags_with_completion=()
|
||||
local flags_completion=()
|
||||
local commands=("completion")
|
||||
local must_have_one_flag=()
|
||||
local must_have_one_noun=()
|
||||
local last_command
|
||||
local nouns=()
|
||||
|
||||
__completion_handle_word
|
||||
}
|
||||
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
complete -o default -F __start_completion completion
|
||||
else
|
||||
complete -o default -o nospace -F __start_completion completion
|
||||
fi
|
||||
|
||||
# ex: ts=4 sw=4 et filetype=sh
|
7
cmd/completion/testdata/TestCompletionGoldenOutput/completion-no-args.golden
vendored
Normal file
7
cmd/completion/testdata/TestCompletionGoldenOutput/completion-no-args.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
Error: shell not specified
|
||||
Usage:
|
||||
completion SHELL [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for completion
|
||||
|
7
cmd/completion/testdata/TestCompletionGoldenOutput/completion-too-many-args.golden
vendored
Normal file
7
cmd/completion/testdata/TestCompletionGoldenOutput/completion-too-many-args.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
Error: too many arguments, expected only the shell type
|
||||
Usage:
|
||||
completion SHELL [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for completion
|
||||
|
7
cmd/completion/testdata/TestCompletionGoldenOutput/completion-unknown-shell.golden
vendored
Normal file
7
cmd/completion/testdata/TestCompletionGoldenOutput/completion-unknown-shell.golden
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
Error: unsupported shell type "fish"
|
||||
Usage:
|
||||
completion SHELL [flags]
|
||||
|
||||
Flags:
|
||||
-h, --help help for completion
|
||||
|
441
cmd/completion/testdata/TestCompletionGoldenOutput/completion-zsh.golden
vendored
Normal file
441
cmd/completion/testdata/TestCompletionGoldenOutput/completion-zsh.golden
vendored
Normal file
@ -0,0 +1,441 @@
|
||||
#compdef airshipctl
|
||||
|
||||
__airshipctl_bash_source() {
|
||||
alias shopt=':'
|
||||
alias _expand=_bash_expand
|
||||
alias _complete=_bash_comp
|
||||
emulate -L sh
|
||||
setopt kshglob noshglob braceexpand
|
||||
source "$@"
|
||||
}
|
||||
__airshipctl_type() {
|
||||
# -t is not supported by zsh
|
||||
if [ "$1" == "-t" ]; then
|
||||
shift
|
||||
# fake Bash 4 to disable "complete -o nospace". Instead
|
||||
# "compopt +-o nospace" is used in the code to toggle trailing
|
||||
# spaces. We don't support that, but leave trailing spaces on
|
||||
# all the time
|
||||
if [ "$1" = "__airshipctl_compopt" ]; then
|
||||
echo builtin
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
type "$@"
|
||||
}
|
||||
__airshipctl_compgen() {
|
||||
local completions w
|
||||
completions=( $(compgen "$@") ) || return $?
|
||||
# filter by given word as prefix
|
||||
while [[ "$1" = -* && "$1" != -- ]]; do
|
||||
shift
|
||||
shift
|
||||
done
|
||||
if [[ "$1" == -- ]]; then
|
||||
shift
|
||||
fi
|
||||
for w in "${completions[@]}"; do
|
||||
if [[ "${w}" = "$1"* ]]; then
|
||||
echo "${w}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
__airshipctl_compopt() {
|
||||
true # don't do anything. Not supported by bashcompinit in zsh
|
||||
}
|
||||
__airshipctl_declare() {
|
||||
if [ "$1" == "-F" ]; then
|
||||
whence -w "$@"
|
||||
else
|
||||
builtin declare "$@"
|
||||
fi
|
||||
}
|
||||
__airshipctl_ltrim_colon_completions()
|
||||
{
|
||||
if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
|
||||
# Remove colon-word prefix from COMPREPLY items
|
||||
local colon_word=${1%${1##*:}}
|
||||
local i=${#COMPREPLY[*]}
|
||||
while [[ $((--i)) -ge 0 ]]; do
|
||||
COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
|
||||
done
|
||||
fi
|
||||
}
|
||||
__airshipctl_get_comp_words_by_ref() {
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
prev="${COMP_WORDS[${COMP_CWORD}-1]}"
|
||||
words=("${COMP_WORDS[@]}")
|
||||
cword=("${COMP_CWORD[@]}")
|
||||
}
|
||||
__airshipctl_filedir() {
|
||||
local RET OLD_IFS w qw
|
||||
__debug "_filedir $@ cur=$cur"
|
||||
if [[ "$1" = \~* ]]; then
|
||||
# somehow does not work. Maybe, zsh does not call this at all
|
||||
eval echo "$1"
|
||||
return 0
|
||||
fi
|
||||
OLD_IFS="$IFS"
|
||||
IFS=$'\n'
|
||||
if [ "$1" = "-d" ]; then
|
||||
shift
|
||||
RET=( $(compgen -d) )
|
||||
else
|
||||
RET=( $(compgen -f) )
|
||||
fi
|
||||
IFS="$OLD_IFS"
|
||||
IFS="," __debug "RET=${RET[@]} len=${#RET[@]}"
|
||||
for w in ${RET[@]}; do
|
||||
if [[ ! "${w}" = "${cur}"* ]]; then
|
||||
continue
|
||||
fi
|
||||
if eval "[[ \"\${w}\" = *.$1 || -d \"\${w}\" ]]"; then
|
||||
qw="$(__airshipctl_quote "${w}")"
|
||||
if [ -d "${w}" ]; then
|
||||
COMPREPLY+=("${qw}/")
|
||||
else
|
||||
COMPREPLY+=("${qw}")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
__airshipctl_quote() {
|
||||
if [[ $1 == \'* || $1 == \"* ]]; then
|
||||
# Leave out first character
|
||||
printf %q "${1:1}"
|
||||
else
|
||||
printf %q "$1"
|
||||
fi
|
||||
}
|
||||
autoload -U +X bashcompinit && bashcompinit
|
||||
# use word boundary patterns for BSD or GNU sed
|
||||
LWORD='[[:<:]]'
|
||||
RWORD='[[:>:]]'
|
||||
if sed --help 2>&1 | grep -q GNU; then
|
||||
LWORD='\<'
|
||||
RWORD='\>'
|
||||
fi
|
||||
__airshipctl_convert_bash_to_zsh() {
|
||||
sed \
|
||||
-e 's/declare -F/whence -w/' \
|
||||
-e 's/_get_comp_words_by_ref "\$@"/_get_comp_words_by_ref "\$*"/' \
|
||||
-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
|
||||
-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
|
||||
-e 's/must_have_one_flag+=("\(--.*\)=")/must_have_one_flag+=("\1")/' \
|
||||
-e "s/${LWORD}_filedir${RWORD}/__airshipctl_filedir/g" \
|
||||
-e "s/${LWORD}_get_comp_words_by_ref${RWORD}/__airshipctl_get_comp_words_by_ref/g" \
|
||||
-e "s/${LWORD}__ltrim_colon_completions${RWORD}/__airshipctl_ltrim_colon_completions/g" \
|
||||
-e "s/${LWORD}compgen${RWORD}/__airshipctl_compgen/g" \
|
||||
-e "s/${LWORD}compopt${RWORD}/__airshipctl_compopt/g" \
|
||||
-e "s/${LWORD}declare${RWORD}/__airshipctl_declare/g" \
|
||||
-e "s/\\\$(type${RWORD}/\$(__airshipctl_type/g" \
|
||||
-e 's/aliashash\["\(.\{1,\}\)"\]/aliashash[\1]/g' \
|
||||
-e 's/FUNCNAME/funcstack/g' \
|
||||
<<'BASH_COMPLETION_EOF'
|
||||
# bash completion for completion -*- shell-script -*-
|
||||
|
||||
__completion_debug()
|
||||
{
|
||||
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
|
||||
echo "$*" >> "${BASH_COMP_DEBUG_FILE}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Homebrew on Macs have version 1.3 of bash-completion which doesn't include
|
||||
# _init_completion. This is a very minimal version of that function.
|
||||
__completion_init_completion()
|
||||
{
|
||||
COMPREPLY=()
|
||||
_get_comp_words_by_ref "$@" cur prev words cword
|
||||
}
|
||||
|
||||
__completion_index_of_word()
|
||||
{
|
||||
local w word=$1
|
||||
shift
|
||||
index=0
|
||||
for w in "$@"; do
|
||||
[[ $w = "$word" ]] && return
|
||||
index=$((index+1))
|
||||
done
|
||||
index=-1
|
||||
}
|
||||
|
||||
__completion_contains_word()
|
||||
{
|
||||
local w word=$1; shift
|
||||
for w in "$@"; do
|
||||
[[ $w = "$word" ]] && return
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
__completion_handle_reply()
|
||||
{
|
||||
__completion_debug "${FUNCNAME[0]}"
|
||||
case $cur in
|
||||
-*)
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
compopt -o nospace
|
||||
fi
|
||||
local allflags
|
||||
if [ ${#must_have_one_flag[@]} -ne 0 ]; then
|
||||
allflags=("${must_have_one_flag[@]}")
|
||||
else
|
||||
allflags=("${flags[*]} ${two_word_flags[*]}")
|
||||
fi
|
||||
COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
[[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
|
||||
fi
|
||||
|
||||
# complete after --flag=abc
|
||||
if [[ $cur == *=* ]]; then
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
compopt +o nospace
|
||||
fi
|
||||
|
||||
local index flag
|
||||
flag="${cur%=*}"
|
||||
__completion_index_of_word "${flag}" "${flags_with_completion[@]}"
|
||||
COMPREPLY=()
|
||||
if [[ ${index} -ge 0 ]]; then
|
||||
PREFIX=""
|
||||
cur="${cur#*=}"
|
||||
${flags_completion[${index}]}
|
||||
if [ -n "${ZSH_VERSION}" ]; then
|
||||
# zsh completion needs --flag= prefix
|
||||
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
return 0;
|
||||
;;
|
||||
esac
|
||||
|
||||
# check if we are handling a flag with special work handling
|
||||
local index
|
||||
__completion_index_of_word "${prev}" "${flags_with_completion[@]}"
|
||||
if [[ ${index} -ge 0 ]]; then
|
||||
${flags_completion[${index}]}
|
||||
return
|
||||
fi
|
||||
|
||||
# we are parsing a flag and don't have a special handler, no completion
|
||||
if [[ ${cur} != "${words[cword]}" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local completions
|
||||
completions=("${commands[@]}")
|
||||
if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
|
||||
completions=("${must_have_one_noun[@]}")
|
||||
fi
|
||||
if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
|
||||
completions+=("${must_have_one_flag[@]}")
|
||||
fi
|
||||
COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
|
||||
|
||||
if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
|
||||
COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
|
||||
fi
|
||||
|
||||
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
|
||||
declare -F __custom_func >/dev/null && __custom_func
|
||||
fi
|
||||
|
||||
# available in bash-completion >= 2, not always present on macOS
|
||||
if declare -F __ltrim_colon_completions >/dev/null; then
|
||||
__ltrim_colon_completions "$cur"
|
||||
fi
|
||||
|
||||
# If there is only 1 completion and it is a flag with an = it will be completed
|
||||
# but we don't want a space after the =
|
||||
if [[ "${#COMPREPLY[@]}" -eq "1" ]] && [[ $(type -t compopt) = "builtin" ]] && [[ "${COMPREPLY[0]}" == --*= ]]; then
|
||||
compopt -o nospace
|
||||
fi
|
||||
}
|
||||
|
||||
# The arguments should be in the form "ext1|ext2|extn"
|
||||
__completion_handle_filename_extension_flag()
|
||||
{
|
||||
local ext="$1"
|
||||
_filedir "@(${ext})"
|
||||
}
|
||||
|
||||
__completion_handle_subdirs_in_dir_flag()
|
||||
{
|
||||
local dir="$1"
|
||||
pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
|
||||
}
|
||||
|
||||
__completion_handle_flag()
|
||||
{
|
||||
__completion_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
# if a command required a flag, and we found it, unset must_have_one_flag()
|
||||
local flagname=${words[c]}
|
||||
local flagvalue
|
||||
# if the word contained an =
|
||||
if [[ ${words[c]} == *"="* ]]; then
|
||||
flagvalue=${flagname#*=} # take in as flagvalue after the =
|
||||
flagname=${flagname%=*} # strip everything after the =
|
||||
flagname="${flagname}=" # but put the = back
|
||||
fi
|
||||
__completion_debug "${FUNCNAME[0]}: looking for ${flagname}"
|
||||
if __completion_contains_word "${flagname}" "${must_have_one_flag[@]}"; then
|
||||
must_have_one_flag=()
|
||||
fi
|
||||
|
||||
# if you set a flag which only applies to this command, don't show subcommands
|
||||
if __completion_contains_word "${flagname}" "${local_nonpersistent_flags[@]}"; then
|
||||
commands=()
|
||||
fi
|
||||
|
||||
# keep flag value with flagname as flaghash
|
||||
# flaghash variable is an associative array which is only supported in bash > 3.
|
||||
if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
|
||||
if [ -n "${flagvalue}" ] ; then
|
||||
flaghash[${flagname}]=${flagvalue}
|
||||
elif [ -n "${words[ $((c+1)) ]}" ] ; then
|
||||
flaghash[${flagname}]=${words[ $((c+1)) ]}
|
||||
else
|
||||
flaghash[${flagname}]="true" # pad "true" for bool flag
|
||||
fi
|
||||
fi
|
||||
|
||||
# skip the argument to a two word flag
|
||||
if __completion_contains_word "${words[c]}" "${two_word_flags[@]}"; then
|
||||
c=$((c+1))
|
||||
# if we are looking for a flags value, don't show commands
|
||||
if [[ $c -eq $cword ]]; then
|
||||
commands=()
|
||||
fi
|
||||
fi
|
||||
|
||||
c=$((c+1))
|
||||
|
||||
}
|
||||
|
||||
__completion_handle_noun()
|
||||
{
|
||||
__completion_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
if __completion_contains_word "${words[c]}" "${must_have_one_noun[@]}"; then
|
||||
must_have_one_noun=()
|
||||
elif __completion_contains_word "${words[c]}" "${noun_aliases[@]}"; then
|
||||
must_have_one_noun=()
|
||||
fi
|
||||
|
||||
nouns+=("${words[c]}")
|
||||
c=$((c+1))
|
||||
}
|
||||
|
||||
__completion_handle_command()
|
||||
{
|
||||
__completion_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
|
||||
local next_command
|
||||
if [[ -n ${last_command} ]]; then
|
||||
next_command="_${last_command}_${words[c]//:/__}"
|
||||
else
|
||||
if [[ $c -eq 0 ]]; then
|
||||
next_command="_completion_root_command"
|
||||
else
|
||||
next_command="_${words[c]//:/__}"
|
||||
fi
|
||||
fi
|
||||
c=$((c+1))
|
||||
__completion_debug "${FUNCNAME[0]}: looking for ${next_command}"
|
||||
declare -F "$next_command" >/dev/null && $next_command
|
||||
}
|
||||
|
||||
__completion_handle_word()
|
||||
{
|
||||
if [[ $c -ge $cword ]]; then
|
||||
__completion_handle_reply
|
||||
return
|
||||
fi
|
||||
__completion_debug "${FUNCNAME[0]}: c is $c words[c] is ${words[c]}"
|
||||
if [[ "${words[c]}" == -* ]]; then
|
||||
__completion_handle_flag
|
||||
elif __completion_contains_word "${words[c]}" "${commands[@]}"; then
|
||||
__completion_handle_command
|
||||
elif [[ $c -eq 0 ]]; then
|
||||
__completion_handle_command
|
||||
elif __completion_contains_word "${words[c]}" "${command_aliases[@]}"; then
|
||||
# aliashash variable is an associative array which is only supported in bash > 3.
|
||||
if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then
|
||||
words[c]=${aliashash[${words[c]}]}
|
||||
__completion_handle_command
|
||||
else
|
||||
__completion_handle_noun
|
||||
fi
|
||||
else
|
||||
__completion_handle_noun
|
||||
fi
|
||||
__completion_handle_word
|
||||
}
|
||||
|
||||
_completion_root_command()
|
||||
{
|
||||
last_command="completion"
|
||||
|
||||
command_aliases=()
|
||||
|
||||
commands=()
|
||||
|
||||
flags=()
|
||||
two_word_flags=()
|
||||
local_nonpersistent_flags=()
|
||||
flags_with_completion=()
|
||||
flags_completion=()
|
||||
|
||||
flags+=("--help")
|
||||
flags+=("-h")
|
||||
local_nonpersistent_flags+=("--help")
|
||||
|
||||
must_have_one_flag=()
|
||||
must_have_one_noun=()
|
||||
must_have_one_noun+=("bash")
|
||||
must_have_one_noun+=("zsh")
|
||||
noun_aliases=()
|
||||
}
|
||||
|
||||
__start_completion()
|
||||
{
|
||||
local cur prev words cword
|
||||
declare -A flaghash 2>/dev/null || :
|
||||
declare -A aliashash 2>/dev/null || :
|
||||
if declare -F _init_completion >/dev/null 2>&1; then
|
||||
_init_completion -s || return
|
||||
else
|
||||
__completion_init_completion -n "=" || return
|
||||
fi
|
||||
|
||||
local c=0
|
||||
local flags=()
|
||||
local two_word_flags=()
|
||||
local local_nonpersistent_flags=()
|
||||
local flags_with_completion=()
|
||||
local flags_completion=()
|
||||
local commands=("completion")
|
||||
local must_have_one_flag=()
|
||||
local must_have_one_noun=()
|
||||
local last_command
|
||||
local nouns=()
|
||||
|
||||
__completion_handle_word
|
||||
}
|
||||
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
complete -o default -F __start_completion completion
|
||||
else
|
||||
complete -o default -o nospace -F __start_completion completion
|
||||
fi
|
||||
|
||||
# ex: ts=4 sw=4 et filetype=sh
|
||||
|
||||
BASH_COMPLETION_EOF
|
||||
}
|
||||
__airshipctl_bash_source <(__airshipctl_convert_bash_to_zsh)
|
22
pkg/util/configreader_test.go
Normal file
22
pkg/util/configreader_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package util_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"opendev.org/airship/airshipctl/pkg/util"
|
||||
)
|
||||
|
||||
func TestReadYAMLFile(t *testing.T) {
|
||||
var actual map[string]interface{}
|
||||
if err := util.ReadYAMLFile("testdata/test.yaml", &actual); err != nil {
|
||||
t.Fatalf("Error while reading YAML: %s", err.Error())
|
||||
}
|
||||
expectedString := "test"
|
||||
actualString, ok := actual["testString"]
|
||||
if !ok {
|
||||
t.Fatalf("Missing \"testString\" attribute")
|
||||
}
|
||||
if actualString != expectedString {
|
||||
t.Errorf("Expected %s, got %s", expectedString, actualString)
|
||||
}
|
||||
}
|
1
pkg/util/testdata/test.yaml
vendored
Normal file
1
pkg/util/testdata/test.yaml
vendored
Normal file
@ -0,0 +1 @@
|
||||
testString: test
|
@ -33,6 +33,9 @@ type CmdTest struct {
|
||||
|
||||
// The instatiated version of the root airshipctl command to test
|
||||
Cmd *cobra.Command
|
||||
|
||||
// The expected error
|
||||
Error error
|
||||
}
|
||||
|
||||
// RunTest either asserts that a specific command's output matches the expected
|
||||
@ -47,9 +50,8 @@ func RunTest(t *testing.T, test *CmdTest) {
|
||||
args := strings.Fields(test.CmdLine)
|
||||
cmd.SetArgs(args)
|
||||
|
||||
if err := cmd.Execute(); err != nil {
|
||||
t.Fatalf("Unexpected error: %s", err.Error())
|
||||
}
|
||||
err := cmd.Execute()
|
||||
checkError(t, err, test.Error)
|
||||
|
||||
if *shouldUpdateGolden {
|
||||
updateGolden(t, test, actual.Bytes())
|
||||
@ -58,6 +60,20 @@ func RunTest(t *testing.T, test *CmdTest) {
|
||||
}
|
||||
}
|
||||
|
||||
// ReadFixtureBytes is a convenience function for opening a test fixture
|
||||
func ReadFixtureBytes(t *testing.T, filename string) []byte {
|
||||
fixtureData, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error while reading fixture at %s: %s", filename, err.Error())
|
||||
}
|
||||
return fixtureData
|
||||
}
|
||||
|
||||
// ReadFixtureString is a convenience function for opening a test fixture
|
||||
func ReadFixtureString(t *testing.T, filename string) string {
|
||||
return string(ReadFixtureBytes(t, filename))
|
||||
}
|
||||
|
||||
func updateGolden(t *testing.T, test *CmdTest, actual []byte) {
|
||||
goldenDir := filepath.Join(testdataDir, t.Name()+goldenDirSuffix)
|
||||
if err := os.MkdirAll(goldenDir, 0775); err != nil {
|
||||
@ -84,6 +100,23 @@ func assertEqualGolden(t *testing.T, test *CmdTest, actual []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func checkError(t *testing.T, actual, expected error) {
|
||||
if expected == nil {
|
||||
if actual == nil {
|
||||
return
|
||||
}
|
||||
t.Fatalf("Unexpected error: %q", actual.Error())
|
||||
}
|
||||
|
||||
if actual == nil {
|
||||
t.Fatalf("Expected error %q, but got nil", expected.Error())
|
||||
}
|
||||
|
||||
if actual.Error() != expected.Error() {
|
||||
t.Fatalf("Expected error %q, but got %q", expected.Error(), actual.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func normalize(in []byte) []byte {
|
||||
return bytes.Replace(in, []byte("\r\n"), []byte("\n"), -1)
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
set -e
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
printf "Usage: %s <coverfile>\n" "$0"
|
||||
|
Loading…
Reference in New Issue
Block a user