Commit bfc1abc4 authored by Stephane Bausseron's avatar Stephane Bausseron

Merge branch 'new_features' into 'master'

New features

See merge request ercom/citbx4gitlab!10
parents 464194d2 1f67d0e8
......@@ -43,15 +43,30 @@ job-with-volumes:
- test -f /path/to/my/volume/content
- 'echo "/path/to/my/volume/content file content: $(cat /path/to/my/volume/content)"'
job-test-services:
job-test-services-mysql:
stage: build
variables:
MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: password
CITBX_WAIT_FOR_SERVICE_START: 10
only:
- /^$/
image: mysql
services:
- mysql
tags:
- test
script:
- mysql -h mysql -u root -ppassword test -e 'SHOW VARIABLES LIKE "%version%";'
job-test-services-postgres:
stage: build
variables:
CITBX_WAIT_FOR_SERVICE_START: 10
only:
- /^$/
image: postgres:9.4
services:
- name: postgres:9.4
alias: db-postgres
entrypoint: ["docker-entrypoint.sh"]
......@@ -59,7 +74,7 @@ job-test-services:
tags:
- test
script:
- "true"
- psql -h db-postgres -U postgres -c 'select version();'
job-test-services-ext:
image: registry.gitlab.com/ercom/cijw4gitlab:2.0.1
......
# Cangelog
## 3.0.0
* Add support of bash completion
* [FIX] remove warning from a test
* [FIX] unset CITBX_GIT_CLEAN for citbx_run_ext_job
* [CI] add job-test-services-mysql and job-test-services-postgres service example jobs
* Update docker run to use CITBX_JOB_SHELL
* [FIX] YAML variable treatment
* Improve messages/help formating
* Add debug-script option
* Remove deprecated JOB_EXT_FILE_NAME variable name
* [3rd] Update bashopts to the version 2.0.0
* Update fetch_file function for update command
* [FIX] docker run exit code on error
* [FIX] Preserve PATH environment variable in user mode
* Add VERSION and a CHANGELOG.md
## 2.2.10
* [FIX] unset CITBX_JOB_RUN_FILE_NAME in citbx_run_ext_job
## 2.2.9
* Improve git worktree support and preserve the working directory on shell mode
## 2.2.8
* Update variable name: CITBX_JOB_RUN_FILE_NAME
## 2.2.7
* Add ncore function
## 2.2.6
* [env-setup/ubuntu] Fix GIT LFS repository
## 2.2.5
* [env-setup/ubuntu] Update GIT LFS apt repository add
## 2.2.4
* Set git lfs as an optional feature
## 2.2.3
* [run] improve docker-dns detection
## 2.2.2
* [env-setup/ubuntu] [Fix] ca-certificates copy
* [Fix] read empty or invalid daemon.json
## 2.2.1
* [env-setup/ubuntu] Add --allow-change-held-packages option to apt-get remove docker.io & docker-engine
* [run] improve CI PROJECT ROOT DIR detection
## 2.2
* [FIX] service-privileged property variable name update
* Add GIT LFS support
* Improve docker-dns option check
## 2.1.1
* [FIX] service with custom commands with default entrypoint
* Add option to start service in privileged mode
## 2.1
* Add git-clean and group options
## 2.0.2
* [FIX] Eval YAML service properties
## 2.0.1
* [FIX] export variables to services
## 2.0
* Add Gitlab services support
## 1.3.2
* [fix] Prevent multiple call of citbx_job_finish
## 1.3.1
* add SIGINT SIGTERM to citbx_job_finish trap callback
## 1.3.0
* [fix] return the good error code on local job execution failure
* Add citbx_docker_run_add_args function
## 1.2.1
* [3rd] Update bashopts to the version 1.3.0
* Add citbx_export function
* [fix] Variable export the SHELL executor
## 1.2
* Changes:
* Add a check on the bash version
* Add submodule-strategy option for GIT_SUBMODULE_STRATEGY
* Add job executor option
* Add job script and job main func check
* Add image entrypoint support
* Remove CITBX_DOCKER_USER option
* reset PWD to CI_PROJECT_DIR before hooks execution
* [FIX] ubuntu setup
* Update the documentation
## 1.1
* Add CITBX_DEFAULT_JOB_SHELL property and CITBX_JOB_SHELL option
* Add job execution time
* Add update tool to fetch the last version
* Add gitlab GIT_SUBMODULE_STRATEGY support
## 1.0
* First stable release
......@@ -19,6 +19,8 @@
set -e
BASHOPTS_VERSION=2.0.0
bashopts_exit_handle() {
local err=$?
set +o xtrace
......@@ -45,29 +47,34 @@ trap 'bashopts_exit_handle' ERR
set -o errtrace
# display a error (fatal)
bashopts_critical() {
>&2 printf "[ERROR] %s\n" "$@"
exit 1
bashopts_log() {
if [ -n "$bashopts_log_handler" ]; then
$bashopts_log_handler "$@"
return;
fi
local level=$1;
shift || bashopts_log C "Usage bashopts_log <level> message"
case "${level,,}" in
c|critical)
>&2 printf "[CRIT] %s\n" "$@"
exit 1
;;
e|error)
>&2 printf "[ERRO] %s\n" "$@"
;;
w|warning)
>&2 printf "[WARN] %s\n" "$@"
;;
*)
bashopts_log C "Invalid log level: $level"
;;
esac
}
if [ ! "${BASH_VERSINFO[0]}" -ge 4 ]; then
bashopts_critical "bashopts require BASH version 4 or greater"
bashopts_log C "bashopts require BASH version 4 or greater"
fi
# display a error (non fatal)
bashopts_error() {
>&2 printf "[ERROR] %s\n" "$@"
}
# display a warning (non fatal)
bashopts_warning() {
>&2 printf "[WARNING] %s\n" "$@"
}
bashopts_regex_escape () {
echo $1 | sed 's/[][()\.^$\/?*+]/\\&/g'
}
# extract the value part of a declaration ("the value")
bashopts_get_def() {
declare | grep "^$1=" | sed -E 's/^[^=]+=//g'
......@@ -88,7 +95,7 @@ bashopts_check_opt_name() {
echo $1
return 0
fi
bashopts_error "'$1' is not a valid variable name"
bashopts_log E "'$1' is not a valid variable name"
return 1
}
......@@ -101,23 +108,23 @@ bashopts_check_number() {
echo $1
return 0
fi
bashopts_error "'$1' is not a valid number"
bashopts_log E "Option $op: '$1' is not a valid number"
return 1
}
# check and format a boolean value
bashopts_check_boolean() {
case "$1" in
''|f|false|F|FALSE|False|0)
case "${1,,}" in
''|f|false|0)
echo "false"
return 0
;;
t|true|T|TRUE|True|1)
t|true|1)
echo "true"
return 0
;;
*)
bashopts_error "'$1' is not a valid boolean value"
bashopts_log E "Option $op: '$1' is not a valid boolean value"
return 1
;;
esac
......@@ -129,6 +136,21 @@ bashopts_check_string() {
return 0
}
# check and format a enumeration value
bashopts_check_enumeration() {
local line expr values
while read -r line; do
expr="^($line)\$"
if [[ "$1" =~ $expr ]]; then
echo "${line##*|}"
return 0
fi
values+=("'${line##*|}'")
done <<< "${2:-${bashopts_optprop_enum_values[$op]}}"
bashopts_log E "Option $op: Invalid value '$1' (accepted values are: ${values[*]})"
return 1
}
# check nothing
bashopts_check_nothing() {
echo "$1"
......@@ -136,7 +158,7 @@ bashopts_check_nothing() {
}
# declare the options property arrays
for f in name default expression short_opt long_opt description type method check setting interactive req_value; do
for f in name default expression short_opt long_opt description type enum_values method check setting interactive req_value; do
eval declare -x -A bashopts_optprop_$f
done
......@@ -155,7 +177,7 @@ bashopts_tool_name=$0
bashopts_setup() {
local arg arglist no_default_opts non_interactive disable_interactive
if ! arglist=$(getopt -o "n:d:u:s:yxp" -n "$0 " -- "$@"); then
bashopts_critical "Usage bashopts_setup:" \
bashopts_log C "Usage bashopts_setup:" \
" -n <val> Tool name" \
" -d <val> Tool description" \
" -u <val> Tool usage description" \
......@@ -178,14 +200,14 @@ bashopts_setup() {
-x) disable_interactive="true";;
-p) bashopts_tool_settings_force_write="true";;
--) break;;
*) bashopts_critical "Fatal error";;
*) bashopts_log C "Fatal error";;
esac
done
if [ -z "$bashopts_tool_name" ]; then
bashopts_critical "Undefined tool name"
bashopts_log C "Undefined tool name"
fi
if [ -z "$bashopts_tool_description" ]; then
bashopts_critical "Undefined tool description"
bashopts_log C "Undefined tool description"
fi
bashopts_tool_usage=${bashopts_tool_usage:-"$bashopts_tool_name [options and commands] [-- [extra args]]"}
# add the default options
......@@ -203,16 +225,17 @@ bashopts_setup() {
# STEP 2: add options
bashopts_declare() {
local arg arglist options
if ! arglist=$(getopt -o "n:v:e:o:l:d:t:m:k:rsi" -n "$0 " -- "$@"); then
bashopts_critical "Usage bashopts_declare:" \
local arg arglist options options_enum_values
if ! arglist=$(getopt -o "n:v:x:o:l:d:t:e:m:k:rsi" -n "$0 " -- "$@"); then
bashopts_log C "Usage bashopts_declare:" \
" -n <val> Name" \
" -v <val> Default value" \
" -e <val> Bash expression: like default but this expression is computed and can contain variables and other bash expression" \
" -x <val> Bash expression: like default but this expression is computed and can contain variables and other bash expression" \
" -o <val> Short option" \
" -l <val> Long option" \
" -d <val> Description" \
" -t <val> Value type: string (default), number, boolean" \
" -t <val> Value type: string, enumeration, number, boolean (default)" \
" -e <val> Enum element: restrict accepted values with a list of '-e <element>' options (you have to set one '-e <val>' by elements)" \
" -m <val> Method: set (DEFAULT: simple value), add (list with several values)" \
" -k <val> Custom check method (bash function)" \
" -r Value required" \
......@@ -227,53 +250,68 @@ bashopts_declare() {
shift
case "$arg" in
-n) options[name]=$(bashopts_check_opt_name $1 || exit 1); shift;;
-v) options[default]=$1; shift;;
-e) options[expression]=$1; shift;;
-o) options[short_opt]=$1; shift;;
-l) options[long_opt]=$1; shift;;
-d) options[description]=$1; shift;;
-t) options[type]=$1; shift;;
-m) options[method]=$1; shift;;
-k) options[check]=$1; shift;;
-v) options[default]=$1; shift;;
-x) options[expression]=$1; shift;;
-o) options[short_opt]=$1; shift;;
-l) options[long_opt]=$1; shift;;
-d) options[description]=$1; shift;;
-t) options[type]=$1; shift;;
-e) options_enum_values+=($1); shift;;
-m) options[method]=$1; shift;;
-k) options[check]=$1; shift;;
-s) options[setting]="true";;
-i) options[interactive]="true";;
-r) options[req_value]="true";;
--) break;;
*) bashopts_critical "Fatal error";;
*) bashopts_log C "Fatal error";;
esac
done
# Check incompatible -v and -r options
if [ -n "${options[default]}" ] && [ "${options[req_value]}" == "true" ]; then
bashopts_critical "bashopts_declare: -r and -v options cannot be activated at the same time"
bashopts_log C "bashopts_declare: -r and -v options cannot be activated at the same time"
fi
# format the type and check/format the default value
case "${options[type]}" in
''|bool|boolean)
case "${options[type],,}" in
''|b|bool|boolean)
options[type]="boolean"
;;
str|string)
e|enum|enumeration)
options[type]="enumeration"
if [ ${#options_enum_values[@]} -lt 2 ]; then
bashopts_log C "bashopts_declare: ${options[name]} enumeration need at least two elements (two '-e <val>' calls at least)"
fi
options[enum_values]="$(IFS=$'\n'; echo "${options_enum_values[*]}")"
;;
s|str|string)
options[type]="string"
;;
num|number)
n|num|number)
options[type]="number"
;;
*)
bashopts_critical "Invalid type ${options[type]}"
bashopts_log C "Invalid type ${options[type]}"
;;
esac
# Check for incompatibility with old version (-e opt moved to -x)
if [ "${options[type]}" != "enumeration" ] && [ ${#options_enum_values[@]} -gt 0 ]; then
bashopts_log C "bashopts_declare: The former '-e' option is now moved to '-x'" \
" => the new '-e' is reserved for enumeration elements"
fi
# Setup check value method
if ! [[ -v options[check] ]]; then
options[check]="bashopts_check_${options[type]}"
fi
# format the option method
case "${options[method]}" in
case "${options[method],,}" in
''|s|set)
# default: simple value - override
options[method]="set"
if [ "${options[type]}" != "string" ] || [[ -v options[default] ]]; then
# Check the default value format
options[default]="$(${options[check]} "${options[default]}")" \
|| bashopts_critical "Invalid default value for ${options[name]} option"
if ! options[default]="$(${options[check]} "${options[default]}" "${options[enum_values]}")"; then
bashopts_log W "Invalid default value for ${options[name]} option, this value will stay unset"
unset options[default]
fi
fi
;;
a|add)
......@@ -281,30 +319,30 @@ bashopts_declare() {
options[method]="add"
;;
*)
bashopts_critical "Invalid method ${options[method]}"
bashopts_log C "Invalid method ${options[method]}"
;;
esac
# Check option name
if [[ -v bashopts_optprop_name[${options[name]}] ]]; then
bashopts_critical "Dupplicate option name '${options[name]}'"
bashopts_log C "Dupplicate option name '${options[name]}'"
fi
# check the short option
if [[ -v options[short_opt] ]]; then
if ! [[ ${options[short_opt]} =~ ^[a-zA-Z0-9_-]$ ]]; then
bashopts_critical "Invalid short option ${options[short_opt]}"
bashopts_log C "Invalid short option ${options[short_opt]}"
fi
if [[ -v bashopts_arg2op[-${options[short_opt]}] ]]; then
bashopts_critical "Dupplicate short option '${options[short_opt]}'"
bashopts_log C "Dupplicate short option '${options[short_opt]}'"
fi
bashopts_arg2op[-${options[short_opt]}]=${options[name]}
fi
# check the long option
if [[ -v options[long_opt] ]]; then
if ! [[ ${options[long_opt]} =~ ^[a-zA-Z0-9_-]{2,}$ ]]; then
bashopts_critical "Invalid long option ${options[long_opt]}"
bashopts_log C "Invalid long option ${options[long_opt]}"
fi
if [[ -v bashopts_arg2op[--${options[long_opt]}] ]]; then
bashopts_critical "Dupplicate long option '${options[long_opt]}'"
bashopts_log C "Dupplicate long option '${options[long_opt]}'"
fi
bashopts_arg2op[--${options[long_opt]}]=${options[name]}
fi
......@@ -315,6 +353,28 @@ bashopts_declare() {
bashopts_optlist+=(${options[name]})
}
bashopts_get_valid_value_list() {
local op
case "$1" in
-*)
op=${bashopts_arg2op[$1]}
;;
*)
op=$1
;;
esac
case "${bashopts_optprop_type[$op]}" in
boolean)
echo -e "true\nfalse"
;;
enumeration)
while read -r line; do
echo "\"${line##*|}\""
done <<< "${bashopts_optprop_enum_values[$op]}"
;;
esac
}
# maximum of two values
bashopts_math_max() {
echo $(($1>$2?$1:$2))
......@@ -328,14 +388,14 @@ bashopts_math_min() {
# join array element
bashopts_join_by() {
local IFS="$1"
shift || bashopts_critical "Usage: bashopts_join_by <character> [elt1 [elt2...]]"
shift || bashopts_log C "Usage: bashopts_join_by <character> [elt1 [elt2...]]"
echo "$*"
}
# dump an option value by its name
bashopts_dump_value() {
local op=$1
shift || bashopts_critical "Usage: bashopts_dump_value op_name"
shift || bashopts_log C "Usage: bashopts_dump_value op_name"
[[ -v "$op" ]] || return 0
if [ "${bashopts_optprop_method[$op]}" == "set" ]; then
if [ "${bashopts_optprop_type[$op]}" == "string" ]; then
......@@ -366,7 +426,7 @@ bashopts_dump_value() {
# display the formated help
bashopts_diplay_help() {
local elts optargs_max_len=8 val dval ncol
local elts optargs_max_len=8 val ncol line
declare -A optargs
ncol=$(tput cols || true) 2> /dev/null
# compute the good arguments comumn size
......@@ -393,25 +453,33 @@ bashopts_diplay_help() {
echo
echo "OPTIONS:"
for op in "${bashopts_optlist[@]}"; do
elts=""
dval=""
if ! [[ $op =~ ^__.*__$ ]]; then
# display additional information the each properties
# discarding special options like --help
if [[ -v bashopts_optprop_expression[$op] ]]; then
elts="- [\$$op] (type:${bashopts_optprop_type[$op]}, default:\"${bashopts_optprop_expression[$op]//\"/\\\"}\")"
elif [[ -v bashopts_optprop_default[$op] ]]; then
if [ "${bashopts_optprop_type[$op]}" == "string" ]; then
elts="- [\$$op] (type:${bashopts_optprop_type[$op]}, default:\"${bashopts_optprop_default[$op]//\"/\\\"}\")"
# display arguments, value if available, description, and additional info if available
printf " %-${optargs_max_len}s %s\n" "${optargs[$op]}" "${bashopts_optprop_description[$op]} $(
if ! [[ $op =~ ^__.*__$ ]]; then
# display additional information the each properties
# discarding special options like --help
echo -n "- [\$$op] (type:${bashopts_optprop_type[$op]}"
if [[ -v bashopts_optprop_expression[$op] ]]; then
echo -n ", default:\"${bashopts_optprop_expression[$op]//\"/\\\"}\""
elif [[ -v bashopts_optprop_default[$op] ]]; then
if [[ "${bashopts_optprop_type[$op]}" =~ ^(string|enumeration)$ ]]; then
echo -n ", default:\"${bashopts_optprop_default[$op]//\"/\\\"}\""
else
echo -n ", default:${bashopts_optprop_default[$op]}"
fi
else
elts="- [\$$op] (type:${bashopts_optprop_type[$op]}, default:${bashopts_optprop_default[$op]})"
elts=")"
fi
if [ "${bashopts_optprop_type[$op]}" == "enumeration" ]; then
echo -n ", accepted values:$(
while read -r line; do
echo -n " '${line##*|}'"
done <<< "${bashopts_optprop_enum_values[$op]}"
)"
fi
else
elts="- [\$$op] (type:${bashopts_optprop_type[$op]})"
echo -n ")"
fi
fi
# display arguments, value if available, description, and additional info if available
printf " %-${optargs_max_len}s %s\n" "${optargs[$op]}" "${bashopts_optprop_description[$op]} $elts"
)"
done
test "$1" != "-e" || exit $2
}
......@@ -507,7 +575,7 @@ bashopts_parse_args() {
esac
;;
*)
bashopts_critical "Fatal error: args"
bashopts_log C "Fatal error: args"
;;
esac
done
......@@ -519,7 +587,7 @@ bashopts_parse_args() {
# display an array: [val1, val2, ...]
bashopts_dump_array() {
local type=$1
shift || bashopts_critical "Usage: bashopts_dump_array type elt1 [elt2...]"
shift || bashopts_log C "Usage: bashopts_dump_array type elt1 [elt2...]"
echo -n "["
if [ "$type" == "string" ]; then
echo -n "\"${1//\"/\\\"}\""
......@@ -538,11 +606,20 @@ bashopts_dump_array() {
echo -n "]"
}
bashopts_read_json_array() {
local line
while read -r line; do
eval "$1+=($line)"
done <<< "$(jq '.[]' <<< "$2")" && return 0 || \
bashopts_log E "Invalid JSON array"
return 1
}
# Process a specified option
bashopts_process_option() {
local dval tval ival op arg arglist check val_req edit_req
if ! arglist=$(getopt -o "n:k:r" -n "bashopts_process_option " -- "$@"); then
bashopts_critical "Usage bashopts_process_opt" \
bashopts_log C "Usage bashopts_process_opt" \
" -n <val> property name" \
" -k <val> override value check function" \
" -r At least one value required"
......@@ -557,11 +634,11 @@ bashopts_process_option() {
-k) check=$1; shift;;
-r) val_req="true";;
--) break;;
*) bashopts_critical "Fatal error";;
*) bashopts_log C "Fatal error";;
esac
done
test -n "$op" || \
bashopts_critical "bashopts_process_option: missing -n option"
bashopts_log C "bashopts_process_option: missing -n option"
if [ -z "$check" ]; then
check="${bashopts_optprop_check[$op]}"
fi
......@@ -585,7 +662,7 @@ bashopts_process_option() {
# Edition no more really required if already defined
edit_req="false"
elif [ "${bashopts_optprop_setting[$op]}" == "true" ] \
&& [ -f "$(readlink -f $bashopts_tool_settings_path)" ] \
&& [ -f "$(readlink -m "$bashopts_tool_settings_path")" ] \
&& grep -E -q "^$op=" $bashopts_tool_settings_path; then
eval "tval=$(grep -E "^${op}=" $bashopts_tool_settings_path | sed -E "s/^[^=]+=//g")"
fi
......@@ -594,17 +671,17 @@ bashopts_process_option() {
for (( i=0; i<${#tval[@]}; i++)); do
if ! $check "${tval[$i]}" > /dev/null; then
if [ "$BASHOPTS_INTERACTIVE" != "true" ]; then
bashopts_critical "Non interactive mode: Exit due to one or more error"
bashopts_log C "Non interactive mode: Exit due to one or more error"
fi
# (re)enable edition
edit_req="true"
break
fi
done
elif [ "$val_req" == "true" ]; then
bashopts_error "At least one value required"
elif [ "$val_req" == "true" ] && [ "$__BASHOPTS_DISPLAY_HELP__" != "true" ]; then
bashopts_log E "At least one value required"
if [ "$BASHOPTS_INTERACTIVE" != "true" ]; then
bashopts_critical "Non interactive mode: Exit due to one or more error"
bashopts_log C "Non interactive mode: Exit due to one or more error"
fi
# (re)enable edition
edit_req="true"
......@@ -618,25 +695,52 @@ bashopts_process_option() {
if [ "$BASHOPTS_INTERACTIVE" == "true" ]; then
# interactive edition
while true; do
echo "* ${bashopts_optprop_description[$op]}"
# Display the property description
echo "* ${bashopts_optprop_description[$op]}$(
# Add possible value list for enumeration type
if [ "${bashopts_optprop_type[$op]}" == "enumeration" ]; then
echo -n " (accepted values:$(
while read -r line; do
echo -n " '${line##*|}'"
done <<< "${bashopts_optprop_enum_values[$op]}"
)"
echo -n ")"
fi
)"
# Add info for array properties
if [ "${bashopts_optprop_method[$op]}" == "add" ]; then
echo " -> List property format: 'single val.' or BASH array '(v1 v2 v3)' or JSON array '[v1, v2, v3]'"
fi
echo -n " $(bashopts_dump_array {bashopts_optprop_type[$op]} "${tval[@]}"): "
read ival || return 1
read ival || bashopts_log C "Unexpected error, aborting..."
if [ -n "$ival" ]; then
if [ "${bashopts_optprop_method[$op]}" == "add" ]; then
# array value
if ! eval "tval=$ival" 2>/dev/null; then
bashopts_error "'$ival' must be written in BASH array format: '( \"val 1\" \"val2\" \"val3...\" )'"
unset tval
continue
fi
tval=()
case "${ival:0:1}" in
'[')
bashopts_read_json_array tval "$ival" || continue
;;
'(')
if ! eval "tval=$ival" 2>/dev/null; then
bashopts_log E "Invalid BASH array"
continue
fi
;;
*)
tval+=("$ival")
;;
esac
else
# non array/normal value
tval=$ival
fi
elif [ "${bashopts_optprop_method[$op]}" == "add" ] && ! [[ -v tval ]]; then
tval=()
fi
# check format
if [ "${#tval[@]}" -eq 0 ] && [ "$val_req" == "true" ]; then
bashopts_error "At least one value required"
bashopts_log E "At least one value required"
unset tval
continue
fi
......@@ -654,7 +758,7 @@ bashopts_process_option() {
unset tval
fi
fi
if [[ -v tval ]]; then
if declare -p tval > /dev/null 2>&1; then
# edit OK, break
break
fi
......@@ -682,9 +786,9 @@ bashopts_process_option() {
# force_write is true
echo "$(bashopts_get_def_full $op)" >> $bashopts_tool_settings_path
fi
) || bashopts_warning "Please check the settings file"
) || bashopts_log W "Please check the settings file"
else
bashopts_warning "No settings file specified"
bashopts_log W "No settings file specified"
fi
fi
if [ "$op" == "BASHOPTS_NON_INTERACTIVE" ] && ! [[ -v BASHOPTS_INTERACTIVE ]]; then
......
PREFIX?=/usr/local
default:
install:
mkdir -p $(DESTDIR)/$(PREFIX)/bin
install citbx4gitlab $(DESTDIR)/$(PREFIX)/bin/
mkdir -p $(DESTDIR)/etc/bash_completion.d
cp bashcomp $(DESTDIR)/etc/bash_completion.d/citbx4gitlab
uninstall:
rm -f $(DESTDIR)/$(PREFIX)/bin/citbx4gitlab $(DESTDIR)/etc/bash_completion.d/citbx4gitlab
# citbx4gitlab - CI toolbox for Gitlab