From 4fdb6d162469daefc28dbc021c0ac9710b7df543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Chastanet?= Date: Sun, 25 Aug 2024 22:27:49 +0200 Subject: [PATCH] compiled megalinter using go compiler --- .framework-config | 2 +- bin/megalinter | 2458 +++++++++-------- cspell.yaml | 2 +- src/_binaries/megalinter.sh | 77 - .../megalinter/binary-megalinter.yaml | 99 + src/_binaries/megalinter/megalinter-main.sh | 64 + .../megalinter/megalinter-options.sh | 107 + src/_binaries/options/command.megalinter.tpl | 174 -- src/_binaries/options/options.base.tpl | 387 --- src/_binaries/options/options.ci.tpl | 20 - src/_binaries/options/options.format.tpl | 25 - .../options/options.skipDockerBuild.tpl | 21 - src/_binaries/options/options.srcDir.tpl | 27 - 13 files changed, 1628 insertions(+), 1835 deletions(-) delete mode 100755 src/_binaries/megalinter.sh create mode 100644 src/_binaries/megalinter/binary-megalinter.yaml create mode 100755 src/_binaries/megalinter/megalinter-main.sh create mode 100755 src/_binaries/megalinter/megalinter-options.sh delete mode 100644 src/_binaries/options/command.megalinter.tpl delete mode 100644 src/_binaries/options/options.base.tpl delete mode 100644 src/_binaries/options/options.ci.tpl delete mode 100644 src/_binaries/options/options.format.tpl delete mode 100644 src/_binaries/options/options.skipDockerBuild.tpl delete mode 100644 src/_binaries/options/options.srcDir.tpl diff --git a/.framework-config b/.framework-config index b532dd09..f557cf2d 100755 --- a/.framework-config +++ b/.framework-config @@ -10,7 +10,7 @@ FRAMEWORK_VENDOR_BIN_DIR="${FRAMEWORK_VENDOR_BIN_DIR:-${FRAMEWORK_ROOT_DIR}/vend if [[ ! -v COMPILE_PARAMETERS ]]; then # compile parameters # srcFile : file that needs to be compiled - # templateDir : directory from which bash-tpl templates will be searched + # templateDir : directory from which templates will be searched # binDir : fallback bin directory in case BIN_FILE has not been provided # rootDir : directory used to compute src file relative path # srcDirs : additional directories where to find the functions diff --git a/bin/megalinter b/bin/megalinter index 4e210a31..193df63e 100755 --- a/bin/megalinter +++ b/bin/megalinter @@ -1,13 +1,12 @@ #!/usr/bin/env bash ############################################################################### -# GENERATED FACADE FROM https://github.com/fchastanet/bash-tools-framework/tree/master/src/_binaries/megalinter.sh +# GENERATED FROM https://github.com/fchastanet/bash-tools-framework/tree/master/src/_binaries/megalinter/binary-megalinter.yaml # DO NOT EDIT IT # @generated ############################################################################### # shellcheck disable=SC2288,SC2034 -# BIN_FILE=${FRAMEWORK_ROOT_DIR}/bin/megalinter -# VAR_RELATIVE_FRAMEWORK_DIR_TO_CURRENT_DIR=.. -# FACADE + + # ensure that no user aliases could interfere with # commands used in this script @@ -62,13 +61,6 @@ interruptManagement() { kill -s INT "$$" } trap interruptManagement INT -SCRIPT_NAME=${0##*/} -REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -if [[ -n "${EMBED_CURRENT_DIR}" ]]; then - CURRENT_DIR="${EMBED_CURRENT_DIR}" -else - CURRENT_DIR="${REAL_SCRIPT_FILE%/*}" -fi ################################################ # Temp dir management @@ -102,6 +94,20 @@ cleanOnExit() { } trap cleanOnExit EXIT HUP QUIT ABRT TERM + +SCRIPT_NAME=${0##*/} +REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="${REAL_SCRIPT_FILE%/*}" +fi +FRAMEWORK_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" +FRAMEWORK_SRC_DIR="${FRAMEWORK_ROOT_DIR}/src" +FRAMEWORK_BIN_DIR="${FRAMEWORK_ROOT_DIR}/bin" +FRAMEWORK_VENDOR_DIR="${FRAMEWORK_ROOT_DIR}/vendor" +FRAMEWORK_VENDOR_BIN_DIR="${FRAMEWORK_ROOT_DIR}/vendor/bin" + # @description Log namespace provides 2 kind of functions # - Log::display* allows to display given message with # given display level @@ -132,310 +138,86 @@ export __VERBOSE_LEVEL_DEBUG=2 # @description verbose level info export __VERBOSE_LEVEL_TRACE=3 -# @description Display message using info color (bg light blue/fg white) -# @arg $1 message:String the message to display -# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs -# @env LOG_CONTEXT String allows to contextualize the log -Log::displayInfo() { - local type="${2:-INFO}" - if ((BASH_FRAMEWORK_DISPLAY_LEVEL >= __LEVEL_INFO)); then - Log::computeDuration - echo -e "${__INFO_COLOR}${type} - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 - fi - Log::logInfo "$1" "${type}" -} - -# @description Display message using debug color (gray) -# @arg $1 message:String the message to display -# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs -# @env LOG_CONTEXT String allows to contextualize the log -Log::displayDebug() { - if ((BASH_FRAMEWORK_DISPLAY_LEVEL >= __LEVEL_DEBUG)); then - Log::computeDuration - echo -e "${__DEBUG_COLOR}DEBUG - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 - fi - Log::logDebug "$1" -} -# @description Display message using warning color (yellow) -# @arg $1 message:String the message to display -# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs -# @env LOG_CONTEXT String allows to contextualize the log -Log::displayWarning() { - if ((BASH_FRAMEWORK_DISPLAY_LEVEL >= __LEVEL_WARNING)); then - Log::computeDuration - echo -e "${__WARNING_COLOR}WARN - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 - fi - Log::logWarning "$1" +# @description concatenate each element of an array with a separator +# +# @arg $1 glue:String +# @arg $@ array:String[] +# @example +# declare -a array=(test1, test2) +# echo "Result= $(Array::join "," "${array[@]})" +# Result= test1,test2 +Array::join() { + local glue="${1-}" + shift || true + local first="${1-}" + shift || true + printf %s "${first}" "${@/#/${glue}}" } -# @description Display message using error color (red) -# @arg $1 message:String the message to display -# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs -# @env LOG_CONTEXT String allows to contextualize the log -Log::displayError() { - if ((BASH_FRAMEWORK_DISPLAY_LEVEL >= __LEVEL_ERROR)); then - Log::computeDuration - echo -e "${__ERROR_COLOR}ERROR - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 - fi - Log::logError "$1" -} -# @description load colors theme constants -# @warning if tty not opened, noColor theme will be chosen -# @arg $1 theme:String the theme to use (default, noColor) -# @arg $@ args:String[] -# @set __ERROR_COLOR String indicate error status -# @set __INFO_COLOR String indicate info status -# @set __SUCCESS_COLOR String indicate success status -# @set __WARNING_COLOR String indicate warning status -# @set __SKIPPED_COLOR String indicate skipped status -# @set __DEBUG_COLOR String indicate debug status -# @set __HELP_COLOR String indicate help status -# @set __TEST_COLOR String not used -# @set __TEST_ERROR_COLOR String not used -# @set __HELP_TITLE_COLOR String used to display help title in help strings -# @set __HELP_OPTION_COLOR String used to display highlight options in help strings -# -# @set __RESET_COLOR String reset default color +# @description concatenate each element of an array with a separator +# but wrapping text when line length is more than provided argument +# The algorithm will try not to cut the array element if it can. +# - if an arg can be placed on current line it will be, +# otherwise current line is printed and arg is added to the new +# current line +# - Empty arg is interpreted as a new line. +# - Add \r to arg in order to force break line and avoid following +# arg to be concatenated with current arg. # -# @set __HELP_EXAMPLE String to remove -# @set __HELP_TITLE String to remove -# @set __HELP_NORMAL String to remove -# shellcheck disable=SC2034 -UI::theme() { - local theme="${1-default}" - if [[ ! "${theme}" =~ -force$ ]] && ! Assert::tty; then - theme="noColor" +# @arg $1 glue:String +# @arg $2 maxLineLength:int +# @arg $3 indentNextLine:int +# @arg $@ array:String[] +Array::wrap2() { + local glue="${1-}" + local -i glueLength="${#glue}" + shift || true + local -i maxLineLength=$1 + shift || true + local -i indentNextLine=$1 + shift || true + local indentStr="" + if ((indentNextLine > 0)); then + indentStr="$(head -c "${indentNextLine}" &2 - Log::logFatal "$1" - exit 1 -} + ( + local currentLine + local -i currentLineLength=0 isNewline=1 argLength=0 + local -a additionalLines + local -i previousLineEmpty=0 + local arg="" -# @description create a temp file using default TMPDIR variable -# initialized in _includes/_commonHeader.sh -# @env TMPDIR String (default value /tmp) -# @arg $1 templateName:String template name to use(optional) -Framework::createTempFile() { - mktemp -p "${TMPDIR:-/tmp}" -t "${1:-}.XXXXXXXXXXXX" -} - -# @description ensure env files are loaded -# @arg $@ list of default files to load at the end -# @exitcode 1 if one of env files fails to load -# @stderr diagnostics information is displayed -# shellcheck disable=SC2120 -Env::requireLoad() { - local -a defaultFiles=("$@") - # get list of possible config files - local -a configFiles=() - if [[ -n "${BASH_FRAMEWORK_ENV_FILES[0]+1}" ]]; then - # BASH_FRAMEWORK_ENV_FILES is an array - configFiles+=("${BASH_FRAMEWORK_ENV_FILES[@]}") - fi - local localFrameworkConfigFile - localFrameworkConfigFile="$(pwd)/.framework-config" - if [[ -f "${localFrameworkConfigFile}" ]]; then - configFiles+=("${localFrameworkConfigFile}") - fi - if [[ -f "${FRAMEWORK_ROOT_DIR}/.framework-config" ]]; then - configFiles+=("${FRAMEWORK_ROOT_DIR}/.framework-config") - fi - configFiles+=("${optionEnvFiles[@]}") - configFiles+=("${defaultFiles[@]}") - - for file in "${configFiles[@]}"; do - # shellcheck source=/.framework-config - CURRENT_LOADED_ENV_FILE="${file}" source "${file}" || { - Log::displayError "while loading config file: ${file}" - return 1 - } - done -} - -# @description activate or not Log::display* and Log::log* functions -# based on BASH_FRAMEWORK_DISPLAY_LEVEL and BASH_FRAMEWORK_LOG_LEVEL -# environment variables loaded by Env::requireLoad -# try to create log file and rotate it if necessary -# @noargs -# @set BASH_FRAMEWORK_LOG_LEVEL int to OFF level if BASH_FRAMEWORK_LOG_FILE is empty or not writable -# @env BASH_FRAMEWORK_DISPLAY_LEVEL int -# @env BASH_FRAMEWORK_LOG_LEVEL int -# @env BASH_FRAMEWORK_LOG_FILE String -# @env BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION int do log rotation if > 0 -# @exitcode 0 always successful -# @stderr diagnostics information about log file is displayed -# @require Env::requireLoad -# @require UI::requireTheme -Log::requireLoad() { - if [[ -z "${BASH_FRAMEWORK_LOG_FILE:-}" ]]; then - BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} - export BASH_FRAMEWORK_LOG_LEVEL - fi - - if ((BASH_FRAMEWORK_LOG_LEVEL > __LEVEL_OFF)); then - if [[ ! -f "${BASH_FRAMEWORK_LOG_FILE}" ]]; then - if [[ ! -d "${BASH_FRAMEWORK_LOG_FILE%/*}" ]]; then - if ! mkdir -p "${BASH_FRAMEWORK_LOG_FILE%/*}" 2>/dev/null; then - BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} - echo -e "${__ERROR_COLOR}ERROR - directory ${BASH_FRAMEWORK_LOG_FILE%/*} is not writable${__RESET_COLOR}" >&2 - fi - elif ! touch --no-create "${BASH_FRAMEWORK_LOG_FILE}" 2>/dev/null; then - BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} - echo -e "${__ERROR_COLOR}ERROR - File ${BASH_FRAMEWORK_LOG_FILE} is not writable${__RESET_COLOR}" >&2 - fi - elif [[ ! -w "${BASH_FRAMEWORK_LOG_FILE}" ]]; then - BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} - echo -e "${__ERROR_COLOR}ERROR - File ${BASH_FRAMEWORK_LOG_FILE} is not writable${__RESET_COLOR}" >&2 - fi - fi - - if ((BASH_FRAMEWORK_LOG_LEVEL > __LEVEL_OFF)); then - # will always be created even if not in info level - Log::logMessage "INFO" "Logging to file ${BASH_FRAMEWORK_LOG_FILE} - Log level ${BASH_FRAMEWORK_LOG_LEVEL}" - if ((BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION > 0)); then - Log::rotate "${BASH_FRAMEWORK_LOG_FILE}" "${BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION}" - fi - fi -} - -# @description concatenate each element of an array with a separator -# but wrapping text when line length is more than provided argument -# The algorithm will try not to cut the array element if it can. -# - if an arg can be placed on current line it will be, -# otherwise current line is printed and arg is added to the new -# current line -# - Empty arg is interpreted as a new line. -# - Add \r to arg in order to force break line and avoid following -# arg to be concatenated with current arg. -# -# @arg $1 glue:String -# @arg $2 maxLineLength:int -# @arg $3 indentNextLine:int -# @arg $@ array:String[] -Array::wrap2() { - local glue="${1-}" - local -i glueLength="${#glue}" - shift || true - local -i maxLineLength=$1 - shift || true - local -i indentNextLine=$1 - shift || true - local indentStr="" - if ((indentNextLine > 0)); then - indentStr="$(head -c "${indentNextLine}" 0)); do - arg="$1" - shift || true + while (($# > 0)); do + arg="$1" + shift || true # replace tab by 2 spaces arg="${arg//$'\t'/ }" @@ -502,6 +284,90 @@ Array::wrap2() { ) | sed -E -e 's/[[:blank:]]+$//' } + +# @description check if command specified exists or return 1 +# with error and message if not +# +# @arg $1 commandName:String on which existence must be checked +# @arg $2 helpIfNotExists:String a help command to display if the command does not exist +# +# @exitcode 1 if the command specified does not exist +# @stderr diagnostic information + help if second argument is provided +Assert::commandExists() { + local commandName="$1" + local helpIfNotExists="$2" + + "${BASH_FRAMEWORK_COMMAND:-command}" -v "${commandName}" >/dev/null 2>/dev/null || { + Log::displayError "${commandName} is not installed, please install it" + if [[ -n "${helpIfNotExists}" ]]; then + Log::displayInfo "${helpIfNotExists}" + fi + return 1 + } + return 0 +} + + +# @description check if tty (interactive mode) is active +# @noargs +# @exitcode 1 if tty not active +# @env NON_INTERACTIVE if 1 consider as not interactive even if environment is interactive +# @env INTERACTIVE if 1 consider as interactive even if environment is not interactive +Assert::tty() { + if [[ "${NON_INTERACTIVE:-0}" = "1" ]]; then + return 1 + fi + if [[ "${INTERACTIVE:-0}" = "1" ]]; then + return 0 + fi + tty -s +} + + +# @description ensure env files are loaded +# @arg $@ list of default files to load at the end +# @exitcode 1 if one of env files fails to load +# @stderr diagnostics information is displayed +# shellcheck disable=SC2120 +Env::requireLoad() { + REQUIRE_FUNCTION_ENV_REQUIRE_LOAD_LOADED=1 + + local -a defaultFiles=("$@") + # get list of possible config files + local -a configFiles=() + if [[ -n "${BASH_FRAMEWORK_ENV_FILES[0]+1}" ]]; then + # BASH_FRAMEWORK_ENV_FILES is an array + configFiles+=("${BASH_FRAMEWORK_ENV_FILES[@]}") + fi + local localFrameworkConfigFile + localFrameworkConfigFile="$(pwd)/.framework-config" + if [[ -f "${localFrameworkConfigFile}" ]]; then + configFiles+=("${localFrameworkConfigFile}") + fi + if [[ -f "${FRAMEWORK_ROOT_DIR}/.framework-config" ]]; then + configFiles+=("${FRAMEWORK_ROOT_DIR}/.framework-config") + fi + configFiles+=("${optionEnvFiles[@]}") + configFiles+=("${defaultFiles[@]}") + + for file in "${configFiles[@]}"; do + # shellcheck source=/.framework-config + CURRENT_LOADED_ENV_FILE="${file}" source "${file}" || { + Log::displayError "while loading config file: ${file}" + return 1 + } + done +} + + +# @description create a temp file using default TMPDIR variable +# @env TMPDIR String (default value /tmp) +# @arg $1 templateName:String template name to use(optional) +Framework::createTempFile() { + mktemp -p "${TMPDIR:-/tmp}" -t "${1:-}.XXXXXXXXXXXX" +} + + # @description Retrieve the latest version number of a github release using Github API using retry # repo arg with fchastanet/bash-tools value would match https://github.com/fchastanet/bash-tools # @arg $1 repo:String repository in the format fchastanet/bash-tools @@ -534,78 +400,18 @@ Github::getLatestRelease() { return 1 } -# @description filter to keep only version number from a string -# @arg $@ files:String[] the files to filter -# @exitcode * if one of the filter command fails -# @stdin you can use stdin as alternative to files argument -# @stdout the filtered content -# shellcheck disable=SC2120 -Version::parse() { - # match anything, print(p), exit on first match(Q) - sed -En \ - -e 's/\x1b\[[0-9;]*[mGKHF]//g' \ - -e 's/[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/' \ - -e '//{p;Q}' \ - "$@" -} -# @description compare 2 version numbers -# @arg $1 version1:String version 1 -# @arg $2 version2:String version 2 -# @exitcode 0 if equal -# @exitcode 1 if version1 > version2 -# @exitcode 2 else -Version::compare() { - if [[ "$1" = "$2" ]]; then - return 0 - fi - local IFS=. - # shellcheck disable=2206 - local i ver1=($1) ver2=($2) - # fill empty fields in ver1 with zeros - for ((i = ${#ver1[@]}; i < ${#ver2[@]}; i++)); do - ver1[i]=0 - done - for ((i = 0; i < ${#ver1[@]}; i++)); do - if [[ -z "${ver2[i]+unset}" ]] || [[ -z ${ver2[i]} ]]; then - # fill empty fields in ver2 with zeros - ver2[i]=0 - fi - if ((10#${ver1[i]} > 10#${ver2[i]})); then - return 1 - fi - if ((10#${ver1[i]} < 10#${ver2[i]})); then - return 2 - fi - done - return 0 -} +# @description ensure command jq is available +# @exitcode 1 if jq command not available +# @stderr diagnostics information is displayed +Linux::requireJqCommand() { + REQUIRE_FUNCTION_LINUX_REQUIRE_JQ_COMMAND_LOADED=1 -# @description concatenate each element of an array with a separator -# -# @arg $1 glue:String -# @arg $@ array:String[] -# @example -# declare -a array=(test1, test2) -# echo "Result= $(Array::join "," "${array[@]})" -# Result= test1,test2 -Array::join() { - local glue="${1-}" - shift || true - local first="${1-}" - shift || true - printf %s "${first}" "${@/#/${glue}}" + if [[ "${SKIP_REQUIRE_JQ:-0}" = "0" && "${SKIP_REQUIRES:-0}" = "0" ]]; then + Assert::commandExists jq + fi } -# @description ensure COMMAND_BIN_DIR env var is set -# and PATH correctly prepared -# @noargs -# @set COMMAND_BIN_DIR string the directory where to find this command -# @set PATH string add directory where to find this command binary -Compiler::Facade::requireCommandBinDir() { - COMMAND_BIN_DIR="${CURRENT_DIR}" - Env::pathPrepend "${COMMAND_BIN_DIR}" -} declare -g FIRST_LOG_DATE LOG_LAST_LOG_DATE LOG_LAST_LOG_DATE_INIT LOG_LAST_DURATION_STR FIRST_LOG_DATE="${EPOCHREALTIME/[^0-9]/}" @@ -645,30 +451,81 @@ Log::computeDuration() { fi } -# @description log message to file + +# @description Display message using debug color (gray) # @arg $1 message:String the message to display -Log::logInfo() { - if ((BASH_FRAMEWORK_LOG_LEVEL >= __LEVEL_INFO)); then - Log::logMessage "${2:-INFO}" "$1" +# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs +# @env LOG_CONTEXT String allows to contextualize the log +Log::displayDebug() { + if ((BASH_FRAMEWORK_DISPLAY_LEVEL >= __LEVEL_DEBUG)); then + Log::computeDuration + echo -e "${__DEBUG_COLOR}DEBUG - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 fi + Log::logDebug "$1" } -# @description log message to file + +# @description Display message using error color (red) # @arg $1 message:String the message to display -Log::logDebug() { - if ((BASH_FRAMEWORK_LOG_LEVEL >= __LEVEL_DEBUG)); then - Log::logMessage "${2:-DEBUG}" "$1" +# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs +# @env LOG_CONTEXT String allows to contextualize the log +Log::displayError() { + if ((BASH_FRAMEWORK_DISPLAY_LEVEL >= __LEVEL_ERROR)); then + Log::computeDuration + echo -e "${__ERROR_COLOR}ERROR - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 fi + Log::logError "$1" } + +# @description Display message using info color (bg light blue/fg white) +# @arg $1 message:String the message to display +# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs +# @env LOG_CONTEXT String allows to contextualize the log +Log::displayInfo() { + local type="${2:-INFO}" + if ((BASH_FRAMEWORK_DISPLAY_LEVEL >= __LEVEL_INFO)); then + Log::computeDuration + echo -e "${__INFO_COLOR}${type} - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 + fi + Log::logInfo "$1" "${type}" +} + + +# @description Display message using warning color (yellow) +# @arg $1 message:String the message to display +# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs +# @env LOG_CONTEXT String allows to contextualize the log +Log::displayWarning() { + if ((BASH_FRAMEWORK_DISPLAY_LEVEL >= __LEVEL_WARNING)); then + Log::computeDuration + echo -e "${__WARNING_COLOR}WARN - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 + fi + Log::logWarning "$1" +} + + +# @description Display message using error color (red) and exit immediately with error status 1 +# @arg $1 message:String the message to display +# @env DISPLAY_DURATION int (default 0) if 1 display elapsed time information between 2 info logs +# @env LOG_CONTEXT String allows to contextualize the log +Log::fatal() { + Log::computeDuration + echo -e "${__ERROR_COLOR}FATAL - ${LOG_CONTEXT:-}${LOG_LAST_DURATION_STR:-}${1}${__RESET_COLOR}" >&2 + Log::logFatal "$1" + exit 1 +} + + # @description log message to file # @arg $1 message:String the message to display -Log::logWarning() { - if ((BASH_FRAMEWORK_LOG_LEVEL >= __LEVEL_WARNING)); then - Log::logMessage "${2:-WARNING}" "$1" +Log::logDebug() { + if ((BASH_FRAMEWORK_LOG_LEVEL >= __LEVEL_DEBUG)); then + Log::logMessage "${2:-DEBUG}" "$1" fi } + # @description log message to file # @arg $1 message:String the message to display Log::logError() { @@ -677,20 +534,6 @@ Log::logError() { fi } -# @description check if tty (interactive mode) is active -# @noargs -# @exitcode 1 if tty not active -# @env NON_INTERACTIVE if 1 consider as not interactive even if environment is interactive -# @env INTERACTIVE if 1 consider as interactive even if environment is not interactive -Assert::tty() { - if [[ "${NON_INTERACTIVE:-0}" = "1" ]]; then - return 1 - fi - if [[ "${INTERACTIVE:-0}" = "1" ]]; then - return 0 - fi - tty -s -} # @description log message to file # @arg $1 message:String the message to display @@ -698,6 +541,16 @@ Log::logFatal() { Log::logMessage "${2:-FATAL}" "$1" } + +# @description log message to file +# @arg $1 message:String the message to display +Log::logInfo() { + if ((BASH_FRAMEWORK_LOG_LEVEL >= __LEVEL_INFO)); then + Log::logMessage "${2:-INFO}" "$1" + fi +} + + # @description Internal: common log message # @example text # [date]|[levelMsg]|message @@ -711,20 +564,97 @@ Log::logFatal() { # @env BASH_FRAMEWORK_LOG_FILE String log file to use, do nothing if empty # @env BASH_FRAMEWORK_LOG_LEVEL int log level log only if > OFF or fatal messages # @stderr diagnostics information is displayed -# @require Env::requireLoad -# @require Log::requireLoad Log::logMessage() { + + if [[ "${REQUIRE_FUNCTION_ENV_REQUIRE_LOAD_LOADED:-0}" != 1 ]]; then + echo >&2 "Requirement Env::requireLoad has not been loaded" + exit 1 + fi + + if [[ "${REQUIRE_FUNCTION_LOG_REQUIRE_LOAD_LOADED:-0}" != 1 ]]; then + echo >&2 "Requirement Log::requireLoad has not been loaded" + exit 1 + fi + local levelMsg="$1" local msg="$2" local date - if [[ -n "${BASH_FRAMEWORK_LOG_FILE}" ]] && ((BASH_FRAMEWORK_LOG_LEVEL > __LEVEL_OFF)); then - date="$(date '+%Y-%m-%d %H:%M:%S')" - touch "${BASH_FRAMEWORK_LOG_FILE}" - printf "%s|%7s|%s\n" "${date}" "${levelMsg}" "${msg}" >>"${BASH_FRAMEWORK_LOG_FILE}" + if [[ -n "${BASH_FRAMEWORK_LOG_FILE}" ]] && ((BASH_FRAMEWORK_LOG_LEVEL > __LEVEL_OFF)); then + date="$(date '+%Y-%m-%d %H:%M:%S')" + touch "${BASH_FRAMEWORK_LOG_FILE}" + printf "%s|%7s|%s\n" "${date}" "${levelMsg}" "${msg}" >>"${BASH_FRAMEWORK_LOG_FILE}" + fi +} + + +# @description log message to file +# @arg $1 message:String the message to display +Log::logWarning() { + if ((BASH_FRAMEWORK_LOG_LEVEL >= __LEVEL_WARNING)); then + Log::logMessage "${2:-WARNING}" "$1" + fi +} + + +# @description activate or not Log::display* and Log::log* functions +# based on BASH_FRAMEWORK_DISPLAY_LEVEL and BASH_FRAMEWORK_LOG_LEVEL +# environment variables loaded by Env::requireLoad +# try to create log file and rotate it if necessary +# @noargs +# @set BASH_FRAMEWORK_LOG_LEVEL int to OFF level if BASH_FRAMEWORK_LOG_FILE is empty or not writable +# @env BASH_FRAMEWORK_DISPLAY_LEVEL int +# @env BASH_FRAMEWORK_LOG_LEVEL int +# @env BASH_FRAMEWORK_LOG_FILE String +# @env BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION int do log rotation if > 0 +# @exitcode 0 always successful +# @stderr diagnostics information about log file is displayed +Log::requireLoad() { + REQUIRE_FUNCTION_LOG_REQUIRE_LOAD_LOADED=1 + + + if [[ "${REQUIRE_FUNCTION_ENV_REQUIRE_LOAD_LOADED:-0}" != 1 ]]; then + echo >&2 "Requirement Env::requireLoad has not been loaded" + exit 1 + fi + + if [[ "${REQUIRE_FUNCTION_UI_REQUIRE_THEME_LOADED:-0}" != 1 ]]; then + echo >&2 "Requirement UI::requireTheme has not been loaded" + exit 1 + fi + + if [[ -z "${BASH_FRAMEWORK_LOG_FILE:-}" ]]; then + BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} + export BASH_FRAMEWORK_LOG_LEVEL + fi + + if ((BASH_FRAMEWORK_LOG_LEVEL > __LEVEL_OFF)); then + if [[ ! -f "${BASH_FRAMEWORK_LOG_FILE}" ]]; then + if [[ ! -d "${BASH_FRAMEWORK_LOG_FILE%/*}" ]]; then + if ! mkdir -p "${BASH_FRAMEWORK_LOG_FILE%/*}" 2>/dev/null; then + BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} + echo -e "${__ERROR_COLOR}ERROR - directory ${BASH_FRAMEWORK_LOG_FILE%/*} is not writable${__RESET_COLOR}" >&2 + fi + elif ! touch --no-create "${BASH_FRAMEWORK_LOG_FILE}" 2>/dev/null; then + BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} + echo -e "${__ERROR_COLOR}ERROR - File ${BASH_FRAMEWORK_LOG_FILE} is not writable${__RESET_COLOR}" >&2 + fi + elif [[ ! -w "${BASH_FRAMEWORK_LOG_FILE}" ]]; then + BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} + echo -e "${__ERROR_COLOR}ERROR - File ${BASH_FRAMEWORK_LOG_FILE} is not writable${__RESET_COLOR}" >&2 + fi + fi + + if ((BASH_FRAMEWORK_LOG_LEVEL > __LEVEL_OFF)); then + # will always be created even if not in info level + Log::logMessage "INFO" "Logging to file ${BASH_FRAMEWORK_LOG_FILE} - Log level ${BASH_FRAMEWORK_LOG_LEVEL}" + if ((BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION > 0)); then + Log::rotate "${BASH_FRAMEWORK_LOG_FILE}" "${BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION}" + fi fi } + # @description To be called before logging in the log file # @arg $1 file:string log file name # @arg $2 maxLogFilesCount:int maximum number of log files @@ -747,6 +677,7 @@ Log::rotate() { fi } + # @description Retry a command 5 times with a delay of 15 seconds between each attempt # @arg $@ command:String[] the command to run # @exitcode 0 on success @@ -757,38 +688,6 @@ Retry::default() { Retry::parameterized "${RETRY_MAX_RETRY:-5}" "${RETRY_DELAY_BETWEEN_RETRIES:-15}" "" "$@" } -# @description extract version number from github api -# @noargs -# @stdin json result of github API -# @exitcode 1 if jq or Version::parse fails -# @stdout the version parsed -# @require Linux::requireJqCommand -Version::githubApiExtractVersion() { - jq -r ".tag_name" -} - -# @description prepend directories to the PATH environment variable -# @arg $@ args:String[] list of directories to prepend -# @set PATH update PATH with the directories prepended -Env::pathPrepend() { - local arg - for arg in "$@"; do - if [[ -d "${arg}" && ":${PATH}:" != *":${arg}:"* ]]; then - PATH="$(realpath "${arg}"):${PATH}" - fi - done -} - -# @description load color theme -# @noargs -# @env BASH_FRAMEWORK_THEME String theme to use -# @env LOAD_THEME int 0 to avoid loading theme -# @exitcode 0 always successful -UI::requireTheme() { - if [[ "${LOAD_THEME:-1}" = "1" ]]; then - UI::theme "${BASH_FRAMEWORK_THEME-default}" - fi -} # @description Retry a command several times depending on parameters # @arg $1 maxRetries:int $1 max retries @@ -827,56 +726,192 @@ Retry::parameterized() { return 0 } -# @description ensure command jq is available -# @exitcode 1 if jq command not available -# @stderr diagnostics information is displayed -Linux::requireJqCommand() { - if [[ "${SKIP_REQUIRE_JQ:-0}" = "0" && "${SKIP_REQUIRES:-0}" = "0" ]]; then - Assert::commandExists jq + +# @description draw a line with the character passed in parameter repeated depending on terminal width +# @arg $1 character:String character to use as separator (default value #) +UI::drawLine() { + local character="${1:-#}" + local -i width=${COLUMNS:-0} + if ((width == 0)) && [[ -t 1 ]]; then + width=$(tput cols) + fi + if ((width == 0)); then + width=80 fi + printf -- "${character}%.0s" $(seq "${COLUMNS:-$([[ -t 1 ]] && tput cols || echo '80')}") + echo } -# @description check if command specified exists or return 1 -# with error and message if not + +# @description load color theme +# @noargs +# @env BASH_FRAMEWORK_THEME String theme to use +# @env LOAD_THEME int 0 to avoid loading theme +# @exitcode 0 always successful +UI::requireTheme() { + REQUIRE_FUNCTION_UI_REQUIRE_THEME_LOADED=1 + + if [[ "${LOAD_THEME:-1}" = "1" ]]; then + UI::theme "${BASH_FRAMEWORK_THEME-default}" + fi +} + + +# @description load colors theme constants +# @warning if tty not opened, noColor theme will be chosen +# @arg $1 theme:String the theme to use (default, noColor) +# @arg $@ args:String[] +# @set __ERROR_COLOR String indicate error status +# @set __INFO_COLOR String indicate info status +# @set __SUCCESS_COLOR String indicate success status +# @set __WARNING_COLOR String indicate warning status +# @set __SKIPPED_COLOR String indicate skipped status +# @set __DEBUG_COLOR String indicate debug status +# @set __HELP_COLOR String indicate help status +# @set __TEST_COLOR String not used +# @set __TEST_ERROR_COLOR String not used +# @set __HELP_TITLE_COLOR String used to display help title in help strings +# @set __HELP_OPTION_COLOR String used to display highlight options in help strings # -# @arg $1 commandName:String on which existence must be checked -# @arg $2 helpIfNotExists:String a help command to display if the command does not exist +# @set __RESET_COLOR String reset default color # -# @exitcode 1 if the command specified does not exist -# @stderr diagnostic information + help if second argument is provided -Assert::commandExists() { - local commandName="$1" - local helpIfNotExists="$2" +# @set __HELP_EXAMPLE String to remove +# @set __HELP_TITLE String to remove +# @set __HELP_NORMAL String to remove +# shellcheck disable=SC2034 +UI::theme() { + local theme="${1-default}" + if [[ ! "${theme}" =~ -force$ ]] && ! Assert::tty; then + theme="noColor" + fi + case "${theme}" in + default | default-force) + theme="default" + ;; + noColor) ;; + *) + Log::fatal "invalid theme provided" + ;; + esac + if [[ "${theme}" = "default" ]]; then + BASH_FRAMEWORK_THEME="default" + # check colors applicable https://misc.flogisoft.com/bash/tip_colors_and_formatting + __ERROR_COLOR='\e[31m' # Red + __INFO_COLOR='\e[44m' # white on lightBlue + __SUCCESS_COLOR='\e[32m' # Green + __WARNING_COLOR='\e[33m' # Yellow + __SKIPPED_COLOR='\e[33m' # Yellow + __DEBUG_COLOR='\e[37m' # Gray + __HELP_COLOR='\e[7;49;33m' # Black on Gold + __TEST_COLOR='\e[100m' # Light magenta + __TEST_ERROR_COLOR='\e[41m' # white on red + __HELP_TITLE_COLOR="\e[1;37m" # Bold + __HELP_OPTION_COLOR="\e[1;34m" # Blue + # Internal: reset color + __RESET_COLOR='\e[0m' # Reset Color + # shellcheck disable=SC2155,SC2034 + __HELP_EXAMPLE="$(echo -e "\e[2;97m")" + # shellcheck disable=SC2155,SC2034 + __HELP_TITLE="$(echo -e "\e[1;37m")" + # shellcheck disable=SC2155,SC2034 + __HELP_NORMAL="$(echo -e "\033[0m")" + else + BASH_FRAMEWORK_THEME="noColor" + # check colors applicable https://misc.flogisoft.com/bash/tip_colors_and_formatting + __ERROR_COLOR='' + __INFO_COLOR='' + __SUCCESS_COLOR='' + __WARNING_COLOR='' + __SKIPPED_COLOR='' + __DEBUG_COLOR='' + __HELP_COLOR='' + __TEST_COLOR='' + __TEST_ERROR_COLOR='' + __HELP_TITLE_COLOR='' + __HELP_OPTION_COLOR='' + # Internal: reset color + __RESET_COLOR='' + __HELP_EXAMPLE='' + __HELP_TITLE='' + __HELP_NORMAL='' + fi +} - "${BASH_FRAMEWORK_COMMAND:-command}" -v "${commandName}" >/dev/null 2>/dev/null || { - Log::displayError "${commandName} is not installed, please install it" - if [[ -n "${helpIfNotExists}" ]]; then - Log::displayInfo "${helpIfNotExists}" + +# @description compare 2 version numbers +# @arg $1 version1:String version 1 +# @arg $2 version2:String version 2 +# @exitcode 0 if equal +# @exitcode 1 if version1 > version2 +# @exitcode 2 else +Version::compare() { + if [[ "$1" = "$2" ]]; then + return 0 + fi + local IFS=. + # shellcheck disable=2206 + local i ver1=($1) ver2=($2) + # fill empty fields in ver1 with zeros + for ((i = ${#ver1[@]}; i < ${#ver2[@]}; i++)); do + ver1[i]=0 + done + for ((i = 0; i < ${#ver1[@]}; i++)); do + if [[ -z "${ver2[i]+unset}" ]] || [[ -z ${ver2[i]} ]]; then + # fill empty fields in ver2 with zeros + ver2[i]=0 fi - return 1 - } + if ((10#${ver1[i]} > 10#${ver2[i]})); then + return 1 + fi + if ((10#${ver1[i]} < 10#${ver2[i]})); then + return 2 + fi + done return 0 } -# FUNCTIONS -facade_main_megalintersh() { -FRAMEWORK_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" -FRAMEWORK_SRC_DIR="${FRAMEWORK_ROOT_DIR}/src" -FRAMEWORK_BIN_DIR="${FRAMEWORK_ROOT_DIR}/bin" -FRAMEWORK_VENDOR_DIR="${FRAMEWORK_ROOT_DIR}/vendor" -FRAMEWORK_VENDOR_BIN_DIR="${FRAMEWORK_ROOT_DIR}/vendor/bin" -# REQUIRES -Env::requireLoad -UI::requireTheme -Log::requireLoad -Linux::requireJqCommand -Compiler::Facade::requireCommandBinDir +# @description extract version number from github api +# @noargs +# @stdin json result of github API +# @exitcode 1 if jq or Version::parse fails +# @stdout the version parsed +Version::githubApiExtractVersion() { + + if [[ "${REQUIRE_FUNCTION_LINUX_REQUIRE_JQ_COMMAND_LOADED:-0}" != 1 ]]; then + echo >&2 "Requirement Linux::requireJqCommand has not been loaded" + exit 1 + fi + + jq -r ".tag_name" +} + + +# @description filter to keep only version number from a string +# @arg $@ files:String[] the files to filter +# @exitcode * if one of the filter command fails +# @stdin you can use stdin as alternative to files argument +# @stdout the filtered content +# shellcheck disable=SC2120 +Version::parse() { + # match anything, print(p), exit on first match(Q) + sed -En \ + -e 's/\x1b\[[0-9;]*[mGKHF]//g' \ + -e 's/[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/' \ + -e '//{p;Q}' \ + "$@" +} +# FUNCTIONS -# @require Compiler::Facade::requireCommandBinDir declare -a BASH_FRAMEWORK_ARGV_FILTERED=() +beforeParseCallback() { + Env::requireLoad + UI::requireTheme + Log::requireLoad +} + copyrightCallback() { if [[ -z "${copyrightBeginYear}" ]]; then copyrightBeginYear="$(date +%Y)" @@ -913,13 +948,14 @@ updateArgListQuietCallback() { :; } # shellcheck disable=SC2317 # if function is overridden optionHelpCallback() { - megalinterCommand help + Log::displayError "optionHelpCallback needs to be overridden" exit 0 } # shellcheck disable=SC2317 # if function is overridden optionVersionCallback() { - echo "${SCRIPT_NAME} version 1.0" + # shellcheck disable=SC2154 + echo "${SCRIPT_NAME} version ${versionNumber}" exit 0 } @@ -937,21 +973,22 @@ optionEnvFileCallback() { optionInfoVerboseCallback() { BASH_FRAMEWORK_ARGS_VERBOSE_OPTION='--verbose' BASH_FRAMEWORK_ARGS_VERBOSE=${__VERBOSE_LEVEL_INFO} - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_INFO}" >> "${overrideEnvFile}" + echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_INFO}" >>"${overrideEnvFile}" } # shellcheck disable=SC2317 # if function is overridden optionDebugVerboseCallback() { BASH_FRAMEWORK_ARGS_VERBOSE_OPTION='-vv' BASH_FRAMEWORK_ARGS_VERBOSE=${__VERBOSE_LEVEL_DEBUG} - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_DEBUG}" >> "${overrideEnvFile}" + echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_DEBUG}" >>"${overrideEnvFile}" } # shellcheck disable=SC2317 # if function is overridden optionTraceVerboseCallback() { + # shellcheck disable=SC2034 BASH_FRAMEWORK_ARGS_VERBOSE_OPTION='-vvv' BASH_FRAMEWORK_ARGS_VERBOSE=${__VERBOSE_LEVEL_TRACE} - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_DEBUG}" >> "${overrideEnvFile}" + echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_DEBUG}" >>"${overrideEnvFile}" } getLevel() { @@ -975,6 +1012,7 @@ getLevel() { *) Log::displayError "Command ${SCRIPT_NAME} - Invalid level ${level}" return 1 + ;; esac } @@ -996,6 +1034,7 @@ getVerboseLevel() { *) Log::displayError "Command ${SCRIPT_NAME} - Invalid level ${level}" return 1 + ;; esac } @@ -1006,7 +1045,7 @@ optionDisplayLevelCallback() { logLevel="$(getLevel "${level}")" verboseLevel="$(getVerboseLevel "${level}")" BASH_FRAMEWORK_ARGS_VERBOSE=${verboseLevel} - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${logLevel}" >> "${overrideEnvFile}" + echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${logLevel}" >>"${overrideEnvFile}" } # shellcheck disable=SC2317 # if function is overridden @@ -1015,19 +1054,20 @@ optionLogLevelCallback() { local logLevel verboseLevel logLevel="$(getLevel "${level}")" verboseLevel="$(getVerboseLevel "${level}")" + # shellcheck disable=SC2034 BASH_FRAMEWORK_ARGS_VERBOSE=${verboseLevel} - echo "BASH_FRAMEWORK_LOG_LEVEL=${logLevel}" >> "${overrideEnvFile}" + echo "BASH_FRAMEWORK_LOG_LEVEL=${logLevel}" >>"${overrideEnvFile}" } # shellcheck disable=SC2317 # if function is overridden optionLogFileCallback() { local logFile="$2" - echo "BASH_FRAMEWORK_LOG_FILE='${logFile}'" >> "${overrideEnvFile}" + echo "BASH_FRAMEWORK_LOG_FILE='${logFile}'" >>"${overrideEnvFile}" } # shellcheck disable=SC2317 # if function is overridden optionQuietCallback() { - echo "BASH_FRAMEWORK_QUIET_MODE=1" >> "${overrideEnvFile}" + echo "BASH_FRAMEWORK_QUIET_MODE=1" >>"${overrideEnvFile}" } # shellcheck disable=SC2317 # if function is overridden @@ -1058,6 +1098,7 @@ optionBashFrameworkConfigCallback() { defaultFrameworkConfig="$( cat <<'EOF' + # copied from src/_includes/.framework-config.default # shellcheck disable=SC2034 @@ -1075,7 +1116,7 @@ NON_FRAMEWORK_FILES_REGEXP="${NON_FRAMEWORK_FILES_REGEXP:-(^bin/|.framework-conf # describe the files that are allowed to not have an associated bats file BATS_FILE_NOT_NEEDED_REGEXP="${BATS_FILE_NOT_NEEDED_REGEXP:-(^bin/|.framework-config|.bats$|/testsData/|^manualTests/|/_.sh$|/ZZZ.sh$|/__all.sh$|^src/batsHeaders.sh$|^src/_includes)}" # describe the files that are allowed to not have a function matching the filename -FRAMEWORK_FILES_FUNCTION_MATCHING_IGNORE_REGEXP="${FRAMEWORK_FILES_FUNCTION_MATCHING_IGNORE_REGEXP:-^bin/|^\.framework-config$|\.tpl$|/testsData/|^manualTests/|\.bats$}" +FRAMEWORK_FILES_FUNCTION_MATCHING_IGNORE_REGEXP="${FRAMEWORK_FILES_FUNCTION_MATCHING_IGNORE_REGEXP:-^bin/|^\.framework-config$|/testsData/|^manualTests/|\.bats$}" # Source directories if [[ ! -v FRAMEWORK_SRC_DIRS ]]; then FRAMEWORK_SRC_DIRS=( @@ -1091,6 +1132,7 @@ BASH_FRAMEWORK_LOG_LEVEL="${BASH_FRAMEWORK_LOG_LEVEL:-0}" BASH_FRAMEWORK_DISPLAY_LEVEL="${BASH_FRAMEWORK_DISPLAY_LEVEL:-3}" BASH_FRAMEWORK_LOG_FILE="${BASH_FRAMEWORK_LOG_FILE:-${FRAMEWORK_ROOT_DIR}/logs/${0##*/}.log}" BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION="${BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION:-5}" + EOF )" @@ -1099,7 +1141,7 @@ overrideEnvFile="$(Framework::createTempFile "overrideEnvFile")" commandOptionParseFinished() { # load default template framework config defaultEnvFile="${PERSISTENT_TMPDIR}/.framework-config" - echo "${defaultFrameworkConfig}" > "${defaultEnvFile}" + echo "${defaultFrameworkConfig}" >"${defaultEnvFile}" local -a files=("${defaultEnvFile}") if [[ -f "${envFile}" ]]; then files+=("${envFile}") @@ -1117,564 +1159,28 @@ commandOptionParseFinished() { fi } -# default option values -declare optionFormat="${optionFormatDefault:-plain}" + + +# shellcheck disable=SC2034 +declare optionContinuousIntegrationMode=0 # shellcheck disable=SC2317 # if function is overridden -updateArgListFormatCallback() { - BASH_FRAMEWORK_ARGV_FILTERED+=("$@") +updateOptionFormat() { + BASH_FRAMEWORK_ARGV_FILTERED+=("$1") } -megalinterCommand() { - local options_parse_cmd="$1" - shift || true - if [[ "${options_parse_cmd}" = "parse" ]]; then - optionFormat="plain" - local -i options_parse_optionParsedCountOptionFormat - ((options_parse_optionParsedCountOptionFormat = 0)) || true - optionFix="0" - local -i options_parse_optionParsedCountOptionFix - ((options_parse_optionParsedCountOptionFix = 0)) || true - optionFilesOnly="0" - local -i options_parse_optionParsedCountOptionFilesOnly - ((options_parse_optionParsedCountOptionFilesOnly = 0)) || true - optionIncremental="0" - local -i options_parse_optionParsedCountOptionIncremental - ((options_parse_optionParsedCountOptionIncremental = 0)) || true - optionMegalinterImage="oxsecurity/megalinter-terraform:v7.10.0" - local -i options_parse_optionParsedCountOptionMegalinterImage - ((options_parse_optionParsedCountOptionMegalinterImage = 0)) || true - optionCheckMegalinterVersion="0" - local -i options_parse_optionParsedCountOptionCheckMegalinterVersion - ((options_parse_optionParsedCountOptionCheckMegalinterVersion = 0)) || true - optionMegalinterConfigFile=".mega-linter.yml" - local -i options_parse_optionParsedCountOptionMegalinterConfigFile - ((options_parse_optionParsedCountOptionMegalinterConfigFile = 0)) || true - local -i options_parse_optionParsedCountOptionBashFrameworkConfig - ((options_parse_optionParsedCountOptionBashFrameworkConfig = 0)) || true - optionConfig="0" - local -i options_parse_optionParsedCountOptionConfig - ((options_parse_optionParsedCountOptionConfig = 0)) || true - optionInfoVerbose="0" - local -i options_parse_optionParsedCountOptionInfoVerbose - ((options_parse_optionParsedCountOptionInfoVerbose = 0)) || true - optionDebugVerbose="0" - local -i options_parse_optionParsedCountOptionDebugVerbose - ((options_parse_optionParsedCountOptionDebugVerbose = 0)) || true - optionTraceVerbose="0" - local -i options_parse_optionParsedCountOptionTraceVerbose - ((options_parse_optionParsedCountOptionTraceVerbose = 0)) || true - optionNoColor="0" - local -i options_parse_optionParsedCountOptionNoColor - ((options_parse_optionParsedCountOptionNoColor = 0)) || true - optionTheme="default" - local -i options_parse_optionParsedCountOptionTheme - ((options_parse_optionParsedCountOptionTheme = 0)) || true - optionHelp="0" - local -i options_parse_optionParsedCountOptionHelp - ((options_parse_optionParsedCountOptionHelp = 0)) || true - optionVersion="0" - local -i options_parse_optionParsedCountOptionVersion - ((options_parse_optionParsedCountOptionVersion = 0)) || true - optionQuiet="0" - local -i options_parse_optionParsedCountOptionQuiet - ((options_parse_optionParsedCountOptionQuiet = 0)) || true - local -i options_parse_optionParsedCountOptionLogLevel - ((options_parse_optionParsedCountOptionLogLevel = 0)) || true - local -i options_parse_optionParsedCountOptionLogFile - ((options_parse_optionParsedCountOptionLogFile = 0)) || true - local -i options_parse_optionParsedCountOptionDisplayLevel - ((options_parse_optionParsedCountOptionDisplayLevel = 0)) || true - # shellcheck disable=SC2034 - local -i options_parse_parsedArgIndex=0 - while (($# > 0)); do - local options_parse_arg="$1" - local argOptDefaultBehavior=0 - case "${options_parse_arg}" in - # Option 1/21 - # Option optionFormat --format variableType String min 0 max 1 authorizedValues 'plain|json' regexp '' - --format) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - if [[ ! "$1" =~ plain|json ]]; then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - value '$1' is not part of authorized values(plain|json)" - return 1 - fi - if ((options_parse_optionParsedCountOptionFormat >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionFormat)) - # shellcheck disable=SC2034 - optionFormat="$1" - updateArgListFormatCallback "${options_parse_arg}" "${optionFormat}" - ;; - # Option 2/21 - # Option optionFix --fix variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --fix) - # shellcheck disable=SC2034 - optionFix="1" - if ((options_parse_optionParsedCountOptionFix >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionFix)) - optionFixCallback "${options_parse_arg}" - ;; - # Option 3/21 - # Option optionFilesOnly --filesOnly variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --filesOnly) - # shellcheck disable=SC2034 - optionFilesOnly="1" - if ((options_parse_optionParsedCountOptionFilesOnly >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionFilesOnly)) - filesOnlyCallback "${options_parse_arg}" - ;; - # Option 4/21 - # Option optionIncremental --incremental|-i variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --incremental | -i) - # shellcheck disable=SC2034 - optionIncremental="1" - if ((options_parse_optionParsedCountOptionIncremental >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionIncremental)) - ;; - # Option 5/21 - # Option optionMegalinterImage --image variableType String min 0 max 1 authorizedValues '' regexp '' - --image) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - if ((options_parse_optionParsedCountOptionMegalinterImage >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionMegalinterImage)) - # shellcheck disable=SC2034 - optionMegalinterImage="$1" - ;; - # Option 6/21 - # Option optionCheckMegalinterVersion --check-megalinter-version variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --check-megalinter-version) - # shellcheck disable=SC2034 - optionCheckMegalinterVersion="1" - if ((options_parse_optionParsedCountOptionCheckMegalinterVersion >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionCheckMegalinterVersion)) - ;; - # Option 7/21 - # Option optionMegalinterConfigFile --config-file variableType String min 0 max 1 authorizedValues '' regexp '' - --config-file) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - if ((options_parse_optionParsedCountOptionMegalinterConfigFile >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionMegalinterConfigFile)) - # shellcheck disable=SC2034 - optionMegalinterConfigFile="$1" - ;; - # Option 8/21 - # Option optionBashFrameworkConfig --bash-framework-config variableType String min 0 max 1 authorizedValues '' regexp '' - --bash-framework-config) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - if ((options_parse_optionParsedCountOptionBashFrameworkConfig >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionBashFrameworkConfig)) - # shellcheck disable=SC2034 - optionBashFrameworkConfig="$1" - optionBashFrameworkConfigCallback "${options_parse_arg}" "${optionBashFrameworkConfig}" - ;; - # Option 9/21 - # Option optionConfig --config variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --config) - # shellcheck disable=SC2034 - optionConfig="1" - if ((options_parse_optionParsedCountOptionConfig >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionConfig)) - ;; - # Option 10/21 - # Option optionInfoVerbose --verbose|-v variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --verbose | -v) - # shellcheck disable=SC2034 - optionInfoVerbose="1" - if ((options_parse_optionParsedCountOptionInfoVerbose >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionInfoVerbose)) - optionInfoVerboseCallback "${options_parse_arg}" - updateArgListInfoVerboseCallback "${options_parse_arg}" - ;; - # Option 11/21 - # Option optionDebugVerbose -vv variableType Boolean min 0 max 1 authorizedValues '' regexp '' - -vv) - # shellcheck disable=SC2034 - optionDebugVerbose="1" - if ((options_parse_optionParsedCountOptionDebugVerbose >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionDebugVerbose)) - optionDebugVerboseCallback "${options_parse_arg}" - updateArgListDebugVerboseCallback "${options_parse_arg}" - ;; - # Option 12/21 - # Option optionTraceVerbose -vvv variableType Boolean min 0 max 1 authorizedValues '' regexp '' - -vvv) - # shellcheck disable=SC2034 - optionTraceVerbose="1" - if ((options_parse_optionParsedCountOptionTraceVerbose >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionTraceVerbose)) - optionTraceVerboseCallback "${options_parse_arg}" - updateArgListTraceVerboseCallback "${options_parse_arg}" - ;; - # Option 13/21 - # Option optionEnvFiles --env-file variableType StringArray min 0 max -1 authorizedValues '' regexp '' - --env-file) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - ((++options_parse_optionParsedCountOptionEnvFiles)) - optionEnvFiles+=("$1") - optionEnvFileCallback "${options_parse_arg}" "${optionEnvFiles[@]}" - updateArgListEnvFileCallback "${options_parse_arg}" "${optionEnvFiles[@]}" - ;; - # Option 14/21 - # Option optionNoColor --no-color variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --no-color) - # shellcheck disable=SC2034 - optionNoColor="1" - if ((options_parse_optionParsedCountOptionNoColor >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionNoColor)) - optionNoColorCallback "${options_parse_arg}" - updateArgListNoColorCallback "${options_parse_arg}" - ;; - # Option 15/21 - # Option optionTheme --theme variableType String min 0 max 1 authorizedValues 'default|default-force|noColor' regexp '' - --theme) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - if [[ ! "$1" =~ default|default-force|noColor ]]; then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - value '$1' is not part of authorized values(default|default-force|noColor)" - return 1 - fi - if ((options_parse_optionParsedCountOptionTheme >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionTheme)) - # shellcheck disable=SC2034 - optionTheme="$1" - optionThemeCallback "${options_parse_arg}" "${optionTheme}" - updateArgListThemeCallback "${options_parse_arg}" "${optionTheme}" - ;; - # Option 16/21 - # Option optionHelp --help|-h variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --help | -h) - # shellcheck disable=SC2034 - optionHelp="1" - if ((options_parse_optionParsedCountOptionHelp >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionHelp)) - optionHelpCallback "${options_parse_arg}" - ;; - # Option 17/21 - # Option optionVersion --version variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --version) - # shellcheck disable=SC2034 - optionVersion="1" - if ((options_parse_optionParsedCountOptionVersion >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionVersion)) - optionVersionCallback "${options_parse_arg}" - ;; - # Option 18/21 - # Option optionQuiet --quiet|-q variableType Boolean min 0 max 1 authorizedValues '' regexp '' - --quiet | -q) - # shellcheck disable=SC2034 - optionQuiet="1" - if ((options_parse_optionParsedCountOptionQuiet >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionQuiet)) - optionQuietCallback "${options_parse_arg}" - updateArgListQuietCallback "${options_parse_arg}" - ;; - # Option 19/21 - # Option optionLogLevel --log-level variableType String min 0 max 1 authorizedValues 'OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE' regexp '' - --log-level) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - if [[ ! "$1" =~ OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE ]]; then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - value '$1' is not part of authorized values(OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE)" - return 1 - fi - if ((options_parse_optionParsedCountOptionLogLevel >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionLogLevel)) - # shellcheck disable=SC2034 - optionLogLevel="$1" - optionLogLevelCallback "${options_parse_arg}" "${optionLogLevel}" - updateArgListLogLevelCallback "${options_parse_arg}" "${optionLogLevel}" - ;; - # Option 20/21 - # Option optionLogFile --log-file variableType String min 0 max 1 authorizedValues '' regexp '' - --log-file) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - if ((options_parse_optionParsedCountOptionLogFile >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionLogFile)) - # shellcheck disable=SC2034 - optionLogFile="$1" - optionLogFileCallback "${options_parse_arg}" "${optionLogFile}" - updateArgListLogFileCallback "${options_parse_arg}" "${optionLogFile}" - ;; - # Option 21/21 - # Option optionDisplayLevel --display-level variableType String min 0 max 1 authorizedValues 'OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE' regexp '' - --display-level) - shift - if (($# == 0)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" - return 1 - fi - if [[ ! "$1" =~ OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE ]]; then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - value '$1' is not part of authorized values(OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE)" - return 1 - fi - if ((options_parse_optionParsedCountOptionDisplayLevel >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionDisplayLevel)) - # shellcheck disable=SC2034 - optionDisplayLevel="$1" - optionDisplayLevelCallback "${options_parse_arg}" "${optionDisplayLevel}" - updateArgListDisplayLevelCallback "${options_parse_arg}" "${optionDisplayLevel}" - ;; - -*) - if [[ "${argOptDefaultBehavior}" = "0" ]]; then - Log::displayError "Command ${SCRIPT_NAME} - Invalid option ${options_parse_arg}" - return 1 - fi - ;; - *) - unknownArg "${options_parse_arg}" - ((++options_parse_parsedArgIndex)) - ;; - esac - shift || true - done - commandOptionParseFinished - commandCallback - Log::displayDebug "Command ${SCRIPT_NAME} - parse arguments: ${BASH_FRAMEWORK_ARGV[*]}" - Log::displayDebug "Command ${SCRIPT_NAME} - parse filtered arguments: ${BASH_FRAMEWORK_ARGV_FILTERED[*]}" - elif [[ "${options_parse_cmd}" = "help" ]]; then - Array::wrap2 " " 80 0 "${__HELP_TITLE_COLOR}DESCRIPTION:${__RESET_COLOR}" "run megalinter over this repository." - echo - - echo -e "$(Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" "${SCRIPT_NAME}" "[OPTIONS]")" - echo -e "$(Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" \ - "${SCRIPT_NAME}" \ - "[--format ]" "[--fix]" "[--filesOnly]" "[--incremental|-i]" "[--image ]" "[--check-megalinter-version]" "[--config-file ]" "[--bash-framework-config ]" "[--config]" "[--verbose|-v]" "[-vv]" "[-vvv]" "[--env-file ]" "[--no-color]" "[--theme ]" "[--help|-h]" "[--version]" "[--quiet|-q]" "[--log-level ]" "[--log-file ]" "[--display-level ]")" - echo - echo -e "${__HELP_TITLE_COLOR}OPTIONS:${__RESET_COLOR}" - echo -e " ${__HELP_OPTION_COLOR}--format ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(define\ output\ format\ of\ this\ command) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo ' Default value: plain' - echo ' Possible values: plain|json' - echo -e " ${__HELP_OPTION_COLOR}--fix${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Apply\ linters\ fixes\ automatically.) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--filesOnly${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Skip\ linters\ that\ run\ in\ project\ mode.) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--incremental${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-i${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Run\ megalinter\ only\ on\ files\ that\ are\ git\ staged) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--image ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Specify\ docker\ megalinter\ image\ name\ to\ use) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo ' Default value: oxsecurity/megalinter-terraform:v7.10.0' - echo -e " ${__HELP_OPTION_COLOR}--check-megalinter-version${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Check\ if\ new\ version\ of\ megalinter\ is\ available\ \(compared\ to\ oxsecurity/megalinter-terraform:v7.10.0\)\ and\ exit\ 1\ if\ yes\ and\ display\ new\ version\ number.) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--config-file ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Specify\ megalinter\ config\ filename\ to\ use) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo ' Default value: .mega-linter.yml' - echo - echo -e "${__HELP_TITLE_COLOR}GLOBAL OPTIONS:${__RESET_COLOR}" - echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(use\ alternate\ bash\ framework\ configuration.) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--config${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Display\ configuration) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--verbose${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-v${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(info\ level\ verbose\ mode\ \(alias\ of\ --display-level\ INFO\)) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}-vv${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(debug\ level\ verbose\ mode\ \(alias\ of\ --display-level\ DEBUG\)) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}-vvv${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(trace\ level\ verbose\ mode\ \(alias\ of\ --display-level\ TRACE\)) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--env-file ${__HELP_NORMAL} {list} (optional)" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Load\ the\ specified\ env\ file\ \(deprecated\,\ please\ use\ --bash-framework-config\ option\ instead\)) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--no-color${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Produce\ monochrome\ output.\ alias\ of\ --theme\ noColor.) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--theme ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(choose\ color\ theme\ -\ default-force\ means\ colors\ will\ be\ produced\ even\ if\ command\ is\ piped) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo ' Default value: default' - echo ' Possible values: default|default-force|noColor' - echo -e " ${__HELP_OPTION_COLOR}--help${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-h${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Display\ this\ command\ help) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--version${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Print\ version\ information\ and\ quit) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--quiet${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-q${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(quiet\ mode\,\ doesn\'t\ display\ any\ output) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--log-level ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Set\ log\ level) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo ' Possible values: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE' - echo -e " ${__HELP_OPTION_COLOR}--log-file ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(Set\ log\ file) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--display-level ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(set\ display\ level) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo ' Possible values: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE' - echo -e """ -megalinter image oxsecurity/megalinter-terraform:v7.10.0 will be used. - - optionally you can provide a list of files to run megalinter on - this mode is incompatible with --incremental option""" - echo - echo -n -e "${__HELP_TITLE_COLOR}VERSION: ${__RESET_COLOR}" - echo '1.0' - echo - echo -e "${__HELP_TITLE_COLOR}AUTHOR:${__RESET_COLOR}" - echo '[François Chastanet](https://github.com/fchastanet)' - echo - echo -e "${__HELP_TITLE_COLOR}SOURCE FILE:${__RESET_COLOR}" - echo 'https://github.com/fchastanet/bash-tools-framework/tree/master/src/_binaries/megalinter.sh' - echo - echo -e "${__HELP_TITLE_COLOR}LICENSE:${__RESET_COLOR}" - echo 'MIT License' - echo - Array::wrap2 ' ' 76 4 "$(copyrightCallback)" - else - Log::displayError "Command ${SCRIPT_NAME} - Option command invalid: '${options_parse_cmd}'" - return 1 - fi -} + +# shellcheck disable=SC2034 declare copyrightBeginYear="2022" -declare optionMegalinterConfigFile=".mega-linter.yml" -declare optionMegalinterImage="oxsecurity/megalinter-terraform:v7.10.0" +declare versionNumber="1.0" declare -a megalinterArgs=() + +optionHelpCallback() { + megalinterCommandHelp + exit 0 +} + unknownArg() { if [[ -f "$1" ]]; then megalinterArgs+=("$1") @@ -1693,32 +1199,37 @@ checkMegalinterVersionAndExit() { Github::getLatestRelease "oxsecurity/megalinter" newVersion newVersion="$(Version::parse <<<"${newVersion}")" local currentVersion + # shellcheck disable=SC2154 currentVersion="$(Version::parse <<<"${optionMegalinterImage}")" local status=0 Version::compare "${currentVersion}" "${newVersion}" || status=$? case ${status} in - 1) - echo -e "${__ERROR_COLOR}version ${currentVersion} is greater than ${newVersion}${__RESET_COLOR}" - exit 2 - ;; - 2) - echo -e "${__WARNING_COLOR}new version ${newVersion} is available, your version is ${currentVersion}${__RESET_COLOR}" - exit 1 - ;; - *) - echo -e "${__INFO_COLOR}no new version available${__RESET_COLOR}" + 1) + echo -e "${__ERROR_COLOR}version ${currentVersion} is greater than ${newVersion}${__RESET_COLOR}" + exit 2 + ;; + 2) + echo -e "${__WARNING_COLOR}new version ${newVersion} is available, your version is ${currentVersion}${__RESET_COLOR}" + exit 1 + ;; + *) + echo -e "${__INFO_COLOR}no new version available${__RESET_COLOR}" + ;; esac exit 0 } commandCallback() { + Linux::requireJqCommand + # shellcheck disable=SC2154 if [[ "${optionCheckMegalinterVersion}" = "1" ]]; then checkMegalinterVersionAndExit fi - if [[ "${optionIncremental}" = "1" ]] && ((${#megalinterArgs[@]}>0)); then + # shellcheck disable=SC2154 + if [[ "${optionIncremental}" = "1" ]] && ((${#megalinterArgs[@]} > 0)); then Log::fatal "you cannot provide a list of files and the --incremental option" fi - if (( ${#megalinterArgs[@]} > 0 )); then + if ((${#megalinterArgs[@]} > 0)); then megalinterOptions+=( -e MEGALINTER_FILES_TO_LINT="$(Array::join "," "${megalinterArgs[@]}")" ) @@ -1730,8 +1241,8 @@ optionFixCallback() { } optionVersionCallback() { - echo -e "${__HELP_TITLE_COLOR}${SCRIPT_NAME} version:${__RESET_COLOR} 1.0" - echo -e "${__HELP_TITLE_COLOR}megalinter image Version:${__RESET_COLOR} oxsecurity/megalinter-terraform:v7.10.0" + echo -e "${__HELP_TITLE_COLOR}${SCRIPT_NAME} version:${__RESET_COLOR} ${versionNumber}" + echo -e "${__HELP_TITLE_COLOR}megalinter image Version:${__RESET_COLOR} ${optionMegalinterImage}" exit 0 } @@ -1746,6 +1257,7 @@ getMegalinterLevel() { *) # ignore return 1 + ;; esac } @@ -1765,77 +1277,819 @@ updateArgListTraceVerboseCallback() { updateArgListLogLevelCallback "$1" "debug" } + +# ------------------------------------------ +# Command megalinterCommand +# ------------------------------------------ + +# options variables initialization +declare optionHelp="0" +declare optionConfig="0" +declare optionBashFrameworkConfig="" +declare optionInfoVerbose="0" +declare optionDebugVerbose="0" +declare optionTraceVerbose="0" +declare -a optionEnvFiles=() +declare optionLogLevel="" +declare optionLogFile="" +declare optionDisplayLevel="" +declare optionNoColor="0" +declare optionTheme="default" +declare optionVersion="0" +declare optionQuiet="0" +declare optionFormat="plain" +declare optionFix="0" +declare optionFilesOnly="0" +declare optionIncremental="0" +declare optionMegalinterImage="oxsecurity/megalinter-terraform:v7.10.0" +declare optionMegalinterConfigFile=".mega-linter.yml" +declare optionCheckMegalinterVersion="0" +# arguments variables initialization +# @description parse command options and arguments for megalinterCommand +megalinterCommandParse() { + Log::displayDebug "Command ${SCRIPT_NAME} - parse arguments: ${BASH_FRAMEWORK_ARGV[*]}" + Log::displayDebug "Command ${SCRIPT_NAME} - parse filtered arguments: ${BASH_FRAMEWORK_ARGV_FILTERED[*]}" + optionHelp="0" + local -i options_parse_optionParsedCountOptionHelp + ((options_parse_optionParsedCountOptionHelp = 0)) || true + optionConfig="0" + local -i options_parse_optionParsedCountOptionConfig + ((options_parse_optionParsedCountOptionConfig = 0)) || true + optionBashFrameworkConfig="" + local -i options_parse_optionParsedCountOptionBashFrameworkConfig + ((options_parse_optionParsedCountOptionBashFrameworkConfig = 0)) || true + optionInfoVerbose="0" + local -i options_parse_optionParsedCountOptionInfoVerbose + ((options_parse_optionParsedCountOptionInfoVerbose = 0)) || true + optionDebugVerbose="0" + local -i options_parse_optionParsedCountOptionDebugVerbose + ((options_parse_optionParsedCountOptionDebugVerbose = 0)) || true + optionTraceVerbose="0" + local -i options_parse_optionParsedCountOptionTraceVerbose + ((options_parse_optionParsedCountOptionTraceVerbose = 0)) || true + + optionLogLevel="" + local -i options_parse_optionParsedCountOptionLogLevel + ((options_parse_optionParsedCountOptionLogLevel = 0)) || true + optionLogFile="" + local -i options_parse_optionParsedCountOptionLogFile + ((options_parse_optionParsedCountOptionLogFile = 0)) || true + optionDisplayLevel="" + local -i options_parse_optionParsedCountOptionDisplayLevel + ((options_parse_optionParsedCountOptionDisplayLevel = 0)) || true + optionNoColor="0" + local -i options_parse_optionParsedCountOptionNoColor + ((options_parse_optionParsedCountOptionNoColor = 0)) || true + optionTheme="default" + local -i options_parse_optionParsedCountOptionTheme + ((options_parse_optionParsedCountOptionTheme = 0)) || true + optionVersion="0" + local -i options_parse_optionParsedCountOptionVersion + ((options_parse_optionParsedCountOptionVersion = 0)) || true + optionQuiet="0" + local -i options_parse_optionParsedCountOptionQuiet + ((options_parse_optionParsedCountOptionQuiet = 0)) || true + optionFormat="plain" + local -i options_parse_optionParsedCountOptionFormat + ((options_parse_optionParsedCountOptionFormat = 0)) || true + optionFix="0" + local -i options_parse_optionParsedCountOptionFix + ((options_parse_optionParsedCountOptionFix = 0)) || true + optionFilesOnly="0" + local -i options_parse_optionParsedCountOptionFilesOnly + ((options_parse_optionParsedCountOptionFilesOnly = 0)) || true + optionIncremental="0" + local -i options_parse_optionParsedCountOptionIncremental + ((options_parse_optionParsedCountOptionIncremental = 0)) || true + optionMegalinterImage="oxsecurity/megalinter-terraform:v7.10.0" + local -i options_parse_optionParsedCountOptionMegalinterImage + ((options_parse_optionParsedCountOptionMegalinterImage = 0)) || true + optionMegalinterConfigFile=".mega-linter.yml" + local -i options_parse_optionParsedCountOptionMegalinterConfigFile + ((options_parse_optionParsedCountOptionMegalinterConfigFile = 0)) || true + optionCheckMegalinterVersion="0" + local -i options_parse_optionParsedCountOptionCheckMegalinterVersion + ((options_parse_optionParsedCountOptionCheckMegalinterVersion = 0)) || true + + + # shellcheck disable=SC2034 + local -i options_parse_parsedArgIndex=0 + while (($# > 0)); do + local options_parse_arg="$1" + local argOptDefaultBehavior=0 + case "${options_parse_arg}" in + # Option 1/21 + # optionHelp alts --help|-h + # type: Boolean min 0 max 1 + --help | -h) + # shellcheck disable=SC2034 + optionHelp="1" + + if ((options_parse_optionParsedCountOptionHelp >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionHelp)) + optionHelpCallback "${options_parse_arg}" "${optionHelp}" + + ;; + + # Option 2/21 + # optionConfig alts --config + # type: Boolean min 0 max 1 + --config) + # shellcheck disable=SC2034 + optionConfig="1" + + if ((options_parse_optionParsedCountOptionConfig >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionConfig)) + ;; + + # Option 3/21 + # optionBashFrameworkConfig alts --bash-framework-config + # type: String min 0 max 1 + --bash-framework-config) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + + if ((options_parse_optionParsedCountOptionBashFrameworkConfig >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionBashFrameworkConfig)) + # shellcheck disable=SC2034 + optionBashFrameworkConfig="$1" + optionBashFrameworkConfigCallback "${options_parse_arg}" "${optionBashFrameworkConfig}" + + ;; + + # Option 4/21 + # optionInfoVerbose alts --verbose|-v + # type: Boolean min 0 max 1 + --verbose | -v) + # shellcheck disable=SC2034 + optionInfoVerbose="1" + + if ((options_parse_optionParsedCountOptionInfoVerbose >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionInfoVerbose)) + optionInfoVerboseCallback "${options_parse_arg}" "${optionInfoVerbose}" + + updateArgListInfoVerboseCallback "${options_parse_arg}" "${optionInfoVerbose}" + + ;; + + # Option 5/21 + # optionDebugVerbose alts -vv + # type: Boolean min 0 max 1 + -vv) + # shellcheck disable=SC2034 + optionDebugVerbose="1" + + if ((options_parse_optionParsedCountOptionDebugVerbose >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionDebugVerbose)) + optionDebugVerboseCallback "${options_parse_arg}" "${optionDebugVerbose}" + + updateArgListDebugVerboseCallback "${options_parse_arg}" "${optionDebugVerbose}" + + ;; + + # Option 6/21 + # optionTraceVerbose alts -vvv + # type: Boolean min 0 max 1 + -vvv) + # shellcheck disable=SC2034 + optionTraceVerbose="1" + + if ((options_parse_optionParsedCountOptionTraceVerbose >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionTraceVerbose)) + optionTraceVerboseCallback "${options_parse_arg}" "${optionTraceVerbose}" + + updateArgListTraceVerboseCallback "${options_parse_arg}" "${optionTraceVerbose}" + + ;; + + # Option 7/21 + # optionEnvFiles alts --env-file + # type: StringArray min 0 max -1 + --env-file) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + + ((++options_parse_optionParsedCountOptionEnvFiles)) + optionEnvFiles+=("$1") + optionEnvFileCallback "${options_parse_arg}" "${optionEnvFiles[@]}" + + updateArgListEnvFileCallback "${options_parse_arg}" "${optionEnvFiles[@]}" + + ;; + + # Option 8/21 + # optionLogLevel alts --log-level + # type: String min 0 max 1 + # authorizedValues: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE + --log-level) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + if [[ ! "$1" =~ OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE ]]; then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - value '$1' is not part of authorized values([OFF ERR ERROR WARN WARNING INFO DEBUG TRACE])" + return 1 + fi + + if ((options_parse_optionParsedCountOptionLogLevel >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionLogLevel)) + # shellcheck disable=SC2034 + optionLogLevel="$1" + optionLogLevelCallback "${options_parse_arg}" "${optionLogLevel}" + + updateArgListLogLevelCallback "${options_parse_arg}" "${optionLogLevel}" + + ;; + + # Option 9/21 + # optionLogFile alts --log-file + # type: String min 0 max 1 + --log-file) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + + if ((options_parse_optionParsedCountOptionLogFile >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionLogFile)) + # shellcheck disable=SC2034 + optionLogFile="$1" + optionLogFileCallback "${options_parse_arg}" "${optionLogFile}" + + updateArgListLogFileCallback "${options_parse_arg}" "${optionLogFile}" + + ;; + + # Option 10/21 + # optionDisplayLevel alts --display-level + # type: String min 0 max 1 + # authorizedValues: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE + --display-level) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + if [[ ! "$1" =~ OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE ]]; then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - value '$1' is not part of authorized values([OFF ERR ERROR WARN WARNING INFO DEBUG TRACE])" + return 1 + fi + + if ((options_parse_optionParsedCountOptionDisplayLevel >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionDisplayLevel)) + # shellcheck disable=SC2034 + optionDisplayLevel="$1" + optionDisplayLevelCallback "${options_parse_arg}" "${optionDisplayLevel}" + + updateArgListDisplayLevelCallback "${options_parse_arg}" "${optionDisplayLevel}" + + ;; + + # Option 11/21 + # optionNoColor alts --no-color + # type: Boolean min 0 max 1 + --no-color) + # shellcheck disable=SC2034 + optionNoColor="1" + + if ((options_parse_optionParsedCountOptionNoColor >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionNoColor)) + optionNoColorCallback "${options_parse_arg}" "${optionNoColor}" + + updateArgListNoColorCallback "${options_parse_arg}" "${optionNoColor}" + + ;; + + # Option 12/21 + # optionTheme alts --theme + # type: String min 0 max 1 + # authorizedValues: default|default-force|noColor + --theme) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + if [[ ! "$1" =~ default|default-force|noColor ]]; then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - value '$1' is not part of authorized values([default default-force noColor])" + return 1 + fi + + if ((options_parse_optionParsedCountOptionTheme >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionTheme)) + # shellcheck disable=SC2034 + optionTheme="$1" + optionThemeCallback "${options_parse_arg}" "${optionTheme}" + + updateArgListThemeCallback "${options_parse_arg}" "${optionTheme}" + + ;; + + # Option 13/21 + # optionVersion alts --version + # type: Boolean min 0 max 1 + --version) + # shellcheck disable=SC2034 + optionVersion="1" + + if ((options_parse_optionParsedCountOptionVersion >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionVersion)) + optionVersionCallback "${options_parse_arg}" "${optionVersion}" + + ;; + + # Option 14/21 + # optionQuiet alts --quiet|-q + # type: Boolean min 0 max 1 + --quiet | -q) + # shellcheck disable=SC2034 + optionQuiet="1" + + if ((options_parse_optionParsedCountOptionQuiet >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionQuiet)) + optionQuietCallback "${options_parse_arg}" "${optionQuiet}" + + updateArgListQuietCallback "${options_parse_arg}" "${optionQuiet}" + + ;; + + # Option 15/21 + # optionFormat alts --format + # type: String min 0 max 1 + # authorizedValues: plain|json + --format) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + if [[ ! "$1" =~ plain|json ]]; then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - value '$1' is not part of authorized values([plain json])" + return 1 + fi + + if ((options_parse_optionParsedCountOptionFormat >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionFormat)) + # shellcheck disable=SC2034 + optionFormat="$1" + updateOptionFormat "${options_parse_arg}" "${optionFormat}" + + ;; + + # Option 16/21 + # optionFix alts --fix + # type: Boolean min 0 max 1 + --fix) + # shellcheck disable=SC2034 + optionFix="1" + + if ((options_parse_optionParsedCountOptionFix >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionFix)) + optionFixCallback "${options_parse_arg}" "${optionFix}" + + ;; + + # Option 17/21 + # optionFilesOnly alts --filesOnly + # type: Boolean min 0 max 1 + --filesOnly) + # shellcheck disable=SC2034 + optionFilesOnly="1" + + if ((options_parse_optionParsedCountOptionFilesOnly >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionFilesOnly)) + filesOnlyCallback "${options_parse_arg}" "${optionFilesOnly}" + + ;; + + # Option 18/21 + # optionIncremental alts --incremental|-i + # type: Boolean min 0 max 1 + --incremental | -i) + # shellcheck disable=SC2034 + optionIncremental="1" + + if ((options_parse_optionParsedCountOptionIncremental >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionIncremental)) + ;; + + # Option 19/21 + # optionMegalinterImage alts --image + # type: String min 0 max 1 + --image) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + + if ((options_parse_optionParsedCountOptionMegalinterImage >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionMegalinterImage)) + # shellcheck disable=SC2034 + optionMegalinterImage="$1" + ;; + + # Option 20/21 + # optionMegalinterConfigFile alts --config-file + # type: String min 0 max 1 + --config-file) + shift + if (($# == 0)); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - a value needs to be specified" + return 1 + fi + + if ((options_parse_optionParsedCountOptionMegalinterConfigFile >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionMegalinterConfigFile)) + # shellcheck disable=SC2034 + optionMegalinterConfigFile="$1" + ;; + + # Option 21/21 + # optionCheckMegalinterVersion alts --check-megalinter-version + # type: Boolean min 0 max 1 + --check-megalinter-version) + # shellcheck disable=SC2034 + optionCheckMegalinterVersion="1" + + if ((options_parse_optionParsedCountOptionCheckMegalinterVersion >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionCheckMegalinterVersion)) + ;; + + -*) + unknownOption "${options_parse_arg}" || argOptDefaultBehavior=$? + ;; + *) + # no arg configured, call unknownArgumentCallback + + # shellcheck disable=SC2317 + unknownArg "${options_parse_arg}" + + ((++options_parse_parsedArgIndex)) + ;; + esac + shift || true + done || return $? + commandCallback + commandOptionParseFinished + +} + +# @description display command options and arguments help for megalinterCommand +megalinterCommandHelp() { + Array::wrap2 ' ' 80 0 "${__HELP_TITLE_COLOR}SYNOPSIS:${__RESET_COLOR}" \ + "Run megalinter over this repository." + echo + echo + + # ------------------------------------------ + # usage section + # ------------------------------------------ + Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" "megalinter [OPTIONS] " + echo + # ------------------------------------------ + # usage/options section + # ------------------------------------------ + optionsAltList=("[--help|-h]" "[--config]" "[--bash-framework-config ]" "[--verbose|-v]" "[-vv]" "[-vvv]" "[--env-file ]" "[--log-level ]" "[--log-file ]" "[--display-level ]" "[--no-color]" "[--theme ]" "[--version]" "[--quiet|-q]" "[--format <>]" "[--fix]" "[--filesOnly]" "[--incremental|-i]" "[--image <>]" "[--config-file <>]" "[--check-megalinter-version]" + ) + Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" \ + "megalinter" "${optionsAltList[@]}" + echo + + # ------------------------------------------ + # options section + # ------------------------------------------ + echo + echo -e "${__HELP_TITLE_COLOR}GLOBAL OPTIONS:${__RESET_COLOR}" + echo -e " ${__HELP_OPTION_COLOR}--help${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-h${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Displays this command help" + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--config${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Displays configuration" + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config bash-framework-config${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Use alternate bash framework configuration." + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--verbose${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-v${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Info level verbose mode (alias of --display-level INFO)" + echo + + + + echo -e " ${__HELP_OPTION_COLOR}-vv${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Debug level verbose mode (alias of --display-level DEBUG)" + echo + + + + echo -e " ${__HELP_OPTION_COLOR}-vvv${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Trace level verbose mode (alias of --display-level TRACE)" + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--env-file env-file${__HELP_NORMAL} {list} (optional)" + Array::wrap2 ' ' 76 4 " " "Load the specified env file (deprecated, please use --bash-framework-config option instead)" + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--log-level log-level${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Set log level" + echo + Array::wrap2 ' ' 76 6 " Possible values: " "OFF, " "ERR, " "ERROR, " "WARN, " "WARNING, " "INFO, " "DEBUG, " "TRACE" + echo + + + echo -e " ${__HELP_OPTION_COLOR}--log-file log-file${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Set log file" + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--display-level display-level${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Set display level" + echo + Array::wrap2 ' ' 76 6 " Possible values: " "OFF, " "ERR, " "ERROR, " "WARN, " "WARNING, " "INFO, " "DEBUG, " "TRACE" + echo + + + echo -e " ${__HELP_OPTION_COLOR}--no-color${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Produce monochrome output. alias of --theme noColor." + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--theme theme${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Choose color theme - default-force means colors will be produced even if command is piped." + echo + Array::wrap2 ' ' 76 6 " Possible values: " "default, " "default-force, " "noColor" + echo + + Array::wrap2 ' ' 76 6 " Default value: " "default" + echo + + echo -e " ${__HELP_OPTION_COLOR}--version${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Print version information and quit." + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--quiet${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-q${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Quiet mode, doesn't display any output." + echo + + + echo + echo -e "${__HELP_TITLE_COLOR}OPTIONS:${__RESET_COLOR}" + echo -e " ${__HELP_OPTION_COLOR}--format ${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Define output format of this command." + echo + Array::wrap2 ' ' 76 6 " Possible values: " "plain, " "json" + echo + + Array::wrap2 ' ' 76 6 " Default value: " "plain" + echo + + echo -e " ${__HELP_OPTION_COLOR}--fix${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Apply linters fixes automatically." + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--filesOnly${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Skip linters that run in project mode." + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--incremental${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-i${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Run megalinter only on files that are git staged." + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--image ${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Specify docker megalinter image name to use." + echo + + + Array::wrap2 ' ' 76 6 " Default value: " "oxsecurity/megalinter-terraform:v7.10.0" + echo + + echo -e " ${__HELP_OPTION_COLOR}--config-file ${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Specify megalinter config filename to use." + echo + + + Array::wrap2 ' ' 76 6 " Default value: " ".mega-linter.yml" + echo + + echo -e " ${__HELP_OPTION_COLOR}--check-megalinter-version${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Check if new version of megalinter is available (compared to default image)." "Exits 1 if yes and displays new version number." "" + echo + + + # ------------------------------------------ + # longDescription section + # ------------------------------------------ + echo + echo + echo -e "${__HELP_TITLE_COLOR}DESCRIPTION:${__RESET_COLOR}" + declare -a megalinterCommandLongDescription=( + "megalinter image ${defaultMegalinterImage} will be used." + " optionally you can provide a list of files to run megalinter on" + "this mode is incompatible with --incremental option." + ) + Array::wrap2 ' ' 76 0 "${megalinterCommandLongDescription[@]}" + echo + # ------------------------------------------ + # version section + # ------------------------------------------ + echo + echo -n -e "${__HELP_TITLE_COLOR}VERSION: ${__RESET_COLOR}" + echo "1.0" + # ------------------------------------------ + # author section + # ------------------------------------------ + echo + echo -n -e "${__HELP_TITLE_COLOR}AUTHOR: ${__RESET_COLOR}" + echo "[François Chastanet](https://github.com/fchastanet)" + # ------------------------------------------ + # sourceFile section + # ------------------------------------------ + echo + echo -n -e "${__HELP_TITLE_COLOR}SOURCE FILE: ${__RESET_COLOR}" + echo "https://github.com/fchastanet/bash-tools-framework/tree/master/src/_binaries/megalinter/binary-megalinter.yaml" + # ------------------------------------------ + # license section + # ------------------------------------------ + echo + echo -n -e "${__HELP_TITLE_COLOR}LICENSE: ${__RESET_COLOR}" + echo "MIT License" + # ------------------------------------------ + # copyright section + # ------------------------------------------ + Array::wrap2 ' ' 76 0 "$(copyrightCallback)" +} + + +beforeParseCallback + +megalinterCommandParse "$@" +MAIN_FUNCTION_NAME="main" +main() { + declare -a megalinterOptions=( -e CLEAR_REPORT_FOLDER=true --workdir /tmp/lint ) -megalinterCommand parse "${BASH_FRAMEWORK_ARGV[@]}" - # shellcheck disable=SC2154 -run() { - if [[ "${optionIncremental}" = "1" ]]; then - local -a updatedFiles - IFS=$'\n' read -r -d '' -a updatedFiles < <(git --no-pager diff --name-only --cached || true) || true - if ((${#updatedFiles[@]} == 0)); then - Log::displayError "No files to lint in incremental mode" - exit 1 - fi - - megalinterOptions+=(-e MEGALINTER_FILES_TO_LINT="$(Array::join "," "${updatedFiles[@]}")") - fi - checkIfMegalinterImageExists() { - ( - if [[ "${optionTraceVerbose}" = "1" ]]; then - set -x - fi - docker image ls -q "${optionMegalinterImage}" - ) - } - if [[ -z "$(checkIfMegalinterImageExists)" ]]; then - ( - if [[ "${optionTraceVerbose}" = "1" ]]; then - set -x - fi - docker pull "${optionMegalinterImage}" - ) - fi - - if tty -s; then - megalinterOptions+=("-it") - fi - - if [[ -d "vendor/bash-tools-framework" ]]; then - megalinterOptions+=( - -v "$(cd vendor/bash-tools-framework && pwd -P):/tmp/lint/vendor/bash-tools-framework" - ) +if [[ "${optionIncremental}" = "1" ]]; then + declare -a updatedFiles + IFS=$'\n' read -r -d '' -a updatedFiles < <(git --no-pager diff --name-only --cached || true) || true + if ((${#updatedFiles[@]} == 0)); then + Log::displayError "No files to lint in incremental mode" + exit 1 fi - declare cmd=( - docker run --rm --name=megalinter - -e HOST_USER_ID="${HOST_USER_ID:-$(id -u)}" - -e HOST_GROUP_ID="${HOST_GROUP_ID:-$(id -g)}" - -e MEGALINTER_CONFIG="${optionMegalinterConfigFile}" - "${megalinterOptions[@]}" - -v /var/run/docker.sock:/var/run/docker.sock:rw - -v .:/tmp/lint:rw - "${optionMegalinterImage}" - ) - Log::displayWarning "Running ${cmd[*]}" + megalinterOptions+=(-e MEGALINTER_FILES_TO_LINT="$(Array::join "," "${updatedFiles[@]}")") +fi +checkIfMegalinterImageExists() { ( + # shellcheck disable=SC2154 if [[ "${optionTraceVerbose}" = "1" ]]; then set -x fi - "${cmd[@]}" + # shellcheck disable=SC2154 + docker image ls -q "${optionMegalinterImage}" ) } +if [[ -z "$(checkIfMegalinterImageExists)" ]]; then + ( + if [[ "${optionTraceVerbose}" = "1" ]]; then + set -x + fi + docker pull "${optionMegalinterImage}" + ) +fi -if [[ "${BASH_FRAMEWORK_QUIET_MODE:-0}" = "1" ]]; then - run &>/dev/null -else - run +if tty -s; then + megalinterOptions+=("-it") +fi + +if [[ -d "vendor/bash-tools-framework" ]]; then + megalinterOptions+=( + -v "$(cd vendor/bash-tools-framework && pwd -P):/tmp/lint/vendor/bash-tools-framework" + ) fi +declare cmd=( + docker run --rm --name=megalinter + -e HOST_USER_ID="${HOST_USER_ID:-$(id -u)}" + -e HOST_GROUP_ID="${HOST_GROUP_ID:-$(id -g)}" + -e MEGALINTER_CONFIG="${optionMegalinterConfigFile}" + "${megalinterOptions[@]}" + -v /var/run/docker.sock:/var/run/docker.sock:rw + -v .:/tmp/lint:rw + "${optionMegalinterImage}" +) +Log::displayWarning "Running ${cmd[*]}" +( + if [[ "${optionTraceVerbose}" = "1" ]]; then + set -x + fi + "${cmd[@]}" +) + } -facade_main_megalintersh "$@" +# if file is sourced avoid calling main function +# shellcheck disable=SC2178 +BASH_SOURCE=".$0" # cannot be changed in bash +# shellcheck disable=SC2128 +if test ".$0" == ".${BASH_SOURCE}"; then + if [[ "${BASH_FRAMEWORK_QUIET_MODE:-0}" = "1" ]]; then + main "$@" &>/dev/null + else + main "$@" + fi +fi diff --git a/cspell.yaml b/cspell.yaml index 7e1da5b6..e724f075 100644 --- a/cspell.yaml +++ b/cspell.yaml @@ -85,7 +85,7 @@ languageSettings: # OVERRIDES overrides: - filename: - - "**/*.{bats,tpl}" + - "**/*.{bats}" - "**/*.env" - "src/Array/wrap.sh" languageId: shellscript diff --git a/src/_binaries/megalinter.sh b/src/_binaries/megalinter.sh deleted file mode 100755 index 20f5ac34..00000000 --- a/src/_binaries/megalinter.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env bash -# BIN_FILE=${FRAMEWORK_ROOT_DIR}/bin/megalinter -# VAR_RELATIVE_FRAMEWORK_DIR_TO_CURRENT_DIR=.. -# FACADE - -.INCLUDE "$(dynamicTemplateDir _binaries/options/command.megalinter.tpl)" - -declare -a megalinterOptions=( - -e CLEAR_REPORT_FOLDER=true - --workdir /tmp/lint -) - -megalinterCommand parse "${BASH_FRAMEWORK_ARGV[@]}" - -# shellcheck disable=SC2154 -run() { - if [[ "${optionIncremental}" = "1" ]]; then - local -a updatedFiles - IFS=$'\n' read -r -d '' -a updatedFiles < <(git --no-pager diff --name-only --cached || true) || true - if ((${#updatedFiles[@]} == 0)); then - Log::displayError "No files to lint in incremental mode" - exit 1 - fi - - megalinterOptions+=(-e MEGALINTER_FILES_TO_LINT="$(Array::join "," "${updatedFiles[@]}")") - fi - checkIfMegalinterImageExists() { - ( - if [[ "${optionTraceVerbose}" = "1" ]]; then - set -x - fi - docker image ls -q "${optionMegalinterImage}" - ) - } - if [[ -z "$(checkIfMegalinterImageExists)" ]]; then - ( - if [[ "${optionTraceVerbose}" = "1" ]]; then - set -x - fi - docker pull "${optionMegalinterImage}" - ) - fi - - if tty -s; then - megalinterOptions+=("-it") - fi - - if [[ -d "vendor/bash-tools-framework" ]]; then - megalinterOptions+=( - -v "$(cd vendor/bash-tools-framework && pwd -P):/tmp/lint/vendor/bash-tools-framework" - ) - fi - - declare cmd=( - docker run --rm --name=megalinter - -e HOST_USER_ID="${HOST_USER_ID:-$(id -u)}" - -e HOST_GROUP_ID="${HOST_GROUP_ID:-$(id -g)}" - -e MEGALINTER_CONFIG="${optionMegalinterConfigFile}" - "${megalinterOptions[@]}" - -v /var/run/docker.sock:/var/run/docker.sock:rw - -v .:/tmp/lint:rw - "${optionMegalinterImage}" - ) - Log::displayWarning "Running ${cmd[*]}" - ( - if [[ "${optionTraceVerbose}" = "1" ]]; then - set -x - fi - "${cmd[@]}" - ) -} - -if [[ "${BASH_FRAMEWORK_QUIET_MODE:-0}" = "1" ]]; then - run &>/dev/null -else - run -fi diff --git a/src/_binaries/megalinter/binary-megalinter.yaml b/src/_binaries/megalinter/binary-megalinter.yaml new file mode 100644 index 00000000..88a0a4fa --- /dev/null +++ b/src/_binaries/megalinter/binary-megalinter.yaml @@ -0,0 +1,99 @@ +extends: + - "${FRAMEWORK_ROOT_DIR}/src/_binaries/commandDefinitions/defaultCommand.yaml" + - "${FRAMEWORK_ROOT_DIR}/src/_binaries/commandDefinitions/frameworkConfig.yaml" + +vars: + SRC_FILE_PATH: src/_binaries/megalinter/binary-megalinter.yaml + +compilerConfig: + targetFile: "${FRAMEWORK_ROOT_DIR}/bin/megalinter" +binData: + commands: + default: + functionName: megalinterCommand + unknownOptionCallbacks: + - unknownOption + unknownArgumentCallbacks: + - unknownArg + beforeParseCallbacks: + - beforeParseCallback + callbacks: + - commandCallback + version: "1.0" + commandName: megalinter + definitionFiles: + 12: "${FRAMEWORK_ROOT_DIR}/src/_binaries/commandDefinitions/optionsFormat.sh" + 20: ${FRAMEWORK_ROOT_DIR}/src/_binaries/megalinter/megalinter-options.sh + mainFile: ${FRAMEWORK_ROOT_DIR}/src/_binaries/megalinter/megalinter-main.sh + help: Run megalinter over this repository. + longDescription: | + megalinter image ${defaultMegalinterImage} will be used. + optionally you can provide a list of files to run megalinter on + this mode is incompatible with --incremental option. + options: + - alts: + - "--format" + group: OptionsGroup + type: String + defaultValue: plain + authorizedValuesList: + - plain + - json + help: Define output format of this command. + helpValueName: + callbacks: + - updateOptionFormat + variableName: optionFormat + + - alts: + - --fix + group: OptionsGroup + help: Apply linters fixes automatically. + type: Boolean + callbacks: + - optionFixCallback + variableName: optionFix + + - alts: + - --filesOnly + group: OptionsGroup + help: Skip linters that run in project mode. + callbacks: + - filesOnlyCallback + type: Boolean + variableName: optionFilesOnly + + - alts: + - --incremental + - -i + group: OptionsGroup + help: Run megalinter only on files that are git staged. + type: Boolean + variableName: optionIncremental + + - alts: + - --image + group: OptionsGroup + help: Specify docker megalinter image name to use. + defaultValue: "oxsecurity/megalinter-terraform:v7.10.0" + type: String + helpValueName: + variableName: optionMegalinterImage + + - alts: + - --config-file + group: OptionsGroup + help: Specify megalinter config filename to use. + defaultValue: ".mega-linter.yml" + type: String + helpValueName: + variableName: optionMegalinterConfigFile + + - alts: + - --check-megalinter-version + group: OptionsGroup + help: | + Check if new version of megalinter is available (compared to default image). + Exits 1 if yes and displays new version number. + type: Boolean + variableName: optionCheckMegalinterVersion diff --git a/src/_binaries/megalinter/megalinter-main.sh b/src/_binaries/megalinter/megalinter-main.sh new file mode 100755 index 00000000..e19d760f --- /dev/null +++ b/src/_binaries/megalinter/megalinter-main.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +declare -a megalinterOptions=( + -e CLEAR_REPORT_FOLDER=true + --workdir /tmp/lint +) + +# shellcheck disable=SC2154 +if [[ "${optionIncremental}" = "1" ]]; then + declare -a updatedFiles + IFS=$'\n' read -r -d '' -a updatedFiles < <(git --no-pager diff --name-only --cached || true) || true + if ((${#updatedFiles[@]} == 0)); then + Log::displayError "No files to lint in incremental mode" + exit 1 + fi + + megalinterOptions+=(-e MEGALINTER_FILES_TO_LINT="$(Array::join "," "${updatedFiles[@]}")") +fi +checkIfMegalinterImageExists() { + ( + # shellcheck disable=SC2154 + if [[ "${optionTraceVerbose}" = "1" ]]; then + set -x + fi + # shellcheck disable=SC2154 + docker image ls -q "${optionMegalinterImage}" + ) +} +if [[ -z "$(checkIfMegalinterImageExists)" ]]; then + ( + if [[ "${optionTraceVerbose}" = "1" ]]; then + set -x + fi + docker pull "${optionMegalinterImage}" + ) +fi + +if tty -s; then + megalinterOptions+=("-it") +fi + +if [[ -d "vendor/bash-tools-framework" ]]; then + megalinterOptions+=( + -v "$(cd vendor/bash-tools-framework && pwd -P):/tmp/lint/vendor/bash-tools-framework" + ) +fi + +declare cmd=( + docker run --rm --name=megalinter + -e HOST_USER_ID="${HOST_USER_ID:-$(id -u)}" + -e HOST_GROUP_ID="${HOST_GROUP_ID:-$(id -g)}" + -e MEGALINTER_CONFIG="${optionMegalinterConfigFile}" + "${megalinterOptions[@]}" + -v /var/run/docker.sock:/var/run/docker.sock:rw + -v .:/tmp/lint:rw + "${optionMegalinterImage}" +) +Log::displayWarning "Running ${cmd[*]}" +( + if [[ "${optionTraceVerbose}" = "1" ]]; then + set -x + fi + "${cmd[@]}" +) diff --git a/src/_binaries/megalinter/megalinter-options.sh b/src/_binaries/megalinter/megalinter-options.sh new file mode 100755 index 00000000..4d6ffecc --- /dev/null +++ b/src/_binaries/megalinter/megalinter-options.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash + +# shellcheck disable=SC2034 +declare copyrightBeginYear="2022" +declare versionNumber="1.0" +declare -a megalinterArgs=() + +optionHelpCallback() { + megalinterCommandHelp + exit 0 +} + +unknownArg() { + if [[ -f "$1" ]]; then + megalinterArgs+=("$1") + else + Log::displayError "Command ${SCRIPT_NAME} - unknown file '$1'" + return 1 + fi +} + +filesOnlyCallback() { + megalinterOptions+=(-e SKIP_CLI_LINT_MODES=project) +} + +checkMegalinterVersionAndExit() { + local newVersion + Github::getLatestRelease "oxsecurity/megalinter" newVersion + newVersion="$(Version::parse <<<"${newVersion}")" + local currentVersion + # shellcheck disable=SC2154 + currentVersion="$(Version::parse <<<"${optionMegalinterImage}")" + local status=0 + Version::compare "${currentVersion}" "${newVersion}" || status=$? + case ${status} in + 1) + echo -e "${__ERROR_COLOR}version ${currentVersion} is greater than ${newVersion}${__RESET_COLOR}" + exit 2 + ;; + 2) + echo -e "${__WARNING_COLOR}new version ${newVersion} is available, your version is ${currentVersion}${__RESET_COLOR}" + exit 1 + ;; + *) + echo -e "${__INFO_COLOR}no new version available${__RESET_COLOR}" + ;; + esac + exit 0 +} + +commandCallback() { + Linux::requireJqCommand + # shellcheck disable=SC2154 + if [[ "${optionCheckMegalinterVersion}" = "1" ]]; then + checkMegalinterVersionAndExit + fi + # shellcheck disable=SC2154 + if [[ "${optionIncremental}" = "1" ]] && ((${#megalinterArgs[@]} > 0)); then + Log::fatal "you cannot provide a list of files and the --incremental option" + fi + if ((${#megalinterArgs[@]} > 0)); then + megalinterOptions+=( + -e MEGALINTER_FILES_TO_LINT="$(Array::join "," "${megalinterArgs[@]}")" + ) + fi +} + +optionFixCallback() { + megalinterOptions+=(-e APPLY_FIXES=all) +} + +optionVersionCallback() { + echo -e "${__HELP_TITLE_COLOR}${SCRIPT_NAME} version:${__RESET_COLOR} ${versionNumber}" + echo -e "${__HELP_TITLE_COLOR}megalinter image Version:${__RESET_COLOR} ${optionMegalinterImage}" + exit 0 +} + +getMegalinterLevel() { + local levelName="$1" + case "${levelName^^}" in + OFF) return 1 ;; + DEBUG | TRACE) echo "debug" ;; + INFO) echo "info" ;; + WARNING) echo "warning" ;; + ERROR) echo "error" ;; + *) + # ignore + return 1 + ;; + esac +} + +updateArgListLogLevelCallback() { + local level="$2" + local megalinterLevel + megalinterLevel="$(getMegalinterLevel "${level}")" || return 0 + megalinterOptions+=(-e "LOG_LEVEL=${megalinterLevel}") +} +updateArgListInfoVerboseCallback() { + updateArgListLogLevelCallback "$1" "warning" +} +updateArgListDebugVerboseCallback() { + updateArgListLogLevelCallback "$1" "info" +} +updateArgListTraceVerboseCallback() { + updateArgListLogLevelCallback "$1" "debug" +} diff --git a/src/_binaries/options/command.megalinter.tpl b/src/_binaries/options/command.megalinter.tpl deleted file mode 100644 index 77775d30..00000000 --- a/src/_binaries/options/command.megalinter.tpl +++ /dev/null @@ -1,174 +0,0 @@ -% -declare defaultMegalinterConfigFile=".mega-linter.yml" -declare defaultMegalinterImage=oxsecurity/megalinter-terraform:v7.10.0 -declare versionNumber="1.0" -declare commandFunctionName="megalinterCommand" -declare help="run megalinter over this repository." -# shellcheck disable=SC2016 -declare longDescription=""" -megalinter image ${defaultMegalinterImage} will be used. - - optionally you can provide a list of files to run megalinter on - this mode is incompatible with --incremental option -""" -declare optionFormatAuthorizedValues="plain|json" -declare optionFormatDefault="plain" -declare optionMegalinterImage="${defaultMegalinterImage}" -% - -.INCLUDE "$(dynamicTemplateDir _binaries/options/options.base.tpl)" -.INCLUDE "$(dynamicTemplateDir _binaries/options/options.format.tpl)" - -% - -# shellcheck source=/dev/null -source <( - Options::generateOption \ - --help "Apply linters fixes automatically." \ - --alt "--fix" \ - --callback optionFixCallback \ - --variable-name "optionFix" \ - --function-name optionFixFunction - - Options::generateOption \ - --help "Skip linters that run in project mode." \ - --alt "--filesOnly" \ - --callback filesOnlyCallback \ - --variable-name "optionFilesOnly" \ - --function-name optionFilesOnlyFunction - - Options::generateOption \ - --help "Run megalinter only on files that are git staged" \ - --alt "--incremental" \ - --alt "-i" \ - --variable-name "optionIncremental" \ - --function-name optionIncrementalFunction - - Options::generateOption \ - --variable-type "String" \ - --help "Specify docker megalinter image name to use" \ - --alt "--image" \ - --variable-name "optionMegalinterImage" \ - --default-value "${defaultMegalinterImage}" \ - --function-name optionMegalinterImageFunction - - Options::generateOption \ - --variable-type "String" \ - --help "Specify megalinter config filename to use" \ - --alt "--config-file" \ - --default-value "${defaultMegalinterConfigFile}" \ - --variable-name "optionMegalinterConfigFile" \ - --function-name optionMegalinterConfigFileFunction - - Options::generateOption \ - --help "Check if new version of megalinter is available (compared to ${defaultMegalinterImage}) and exit 1 if yes and display new version number." \ - --alt "--check-megalinter-version" \ - --variable-name "optionCheckMegalinterVersion" \ - --function-name optionCheckMegalinterVersionFunction -) - -options+=( - --unknown-argument-callback unknownArg - --callback commandCallback - optionFixFunction - optionFilesOnlyFunction - optionIncrementalFunction - optionMegalinterImageFunction - optionCheckMegalinterVersionFunction - optionMegalinterConfigFileFunction -) -Options::generateCommand "${options[@]}" -% -declare copyrightBeginYear="2022" -declare optionMegalinterConfigFile="<% ${defaultMegalinterConfigFile} %>" -declare optionMegalinterImage="<% ${defaultMegalinterImage} %>" -declare -a megalinterArgs=() -unknownArg() { - if [[ -f "$1" ]]; then - megalinterArgs+=("$1") - else - Log::displayError "Command ${SCRIPT_NAME} - unknown file '$1'" - return 1 - fi -} - -filesOnlyCallback() { - megalinterOptions+=(-e SKIP_CLI_LINT_MODES=project) -} - -checkMegalinterVersionAndExit() { - local newVersion - Github::getLatestRelease "oxsecurity/megalinter" newVersion - newVersion="$(Version::parse <<<"${newVersion}")" - local currentVersion - currentVersion="$(Version::parse <<<"${optionMegalinterImage}")" - local status=0 - Version::compare "${currentVersion}" "${newVersion}" || status=$? - case ${status} in - 1) - echo -e "${__ERROR_COLOR}version ${currentVersion} is greater than ${newVersion}${__RESET_COLOR}" - exit 2 - ;; - 2) - echo -e "${__WARNING_COLOR}new version ${newVersion} is available, your version is ${currentVersion}${__RESET_COLOR}" - exit 1 - ;; - *) - echo -e "${__INFO_COLOR}no new version available${__RESET_COLOR}" - esac - exit 0 -} - -commandCallback() { - if [[ "${optionCheckMegalinterVersion}" = "1" ]]; then - checkMegalinterVersionAndExit - fi - if [[ "${optionIncremental}" = "1" ]] && ((${#megalinterArgs[@]}>0)); then - Log::fatal "you cannot provide a list of files and the --incremental option" - fi - if (( ${#megalinterArgs[@]} > 0 )); then - megalinterOptions+=( - -e MEGALINTER_FILES_TO_LINT="$(Array::join "," "${megalinterArgs[@]}")" - ) - fi -} - -optionFixCallback() { - megalinterOptions+=(-e APPLY_FIXES=all) -} - -optionVersionCallback() { - echo -e "${__HELP_TITLE_COLOR}${SCRIPT_NAME} version:${__RESET_COLOR} <% ${versionNumber} %>" - echo -e "${__HELP_TITLE_COLOR}megalinter image Version:${__RESET_COLOR} <% ${optionMegalinterImage} %>" - exit 0 -} - -getMegalinterLevel() { - local levelName="$1" - case "${levelName^^}" in - OFF) return 1 ;; - DEBUG | TRACE) echo "debug" ;; - INFO) echo "info" ;; - WARNING) echo "warning" ;; - ERROR) echo "error" ;; - *) - # ignore - return 1 - esac -} - -updateArgListLogLevelCallback() { - local level="$2" - local megalinterLevel - megalinterLevel="$(getMegalinterLevel "${level}")" || return 0 - megalinterOptions+=(-e "LOG_LEVEL=${megalinterLevel}") -} -updateArgListInfoVerboseCallback() { - updateArgListLogLevelCallback "$1" "warning" -} -updateArgListDebugVerboseCallback() { - updateArgListLogLevelCallback "$1" "info" -} -updateArgListTraceVerboseCallback() { - updateArgListLogLevelCallback "$1" "debug" -} diff --git a/src/_binaries/options/options.base.tpl b/src/_binaries/options/options.base.tpl deleted file mode 100644 index 703f5075..00000000 --- a/src/_binaries/options/options.base.tpl +++ /dev/null @@ -1,387 +0,0 @@ -%# Needed variables -%# - versionNumber -%# - commandFunctionName -%# - SCRIPT_NAME -%# - help -%# - longDescription -%# - copyrightBeginYear -% - # shellcheck source=/dev/null - source <( - Options::generateGroup \ - --title "GLOBAL OPTIONS:" \ - --function-name zzzGroupGlobalOptionsFunction - - Options::generateOption \ - --help "Display this command help" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--help" \ - --alt "-h" \ - --callback optionHelpCallback \ - --variable-name "optionHelp" \ - --function-name optionHelpFunction - - Options::generateOption \ - --help "Display configuration" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--config" \ - --variable-name "optionConfig" \ - --function-name optionConfigFunction - - Options::generateOption \ - --variable-type String \ - --help "use alternate bash framework configuration." \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--bash-framework-config" \ - --callback optionBashFrameworkConfigCallback \ - --variable-name "optionBashFrameworkConfig" \ - --function-name optionBashFrameworkConfigFunction - - Options::generateOption \ - --help "info level verbose mode (alias of --display-level INFO)" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--verbose" --alt "-v" \ - --callback optionInfoVerboseCallback \ - --callback updateArgListInfoVerboseCallback \ - --variable-name "optionInfoVerbose" \ - --function-name optionInfoVerboseFunction - - Options::generateOption \ - --help "debug level verbose mode (alias of --display-level DEBUG)" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "-vv" \ - --callback optionDebugVerboseCallback \ - --callback updateArgListDebugVerboseCallback \ - --variable-name "optionDebugVerbose" \ - --function-name optionDebugVerboseFunction - - Options::generateOption \ - --help "trace level verbose mode (alias of --display-level TRACE)" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "-vvv" \ - --callback optionTraceVerboseCallback \ - --callback updateArgListTraceVerboseCallback \ - --variable-name "optionTraceVerbose" \ - --function-name optionTraceVerboseFunction - - Options::generateOption \ - --variable-type StringArray \ - --help "Load the specified env file (deprecated, please use --bash-framework-config option instead)" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--env-file" \ - --max -1 \ - --callback optionEnvFileCallback \ - --callback updateArgListEnvFileCallback \ - --variable-name "optionEnvFiles" \ - --function-name optionEnvFilesFunction - - Options::generateOption \ - --variable-type String \ - --help "Set log level" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--log-level" \ - --authorized-values "OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE" \ - --callback "optionLogLevelCallback" \ - --callback updateArgListLogLevelCallback \ - --variable-name "optionLogLevel" \ - --function-name optionLogLevelFunction - - Options::generateOption \ - --variable-type String \ - --help "Set log file" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--log-file" \ - --callback "optionLogFileCallback" \ - --callback updateArgListLogFileCallback \ - --variable-name "optionLogFile" \ - --function-name optionLogFileFunction - - Options::generateOption \ - --variable-type String \ - --help "set display level" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--display-level" \ - --authorized-values "OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE" \ - --callback optionDisplayLevelCallback \ - --callback updateArgListDisplayLevelCallback \ - --variable-name "optionDisplayLevel" \ - --function-name optionDisplayLevelFunction - - Options::generateOption \ - --help "Produce monochrome output. alias of --theme noColor." \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--no-color" \ - --callback optionNoColorCallback \ - --callback updateArgListNoColorCallback \ - --variable-name "optionNoColor" \ - --function-name optionNoColorFunction - - Options::generateOption \ - --variable-type String \ - --help 'choose color theme - default-force means colors will be produced even if command is piped' \ - --default-value "default" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--theme" \ - --authorized-values "default|default-force|noColor" \ - --callback optionThemeCallback \ - --callback updateArgListThemeCallback \ - --variable-name "optionTheme" \ - --function-name optionThemeFunction - - Options::generateOption \ - --help "Print version information and quit" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--version" \ - --callback optionVersionCallback \ - --variable-name "optionVersion" \ - --function-name optionVersionFunction - - Options::generateOption \ - --help "quiet mode, doesn't display any output" \ - --group zzzGroupGlobalOptionsFunction \ - --alt "--quiet" --alt "-q" \ - --callback optionQuietCallback \ - --callback updateArgListQuietCallback \ - --variable-name "optionQuiet" \ - --function-name optionQuietFunction - ) - - copyrightCallback() { :; } - declare -a options=( - --author "[François Chastanet](https://github.com/fchastanet)" - --source-file "${REPOSITORY_URL}/tree/master/${SRC_FILE_PATH}" - --license "MIT License" - --copyright copyrightCallback - --version "${versionNumber}" - --function-name "${commandFunctionName}" - --command-name "${SCRIPT_NAME}" - --callback commandOptionParseFinished - --help "${help}" - --long-description """${longDescription}""" - optionBashFrameworkConfigFunction - optionConfigFunction - optionNoColorFunction - optionThemeFunction - optionHelpFunction - optionVersionFunction - optionQuietFunction - optionLogLevelFunction - optionLogFileFunction - optionDisplayLevelFunction - optionInfoVerboseFunction - optionDebugVerboseFunction - optionTraceVerboseFunction - optionEnvFilesFunction - ) -% - -%# default add option callbacks -declare -a BASH_FRAMEWORK_ARGV_FILTERED=() - -copyrightCallback() { - if [[ -z "${copyrightBeginYear}" ]]; then - copyrightBeginYear="$(date +%Y)" - fi - echo "Copyright (c) ${copyrightBeginYear}-now François Chastanet" -} - -# shellcheck disable=SC2317 # if function is overridden -updateArgListInfoVerboseCallback() { - BASH_FRAMEWORK_ARGV_FILTERED+=(--verbose) -} -# shellcheck disable=SC2317 # if function is overridden -updateArgListDebugVerboseCallback() { - BASH_FRAMEWORK_ARGV_FILTERED+=(-vv) -} -# shellcheck disable=SC2317 # if function is overridden -updateArgListTraceVerboseCallback() { - BASH_FRAMEWORK_ARGV_FILTERED+=(-vvv) -} -# shellcheck disable=SC2317 # if function is overridden -updateArgListEnvFileCallback() { :; } -# shellcheck disable=SC2317 # if function is overridden -updateArgListLogLevelCallback() { :; } -# shellcheck disable=SC2317 # if function is overridden -updateArgListDisplayLevelCallback() { :; } -# shellcheck disable=SC2317 # if function is overridden -updateArgListNoColorCallback() { - BASH_FRAMEWORK_ARGV_FILTERED+=(--no-color) -} -# shellcheck disable=SC2317 # if function is overridden -updateArgListThemeCallback() { :; } -# shellcheck disable=SC2317 # if function is overridden -updateArgListQuietCallback() { :; } - -# shellcheck disable=SC2317 # if function is overridden -optionHelpCallback() { - <% ${commandFunctionName} %> help - exit 0 -} - -# shellcheck disable=SC2317 # if function is overridden -optionVersionCallback() { - echo "${SCRIPT_NAME} version <% ${versionNumber} %>" - exit 0 -} - -# shellcheck disable=SC2317 # if function is overridden -optionEnvFileCallback() { - local envFile="$2" - Log::displayWarning "Command ${SCRIPT_NAME} - Option --env-file is deprecated and will be removed in the future" - if [[ ! -f "${envFile}" || ! -r "${envFile}" ]]; then - Log::displayError "Command ${SCRIPT_NAME} - Option --env-file - File '${envFile}' doesn't exist" - exit 1 - fi -} - -# shellcheck disable=SC2317 # if function is overridden -optionInfoVerboseCallback() { - BASH_FRAMEWORK_ARGS_VERBOSE_OPTION='--verbose' - BASH_FRAMEWORK_ARGS_VERBOSE=${__VERBOSE_LEVEL_INFO} - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_INFO}" >> "${overrideEnvFile}" -} - -# shellcheck disable=SC2317 # if function is overridden -optionDebugVerboseCallback() { - BASH_FRAMEWORK_ARGS_VERBOSE_OPTION='-vv' - BASH_FRAMEWORK_ARGS_VERBOSE=${__VERBOSE_LEVEL_DEBUG} - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_DEBUG}" >> "${overrideEnvFile}" -} - -# shellcheck disable=SC2317 # if function is overridden -optionTraceVerboseCallback() { - BASH_FRAMEWORK_ARGS_VERBOSE_OPTION='-vvv' - BASH_FRAMEWORK_ARGS_VERBOSE=${__VERBOSE_LEVEL_TRACE} - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${__LEVEL_DEBUG}" >> "${overrideEnvFile}" -} - -getLevel() { - local levelName="$1" - case "${levelName^^}" in - OFF) - echo "${__LEVEL_OFF}" - ;; - ERR | ERROR) - echo "${__LEVEL_ERROR}" - ;; - WARN | WARNING) - echo "${__LEVEL_WARNING}" - ;; - INFO) - echo "${__LEVEL_INFO}" - ;; - DEBUG | TRACE) - echo "${__LEVEL_DEBUG}" - ;; - *) - Log::displayError "Command ${SCRIPT_NAME} - Invalid level ${level}" - return 1 - esac -} - -getVerboseLevel() { - local levelName="$1" - case "${levelName^^}" in - OFF) - echo "${__VERBOSE_LEVEL_OFF}" - ;; - ERR | ERROR | WARN | WARNING | INFO) - echo "${__VERBOSE_LEVEL_INFO}" - ;; - DEBUG) - echo "${__VERBOSE_LEVEL_DEBUG}" - ;; - TRACE) - echo "${__VERBOSE_LEVEL_TRACE}" - ;; - *) - Log::displayError "Command ${SCRIPT_NAME} - Invalid level ${level}" - return 1 - esac -} - -# shellcheck disable=SC2317 # if function is overridden -optionDisplayLevelCallback() { - local level="$2" - local logLevel verboseLevel - logLevel="$(getLevel "${level}")" - verboseLevel="$(getVerboseLevel "${level}")" - BASH_FRAMEWORK_ARGS_VERBOSE=${verboseLevel} - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${logLevel}" >> "${overrideEnvFile}" -} - -# shellcheck disable=SC2317 # if function is overridden -optionLogLevelCallback() { - local level="$2" - local logLevel verboseLevel - logLevel="$(getLevel "${level}")" - verboseLevel="$(getVerboseLevel "${level}")" - BASH_FRAMEWORK_ARGS_VERBOSE=${verboseLevel} - echo "BASH_FRAMEWORK_LOG_LEVEL=${logLevel}" >> "${overrideEnvFile}" -} - -# shellcheck disable=SC2317 # if function is overridden -optionLogFileCallback() { - local logFile="$2" - echo "BASH_FRAMEWORK_LOG_FILE='${logFile}'" >> "${overrideEnvFile}" -} - -# shellcheck disable=SC2317 # if function is overridden -optionQuietCallback() { - echo "BASH_FRAMEWORK_QUIET_MODE=1" >> "${overrideEnvFile}" -} - -# shellcheck disable=SC2317 # if function is overridden -optionNoColorCallback() { - UI::theme "noColor" -} - -# shellcheck disable=SC2317 # if function is overridden -optionThemeCallback() { - UI::theme "$2" -} - -displayConfig() { - echo "Config" - UI::drawLine "-" - local var - while read -r var; do - printf '%-40s = %s\n' "${var}" "$(declare -p "${var}" | sed -E -e 's/^[^=]+=(.*)/\1/')" - done < <(typeset -p | awk 'match($3, "^(BASH_FRAMEWORK_[^=]+)=", m) { print m[1] }' | sort) - exit 0 -} - -optionBashFrameworkConfigCallback() { - if [[ ! -f "$2" ]]; then - Log::fatal "Command ${SCRIPT_NAME} - Bash framework config file '$2' does not exists" - fi -} - -defaultFrameworkConfig="$( - cat <<'EOF' -.INCLUDE "${ORIGINAL_TEMPLATE_DIR}/_includes/.framework-config.default" -EOF -)" - -overrideEnvFile="$(Framework::createTempFile "overrideEnvFile")" - -commandOptionParseFinished() { - # load default template framework config - defaultEnvFile="${PERSISTENT_TMPDIR}/.framework-config" - echo "${defaultFrameworkConfig}" > "${defaultEnvFile}" - local -a files=("${defaultEnvFile}") - if [[ -f "${envFile}" ]]; then - files+=("${envFile}") - fi - # shellcheck disable=SC2154 - if [[ -f "${optionBashFrameworkConfig}" ]]; then - files+=("${optionBashFrameworkConfig}") - fi - files+=("${overrideEnvFile}") - Env::requireLoad "${files[@]}" - Log::requireLoad - # shellcheck disable=SC2154 - if [[ "${optionConfig}" = "1" ]]; then - displayConfig - fi -} diff --git a/src/_binaries/options/options.ci.tpl b/src/_binaries/options/options.ci.tpl deleted file mode 100644 index 9e391a82..00000000 --- a/src/_binaries/options/options.ci.tpl +++ /dev/null @@ -1,20 +0,0 @@ -% -# shellcheck source=/dev/null -source <( - Options::generateOption \ - --help "activate continuous integration mode (tmp folder not shared with host)" \ - --alt "--ci" \ - --callback updateOptionContinuousIntegrationMode \ - --variable-name "optionContinuousIntegrationMode" \ - --function-name optionContinuousIntegrationModeFunction -) -options+=( - optionContinuousIntegrationModeFunction -) -% -declare optionContinuousIntegrationMode=0 - -# shellcheck disable=SC2317 # if function is overridden -updateOptionContinuousIntegrationMode() { - BASH_FRAMEWORK_ARGV_FILTERED+=("$1") -} diff --git a/src/_binaries/options/options.format.tpl b/src/_binaries/options/options.format.tpl deleted file mode 100644 index 2a046bcf..00000000 --- a/src/_binaries/options/options.format.tpl +++ /dev/null @@ -1,25 +0,0 @@ -% -# shellcheck source=/dev/null -source <( - Options::generateOption \ - --variable-type String \ - --default-value "${optionFormatDefault:-plain}" \ - --help "define output format of this command" \ - --alt "--format" \ - --authorized-values "${optionFormatAuthorizedValues:-plain|checkstyle}" \ - --callback updateArgListFormatCallback \ - --variable-name "optionFormat" \ - --function-name optionFormatFunction -) -options+=( - optionFormatFunction -) -% - -# default option values -declare optionFormat="${optionFormatDefault:-plain}" - -# shellcheck disable=SC2317 # if function is overridden -updateArgListFormatCallback() { - BASH_FRAMEWORK_ARGV_FILTERED+=("$@") -} diff --git a/src/_binaries/options/options.skipDockerBuild.tpl b/src/_binaries/options/options.skipDockerBuild.tpl deleted file mode 100644 index e4c5394c..00000000 --- a/src/_binaries/options/options.skipDockerBuild.tpl +++ /dev/null @@ -1,21 +0,0 @@ -% -# shellcheck source=/dev/null -source <( - Options::generateOption \ - --help "skip docker image build if option provided" \ - --alt "--skip-docker-build" \ - --callback updateOptionSkipDockerBuildCallback \ - --variable-name "optionSkipDockerBuild" \ - --function-name optionSkipDockerBuildFunction -) -options+=( - optionSkipDockerBuildFunction -) -% - -declare optionSkipDockerBuild=0 - -# shellcheck disable=SC2317 # if function is overridden -updateOptionSkipDockerBuildCallback() { - BASH_FRAMEWORK_ARGV_FILTERED+=("$1") -} diff --git a/src/_binaries/options/options.srcDir.tpl b/src/_binaries/options/options.srcDir.tpl deleted file mode 100644 index 4e6613ac..00000000 --- a/src/_binaries/options/options.srcDir.tpl +++ /dev/null @@ -1,27 +0,0 @@ -% -# shellcheck source=/dev/null -source <( - Options::generateOption \ - --variable-type StringArray \ - --help "provide the directory where to find the functions source code. (Prefer using .framework-config file)" \ - --max -1 \ - --alt "--src-dir" \ - --alt "-s" \ - --callback optionSrcDirsCallback \ - --variable-name "optionSrcDirs" \ - --function-name optionSrcDirsFunction -) -options+=( - optionSrcDirsFunction -) -% - -# default option values -declare -a optionSrcDirs=() - -optionSrcDirsCallback() { - if [[ ! -d "$1" ]]; then - Log::fatal "Command ${SCRIPT_NAME} - Directory '$1' does not exists" - fi - FRAMEWORK_SRC_DIRS+=("$(realpath --physical "$1")") -}