From b2bbc60529aa021bc6aae018ee44c88fa39dd8fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Chastanet?= Date: Sat, 31 Aug 2024 19:53:26 +0200 Subject: [PATCH] compiled dbImportProfile using go compiler --- .framework-config | 2 +- .pre-commit-config-github.yaml | 6 +- .pre-commit-config.yaml | 6 +- Commands.tmpl.md | 23 +- bin/dbImport | 47 +- bin/dbImportProfile | 3023 ++++++++++------- bin/doc | 14 +- bin/install | 12 +- bin/installRequirements | 12 +- bin/mysql2puml | 18 +- src/BashTools/Conf/requireLoad.bats | 1 - .../mysql2puml/binary-mysql2puml.yaml | 2 +- .../mysql2puml/testsData/mysql2puml.help.txt | 18 +- .../Database/dbImport/binary-dbImport.yaml | 4 +- .../Database/dbImport/dbImport-main.sh | 6 - .../Database/dbImport/dbImport-options.sh | 14 + src/_binaries/Database/dbImport/dbImport.bats | 2 +- .../dbImport/testsData/dbImport.help.txt | 32 +- .../testsData/dbImportProfile.help.txt | 89 - .../testsData/dbImportStream.help.txt | 92 - .../dbImport/testsData/dbImportTableDump.sql | 35 - .../dbImport/testsData/empty-dump.sql | 1 - .../testsData/expectedDbImportTableDump.sql | 42 - .../expectedDbImportTableDumpRenamed.sql | 42 - .../dbImport/testsData/tableSizeQuery.sql | 1 - .../binary-dbImportProfile.yaml | 67 + .../dbImportProfile/dbImportProfile-main.sh | 67 + .../dbImportProfile-options.sh | 84 + .../dbImportProfile}/dbImportProfile.bats | 2 +- .../testsData/auto_default.local_fromDb_20.sh | 0 .../testsData/auto_default.local_fromDb_70.sh | 0 .../testsData/dbImportProfile.help.txt | 91 + .../testsData/dbImportProfile.tableList1 | 0 .../testsData/dbImportProfiles/all.sh | 4 + .../testsData/dbImportProfiles/default.sh | 15 + .../testsData/dbImportProfiles/none.sh | 6 + .../testsData/dsn/default.local.env | 13 + .../testsData/dsn/default.remote.env | 12 + .../testsData/dsn/localhost-root.env | 12 + .../expectedDbImportProfileTableListQuery.sql | 0 src/_binaries/DbImport/dbImport.options.tpl | 141 - src/_binaries/DbImport/dbImport.sh | 215 -- .../DbImport/dbImportProfile.options.tpl | 110 - src/_binaries/DbImport/dbImportProfile.sh | 85 - .../DbImport/dbImportStream.options.tpl | 2 +- .../testsData/dbImportProfile.help.txt | 89 - .../dbQueryAllDatabases.options.tpl | 2 +- src/_binaries/build/doc/doc-main.sh | 2 +- .../optionsMysqlCollationName.yaml | 2 +- .../optionsMysqlSource.yaml | 4 +- .../optionsMysqlTarget.yaml | 4 +- .../commandDefinitions/optionsProfile.yaml | 4 +- 52 files changed, 2243 insertions(+), 2334 deletions(-) delete mode 100644 src/_binaries/Database/dbImport/testsData/dbImportProfile.help.txt delete mode 100644 src/_binaries/Database/dbImport/testsData/dbImportStream.help.txt delete mode 100644 src/_binaries/Database/dbImport/testsData/dbImportTableDump.sql delete mode 100644 src/_binaries/Database/dbImport/testsData/empty-dump.sql delete mode 100644 src/_binaries/Database/dbImport/testsData/expectedDbImportTableDump.sql delete mode 100644 src/_binaries/Database/dbImport/testsData/expectedDbImportTableDumpRenamed.sql delete mode 100644 src/_binaries/Database/dbImport/testsData/tableSizeQuery.sql create mode 100644 src/_binaries/Database/dbImportProfile/binary-dbImportProfile.yaml create mode 100755 src/_binaries/Database/dbImportProfile/dbImportProfile-main.sh create mode 100755 src/_binaries/Database/dbImportProfile/dbImportProfile-options.sh rename src/_binaries/{DbImport => Database/dbImportProfile}/dbImportProfile.bats (98%) rename src/_binaries/Database/{dbImport => dbImportProfile}/testsData/auto_default.local_fromDb_20.sh (100%) rename src/_binaries/Database/{dbImport => dbImportProfile}/testsData/auto_default.local_fromDb_70.sh (100%) create mode 100644 src/_binaries/Database/dbImportProfile/testsData/dbImportProfile.help.txt rename src/_binaries/Database/{dbImport => dbImportProfile}/testsData/dbImportProfile.tableList1 (100%) create mode 100755 src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/all.sh create mode 100755 src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/default.sh create mode 100755 src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/none.sh create mode 100644 src/_binaries/Database/dbImportProfile/testsData/dsn/default.local.env create mode 100644 src/_binaries/Database/dbImportProfile/testsData/dsn/default.remote.env create mode 100644 src/_binaries/Database/dbImportProfile/testsData/dsn/localhost-root.env rename src/_binaries/Database/{dbImport => dbImportProfile}/testsData/expectedDbImportProfileTableListQuery.sql (100%) delete mode 100644 src/_binaries/DbImport/dbImport.options.tpl delete mode 100755 src/_binaries/DbImport/dbImport.sh delete mode 100644 src/_binaries/DbImport/dbImportProfile.options.tpl delete mode 100755 src/_binaries/DbImport/dbImportProfile.sh delete mode 100644 src/_binaries/DbImport/testsData/dbImportProfile.help.txt diff --git a/.framework-config b/.framework-config index c7922347..f89ee4da 100755 --- a/.framework-config +++ b/.framework-config @@ -32,7 +32,7 @@ FRAMEWORK_FUNCTIONS_IGNORE_REGEXP="${FRAMEWORK_FUNCTIONS_IGNORE_REGEXP:-^(Namesp # describe the files that do not contain function to be imported NON_FRAMEWORK_FILES_REGEXP="${NON_FRAMEWORK_FILES_REGEXP:-(^bin/|\.framework-config|^test\.sh$|^\.github/preCommitGeneration\.sh$|^install$|\.bats$|/testsData/|^manualTests/|/_\.sh$|/ZZZ\.sh$|/__all\.sh$|^src/_binaries|^src/_includes|^src/batsHeaders\.sh$|^conf/)}" # describe the files that are allowed to not have an associated bats file -BATS_FILE_NOT_NEEDED_REGEXP="${BATS_FILE_NOT_NEEDED_REGEXP:-(^conf/|^bin/|^\.github/preCommitGeneration\.sh$|.framework-config|^install$|\.bats$|/testsData/|^manualTests/|/_\.sh$|/ZZZ\.sh$|/__all\.sh$|^src/batsHeaders\.sh$|^src/_includes)}" +BATS_FILE_NOT_NEEDED_REGEXP="${BATS_FILE_NOT_NEEDED_REGEXP:-(^conf/|^bin/|^\.github/preCommitGeneration\.sh$|.framework-config|^install$|\.bats$|/testsData/|^manualTests/|/_\.sh$|/ZZZ\.sh$|/__all\.sh$|^src/batsHeaders\.sh$|^src/_includes|^src/_binaries/.*-(options|main)\.sh$|^conf/|^src/_binaries/commandDefinitions/options.*\.sh$|/testsData/|^test\.sh$)}" # 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:-^conf/|^bin/|^\.framework-config$|\.tpl$|testsData/binaryFile$}" # Source directories diff --git a/.pre-commit-config-github.yaml b/.pre-commit-config-github.yaml index 200b46a0..0b065dce 100644 --- a/.pre-commit-config-github.yaml +++ b/.pre-commit-config-github.yaml @@ -161,7 +161,7 @@ repos: exclude: /testsData/ - repo: https://github.com/fchastanet/bash-tools-framework - rev: 5.0.0 + rev: 5.1.0 hooks: - id: fixShebangExecutionBit - id: awkLint @@ -171,7 +171,7 @@ repos: args: [ --expected-warnings-count, - "6", + "4", --format, plain, --theme, @@ -205,6 +205,6 @@ repos: stages: [manual] # GITHUB - repo: https://github.com/fchastanet/bash-compiler - rev: 0.3.0 + rev: 0.3.1 hooks: - id: buildBashBinaries diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f8a4606e..2de7aa40 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -156,7 +156,7 @@ repos: exclude: /testsData/ - repo: https://github.com/fchastanet/bash-tools-framework - rev: 5.0.0 + rev: 5.1.0 hooks: - id: fixShebangExecutionBit - id: awkLint @@ -166,7 +166,7 @@ repos: args: [ --expected-warnings-count, - "6", + "4", --format, plain, --theme, @@ -200,6 +200,6 @@ repos: stages: [] # GITHUB - repo: https://github.com/fchastanet/bash-compiler - rev: 0.3.0 + rev: 0.3.1 hooks: - id: buildBashBinaries diff --git a/Commands.tmpl.md b/Commands.tmpl.md index 60f6a14b..05797617 100644 --- a/Commands.tmpl.md +++ b/Commands.tmpl.md @@ -1,10 +1,11 @@ # The commands - [1. Build tools](#1-build-tools) - - [1.1. bin/installRequirements](#11-bininstallrequirements) - - [1.2. bin/waitForIt](#12-binwaitforit) - - [1.3. bin/waitForMysql](#13-binwaitformysql) - - [1.4. bin/doc](#14-bindoc) + - [1.1. bin/install](#11-bininstall) + - [1.2. bin/installRequirements](#12-bininstallrequirements) + - [1.3. bin/waitForIt](#13-binwaitforit) + - [1.4. bin/waitForMysql](#14-binwaitformysql) + - [1.5. bin/doc](#15-bindoc) - [2. Converter and Generator tools](#2-converter-and-generator-tools) - [2.1. bin/mysql2puml](#21-binmysql2puml) - [2.1.1. Help](#211-help) @@ -36,25 +37,31 @@ ## 1. Build tools -### 1.1. bin/installRequirements +### 1.1. bin/install + +```text +@@@install_help@@@ +``` + +### 1.2. bin/installRequirements ```text @@@installRequirements_help@@@ ``` -### 1.2. bin/waitForIt +### 1.3. bin/waitForIt ```text @@@waitForIt_help@@@ ``` -### 1.3. bin/waitForMysql +### 1.4. bin/waitForMysql ```text @@@waitForMysql_help@@@ ``` -### 1.4. bin/doc +### 1.5. bin/doc ```text @@@doc_help@@@ diff --git a/bin/dbImport b/bin/dbImport index 03f36544..e0425b9b 100755 --- a/bin/dbImport +++ b/bin/dbImport @@ -1686,6 +1686,13 @@ declare versionNumber="2.0" declare optionBashFrameworkConfig="${BASH_TOOLS_ROOT_DIR}/.framework-config" declare defaultTargetCharacterSet="" +declare TIMEFORMAT='time spent : %3R' +declare DOWNLOAD_DUMP=0 + +declare DB_IMPORT_DUMP_DIR +declare PROFILES_DIR +declare HOME_PROFILES_DIR + beforeParseCallback() { BashTools::Conf::requireLoad Env::requireLoad @@ -1695,6 +1702,13 @@ beforeParseCallback() { Linux::requireExecutedAsUser } +initConf() { + # shellcheck disable=SC2034 + DB_IMPORT_DUMP_DIR=${DB_IMPORT_DUMP_DIR%/} + PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" + HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" +} + optionHelpCallback() { dbImportCommandHelp exit 0 @@ -2431,7 +2445,7 @@ dbImportCommandParse() { elif (( options_parse_parsedArgIndex >= minParsedArgIndex0 && options_parse_parsedArgIndex < maxParsedArgIndex1 )); then if ((options_parse_argParsedCountFromDbName >= 1 )); then - Log::displayError "Command ${SCRIPT_NAME} - Argument - Maximum number of argument occurrences reached(1)" + Log::displayError "Command ${SCRIPT_NAME} - Argument fromDbName - Maximum number of argument occurrences reached(1)" return 1 fi ((++options_parse_argParsedCountFromDbName)) @@ -2494,7 +2508,7 @@ dbImportCommandParse() { if ((options_parse_argParsedCountFromDbName < 1 )); then - Log::displayError "Command ${SCRIPT_NAME} - Argument '' should be provided at least 1 time(s)" + Log::displayError "Command ${SCRIPT_NAME} - Argument 'fromDbName' should be provided at least 1 time(s)" return 1 fi || return $? @@ -2521,7 +2535,7 @@ dbImportCommandHelp() { # ------------------------------------------ # usage/options section # ------------------------------------------ - optionsAltList=("[--collation-name|-o <>]" "[--target-dsn|-t <>]" "[--character-set|-c <>]" "[--profile|-p <>]" "[--tables <>]" "[--skip-schema|-s]" "[--from-dsn|-f <>]" "[--from-aws|-a <>]" "[--help|-h]" "[--config]" "[--bash-framework-config ]" "[--verbose|-v]" "[-vv]" "[-vvv]" "[--env-file ]" "[--log-level ]" "[--log-file ]" "[--display-level ]" "[--no-color]" "[--theme ]" "[--version]" "[--quiet|-q]" + optionsAltList=("[--collation-name|-o ]" "[--target-dsn|-t ]" "[--character-set|-c ]" "[--profile|-p ]" "[--tables ]" "[--skip-schema|-s]" "[--from-dsn|-f ]" "[--from-aws|-a ]" "[--help|-h]" "[--config]" "[--bash-framework-config ]" "[--verbose|-v]" "[-vv]" "[-vvv]" "[--env-file ]" "[--log-level ]" "[--log-file ]" "[--display-level ]" "[--no-color]" "[--theme ]" "[--version]" "[--quiet|-q]" ) Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" \ "dbImport" "${optionsAltList[@]}" @@ -2533,11 +2547,11 @@ dbImportCommandHelp() { echo echo -e "${__HELP_TITLE_COLOR}ARGUMENTS:${__RESET_COLOR}" - Array::wrap2 " " 80 2 " ${__HELP_OPTION_COLOR}${__HELP_NORMAL}{single} (mandatory) + Array::wrap2 " " 80 2 " ${__HELP_OPTION_COLOR}fromDbName${__HELP_NORMAL} {single} (mandatory) " Array::wrap2 ' ' 76 4 " " "The name of the source/remote database." echo - Array::wrap2 " " 80 2 " [${__HELP_OPTION_COLOR}${__HELP_NORMAL}{single}] + Array::wrap2 " " 80 2 " [${__HELP_OPTION_COLOR}${__HELP_NORMAL} {single}] " Array::wrap2 ' ' 76 4 " " "The name of the target database" "Default value: (without extension)" "" echo @@ -2560,14 +2574,14 @@ dbImportCommandHelp() { Array::wrap2 ' ' 76 6 " Default value: " "default.local" echo - echo -e " ${__HELP_OPTION_COLOR}--character-set${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-c ${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--character-set${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-c ${__HELP_NORMAL} {single}" Array::wrap2 ' ' 76 4 " " "Change the character set used during database creation." echo echo echo -e "${__HELP_TITLE_COLOR}PROFILE OPTIONS:${__RESET_COLOR}" - echo -e " ${__HELP_OPTION_COLOR}--profile${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-p ${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--profile${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-p ${__HELP_NORMAL} {single}" profileOptionHelpFunction @@ -2613,7 +2627,7 @@ dbImportCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config bash-framework-config${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config ${__HELP_NORMAL} {single}" Array::wrap2 ' ' 76 4 " " "Use alternate bash framework configuration." echo @@ -2637,26 +2651,26 @@ dbImportCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--env-file env-file${__HELP_NORMAL} {list} (optional)" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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" @@ -2669,7 +2683,7 @@ dbImportCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--theme theme${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--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" @@ -2721,6 +2735,7 @@ dbImportCommandHelp() { beforeParseCallback +initConf dbImportCommandParse "$@" MAIN_FUNCTION_NAME="main" @@ -2735,12 +2750,6 @@ Compiler::Embed::extractFileFromBase64 \ declare -gx embed_file_dumpSizeQuery="${PERSISTENT_TMPDIR:-/tmp}/95e2e89e049fcfcd74a8b75390f067bf/dumpSizeQuery" -declare TIMEFORMAT='time spent : %3R' -declare DB_IMPORT_DUMP_DIR=${DB_IMPORT_DUMP_DIR%/} -declare PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" -declare HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" -declare DOWNLOAD_DUMP=0 - # dump header/footer read -r -d '\0' DUMP_HEADER <<-EOM SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0; diff --git a/bin/dbImportProfile b/bin/dbImportProfile index 8be14864..dafd0bca 100755 --- a/bin/dbImportProfile +++ b/bin/dbImportProfile @@ -1,13 +1,12 @@ #!/usr/bin/env bash ############################################################################### -# GENERATED FACADE FROM https://github.com/fchastanet/bash-tools/tree/master/src/_binaries/DbImport/dbImportProfile.sh +# GENERATED FROM https://github.com/fchastanet/bash-tools-framework/tree/master/src/_binaries/Database/dbImportProfile/binary-dbImportProfile.yaml # DO NOT EDIT IT # @generated ############################################################################### # shellcheck disable=SC2288,SC2034 -# BIN_FILE=${BASH_TOOLS_ROOT_DIR}/bin/dbImportProfile -# 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,376 +138,358 @@ 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 + +# @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 + + # replace tab by 2 spaces + arg="${arg//$'\t'/ }" + # remove trailing spaces + arg="${arg%[[:blank:]]}" + if [[ "${arg}" = $'\n' || -z "${arg}" ]]; then + printCurrentLine + ((previousLineEmpty = 1)) + continue + else + if ((previousLineEmpty == 1)); then + printCurrentLine + fi + ((previousLineEmpty = 0)) || true + fi + # convert eol to args + mapfile -t additionalLines <<<"${arg}" + if ((${#additionalLines[@]} > 1)); then + set -- "${additionalLines[@]}" "$@" + continue + fi + + ((argLength = ${#arg})) || true + + # empty arg + if ((argLength == 0)); then + if ((isNewline == 0)); then + # isNewline = 0 means currentLine is not empty + printCurrentLine + fi + continue + fi + + if ((isNewline == 0)); then + glueLength="${#glue}" + else + glueLength="0" + fi + if ((currentLineLength + argLength + glueLength > maxLineLength)); then + if ((argLength + glueLength > maxLineLength)); then + # arg is too long to even fit on one line + # we have to split the arg on current and next line + local -i remainingLineLength + ((remainingLineLength = maxLineLength - currentLineLength - glueLength)) + appendToCurrentLine "${glue:0:${glueLength}}${arg:0:${remainingLineLength}}" "$((glueLength + remainingLineLength))" + printCurrentLine + arg="${arg:${remainingLineLength}}" + # remove leading spaces + arg="${arg##[[:blank:]]}" + + set -- "${arg}" "$@" + else + # the arg can fit on next line + printCurrentLine + appendToCurrentLine "${arg}" "${argLength}" + fi + else + appendToCurrentLine "${glue:0:${glueLength}}${arg}" "$((glueLength + argLength))" + fi + done + if [[ "${currentLine}" != "" ]] && [[ ! "${currentLine}" =~ ^[\ \t]+$ ]]; then + printCurrentLine + fi + ) | sed -E -e 's/[[:blank:]]+$//' } -# @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 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 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 + +# @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 - Log::logWarning "$1" + if [[ "${INTERACTIVE:-0}" = "1" ]]; then + return 0 + fi + tty -s } -# @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 ignore exit code 141 from simple command pipes +# @example use with: +# local resultingStatus=0 +# local -a originalPipeStatus=() +# cmd1 | cmd2 || Bash::handlePipelineFailure resultingStatus originalPipeStatus || true +# [[ "${resultingStatus}" = "0" ]] +# @arg $1 resultingStatusCode:&int (passed by reference) (optional) resulting status code +# @arg $2 originalStatus:int[] (passed by reference) (optional) copy of original PIPESTATUS array +# @env PIPESTATUS assuming that this function is called like in the example provided +# @see https://unix.stackexchange.com/a/709880/582856 +Bash::handlePipelineFailure() { + local -a pipeStatusBackup=("${PIPESTATUS[@]}") + local -n handlePipelineFailure_resultingStatusCode=$1 + local -n handlePipelineFailure_originalStatus=$2 + # shellcheck disable=SC2034 + handlePipelineFailure_originalStatus=("${pipeStatusBackup[@]}") + handlePipelineFailure_resultingStatusCode=0 + local statusCode + for statusCode in "${pipeStatusBackup[@]}"; do + if ((statusCode == 141)); then + return 0 + elif ((statusCode > 0)); then + # shellcheck disable=SC2034 + handlePipelineFailure_resultingStatusCode="${statusCode}" + break + fi + done + return "${handlePipelineFailure_resultingStatusCode}" } -# @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 -# -# @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 -} - -# @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 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 loads ~/.bash-tools/.env if available +# if not creates it from a default template +# else check if new options need to be added +BashTools::Conf::requireLoad() { +Linux::requireTarCommand +Compiler::Embed::extractFileFromBase64 \ + "${PERSISTENT_TMPDIR:-/tmp}/db87222729e0f1ed9c597a486a61a08c/bashToolsDefaultConfigTemplate" \ + "IyEvdXNyL2Jpbi9lbnYgYmFzaAojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKCiMgRGVmYXVsdCBzZXR0aW5ncwojIHlvdSBjYW4gb3ZlcnJpZGUgdGhlc2Ugc2V0dGluZ3MgYnkgY3JlYXRpbmcgJHtIT01FfS8uYmFzaC10b29scy8uZW52IGZpbGUKCiMjIwojIyMgRElTUExBWSBMZXZlbAojIyMgbWluaW11bSBsZXZlbCBvZiB0aGUgbWVzc2FnZXMgdGhhdCB3aWxsIGJlIGRpc3BsYXllZCBvbiBzY3JlZW4KIyMjCiMjIyAwOiBOTyBMT0cKIyMjIDE6IEVSUk9SCiMjIyAyOiBXQVJOSU5HCiMjIyAzOiBJTkZPCiMjIyA0OiBERUJVRwojIyMKQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTD0ke0JBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUw6LTN9CgojIyMKIyMjIERJU1BMQVkgZHVyYXRpb24KIyMjIDA6IG5vIGR1cmF0aW9uIGlzIGRpc3BsYXllZCBvbiB0aGUgbWVzc2FnZXMKIyMjIDE6IGR1cmF0aW9uIGJldHdlZW4gcHJldmlvdXMgbWVzc2FnZSBhbmQgY3VycmVudCBpcyBkaXNwbGF5ZWQKIyMjIHdpdGggdGhlIG1lc3NhZ2UKIyMjCkRJU1BMQVlfRFVSQVRJT049JHtESVNQTEFZX0RVUkFUSU9OOjB9CgojIyMKIyMjIExvZyB0byBmaWxlCiMjIwojIyMgYWxsIGxvZyBtZXNzYWdlcyB3aWxsIGJlIHJlZGlyZWN0ZWQgdG8gbG9nIGZpbGUgc3BlY2lmaWVkCiMjIyB0aGlzIHNhbWUgcGF0aCB3aWxsIGJlIHVzZWQgaW5zaWRlIGFuZCBvdXRzaWRlIG9mIHRoZSBjb250YWluZXIKIyMjCkJBU0hfRlJBTUVXT1JLX0xPR19GSUxFPSR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEU6LSR7RlJBTUVXT1JLX1JPT1RfRElSfS9sb2dzL2Jhc2gubG9nfQoKIyMjCiMjIyBMT0cgTGV2ZWwKIyMjIG1pbmltdW0gbGV2ZWwgb2YgdGhlIG1lc3NhZ2VzIHRoYXQgd2lsbCBiZSBsb2dnZWQgaW50byBMT0dfRklMRQojIyMKIyMjIDA6IE5PIExPRwojIyMgMTogRVJST1IKIyMjIDI6IFdBUk5JTkcKIyMjIDM6IElORk8KIyMjIDQ6IERFQlVHCiMjIwpCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw6LTB9CgojIGFic29sdXRlIGRpcmVjdG9yeSBjb250YWluaW5nIGRiIGltcG9ydCBzcWwgZHVtcHMKREJfSU1QT1JUX0RVTVBfRElSPSR7REJfSU1QT1JUX0RVTVBfRElSOi0ke0hPTUV9Ly5iYXNoLXRvb2xzL2RiSW1wb3J0RHVtcHN9CgojIGdhcmJhZ2UgY29sbGVjdCBhbGwgZmlsZXMgZm9yIHdoaWNoIG1vZGlmaWNhdGlvbiBpcyBncmVhdGVyIHRoYW4gZWc6IDMwIGRheXMgKCszMCkKIyBlYWNoIHRpbWUgYW4gZXhpc3RpbmcgZmlsZSBpcyB1c2VkIGJ5IGRiSW1wb3J0L2RiSW1wb3J0VGFibGUKIyB0aGUgZmlsZSBtb2RpZmljYXRpb24gdGltZSBpcyBzZXQgdG8gbm93CkRCX0lNUE9SVF9HQVJCQUdFX0NPTExFQ1RfREFZUz0ke0RCX0lNUE9SVF9HQVJCQUdFX0NPTExFQ1RfREFZUzotKzMwfQoKIyBhYnNvbHV0ZSBkaXJlY3RvcnkgY29udGFpbmluZyBkYlNjcmlwdHMgdXNlZCBieSBkYlNjcmlwdEFsbERhdGFiYXNlcwpTQ1JJUFRTX0ZPTERFUj0ke1NDUklQVFNfRk9MREVSOi0ke0hPTUV9Ly5iYXNoLXRvb2xzL2NvbmYvZGJTY3JpcHRzfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIEFXUyBQYXJhbWV0ZXJzCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUzNfQkFTRV9VUkw9JHtTM19CQVNFX1VSTDotfQoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojIFBvc3RtYW4gUGFyYW1ldGVycwojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClBPU1RNQU5fQVBJX0tFWT0K" \ + "755" -# @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" -} +declare -gx embed_file_bashToolsDefaultConfigTemplate="${PERSISTENT_TMPDIR:-/tmp}/db87222729e0f1ed9c597a486a61a08c/bashToolsDefaultConfigTemplate" -# @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}") + BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/${RELATIVE_FRAMEWORK_DIR_TO_CURRENT_DIR}" && pwd -P)" + if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then + FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" + else + # if the directory does not exist yet, give a value to FRAMEWORK_ROOT_DIR + FRAMEWORK_ROOT_DIR="${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" fi - if [[ -f "${FRAMEWORK_ROOT_DIR}/.framework-config" ]]; then - configFiles+=("${FRAMEWORK_ROOT_DIR}/.framework-config") + # shellcheck disable=SC2034 + FRAMEWORK_SRC_DIR="${FRAMEWORK_ROOT_DIR}/src" + # shellcheck disable=SC2034 + FRAMEWORK_BIN_DIR="${FRAMEWORK_ROOT_DIR}/bin" + # shellcheck disable=SC2034 + FRAMEWORK_VENDOR_DIR="${FRAMEWORK_ROOT_DIR}/vendor" + # shellcheck disable=SC2034 + FRAMEWORK_VENDOR_BIN_DIR="${FRAMEWORK_ROOT_DIR}/vendor/bin" + + if [[ -f "${HOME}/.bash-tools/.env" ]]; then + # shellcheck disable=SC2034 + BASH_FRAMEWORK_ENV_FILES=("${HOME}/.bash-tools/.env") 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 + local envFile="${HOME}/.bash-tools/.env" + if [[ ! -f "${envFile}" ]]; then + mkdir -p "${HOME}/.bash-tools" + ( + echo "#!/usr/bin/env bash" + # shellcheck disable=SC2154 + echo "${embed_file_bashToolsDefaultConfigTemplate}" + ) >"${envFile}" + Log::displayInfo "Configuration file '${envFile}' created" + else + if ! grep -q '^POSTMAN_API_KEY=' "${envFile}"; then + ( + echo '# -----------------------------------------------------' + echo '# Postman Parameters' + echo '# -----------------------------------------------------' + echo 'POSTMAN_API_KEY=' + ) >>"${envFile}" + fi + fi + # shellcheck source=/conf/.env + source "${envFile}" || { + Log::displayError "impossible to load '${envFile}'" + exit 1 + } } -# @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 +# @description convert base64 encoded back to target file +# if target file is executable prepend dir of target +# file to PATH to make binary available everywhere +# it is advised to include in the path of the target file +# the md5sum of the binFile +# +# @arg $1 targetFile:String the file to write +# @arg $2 binFileBase64:String the base64 encoded file +# @arg $3 fileMode:String the chmod to set on the file +# @set PATH String prepend target embedded file binary directory to PATH variable if binary executable +Compiler::Embed::extractFileFromBase64() { + local targetFile="$1" + local binFileBase64="$2" + local fileMode="${3:-+x}" + local targetDir="${targetFile%/*}" + + if [[ ! -f "${targetFile}" ]]; then + if [[ ! -d "${targetDir}" ]]; then + mkdir -p "${targetDir}" fi + base64 -d >"${targetFile}" <<<"${binFileBase64}" + chmod "${fileMode}" "${targetFile}" 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 + if [[ -x "${targetFile}" ]]; then + Env::pathPrepend "${targetDir}" 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. + +# @description get absolute conf file from specified conf folder deduced using these rules +# * from absolute file (ignores and ) +# * relative to where script is executed (ignores and ) +# * from home/.bash-tools/ +# * from framework conf/ # -# @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}" /dev/null)" + # shellcheck disable=SC2181 + if [[ "$?" = "0" && -f "${result}" ]]; then + echo "${result}" + return 0 fi + return 1 } - ( - local currentLine - local -i currentLineLength=0 isNewline=1 argLength=0 - local -a additionalLines - local -i previousLineEmpty=0 - local arg="" - - while (($# > 0)); do - arg="$1" - shift || true + # conf is absolute file (including extension) + testAbs "${confFolder}${extension}" && return 0 + # conf is absolute file + testAbs "${confFolder}" && return 0 + # conf is absolute file (including extension) + testAbs "${conf}${extension}" && return 0 + # conf is absolute file + testAbs "${conf}" && return 0 - # replace tab by 2 spaces - arg="${arg//$'\t'/ }" - # remove trailing spaces - arg="${arg%[[:blank:]]}" - if [[ "${arg}" = $'\n' || -z "${arg}" ]]; then - printCurrentLine - ((previousLineEmpty = 1)) - continue - else - if ((previousLineEmpty == 1)); then - printCurrentLine - fi - ((previousLineEmpty = 0)) || true - fi - # convert eol to args - mapfile -t additionalLines <<<"${arg}" - if ((${#additionalLines[@]} > 1)); then - set -- "${additionalLines[@]}" "$@" - continue - fi + # relative to where script is executed (including extension) + if [[ -n "${CURRENT_DIR+xxx}" ]]; then + testAbs "$(File::concatenatePath "${CURRENT_DIR}" "${confFolder}")/${conf}${extension}" && return 0 + fi + # from home/.bash-tools/ + testAbs "$(File::concatenatePath "${HOME}/.bash-tools" "${confFolder}")/${conf}${extension}" && return 0 - ((argLength = ${#arg})) || true + if [[ -n "${FRAMEWORK_ROOT_DIR+xxx}" ]]; then + # from framework conf/ (including extension) + testAbs "$(File::concatenatePath "${FRAMEWORK_ROOT_DIR}/conf" "${confFolder}")/${conf}${extension}" && return 0 - # empty arg - if ((argLength == 0)); then - if ((isNewline == 0)); then - # isNewline = 0 means currentLine is not empty - printCurrentLine - fi - continue - fi + # from framework conf/ + testAbs "$(File::concatenatePath "${FRAMEWORK_ROOT_DIR}/conf" "${confFolder}")/${conf}" && return 0 + fi - if ((isNewline == 0)); then - glueLength="${#glue}" - else - glueLength="0" - fi - if ((currentLineLength + argLength + glueLength > maxLineLength)); then - if ((argLength + glueLength > maxLineLength)); then - # arg is too long to even fit on one line - # we have to split the arg on current and next line - local -i remainingLineLength - ((remainingLineLength = maxLineLength - currentLineLength - glueLength)) - appendToCurrentLine "${glue:0:${glueLength}}${arg:0:${remainingLineLength}}" "$((glueLength + remainingLineLength))" - printCurrentLine - arg="${arg:${remainingLineLength}}" - # remove leading spaces - arg="${arg##[[:blank:]]}" + # file not found + Log::displayError "conf file '${conf}' not found" - set -- "${arg}" "$@" - else - # the arg can fit on next line - printCurrentLine - appendToCurrentLine "${arg}" "${argLength}" - fi - else - appendToCurrentLine "${glue:0:${glueLength}}${arg}" "$((glueLength + argLength))" - fi - done - if [[ "${currentLine}" != "" ]] && [[ ! "${currentLine}" =~ ^[\ \t]+$ ]]; then - printCurrentLine - fi - ) | sed -E -e 's/[[:blank:]]+$//' + return 1 } + # @description list the conf files list available in bash-tools/conf/ folder # and those overridden in ${HOME}/.bash-tools/ folder # @@ -532,28 +520,118 @@ Conf::getMergedList() { ) | sort | uniq } -# @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 + +# @description list files of dir with given extension and display it as a list one by line +# +# @arg $1 dir:String the directory to list +# @arg $2 prefix:String the profile file prefix (default: "") +# @arg $3 ext:String the extension +# @arg $4 findOptions:String find options, eg: -type d (Default value: '-type f') +# @arg $5 indentStr:String the indentation can be any string compatible with sed not containing any / (Default value: ' - ') +# @stdout list of files without extension/directory +# @example text +# - default.local +# - default.remote +# - localhost-root +# @exitcode 1 if directory does not exists +Conf::list() { + local dir="$1" + local prefix="${2:-}" + local ext="${3}" + local findOptions="${4--type f}" + local indentStr="${5- - }" + + if [[ ! -d "${dir}" ]]; then + Log::displayError "Directory ${dir} does not exist" + fi + if [[ -n "${ext}" && "${ext:0:1}" != "." ]]; then + ext=".${ext}" + fi + ( + # shellcheck disable=SC2086 + cd "${dir}" && + find . -maxdepth 1 ${findOptions} -name "${prefix}*${ext}" | + sed -E "s#^\./${prefix}##g" | + sed -E "s#${ext}\$##g" | sort | sed -E "s#^#${indentStr}#" + ) +} + + +# @description check if dsn file has all the mandatory variables set +# Mandatory variables are: HOSTNAME, USER, PASSWORD, PORT +# +# @arg $1 dsnFileName:String dsn absolute filename +# @set HOSTNAME loaded from dsn file +# @set PORT loaded from dsn file +# @set USER loaded from dsn file +# @set PASSWORD loaded from dsn file +# @exitcode 0 on valid file +# @exitcode 1 if one of the properties of the conf file is invalid or if file not found +# @stderr log output if error found in conf file +Database::checkDsnFile() { + local dsnFileName="$1" + if [[ ! -f "${dsnFileName}" ]]; then + Log::displayError "dsn file ${dsnFileName} not found" + return 1 + fi + + ( + unset HOSTNAME PORT PASSWORD USER + # shellcheck source=/src/Database/testsData/dsn_valid.env + source "${dsnFileName}" + if [[ -z ${HOSTNAME+x} ]]; then + Log::displayError "dsn file ${dsnFileName} : HOSTNAME not provided" + return 1 + fi + if [[ -z "${HOSTNAME}" ]]; then + Log::displayWarning "dsn file ${dsnFileName} : HOSTNAME value not provided" + fi + if [[ "${HOSTNAME}" = "localhost" ]]; then + Log::displayWarning "dsn file ${dsnFileName} : check that HOSTNAME should not be 127.0.0.1 instead of localhost" + fi + if [[ -z "${PORT+x}" ]]; then + Log::displayError "dsn file ${dsnFileName} : PORT not provided" + return 1 + fi + if ! [[ ${PORT} =~ ^[0-9]+$ ]]; then + Log::displayError "dsn file ${dsnFileName} : PORT invalid" + return 1 + fi + if [[ -z "${USER+x}" ]]; then + Log::displayError "dsn file ${dsnFileName} : USER not provided" + return 1 + fi + if [[ -z "${PASSWORD+x}" ]]; then + Log::displayError "dsn file ${dsnFileName} : PASSWORD not provided" + return 1 + fi + ) +} + + +# @description check if given database exists # -# @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" +# @arg $1 instanceIfDbExists:&Map (passed by reference) database instance to use +# @arg $2 dbName:String database name +# @exitcode 1 if db doesn't exist +# @stderr debug command +Database::ifDbExists() { + local -n instanceIfDbExists=$1 + local dbName="$2" + local result + local -a mysqlCommand=() - "${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 + mysqlCommand+=(mysqlshow) + mysqlCommand+=("--defaults-extra-file=${instanceIfDbExists['AUTH_FILE']}") + # shellcheck disable=SC2206 + mysqlCommand+=(${instanceIfDbExists['SSL_OPTIONS']}) + mysqlCommand+=("${dbName}") + Log::displayDebug "execute command: '${mysqlCommand[*]}'" + result="$(MSYS_NO_PATHCONV=1 "${mysqlCommand[@]}" 2>/dev/null | grep '^Database: ' | grep -o "${dbName}")" + [[ "${result}" = "${dbName}" ]] } + # @description create a new db instance # Returns immediately if the instance is already initialized # @@ -606,44 +684,12 @@ Database::newInstance() { instanceNewInstance['SKIP_COLUMN_NAMES']="${SKIP_COLUMN_NAMES:-1}" instanceNewInstance['SSL_OPTIONS']="${MYSQL_SSL_OPTIONS:---ssl-mode=DISABLED}" instanceNewInstance['QUERY_OPTIONS']="${MYSQL_QUERY_OPTIONS:---batch --raw --default-character-set=utf8}" - instanceNewInstance['DUMP_OPTIONS']="${MYSQL_DUMP_OPTIONS:---default-character-set=utf8 --compress --hex-blob --routines --triggers --single-transaction --set-gtid-purged=OFF --column-statistics=0 ${instanceNewInstance['SSL_OPTIONS']}}" + instanceNewInstance['DUMP_OPTIONS']="${MYSQL_DUMP_OPTIONS:---default-character-set=utf8 --compression-algorithms --hex-blob --routines --triggers --single-transaction --set-gtid-purged=OFF --column-statistics=0 ${instanceNewInstance['SSL_OPTIONS']}}" instanceNewInstance['DB_IMPORT_OPTIONS']="${DB_IMPORT_OPTIONS:---connect-timeout=5 --batch --raw --default-character-set=utf8}" instanceNewInstance['INITIALIZED']=1 } -# @description set the general options to use on mysql command to query the database -# Differs than setOptions in the way that these options could change each time -# -# @arg $1 instanceSetQueryOptions:&Map (passed by reference) database instance to use -# @arg $2 optionsList:String query options list -Database::setQueryOptions() { - local -n instanceSetQueryOptions=$1 - # shellcheck disable=SC2034 - instanceSetQueryOptions['QUERY_OPTIONS']="$2" -} - -# @description check if given database exists -# -# @arg $1 instanceIfDbExists:&Map (passed by reference) database instance to use -# @arg $2 dbName:String database name -# @exitcode 1 if db doesn't exist -# @stderr debug command -Database::ifDbExists() { - local -n instanceIfDbExists=$1 - local dbName="$2" - local result - local -a mysqlCommand=() - - mysqlCommand+=(mysqlshow) - mysqlCommand+=("--defaults-extra-file=${instanceIfDbExists['AUTH_FILE']}") - # shellcheck disable=SC2206 - mysqlCommand+=(${instanceIfDbExists['SSL_OPTIONS']}) - mysqlCommand+=("${dbName}") - Log::displayDebug "execute command: '${mysqlCommand[*]}'" - result="$(MSYS_NO_PATHCONV=1 "${mysqlCommand[@]}" 2>/dev/null | grep '^Database: ' | grep -o "${dbName}")" - [[ "${result}" = "${dbName}" ]] -} # @description mysql query on a given db # @warning could use QUERY_OPTIONS variable from dsn if defined @@ -684,115 +730,113 @@ Database::query() { fi } -bashToolsDefaultConfigTemplate="${bashToolsDefaultConfigTemplate:-$( - cat <<'EOF' -# shellcheck disable=SC2034 -# Default settings -# you can override these settings by creating ${HOME}/.bash-tools/.env file - -### -### DISPLAY Level -### minimum level of the messages that will be displayed on screen -### -### 0: NO LOG -### 1: ERROR -### 2: WARNING -### 3: INFO -### 4: DEBUG -### -BASH_FRAMEWORK_DISPLAY_LEVEL=${BASH_FRAMEWORK_DISPLAY_LEVEL:-3} - -### -### DISPLAY duration -### 0: no duration is displayed on the messages -### 1: duration between previous message and current is displayed -### with the message -### -DISPLAY_DURATION=${DISPLAY_DURATION:0} - -### -### Log to file -### -### all log messages will be redirected to log file specified -### this same path will be used inside and outside of the container -### -BASH_FRAMEWORK_LOG_FILE=${BASH_FRAMEWORK_LOG_FILE:-${FRAMEWORK_ROOT_DIR}/logs/bash.log} - -### -### LOG Level -### minimum level of the messages that will be logged into LOG_FILE -### -### 0: NO LOG -### 1: ERROR -### 2: WARNING -### 3: INFO -### 4: DEBUG -### -BASH_FRAMEWORK_LOG_LEVEL=${BASH_FRAMEWORK_LOG_LEVEL:-0} - -# absolute directory containing db import sql dumps -DB_IMPORT_DUMP_DIR=${DB_IMPORT_DUMP_DIR:-${HOME}/.bash-tools/dbImportDumps} - -# garbage collect all files for which modification is greater than eg: 30 days (+30) -# each time an existing file is used by dbImport/dbImportTable -# the file modification time is set to now -DB_IMPORT_GARBAGE_COLLECT_DAYS=${DB_IMPORT_GARBAGE_COLLECT_DAYS:-+30} - -# absolute directory containing dbScripts used by dbScriptAllDatabases -SCRIPTS_FOLDER=${SCRIPTS_FOLDER:-${HOME}/.bash-tools/conf/dbScripts} - -# ----------------------------------------------------- -# AWS Parameters -# ----------------------------------------------------- -S3_BASE_URL=${S3_BASE_URL:-} - -# ----------------------------------------------------- -# Postman Parameters -# ----------------------------------------------------- -POSTMAN_API_KEY= -EOF -)}" +# @description set the general options to use on mysql command to query the database +# Differs than setOptions in the way that these options could change each time +# +# @arg $1 instanceSetQueryOptions:&Map (passed by reference) database instance to use +# @arg $2 optionsList:String query options list +Database::setQueryOptions() { + local -n instanceSetQueryOptions=$1 + # shellcheck disable=SC2034 + instanceSetQueryOptions['QUERY_OPTIONS']="$2" +} -# @description loads ~/.bash-tools/.env if available -# if not creates it from a default template -# else check if new options need to be added -BashTools::Conf::requireLoad() { - local envFile="${HOME}/.bash-tools/.env" - if [[ ! -f "${envFile}" ]]; then - mkdir -p "${HOME}/.bash-tools" - ( - echo "#!/usr/bin/env bash" - echo "${bashToolsDefaultConfigTemplate}" - ) >"${envFile}" - Log::displayInfo "Configuration file '${envFile}' created" - else - if ! grep -q '^POSTMAN_API_KEY=' "${envFile}"; then - ( - echo '# -----------------------------------------------------' - echo '# Postman Parameters' - echo '# -----------------------------------------------------' - echo 'POSTMAN_API_KEY=' - ) >>"${envFile}" + +# @description check if all requirements are satisfied +# to execute dbImport commands +Db::checkRequirements() { + if [[ "${SKIP_REQUIREMENTS_CHECKS:-0}" = "1" ]]; then + return 0 + fi + local -i failures=0 + echo + Assert::commandExists mysql "sudo apt-get install -y mysql-client" || ((++failures)) + Assert::commandExists mysqlshow "sudo apt-get install -y mysql-client" || ((++failures)) + Assert::commandExists mysqldump "sudo apt-get install -y mysql-client" || ((++failures)) + Assert::commandExists pv "sudo apt-get install -y pv" || ((++failures)) + Assert::commandExists gawk "sudo apt-get install -y gawk" || ((++failures)) + Assert::commandExists awk "sudo apt-get install -y gawk" || ((++failures)) + Version::checkMinimal "gawk" "--version" "5.0.1" || ((++failures)) + return "${failures}" +} + + +# @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 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 - # shellcheck source=/conf/.env - source "${envFile}" || { - Log::displayError "impossible to load '${envFile}'" + 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 concatenate 2 paths and ensure the path is correct using realpath -m +# @arg $1 basePath:String +# @arg $2 subPath:String +File::concatenatePath() { + + if [[ "${REQUIRE_FUNCTION_LINUX_REQUIRE_REALPATH_COMMAND_LOADED:-0}" != 1 ]]; then + echo >&2 "Requirement Linux::requireRealpathCommand has not been loaded" exit 1 - } + fi + + local basePath="$1" + local subPath="$2" + local fullPath="${basePath:+${basePath}/}${subPath}" + + realpath -m "${fullPath}" 2>/dev/null } -# @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}" + +# @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 ensure running user is not root # @exitcode 1 if current user is root # @stderr diagnostics information is displayed @@ -802,6 +846,25 @@ Linux::requireExecutedAsUser() { fi } + +# @description ensure command realpath is available +# @exitcode 1 if realpath command not available +# @stderr diagnostics information is displayed +Linux::requireRealpathCommand() { + REQUIRE_FUNCTION_LINUX_REQUIRE_REALPATH_COMMAND_LOADED=1 + + Assert::commandExists realpath +} + + +# @description ensure command tar is available +# @exitcode 1 if tar command not available +# @stderr diagnostics information is displayed +Linux::requireTarCommand() { + Assert::commandExists tar +} + + declare -g FIRST_LOG_DATE LOG_LAST_LOG_DATE LOG_LAST_LOG_DATE_INIT LOG_LAST_DURATION_STR FIRST_LOG_DATE="${EPOCHREALTIME/[^0-9]/}" LOG_LAST_LOG_DATE="${FIRST_LOG_DATE}" @@ -840,14 +903,72 @@ 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 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 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::logDebug() { @@ -856,13 +977,6 @@ Log::logDebug() { 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 log message to file # @arg $1 message:String the message to display @@ -872,20 +986,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 @@ -893,6 +993,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 @@ -906,9 +1016,18 @@ 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 @@ -920,6 +1039,74 @@ Log::logMessage() { 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 @@ -942,164 +1129,22 @@ Log::rotate() { fi } -# @description list files of dir with given extension and display it as a list one by line -# -# @arg $1 dir:String the directory to list -# @arg $2 prefix:String the profile file prefix (default: "") -# @arg $3 ext:String the extension -# @arg $4 findOptions:String find options, eg: -type d (Default value: '-type f') -# @arg $5 indentStr:String the indentation can be any string compatible with sed not containing any / (Default value: ' - ') -# @stdout list of files without extension/directory -# @example text -# - default.local -# - default.remote -# - localhost-root -# @exitcode 1 if directory does not exists -Conf::list() { - local dir="$1" - local prefix="${2:-}" - local ext="${3}" - local findOptions="${4--type f}" - local indentStr="${5- - }" - - if [[ ! -d "${dir}" ]]; then - Log::displayError "Directory ${dir} does not exist" - fi - if [[ -n "${ext}" && "${ext:0:1}" != "." ]]; then - ext=".${ext}" - fi - ( - # shellcheck disable=SC2086 - cd "${dir}" && - find . -maxdepth 1 ${findOptions} -name "${prefix}*${ext}" | - sed -E "s#^\./${prefix}##g" | - sed -E "s#${ext}\$##g" | sort | sed -E "s#^#${indentStr}#" - ) -} - -# @description get absolute conf file from specified conf folder deduced using these rules -# * from absolute file (ignores and ) -# * relative to where script is executed (ignores and ) -# * from home/.bash-tools/ -# * from framework conf/ -# -# @arg $1 confFolder:String the directory name (not the path) to list -# @arg $2 conf:String file to use without extension -# @arg $3 extension:String the extension (.sh by default) -# -# @stdout absolute conf filename -# @exitcode 1 if file is not found in any location -Conf::getAbsoluteFile() { - local confFolder="$1" - local conf="$2" - local extension="${3-.sh}" - if [[ -n "${extension}" && "${extension:0:1}" != "." ]]; then - extension=".${extension}" - fi - - testAbs() { - local result - result="$(realpath -e "$1" 2>/dev/null)" - # shellcheck disable=SC2181 - if [[ "$?" = "0" && -f "${result}" ]]; then - echo "${result}" - return 0 - fi - return 1 - } - - # conf is absolute file (including extension) - testAbs "${confFolder}${extension}" && return 0 - # conf is absolute file - testAbs "${confFolder}" && return 0 - # conf is absolute file (including extension) - testAbs "${conf}${extension}" && return 0 - # conf is absolute file - testAbs "${conf}" && return 0 - - # relative to where script is executed (including extension) - if [[ -n "${CURRENT_DIR+xxx}" ]]; then - testAbs "$(File::concatenatePath "${CURRENT_DIR}" "${confFolder}")/${conf}${extension}" && return 0 - fi - # from home/.bash-tools/ - testAbs "$(File::concatenatePath "${HOME}/.bash-tools" "${confFolder}")/${conf}${extension}" && return 0 - - if [[ -n "${FRAMEWORK_ROOT_DIR+xxx}" ]]; then - # from framework conf/ (including extension) - testAbs "$(File::concatenatePath "${FRAMEWORK_ROOT_DIR}/conf" "${confFolder}")/${conf}${extension}" && return 0 - # from framework conf/ - testAbs "$(File::concatenatePath "${FRAMEWORK_ROOT_DIR}/conf" "${confFolder}")/${conf}" && return 0 +# @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 - - # file not found - Log::displayError "conf file '${conf}' not found" - - return 1 -} - -# @description check if dsn file has all the mandatory variables set -# Mandatory variables are: HOSTNAME, USER, PASSWORD, PORT -# -# @arg $1 dsnFileName:String dsn absolute filename -# @set HOSTNAME loaded from dsn file -# @set PORT loaded from dsn file -# @set USER loaded from dsn file -# @set PASSWORD loaded from dsn file -# @exitcode 0 on valid file -# @exitcode 1 if one of the properties of the conf file is invalid or if file not found -# @stderr log output if error found in conf file -Database::checkDsnFile() { - local dsnFileName="$1" - if [[ ! -f "${dsnFileName}" ]]; then - Log::displayError "dsn file ${dsnFileName} not found" - return 1 + if ((width == 0)); then + width=80 fi - - ( - unset HOSTNAME PORT PASSWORD USER - # shellcheck source=/src/Database/testsData/dsn_valid.env - source "${dsnFileName}" - if [[ -z ${HOSTNAME+x} ]]; then - Log::displayError "dsn file ${dsnFileName} : HOSTNAME not provided" - return 1 - fi - if [[ -z "${HOSTNAME}" ]]; then - Log::displayWarning "dsn file ${dsnFileName} : HOSTNAME value not provided" - fi - if [[ "${HOSTNAME}" = "localhost" ]]; then - Log::displayWarning "dsn file ${dsnFileName} : check that HOSTNAME should not be 127.0.0.1 instead of localhost" - fi - if [[ -z "${PORT+x}" ]]; then - Log::displayError "dsn file ${dsnFileName} : PORT not provided" - return 1 - fi - if ! [[ ${PORT} =~ ^[0-9]+$ ]]; then - Log::displayError "dsn file ${dsnFileName} : PORT invalid" - return 1 - fi - if [[ -z "${USER+x}" ]]; then - Log::displayError "dsn file ${dsnFileName} : USER not provided" - return 1 - fi - if [[ -z "${PASSWORD+x}" ]]; then - Log::displayError "dsn file ${dsnFileName} : PASSWORD not provided" - return 1 - fi - ) + printf -- "${character}%.0s" $(seq "${COLUMNS:-$([[ -t 1 ]] && tput cols || echo '80')}") + echo } -# @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 @@ -1107,74 +1152,196 @@ Env::pathPrepend() { # @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 concatenate 2 paths and ensure the path is correct using realpath -m -# @arg $1 basePath:String -# @arg $2 subPath:String -# @require Linux::requireRealpathCommand -File::concatenatePath() { - local basePath="$1" - local subPath="$2" - local fullPath="${basePath:+${basePath}/}${subPath}" - realpath -m "${fullPath}" 2>/dev/null +# @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 +# +# @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 } -# @description ensure command realpath is available -# @exitcode 1 if realpath command not available -# @stderr diagnostics information is displayed -Linux::requireRealpathCommand() { - Assert::commandExists realpath -} -# FUNCTIONS +# @description Check that command version is greater than expected minimal version +# display warning if command version greater than expected minimal version +# display error if command version less than expected minimal version and exit 1 +# @arg $1 commandName:String command path +# @arg $2 argVersion:String command line parameters to launch to get command version +# @arg $3 minimalVersion:String expected minimal command version +# @arg $4 parseVersionCallback:Function +# @arg $5 help:String optional help message to display if command does not exist +# @exitcode 0 if command version greater or equal to expected minimal version +# @exitcode 1 if command version less than expected minimal version +# @exitcode 2 if command does not exist +Version::checkMinimal() { + local commandName="$1" + local argVersion="$2" + local minimalVersion="$3" + local parseVersionCallback=${4:-Version::parse} + local help="${5:-}" -facade_main_dbImportProfilesh() { -BASH_TOOLS_ROOT_DIR="$(cd "${CURRENT_DIR}/.." && pwd -P)" -if [[ -d "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework/" ]]; then - FRAMEWORK_ROOT_DIR="$(cd "${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" && pwd -P)" -else - # if the directory does not exist yet, give a value to FRAMEWORK_ROOT_DIR - FRAMEWORK_ROOT_DIR="${BASH_TOOLS_ROOT_DIR}/vendor/bash-tools-framework" -fi -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" + Assert::commandExists "${commandName}" "${help}" || return 2 -# @require BashTools::Conf::requireLoad -if [[ -f "${HOME}/.bash-tools/.env" ]]; then - export BASH_FRAMEWORK_ENV_FILES=("${HOME}/.bash-tools/.env") -fi -# REQUIRES -Env::requireLoad -UI::requireTheme -Log::requireLoad -Linux::requireRealpathCommand -BashTools::Conf::requireLoad -Compiler::Facade::requireCommandBinDir -Linux::requireExecutedAsUser + # shellcheck disable=SC2034 + local status=0 + # shellcheck disable=SC2034 + local -a pipeStatus=() + local version + version="$("${commandName}" "${argVersion}" 2>&1 | ${parseVersionCallback} || Bash::handlePipelineFailure status pipeStatus)" + + Log::displayDebug "check ${commandName} version ${version} against minimal ${minimalVersion}" + + Version::compare "${version}" "${minimalVersion}" || { + local result=$? + if [[ "${result}" = "1" ]]; then + Log::displayInfo "${commandName} version is ${version} greater than ${minimalVersion}" + elif [[ "${result}" = "2" ]]; then + Log::displayError "${commandName} minimal version is ${minimalVersion}, your version is ${version}" + return 1 + fi + return 0 + } -# @require Compiler::Facade::requireCommandBinDir -# shellcheck disable=SC2034 +} -# default values -declare optionProfile="" -declare fromDbName="" -declare optionFromDsn="default.remote" -declare optionRatio=70 -# other configuration -declare copyrightBeginYear="2020" -declare PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" -declare HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" +# @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 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 + declare -a BASH_FRAMEWORK_ARGV_FILTERED=() +beforeParseCallback() { + Env::requireLoad + UI::requireTheme + Log::requireLoad +} + copyrightCallback() { if [[ -z "${copyrightBeginYear}" ]]; then copyrightBeginYear="$(date +%Y)" @@ -1211,13 +1378,14 @@ updateArgListQuietCallback() { :; } # shellcheck disable=SC2317 # if function is overridden optionHelpCallback() { - dbImportProfileCommand help + Log::displayError "optionHelpCallback needs to be overridden" exit 0 } # shellcheck disable=SC2317 # if function is overridden optionVersionCallback() { - echo "${SCRIPT_NAME} version 2.0" + # shellcheck disable=SC2154 + echo "${SCRIPT_NAME} version ${versionNumber}" exit 0 } @@ -1235,21 +1403,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() { @@ -1273,6 +1442,7 @@ getLevel() { *) Log::displayError "Command ${SCRIPT_NAME} - Invalid level ${level}" return 1 + ;; esac } @@ -1294,6 +1464,7 @@ getVerboseLevel() { *) Log::displayError "Command ${SCRIPT_NAME} - Invalid level ${level}" return 1 + ;; esac } @@ -1304,7 +1475,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 @@ -1313,19 +1484,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 @@ -1356,6 +1528,7 @@ optionBashFrameworkConfigCallback() { defaultFrameworkConfig="$( cat <<'EOF' + # copied from src/_includes/.framework-config.default # shellcheck disable=SC2034 @@ -1373,7 +1546,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=( @@ -1389,6 +1562,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 )" @@ -1397,7 +1571,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}") @@ -1415,510 +1589,69 @@ commandOptionParseFinished() { fi } -dbImportProfileCommand() { - local options_parse_cmd="$1" - shift || true - - if [[ "${options_parse_cmd}" = "parse" ]]; then - local -i options_parse_optionParsedCountOptionProfile - ((options_parse_optionParsedCountOptionProfile = 0)) || true - local -i options_parse_optionParsedCountOptionFromDsn - ((options_parse_optionParsedCountOptionFromDsn = 0)) || true - local -i options_parse_optionParsedCountOptionRatio - ((options_parse_optionParsedCountOptionRatio = 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 - local -i options_parse_argParsedCountFromDbName - ((options_parse_argParsedCountFromDbName = 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/17 - # Option optionProfile --profile|-p variableType String min 0 max 1 authorizedValues '' regexp '' - --profile | -p) - 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_optionParsedCountOptionProfile >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionProfile)) - # shellcheck disable=SC2034 - optionProfile="$1" - ;; - # Option 2/17 - # Option optionFromDsn --from-dsn|-f variableType String min 0 max 1 authorizedValues '' regexp '' - --from-dsn | -f) - 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_optionParsedCountOptionFromDsn >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionFromDsn)) - # shellcheck disable=SC2034 - optionFromDsn="$1" - ;; - # Option 3/17 - # Option optionRatio --ratio|-r variableType String min 0 max 1 authorizedValues '' regexp '' - --ratio | -r) - 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_optionParsedCountOptionRatio >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" - return 1 - fi - ((++options_parse_optionParsedCountOptionRatio)) - # shellcheck disable=SC2034 - optionRatio="$1" - ;; - # Option 4/17 - # 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 5/17 - # 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 6/17 - # 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 7/17 - # 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 8/17 - # 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 9/17 - # 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 10/17 - # 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 11/17 - # 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 12/17 - # 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 13/17 - # 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 14/17 - # 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 15/17 - # 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 16/17 - # 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 17/17 - # 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 - ;; - *) - if ((0)); then - # Technical if - never reached - : - # Argument 1/1 - # Argument fromDbName min 1 max 1 authorizedValues '' regexp '' - elif ((options_parse_parsedArgIndex >= 0 && options_parse_parsedArgIndex < 1)); then - if ((options_parse_argParsedCountFromDbName >= 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Argument fromDbName - Maximum number of argument occurrences reached(1)" - return 1 - fi - ((++options_parse_argParsedCountFromDbName)) - # shellcheck disable=SC2034 - fromDbName="${options_parse_arg}" - else - if [[ "${argOptDefaultBehavior}" = "0" ]]; then - Log::displayError "Command ${SCRIPT_NAME} - Argument - too much arguments provided: $*" - return 1 - fi - fi - ((++options_parse_parsedArgIndex)) - ;; - esac - shift || true - done - if ((options_parse_argParsedCountFromDbName < 1)); then - Log::displayError "Command ${SCRIPT_NAME} - Argument 'fromDbName' should be provided at least 1 time(s)" - return 1 - fi - commandOptionParseFinished - dbImportProfileCommandCallback - 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}" "generate optimized profiles to be used by dbImport" - echo - echo -e "$(Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" "${SCRIPT_NAME}" "[OPTIONS]" "[ARGUMENTS]")" - echo -e "$(Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" \ - "${SCRIPT_NAME}" \ - "[--profile|-p ]" "[--from-dsn|-f ]" "[--ratio|-r ]" "[--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}ARGUMENTS:${__RESET_COLOR}" - echo -e " ${__HELP_OPTION_COLOR}fromDbName${__HELP_NORMAL} {single} (mandatory)" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(the\ name\ of\ the\ source/remote\ database) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo - echo -e "${__HELP_TITLE_COLOR}OPTIONS:${__RESET_COLOR}" - echo -e " ${__HELP_OPTION_COLOR}--profile${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-p ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(the\ name\ of\ the\ profile\ to\ write\ in\ profiles\ directory.\ \ If\ not\ provided\,\ the\ file\ name\ pattern\ will\ be\ \'auto_\_\.sh\') - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--from-dsn${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-f ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(dsn\ to\ use\ for\ source\ database\ \(Default:\ default.remote\)\ if\ not\ provided\,\ the\ file\ name\ pattern\ will\ be\ \'auto_\_\.sh\') - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - echo -e " ${__HELP_OPTION_COLOR}--ratio${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-r ${__HELP_NORMAL} {single}" - local -a helpArray - # shellcheck disable=SC2054 - helpArray=(define\ the\ ratio\ to\ use\ \(0\ to\ 100%\ -\ default\ 70\).\ \ 0\ means\ profile\ will\ filter\ out\ all\ the\ tables.\ \ 100\ means\ profile\ will\ keep\ all\ the\ tables.\ \ Eg:\ 70\ means\ that\ tables\ with\ size\(table+index\)\ that\ are\ greater\ that\ 70%\ of\ the\ max\ table\ size\ will\ be\ excluded.) - echo -e " $(Array::wrap2 " " 76 4 "${helpArray[@]}")" - 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 """ -${__HELP_TITLE}Default profiles directory:${__HELP_NORMAL} -${PROFILES_DIR-configuration error} - -${__HELP_TITLE}User profiles directory:${__HELP_NORMAL} -${HOME_PROFILES_DIR-configuration error} -Allows to override profiles defined in "Default profiles directory" - -${__HELP_TITLE}List of available profiles:${__HELP_NORMAL} -${profilesList} - -${__HELP_TITLE}List of available dsn:${__HELP_NORMAL} -${dsnList}""" - echo - echo -n -e "${__HELP_TITLE_COLOR}VERSION: ${__RESET_COLOR}" - echo '2.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/tree/master/src/_binaries/DbImport/dbImportProfile.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 +declare defaultFromDsn="default.remote" +# shellcheck disable=SC2034 +declare versionNumber="2.0" +# shellcheck disable=SC2034 +declare copyrightBeginYear="2020" +# shellcheck disable=SC2034 +declare PROFILES_DIR +declare HOME_PROFILES_DIR + +initConf() { + # shellcheck disable=SC2034 + PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" + HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" } optionHelpCallback() { + dbImportProfileCommandHelp + exit 0 +} + +longDescriptionFunction() { local profilesList="" local dsnList="" dsnList="$(Conf::getMergedList "dsn" "env")" profilesList="$(Conf::getMergedList "dbImportProfiles" "sh" || true)" - dbImportProfileCommand help | envsubst - exit 0 + echo -e "${__HELP_TITLE}Default profiles directory:${__HELP_NORMAL}" + echo -e "${PROFILES_DIR-configuration error}" + echo + echo -e "${__HELP_TITLE}User profiles directory:${__HELP_NORMAL}" + echo -e "${HOME_PROFILES_DIR-configuration error}" + echo -e 'Allows to override profiles defined in "Default profiles directory"' + echo + echo -e "${__HELP_TITLE}List of available profiles:${__HELP_NORMAL}" + echo -e "${profilesList}" + echo + echo -e "${__HELP_TITLE}List of available dsn:${__HELP_NORMAL}" + echo -e "${dsnList}" +} + +optionProfileHelpFunction() { + Array::wrap2 " " 80 4 \ + " The name of the profile to write in profiles directory.\r" \ + "If not provided, the file name pattern will be 'auto__.sh'" + echo +} + +optionFromDsnHelpFunction() { + Array::wrap2 " " 80 4 \ + " dsn to use for source database (Default: ${defaultFromDsn})\r" \ + "if not provided, the file name pattern will be 'auto__.sh'" + echo +} + +optionRatioHelpFunction() { + Array::wrap2 " " 80 4 \ + " define the ratio to use (0 to 100% - default 70).\r" \ + "- 0 means profile will filter out all the tables\r" \ + "- 100 means profile will keep all the tables.\r" \ + "Eg: 70 means that tables with size(table+index)\r" \ + "that are greater than 70% of the max table size will be excluded." + echo } dbImportProfileCommandCallback() { @@ -1927,9 +1660,11 @@ dbImportProfileCommandCallback() { fi if [[ -z "${optionProfile}" ]]; then - optionProfile="auto_${optionFromDsn}_${fromDbName}.sh" + # shellcheck disable=SC2154 + optionProfile="auto_${optionFromDsn}_${fromDbName}" fi + # shellcheck disable=SC2154 if ! [[ "${optionRatio}" =~ ^-?[0-9]+$ ]]; then Log::fatal "Ratio value should be a number" fi @@ -1939,8 +1674,722 @@ dbImportProfileCommandCallback() { fi } -dbImportProfileCommand parse "${BASH_FRAMEWORK_ARGV[@]}" + +optionVersionCallback() { + # shellcheck disable=SC2154 + echo "${SCRIPT_NAME} version ${versionNumber}" + Db::checkRequirements + exit 0 +} + + + +beforeParseCallback() { + BashTools::Conf::requireLoad + Env::requireLoad + UI::requireTheme + Log::requireLoad +} + + +# ------------------------------------------ +# Command dbImportProfileCommand +# ------------------------------------------ + +# 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 optionProfile="" +declare optionFromDsn="default.remote" +declare optionRatio="70" +# arguments variables initialization +declare fromDbName="" +# @description parse command options and arguments for dbImportProfileCommand +dbImportProfileCommandParse() { + 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 + optionProfile="" + local -i options_parse_optionParsedCountOptionProfile + ((options_parse_optionParsedCountOptionProfile = 0)) || true + optionFromDsn="default.remote" + local -i options_parse_optionParsedCountOptionFromDsn + ((options_parse_optionParsedCountOptionFromDsn = 0)) || true + optionRatio="70" + local -i options_parse_optionParsedCountOptionRatio + ((options_parse_optionParsedCountOptionRatio = 0)) || true + + fromDbName="" + local -i options_parse_argParsedCountFromDbName + ((options_parse_argParsedCountFromDbName = 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # 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/17 + # optionProfile alts --profile|-p + # type: String min 0 max 1 + --profile | -p) + 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_optionParsedCountOptionProfile >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionProfile)) + # shellcheck disable=SC2034 + optionProfile="$1" + ;; + + # Option 16/17 + # optionFromDsn alts --from-dsn|-f + # type: String min 0 max 1 + --from-dsn | -f) + 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_optionParsedCountOptionFromDsn >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionFromDsn)) + # shellcheck disable=SC2034 + optionFromDsn="$1" + ;; + + # Option 17/17 + # optionRatio alts --ratio|-r + # type: String min 0 max 1 + --ratio | -r) + 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_optionParsedCountOptionRatio >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Option ${options_parse_arg} - Maximum number of option occurrences reached(1)" + return 1 + fi + ((++options_parse_optionParsedCountOptionRatio)) + # shellcheck disable=SC2034 + optionRatio="$1" + ;; + + -*) + if [[ "${argOptDefaultBehavior}" = "0" ]]; then + Log::displayError "Command ${SCRIPT_NAME} - Invalid option ${options_parse_arg}" + return 1 + fi + ;; + *) + ((minParsedArgIndex0 = 0)) || true + ((maxParsedArgIndex0 = 0)) || true + ((minParsedArgIndex1 = minParsedArgIndex0 + 1)) || true + ((maxParsedArgIndex1 = maxParsedArgIndex0 + 1)) || true + ((incrementArg = 1 )) + if ((0)); then + # Technical if - never reached + : + + # Argument 1/1 - fromDbName + # Argument fromDbName min 1 max 1 + # Argument fromDbName authorizedValues: + elif (( options_parse_parsedArgIndex >= minParsedArgIndex0 && + options_parse_parsedArgIndex < maxParsedArgIndex1 )); then + if ((options_parse_argParsedCountFromDbName >= 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Argument fromDbName - Maximum number of argument occurrences reached(1)" + return 1 + fi + ((++options_parse_argParsedCountFromDbName)) + # shellcheck disable=SC2034 + fromDbName="${options_parse_arg}" + + + # else too much args + else + + + if [[ "${argOptDefaultBehavior}" = "0" ]]; then + # too much args and no unknownArgumentCallbacks configured + Log::displayError "Command ${SCRIPT_NAME} - Argument - too much arguments provided: $*" + return 1 + fi + + fi + if ((incrementArg == 1)); then + ((++options_parse_parsedArgIndex)) + fi + ;; + esac + shift || true + done + + + + + + + + + + + + + + + + + + if ((options_parse_argParsedCountFromDbName < 1 )); then + Log::displayError "Command ${SCRIPT_NAME} - Argument 'fromDbName' should be provided at least 1 time(s)" + return 1 + fi || return $? + + + commandOptionParseFinished + dbImportProfileCommandCallback + +} + +# @description display command options and arguments help for dbImportProfileCommand +dbImportProfileCommandHelp() { + Array::wrap2 ' ' 80 0 "${__HELP_TITLE_COLOR}SYNOPSIS:${__RESET_COLOR}" \ + "Generate optimized profiles to be used by dbImport." + echo + echo + + # ------------------------------------------ + # usage section + # ------------------------------------------ + Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" "dbImportProfile [OPTIONS] [ARGUMENTS]" + 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]" "[--profile|-p ]" "[--from-dsn|-f ]" "[--ratio|-r ]" + ) + Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" \ + "dbImportProfile" "${optionsAltList[@]}" + echo + + # ------------------------------------------ + # usage/arguments section + # ------------------------------------------ + echo + echo -e "${__HELP_TITLE_COLOR}ARGUMENTS:${__RESET_COLOR}" + + Array::wrap2 " " 80 2 " ${__HELP_OPTION_COLOR}fromDbName${__HELP_NORMAL} {single} (mandatory) + " + Array::wrap2 ' ' 76 4 " " "The name of the source/remote database." + 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 ${__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 ${__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 ${__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 ${__HELP_NORMAL} {single}" + Array::wrap2 ' ' 76 4 " " "Set log file" + echo + + + + echo -e " ${__HELP_OPTION_COLOR}--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 ${__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}--profile${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-p ${__HELP_NORMAL} {single}" + optionProfileHelpFunction + + + + + echo -e " ${__HELP_OPTION_COLOR}--from-dsn${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-f ${__HELP_NORMAL} {single}" + optionFromDsnHelpFunction + + + + Array::wrap2 ' ' 76 6 " Default value: " "default.remote" + echo + + echo -e " ${__HELP_OPTION_COLOR}--ratio${__HELP_NORMAL}, ${__HELP_OPTION_COLOR}-r ${__HELP_NORMAL} {single}" + optionRatioHelpFunction + + + + Array::wrap2 ' ' 76 6 " Default value: " "70" + echo + # ------------------------------------------ + # longDescription section + # ------------------------------------------ + echo + echo + echo -e "${__HELP_TITLE_COLOR}DESCRIPTION:${__RESET_COLOR}" + longDescriptionFunction + # ------------------------------------------ + # version section + # ------------------------------------------ + echo + echo -n -e "${__HELP_TITLE_COLOR}VERSION: ${__RESET_COLOR}" + echo "2.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/Database/dbImportProfile/binary-dbImportProfile.yaml" + # ------------------------------------------ + # license section + # ------------------------------------------ + echo + echo -n -e "${__HELP_TITLE_COLOR}LICENSE: ${__RESET_COLOR}" + echo "MIT License" + # ------------------------------------------ + # copyright section + # ------------------------------------------ + Array::wrap2 ' ' 76 0 "$(copyrightCallback)" +} + + +beforeParseCallback +initConf + +dbImportProfileCommandParse "$@" +MAIN_FUNCTION_NAME="main" +main() { + +# other configuration read -r -d '' QUERY <"${HOME_PROFILES_DIR}/${optionProfile}" +# first table is the biggest one +declare maxTableSize +maxTableSize="$(echo "${tableList}" | head -1 | awk -F ' ' '{print $2}')" - Log::displayInfo "File saved in '${HOME_PROFILES_DIR}/${optionProfile}'" -} +# shellcheck disable=SC2154 +( + echo "#!/usr/bin/env bash" + echo + echo "# cat represents the whole list of tables" + echo "cat |" + declare -i excludedTablesCount + ((excludedTablesCount = 0)) || true + declare tableSize + declare tableName + while IFS="" read -r line || [[ -n "${line}" ]]; do + tableSize="$(echo "${line}" | awk -F ' ' '{print $2}')" + tableName="$(echo "${line}" | awk -F ' ' '{print $1}')" + if ((tableSize < maxTableSize * optionRatio / 100)); then + echo -n ' #' + else + excludedTablesCount=$((excludedTablesCount + 1)) + fi + echo " grep -v '^${tableName}$' | # table size ${tableSize}MB" + done < <(echo "${tableList}") + echo " cat" + tablesCount="$(echo "${tableList}" | wc -l)" + Log::displayInfo "Profile generated - ${excludedTablesCount}/${tablesCount} tables bigger than ${optionRatio}% of max table size (${maxTableSize}MB) automatically excluded" +) >"${HOME_PROFILES_DIR}/${optionProfile}.sh" -if [[ "${BASH_FRAMEWORK_QUIET_MODE:-0}" = "1" ]]; then - run &>/dev/null -else - run -fi +Log::displayInfo "File saved in '${HOME_PROFILES_DIR}/${optionProfile}.sh'" } -facade_main_dbImportProfilesh "$@" +# 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/bin/doc b/bin/doc index 06146676..395b2fa7 100755 --- a/bin/doc +++ b/bin/doc @@ -1820,7 +1820,7 @@ docCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config bash-framework-config${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config ${__HELP_NORMAL} {single}" Array::wrap2 ' ' 76 4 " " "Use alternate bash framework configuration." echo @@ -1844,26 +1844,26 @@ docCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--env-file env-file${__HELP_NORMAL} {list} (optional)" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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" @@ -1876,7 +1876,7 @@ docCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--theme theme${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--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" @@ -2023,7 +2023,7 @@ generateDoc() { "${DOC_DIR}/Commands.md" mkdir -p "${DOC_DIR}/src/_binaries/Converters/testsData" || true - cp "${BASH_TOOLS_ROOT_DIR}/src/_binaries/Converters/testsData/mysql2puml-model.png" "${DOC_DIR}/src/_binaries/Converters/testsData" + cp "${BASH_TOOLS_ROOT_DIR}/src/_binaries/Converters/mysql2puml/testsData/mysql2puml-model.png" "${DOC_DIR}/src/_binaries/Converters/testsData" # copy other files cp "${BASH_TOOLS_ROOT_DIR}/README.md" "${DOC_DIR}/README.md" diff --git a/bin/install b/bin/install index b8ff79bf..d6c2443f 100755 --- a/bin/install +++ b/bin/install @@ -1523,7 +1523,7 @@ installCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config bash-framework-config${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config ${__HELP_NORMAL} {single}" Array::wrap2 ' ' 76 4 " " "Use alternate bash framework configuration." echo @@ -1547,26 +1547,26 @@ installCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--env-file env-file${__HELP_NORMAL} {list} (optional)" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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" @@ -1579,7 +1579,7 @@ installCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--theme theme${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--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" diff --git a/bin/installRequirements b/bin/installRequirements index 8f8be3c8..1df2e575 100755 --- a/bin/installRequirements +++ b/bin/installRequirements @@ -1526,7 +1526,7 @@ installRequirementsCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config bash-framework-config${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config ${__HELP_NORMAL} {single}" Array::wrap2 ' ' 76 4 " " "Use alternate bash framework configuration." echo @@ -1550,26 +1550,26 @@ installRequirementsCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--env-file env-file${__HELP_NORMAL} {list} (optional)" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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" @@ -1582,7 +1582,7 @@ installRequirementsCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--theme theme${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--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" diff --git a/bin/mysql2puml b/bin/mysql2puml index 037f77bd..ca4279ee 100755 --- a/bin/mysql2puml +++ b/bin/mysql2puml @@ -1737,7 +1737,7 @@ mysql2pumlCommandHelp() { # ------------------------------------------ # 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]" "[--skin <>]" + 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]" "[--skin ]" ) Array::wrap2 " " 80 2 "${__HELP_TITLE_COLOR}USAGE:${__RESET_COLOR}" \ "mysql2puml" "${optionsAltList[@]}" @@ -1749,7 +1749,7 @@ mysql2pumlCommandHelp() { echo echo -e "${__HELP_TITLE_COLOR}ARGUMENTS:${__RESET_COLOR}" - Array::wrap2 " " 80 2 " [${__HELP_OPTION_COLOR}sqlFile${__HELP_NORMAL}{single}] + Array::wrap2 " " 80 2 " [${__HELP_OPTION_COLOR}sqlFile${__HELP_NORMAL} {single}] " Array::wrap2 ' ' 76 4 " " "Sql filepath to parse (read from stdin if not provided)." echo @@ -1770,7 +1770,7 @@ mysql2pumlCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config bash-framework-config${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--bash-framework-config ${__HELP_NORMAL} {single}" Array::wrap2 ' ' 76 4 " " "Use alternate bash framework configuration." echo @@ -1794,26 +1794,26 @@ mysql2pumlCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--env-file env-file${__HELP_NORMAL} {list} (optional)" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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}" + echo -e " ${__HELP_OPTION_COLOR}--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" @@ -1826,7 +1826,7 @@ mysql2pumlCommandHelp() { - echo -e " ${__HELP_OPTION_COLOR}--theme theme${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--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" @@ -1848,7 +1848,7 @@ mysql2pumlCommandHelp() { echo echo -e "${__HELP_TITLE_COLOR}OPTIONS:${__RESET_COLOR}" - echo -e " ${__HELP_OPTION_COLOR}--skin ${__HELP_NORMAL} {single}" + echo -e " ${__HELP_OPTION_COLOR}--skin ${__HELP_NORMAL} {single}" Array::wrap2 ' ' 76 4 " " "Header configuration of the plantuml file." echo diff --git a/src/BashTools/Conf/requireLoad.bats b/src/BashTools/Conf/requireLoad.bats index a94dcdc5..e0e77315 100755 --- a/src/BashTools/Conf/requireLoad.bats +++ b/src/BashTools/Conf/requireLoad.bats @@ -10,7 +10,6 @@ source "${rootDir}/src/BashTools/Conf/requireLoad.sh" setup() { export TMPDIR="${BATS_TEST_TMPDIR}" export HOME="${BATS_TEST_TMPDIR}/home" - export POSTMAN_API_KEY="fake" export BASH_FRAMEWORK_THEME="noColor" export bashToolsDefaultConfigTemplate="$(cat "${rootDir}/conf/.env")" } diff --git a/src/_binaries/Converters/mysql2puml/binary-mysql2puml.yaml b/src/_binaries/Converters/mysql2puml/binary-mysql2puml.yaml index 1c3cfd98..22e7a3b3 100644 --- a/src/_binaries/Converters/mysql2puml/binary-mysql2puml.yaml +++ b/src/_binaries/Converters/mysql2puml/binary-mysql2puml.yaml @@ -28,7 +28,7 @@ binData: type: String defaultValue: default help: Header configuration of the plantuml file. - helpValueName: + helpValueName: skin callbacks: - optionSkinCallback variableName: optionSkin diff --git a/src/_binaries/Converters/mysql2puml/testsData/mysql2puml.help.txt b/src/_binaries/Converters/mysql2puml/testsData/mysql2puml.help.txt index dd7e5764..897faea0 100644 --- a/src/_binaries/Converters/mysql2puml/testsData/mysql2puml.help.txt +++ b/src/_binaries/Converters/mysql2puml/testsData/mysql2puml.help.txt @@ -5,10 +5,10 @@ [--bash-framework-config ] [--verbose|-v] [-vv] [-vvv] [--env-file ] [--log-level ] [--log-file ] [--display-level ] [--no-color] [--theme ] [--version] - [--quiet|-q] [--skin <>] + [--quiet|-q] [--skin ] ARGUMENTS: - [sqlFile{single}] + [sqlFile {single}] Sql filepath to parse (read from stdin if not provided). GLOBAL OPTIONS: @@ -16,7 +16,7 @@ Displays this command help --config {single} Displays configuration - --bash-framework-config bash-framework-config {single} + --bash-framework-config  {single} Use alternate bash framework configuration. --verbose, -v {single} Info level verbose mode (alias of --display-level INFO) @@ -24,20 +24,20 @@ Debug level verbose mode (alias of --display-level DEBUG) -vvv {single} Trace level verbose mode (alias of --display-level TRACE) - --env-file env-file {list} (optional) + --env-file  {list} (optional) Load the specified env file (deprecated, please use --bash-framework-con fig option instead) - --log-level log-level {single} + --log-level  {single} Set log level Possible values: OFF, ERR, ERROR, WARN, WARNING, INFO, DEBUG, TRACE - --log-file log-file {single} + --log-file  {single} Set log file - --display-level display-level {single} + --display-level  {single} Set display level Possible values: OFF, ERR, ERROR, WARN, WARNING, INFO, DEBUG, TRACE --no-color {single} Produce monochrome output. alias of --theme noColor. - --theme theme {single} + --theme  {single} Choose color theme - default-force means colors will be produced even if command is piped. Possible values: default, default-force, noColor @@ -48,7 +48,7 @@ Quiet mode, doesn't display any output. OPTIONS: - --skin  {single} + --skin  {single} Header configuration of the plantuml file. Default value: default diff --git a/src/_binaries/Database/dbImport/binary-dbImport.yaml b/src/_binaries/Database/dbImport/binary-dbImport.yaml index ca17643a..0b291789 100644 --- a/src/_binaries/Database/dbImport/binary-dbImport.yaml +++ b/src/_binaries/Database/dbImport/binary-dbImport.yaml @@ -23,11 +23,11 @@ binData: commandName: dbImport beforeParseCallbacks: - beforeParseCallback + - initConf callbacks: - dbImportCommandCallback@100 definitionFiles: 20: ${BASH_TOOLS_ROOT_DIR}/src/_binaries/Database/dbImport/dbImport-options.sh - #99: ${BASH_TOOLS_ROOT_DIR}/src/_binaries/commandDefinitions/optionsDefault.sh mainFile: ${BASH_TOOLS_ROOT_DIR}/src/_binaries/Database/dbImport/dbImport-main.sh help: Import source db into target db using eventual table filter. args: @@ -35,7 +35,7 @@ binData: type: String min: 1 max: 1 - name: + name: fromDbName variableName: fromDbName - help: | diff --git a/src/_binaries/Database/dbImport/dbImport-main.sh b/src/_binaries/Database/dbImport/dbImport-main.sh index 08b69b22..9b228f6a 100755 --- a/src/_binaries/Database/dbImport/dbImport-main.sh +++ b/src/_binaries/Database/dbImport/dbImport-main.sh @@ -1,12 +1,6 @@ #!/usr/bin/env bash # @embed "${BASH_TOOLS_ROOT_DIR}/src/_binaries/DbImport/dumpSizeQuery.sql" AS dumpSizeQuery -declare TIMEFORMAT='time spent : %3R' -declare DB_IMPORT_DUMP_DIR=${DB_IMPORT_DUMP_DIR%/} -declare PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" -declare HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" -declare DOWNLOAD_DUMP=0 - # dump header/footer read -r -d '\0' DUMP_HEADER <<-EOM SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0; diff --git a/src/_binaries/Database/dbImport/dbImport-options.sh b/src/_binaries/Database/dbImport/dbImport-options.sh index 60bb1622..4dbceee9 100755 --- a/src/_binaries/Database/dbImport/dbImport-options.sh +++ b/src/_binaries/Database/dbImport/dbImport-options.sh @@ -8,6 +8,13 @@ declare versionNumber="2.0" declare optionBashFrameworkConfig="${BASH_TOOLS_ROOT_DIR}/.framework-config" declare defaultTargetCharacterSet="" +declare TIMEFORMAT='time spent : %3R' +declare DOWNLOAD_DUMP=0 + +declare DB_IMPORT_DUMP_DIR +declare PROFILES_DIR +declare HOME_PROFILES_DIR + beforeParseCallback() { BashTools::Conf::requireLoad Env::requireLoad @@ -17,6 +24,13 @@ beforeParseCallback() { Linux::requireExecutedAsUser } +initConf() { + # shellcheck disable=SC2034 + DB_IMPORT_DUMP_DIR=${DB_IMPORT_DUMP_DIR%/} + PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" + HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" +} + optionHelpCallback() { dbImportCommandHelp exit 0 diff --git a/src/_binaries/Database/dbImport/dbImport.bats b/src/_binaries/Database/dbImport/dbImport.bats index b2a4c0db..8462a9f2 100755 --- a/src/_binaries/Database/dbImport/dbImport.bats +++ b/src/_binaries/Database/dbImport/dbImport.bats @@ -41,7 +41,7 @@ function Database::dbImport::remoteDbName_not_provided { #@test run "${binDir}/dbImport" 2>&1 assert_failure 1 assert_lines_count 1 - assert_output --partial "ERROR - Command dbImport - Argument '' should be provided at least 1 time(s)" + assert_output --partial "ERROR - Command dbImport - Argument 'fromDbName' should be provided at least 1 time(s)" } function Database::dbImport::from_aws_and_aws_not_installed { #@test diff --git a/src/_binaries/Database/dbImport/testsData/dbImport.help.txt b/src/_binaries/Database/dbImport/testsData/dbImport.help.txt index 8447c2c7..29dc37e7 100644 --- a/src/_binaries/Database/dbImport/testsData/dbImport.help.txt +++ b/src/_binaries/Database/dbImport/testsData/dbImport.help.txt @@ -2,19 +2,19 @@ Import source db into target db using eventual table filter. USAGE: dbImport [OPTIONS] [ARGUMENTS] -USAGE: dbImport [--collation-name|-o <>] - [--target-dsn|-t <>] [--character-set|-c <>] - [--profile|-p <>] [--tables <>] - [--skip-schema|-s] [--from-dsn|-f <>] [--from-aws|-a <>] - [--help|-h] [--config] [--bash-framework-config ] - [--verbose|-v] [-vv] [-vvv] [--env-file ] [--log-level ] +USAGE: dbImport [--collation-name|-o ] + [--target-dsn|-t ] [--character-set|-c ] + [--profile|-p ] [--tables ] + [--skip-schema|-s] [--from-dsn|-f ] [--from-aws|-a ] [--help|-h] + [--config] [--bash-framework-config ] [--verbose|-v] + [-vv] [-vvv] [--env-file ] [--log-level ] [--log-file ] [--display-level ] [--no-color] [--theme ] [--version] [--quiet|-q] ARGUMENTS: - {single} (mandatory) + fromDbName {single} (mandatory) The name of the source/remote database. - [{single}] + [ {single}] The name of the target database Default value: (without extension) @@ -25,11 +25,11 @@ Import source db into target db using eventual table filter. --target-dsn, -t  {single} Dsn to use for target database. Default value: default.local - --character-set, -c  {single} + --character-set, -c  {single} Change the character set used during database creation. PROFILE OPTIONS: - --profile, -p  {single} + --profile, -p  {single} The name of the profile to use in order to include or exclude tables. Default value: default --tables  {single} @@ -54,7 +54,7 @@ Import source db into target db using eventual table filter. Displays this command help --config {single} Displays configuration - --bash-framework-config bash-framework-config {single} + --bash-framework-config  {single} Use alternate bash framework configuration. --verbose, -v {single} Info level verbose mode (alias of --display-level INFO) @@ -62,20 +62,20 @@ Import source db into target db using eventual table filter. Debug level verbose mode (alias of --display-level DEBUG) -vvv {single} Trace level verbose mode (alias of --display-level TRACE) - --env-file env-file {list} (optional) + --env-file  {list} (optional) Load the specified env file (deprecated, please use --bash-framework-con fig option instead) - --log-level log-level {single} + --log-level  {single} Set log level Possible values: OFF, ERR, ERROR, WARN, WARNING, INFO, DEBUG, TRACE - --log-file log-file {single} + --log-file  {single} Set log file - --display-level display-level {single} + --display-level  {single} Set display level Possible values: OFF, ERR, ERROR, WARN, WARNING, INFO, DEBUG, TRACE --no-color {single} Produce monochrome output. alias of --theme noColor. - --theme theme {single} + --theme  {single} Choose color theme - default-force means colors will be produced even if command is piped. Possible values: default, default-force, noColor diff --git a/src/_binaries/Database/dbImport/testsData/dbImportProfile.help.txt b/src/_binaries/Database/dbImport/testsData/dbImportProfile.help.txt deleted file mode 100644 index ee081e13..00000000 --- a/src/_binaries/Database/dbImport/testsData/dbImportProfile.help.txt +++ /dev/null @@ -1,89 +0,0 @@ -DESCRIPTION: generate optimized profiles to be used by dbImport -USAGE: dbImportProfile [OPTIONS] [ARGUMENTS] -USAGE: dbImportProfile [--profile|-p ] - [--from-dsn|-f ] [--ratio|-r ] - [--bash-framework-config ] [--config] [--verbose|-v] [-vv] [-vvv] - [--env-file ] [--no-color] [--theme ] [--help|-h] [--version] - [--quiet|-q] [--log-level ] [--log-file ] - [--display-level ] - -ARGUMENTS: - fromDbName {single} (mandatory) - the name of the source/remote database - -OPTIONS: - --profile, -p  {single} - the name of the profile to write in profiles directory. If not provided, th - e file name pattern will be 'auto__.sh' - --from-dsn, -f  {single} - dsn to use for source database (Default: default.remote) if not provided, th - e file name pattern will be 'auto__.sh' - --ratio, -r  {single} - define the ratio to use (0 to 100% - default 70). 0 means profile will filt - er out all the tables. 100 means profile will keep all the tables. Eg: - 70 means that tables with size(table+index) that are greater that 70% of - the max table size will be excluded. - -GLOBAL OPTIONS: - --bash-framework-config  {single} - use alternate bash framework configuration. - --config {single} - Display configuration - --verbose, -v {single} - info level verbose mode (alias of --display-level INFO) - -vv {single} - debug level verbose mode (alias of --display-level DEBUG) - -vvv {single} - trace level verbose mode (alias of --display-level TRACE) - --env-file  {list} (optional) - Load the specified env file (deprecated, please use --bash-framework-config - option instead) - --no-color {single} - Produce monochrome output. alias of --theme noColor. - --theme  {single} - choose color theme - default-force means colors will be produced even if com - mand is piped - Default value: default - Possible values: default|default-force|noColor - --help, -h {single} - Display this command help - --version {single} - Print version information and quit - --quiet, -q {single} - quiet mode, doesn't display any output - --log-level  {single} - Set log level - Possible values: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE - --log-file  {single} - Set log file - --display-level  {single} - set display level - Possible values: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE - -Default profiles directory: -/bash/conf/dbImportProfiles - -User profiles directory: -home/.bash-tools/dbImportProfiles -Allows to override profiles defined in Default profiles directory - -List of available profiles: - - -List of available dsn: - - default.local - - default.remote - - localhost-root - -VERSION: 2.0 - -AUTHOR: -[François Chastanet](https://github.com/fchastanet) - -SOURCE FILE: -https://github.com/fchastanet/bash-tools/tree/master/src/_binaries/DbImport/dbImportProfile.sh - -LICENSE: -MIT License - -Copyright (c) 2020-now François Chastanet diff --git a/src/_binaries/Database/dbImport/testsData/dbImportStream.help.txt b/src/_binaries/Database/dbImport/testsData/dbImportStream.help.txt deleted file mode 100644 index 0ff1b343..00000000 --- a/src/_binaries/Database/dbImport/testsData/dbImportStream.help.txt +++ /dev/null @@ -1,92 +0,0 @@ -DESCRIPTION: stream tar.gz file or gz file through mysql -USAGE: dbImportStream [OPTIONS] [ARGUMENTS] -USAGE: dbImportStream [--profile|-p ] - [--tables ] [--target-dsn|-t ] - [--character-set|-c ] [--bash-framework-config ] [--config] - [--verbose|-v] [-vv] [-vvv] [--env-file ] [--no-color] - [--theme ] [--help|-h] [--version] [--quiet|-q] [--log-level ] - [--log-file ] [--display-level ] - -ARGUMENTS: - argDumpFile {single} (mandatory) - the of the file that will be streamed through mysql - argTargetDbName {single} (mandatory) - the name of the mysql target database - -PROFILE OPTIONS: - --profile, -p  {single} - the name of the profile to use in order to include or exclude tables (if not - specified in default.sh from 'User profiles directory' if exists or 'Def - ault profiles directory') - --tables  {single} - import only table specified in the list. If aws mode, ignore profile option - -TARGET OPTIONS: - --target-dsn, -t  {single} - dsn to use for target database (Default: default.local) - --character-set, -c  {single} - change the character set used during database creation (default value: utf8) - -GLOBAL OPTIONS: - --bash-framework-config  {single} - use alternate bash framework configuration. - --config {single} - Display configuration - --verbose, -v {single} - info level verbose mode (alias of --display-level INFO) - -vv {single} - debug level verbose mode (alias of --display-level DEBUG) - -vvv {single} - trace level verbose mode (alias of --display-level TRACE) - --env-file  {list} (optional) - Load the specified env file (deprecated, please use --bash-framework-config - option instead) - --no-color {single} - Produce monochrome output. alias of --theme noColor. - --theme  {single} - choose color theme - default-force means colors will be produced even if com - mand is piped - Default value: default - Possible values: default|default-force|noColor - --help, -h {single} - Display this command help - --version {single} - Print version information and quit - --quiet, -q {single} - quiet mode, doesn't display any output - --log-level  {single} - Set log level - Possible values: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE - --log-file  {single} - Set log file - --display-level  {single} - set display level - Possible values: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE - -Default profiles directory: -/bash/conf/dbImportProfiles - -User profiles directory: -home/.bash-tools/dbImportProfiles -Allows to override profiles defined in Default profiles directory - -List of available profiles: - - -List of available dsn: - - default.local - - default.remote - - localhost-root - -VERSION: 2.0 - -AUTHOR: -[François Chastanet](https://github.com/fchastanet) - -SOURCE FILE: -https://github.com/fchastanet/bash-tools/tree/master/src/_binaries/DbImport/dbImportStream.sh - -LICENSE: -MIT License - -Copyright (c) 2020-now François Chastanet diff --git a/src/_binaries/Database/dbImport/testsData/dbImportTableDump.sql b/src/_binaries/Database/dbImport/testsData/dbImportTableDump.sql deleted file mode 100644 index e832194e..00000000 --- a/src/_binaries/Database/dbImport/testsData/dbImportTableDump.sql +++ /dev/null @@ -1,35 +0,0 @@ --- MySQL dump 10.13 Distrib 8.0.22, for Linux (x86_64) --- --- Host: 127.0.0.1 Database: fromDb --- ------------------------------------------------------ --- Server version 8.0.21 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!50503 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Dumping data for table `emptyTable` --- - -DROP TABLE IF EXISTS `dataTable`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `dataTable` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `modification_date` datetime NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=2011640 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - -LOCK TABLES `dataTable` WRITE; -/*!40000 ALTER TABLE `dataTable` DISABLE KEYS */; -INSERT INTO `dataTable` VALUES (1,1,'Picture:','en-GB'),(2,2,'Name:','en-GB'),(3,3,'First name:','en-GB'),(4,4,'Login:','en-GB'),(5,5,'Password:','en-GB'),(6,6,'E-mail:','en-GB'),(7,7,'Reference number:','en-GB'),(8,8,'Presentation:','en-GB'),(9,9,'Web:','en-GB'),(10,10,'Twitter:','en-GB'),(11,11,'LinkedIn:','en-GB'),(12,12,'Languages:','en-GB'),(13,13,'Time zone:','en-GB'); -/*!40000 ALTER TABLE `dataTable` ENABLE KEYS */; diff --git a/src/_binaries/Database/dbImport/testsData/empty-dump.sql b/src/_binaries/Database/dbImport/testsData/empty-dump.sql deleted file mode 100644 index c378ac9a..00000000 --- a/src/_binaries/Database/dbImport/testsData/empty-dump.sql +++ /dev/null @@ -1 +0,0 @@ --- EMPTY DUMP diff --git a/src/_binaries/Database/dbImport/testsData/expectedDbImportTableDump.sql b/src/_binaries/Database/dbImport/testsData/expectedDbImportTableDump.sql deleted file mode 100644 index 8291932a..00000000 --- a/src/_binaries/Database/dbImport/testsData/expectedDbImportTableDump.sql +++ /dev/null @@ -1,42 +0,0 @@ -SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0; -SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, AUTOCOMMIT = 0; -SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS = 0; --- MySQL dump 10.13 Distrib 8.0.22, for Linux (x86_64) --- --- Host: 127.0.0.1 Database: fromDb --- ------------------------------------------------------ --- Server version 8.0.21 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!50503 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Dumping data for table `emptyTable` --- - -DROP TABLE IF EXISTS `dataTable`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `dataTable` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `modification_date` datetime NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=2011640 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - -LOCK TABLES `dataTable` WRITE; -/*!40000 ALTER TABLE `dataTable` DISABLE KEYS */; -INSERT INTO `dataTable` VALUES (1,1,'Picture:','en-GB'),(2,2,'Name:','en-GB'),(3,3,'First name:','en-GB'),(4,4,'Login:','en-GB'),(5,5,'Password:','en-GB'),(6,6,'E-mail:','en-GB'),(7,7,'Reference number:','en-GB'),(8,8,'Presentation:','en-GB'),(9,9,'Web:','en-GB'),(10,10,'Twitter:','en-GB'),(11,11,'LinkedIn:','en-GB'),(12,12,'Languages:','en-GB'),(13,13,'Time zone:','en-GB'); -/*!40000 ALTER TABLE `dataTable` ENABLE KEYS */; -UNLOCK TABLES; -SET AUTOCOMMIT=@OLD_AUTOCOMMIT; -SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; -SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/src/_binaries/Database/dbImport/testsData/expectedDbImportTableDumpRenamed.sql b/src/_binaries/Database/dbImport/testsData/expectedDbImportTableDumpRenamed.sql deleted file mode 100644 index 2818b786..00000000 --- a/src/_binaries/Database/dbImport/testsData/expectedDbImportTableDumpRenamed.sql +++ /dev/null @@ -1,42 +0,0 @@ -SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0; -SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, AUTOCOMMIT = 0; -SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS = 0; --- MySQL dump 10.13 Distrib 8.0.22, for Linux (x86_64) --- --- Host: 127.0.0.1 Database: fromDb --- ------------------------------------------------------ --- Server version 8.0.21 - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!50503 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Dumping data for table `emptyTable` --- - -DROP TABLE IF EXISTS `newTableName`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `newTableName` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `modification_date` datetime NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=2011640 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - -LOCK TABLES `newTableName` WRITE; -/*!40000 ALTER TABLE `newTableName` DISABLE KEYS */; -INSERT INTO `newTableName` VALUES (1,1,'Picture:','en-GB'),(2,2,'Name:','en-GB'),(3,3,'First name:','en-GB'),(4,4,'Login:','en-GB'),(5,5,'Password:','en-GB'),(6,6,'E-mail:','en-GB'),(7,7,'Reference number:','en-GB'),(8,8,'Presentation:','en-GB'),(9,9,'Web:','en-GB'),(10,10,'Twitter:','en-GB'),(11,11,'LinkedIn:','en-GB'),(12,12,'Languages:','en-GB'),(13,13,'Time zone:','en-GB'); -/*!40000 ALTER TABLE `newTableName` ENABLE KEYS */; -UNLOCK TABLES; -SET AUTOCOMMIT=@OLD_AUTOCOMMIT; -SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; -SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; diff --git a/src/_binaries/Database/dbImport/testsData/tableSizeQuery.sql b/src/_binaries/Database/dbImport/testsData/tableSizeQuery.sql deleted file mode 100644 index e169bb05..00000000 --- a/src/_binaries/Database/dbImport/testsData/tableSizeQuery.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 0) AS size FROM information_schema.TABLES WHERE table_schema="fromDb" AND table_name='tableName' GROUP BY table_schema diff --git a/src/_binaries/Database/dbImportProfile/binary-dbImportProfile.yaml b/src/_binaries/Database/dbImportProfile/binary-dbImportProfile.yaml new file mode 100644 index 00000000..bbab2601 --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/binary-dbImportProfile.yaml @@ -0,0 +1,67 @@ +extends: + - "${BASH_TOOLS_ROOT_DIR}/src/_binaries/commandDefinitions/optionsVersion.yaml" + - "${FRAMEWORK_ROOT_DIR}/src/_binaries/commandDefinitions/defaultCommand.yaml" + - "${FRAMEWORK_ROOT_DIR}/src/_binaries/commandDefinitions/frameworkConfig.yaml" + +vars: + SRC_FILE_PATH: src/_binaries/Database/dbImportProfile/binary-dbImportProfile.yaml + +compilerConfig: + targetFile: "${BASH_TOOLS_ROOT_DIR}/bin/dbImportProfile" + relativeRootDirBasedOnTargetDir: .. + srcDirs: + - ${BASH_TOOLS_ROOT_DIR}/src +binData: + commands: + default: + functionName: dbImportProfileCommand + version: "2.0" + commandName: dbImportProfile + beforeParseCallbacks: + - beforeParseCallback + - initConf + callbacks: + - dbImportProfileCommandCallback@100 + definitionFiles: + 20: ${BASH_TOOLS_ROOT_DIR}/src/_binaries/Database/dbImportProfile/dbImportProfile-options.sh + 99: ${BASH_TOOLS_ROOT_DIR}/src/_binaries/commandDefinitions/optionsDefault.sh + mainFile: ${BASH_TOOLS_ROOT_DIR}/src/_binaries/Database/dbImportProfile/dbImportProfile-main.sh + help: Generate optimized profiles to be used by dbImport. + longDescription: longDescriptionFunction + options: + - variableName: optionProfile + group: OptionsGroup + type: String + help: optionProfileHelpFunction + helpValueName: profile + alts: + - --profile + - -p + + - variableName: optionFromDsn + group: OptionsGroup + type: String + defaultValue: default.remote + help: optionFromDsnHelpFunction + helpValueName: dsn + alts: + - --from-dsn + - -f + + - variableName: optionRatio + group: OptionsGroup + type: String + help: optionRatioHelpFunction + helpValueName: ratio + defaultValue: 70 + alts: + - --ratio + - -r + + args: + - help: The name of the source/remote database. + type: String + min: 1 + max: 1 + name: fromDbName + variableName: fromDbName diff --git a/src/_binaries/Database/dbImportProfile/dbImportProfile-main.sh b/src/_binaries/Database/dbImportProfile/dbImportProfile-main.sh new file mode 100755 index 00000000..0aecadda --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/dbImportProfile-main.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# other configuration +read -r -d '' QUERY <"${HOME_PROFILES_DIR}/${optionProfile}.sh" + +Log::displayInfo "File saved in '${HOME_PROFILES_DIR}/${optionProfile}.sh'" diff --git a/src/_binaries/Database/dbImportProfile/dbImportProfile-options.sh b/src/_binaries/Database/dbImportProfile/dbImportProfile-options.sh new file mode 100755 index 00000000..c5130972 --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/dbImportProfile-options.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +declare defaultFromDsn="default.remote" +# shellcheck disable=SC2034 +declare versionNumber="2.0" +# shellcheck disable=SC2034 +declare copyrightBeginYear="2020" +# shellcheck disable=SC2034 +declare PROFILES_DIR +declare HOME_PROFILES_DIR + +initConf() { + # shellcheck disable=SC2034 + PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" + HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" +} + +optionHelpCallback() { + dbImportProfileCommandHelp + exit 0 +} + +longDescriptionFunction() { + local profilesList="" + local dsnList="" + dsnList="$(Conf::getMergedList "dsn" "env")" + profilesList="$(Conf::getMergedList "dbImportProfiles" "sh" || true)" + + echo -e "${__HELP_TITLE}Default profiles directory:${__HELP_NORMAL}" + echo -e "${PROFILES_DIR-configuration error}" + echo + echo -e "${__HELP_TITLE}User profiles directory:${__HELP_NORMAL}" + echo -e "${HOME_PROFILES_DIR-configuration error}" + echo -e 'Allows to override profiles defined in "Default profiles directory"' + echo + echo -e "${__HELP_TITLE}List of available profiles:${__HELP_NORMAL}" + echo -e "${profilesList}" + echo + echo -e "${__HELP_TITLE}List of available dsn:${__HELP_NORMAL}" + echo -e "${dsnList}" +} + +optionProfileHelpFunction() { + Array::wrap2 " " 80 4 \ + " The name of the profile to write in profiles directory.\r" \ + "If not provided, the file name pattern will be 'auto__.sh'" + echo +} + +optionFromDsnHelpFunction() { + Array::wrap2 " " 80 4 \ + " dsn to use for source database (Default: ${defaultFromDsn})\r" \ + "if not provided, the file name pattern will be 'auto__.sh'" + echo +} + +optionRatioHelpFunction() { + Array::wrap2 " " 80 4 \ + " define the ratio to use (0 to 100% - default 70).\r" \ + "- 0 means profile will filter out all the tables\r" \ + "- 100 means profile will keep all the tables.\r" \ + "Eg: 70 means that tables with size(table+index)\r" \ + "that are greater than 70% of the max table size will be excluded." + echo +} + +dbImportProfileCommandCallback() { + if [[ -z "${fromDbName}" ]]; then + Log::fatal "you must provide fromDbName" + fi + + if [[ -z "${optionProfile}" ]]; then + # shellcheck disable=SC2154 + optionProfile="auto_${optionFromDsn}_${fromDbName}" + fi + + # shellcheck disable=SC2154 + if ! [[ "${optionRatio}" =~ ^-?[0-9]+$ ]]; then + Log::fatal "Ratio value should be a number" + fi + + if ((optionRatio < 0 || optionRatio > 100)); then + Log::fatal "Ratio value should be between 0 and 100" + fi +} diff --git a/src/_binaries/DbImport/dbImportProfile.bats b/src/_binaries/Database/dbImportProfile/dbImportProfile.bats similarity index 98% rename from src/_binaries/DbImport/dbImportProfile.bats rename to src/_binaries/Database/dbImportProfile/dbImportProfile.bats index 8e169b5a..57ee26f5 100755 --- a/src/_binaries/DbImport/dbImportProfile.bats +++ b/src/_binaries/Database/dbImportProfile/dbImportProfile.bats @@ -1,7 +1,7 @@ #!/usr/bin/env bash # shellcheck source=src/batsHeaders.sh -source "$(cd "${BATS_TEST_DIRNAME}/../.." && pwd)/batsHeaders.sh" +source "$(cd "${BATS_TEST_DIRNAME}/../../.." && pwd)/batsHeaders.sh" # shellcheck source=vendor/bash-tools-framework/src/Log/_.sh source "${FRAMEWORK_ROOT_DIR}/src/Log/_.sh" || exit 1 diff --git a/src/_binaries/Database/dbImport/testsData/auto_default.local_fromDb_20.sh b/src/_binaries/Database/dbImportProfile/testsData/auto_default.local_fromDb_20.sh similarity index 100% rename from src/_binaries/Database/dbImport/testsData/auto_default.local_fromDb_20.sh rename to src/_binaries/Database/dbImportProfile/testsData/auto_default.local_fromDb_20.sh diff --git a/src/_binaries/Database/dbImport/testsData/auto_default.local_fromDb_70.sh b/src/_binaries/Database/dbImportProfile/testsData/auto_default.local_fromDb_70.sh similarity index 100% rename from src/_binaries/Database/dbImport/testsData/auto_default.local_fromDb_70.sh rename to src/_binaries/Database/dbImportProfile/testsData/auto_default.local_fromDb_70.sh diff --git a/src/_binaries/Database/dbImportProfile/testsData/dbImportProfile.help.txt b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfile.help.txt new file mode 100644 index 00000000..18aa4a26 --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfile.help.txt @@ -0,0 +1,91 @@ +SYNOPSIS: Generate optimized profiles to be used by dbImport. + +USAGE: dbImportProfile [OPTIONS] [ARGUMENTS] +USAGE: dbImportProfile [--help|-h] [--config] + [--bash-framework-config ] [--verbose|-v] [-vv] [-vvv] + [--env-file ] [--log-level ] [--log-file ] + [--display-level ] [--no-color] [--theme ] [--version] + [--quiet|-q] [--profile|-p ] [--from-dsn|-f ] + [--ratio|-r ] + +ARGUMENTS: + fromDbName {single} (mandatory) + The name of the source/remote database. + +GLOBAL OPTIONS: + --help, -h {single} + Displays this command help + --config {single} + Displays configuration + --bash-framework-config  {single} + Use alternate bash framework configuration. + --verbose, -v {single} + Info level verbose mode (alias of --display-level INFO) + -vv {single} + Debug level verbose mode (alias of --display-level DEBUG) + -vvv {single} + Trace level verbose mode (alias of --display-level TRACE) + --env-file  {list} (optional) + Load the specified env file (deprecated, please use --bash-framework-con + fig option instead) + --log-level  {single} + Set log level + Possible values: OFF, ERR, ERROR, WARN, WARNING, INFO, DEBUG, TRACE + --log-file  {single} + Set log file + --display-level  {single} + Set display level + Possible values: OFF, ERR, ERROR, WARN, WARNING, INFO, DEBUG, TRACE + --no-color {single} + Produce monochrome output. alias of --theme noColor. + --theme  {single} + Choose color theme - default-force means colors will be produced even if + command is piped. + Possible values: default, default-force, noColor + Default value: default + --version {single} + Print version information and quit. + --quiet, -q {single} + Quiet mode, doesn't display any output. + +OPTIONS: + --profile, -p  {single} + The name of the profile to write in profiles directory. + If not provided, the file name pattern will be 'auto__.sh' + --from-dsn, -f  {single} + dsn to use for source database (Default: default.remote) + if not provided, the file name pattern will be 'auto__.sh' + Default value: default.remote + --ratio, -r  {single} + define the ratio to use (0 to 100% - default 70). + - 0 means profile will filter out all the tables + - 100 means profile will keep all the tables. + Eg: 70 means that tables with size(table+index) + that are greater than 70% of the max table size will be excluded. + Default value: 70 + + +DESCRIPTION: +Default profiles directory: +/bash/conf/dbImportProfiles + +User profiles directory: +home/.bash-tools/dbImportProfiles +Allows to override profiles defined in "Default profiles directory" + +List of available profiles: + + +List of available dsn: + - default.local + - default.remote + - localhost-root + +VERSION: 2.0 + +AUTHOR: [François Chastanet](https://github.com/fchastanet) + +SOURCE FILE: https://github.com/fchastanet/bash-tools-framework/tree/master/src/_binaries/Database/dbImportProfile/binary-dbImportProfile.yaml + +LICENSE: MIT License +Copyright (c) 2020-now François Chastanet diff --git a/src/_binaries/Database/dbImport/testsData/dbImportProfile.tableList1 b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfile.tableList1 similarity index 100% rename from src/_binaries/Database/dbImport/testsData/dbImportProfile.tableList1 rename to src/_binaries/Database/dbImportProfile/testsData/dbImportProfile.tableList1 diff --git a/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/all.sh b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/all.sh new file mode 100755 index 00000000..09b79b19 --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/all.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +# cat represents the whole list of tables +cat diff --git a/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/default.sh b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/default.sh new file mode 100755 index 00000000..8cf9b92b --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/default.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# cat represents the whole list of tables +cat | + grep -v '.*_log' | + grep -v '.*logs' | + grep -v '.*tracking' | + grep -v '.*stats' | + grep -v '.*history.*' | + # always finish by a cat to be sure the command does not return exit code != 0 + cat || { + # avoid failure on premature process close (check Bash::handlePipelineFailure) + declare exitCode=$?; if (( exitCode == 141 )); then exit 0; fi + exit "${exitCode}" + } diff --git a/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/none.sh b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/none.sh new file mode 100755 index 00000000..5604fdca --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/testsData/dbImportProfiles/none.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +# useful if you want to dump only the db structure + +# cat represents the whole list of tables +echo 'propel_migration' diff --git a/src/_binaries/Database/dbImportProfile/testsData/dsn/default.local.env b/src/_binaries/Database/dbImportProfile/testsData/dsn/default.local.env new file mode 100644 index 00000000..ccb2e265 --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/testsData/dsn/default.local.env @@ -0,0 +1,13 @@ +# shellcheck disable=SC2034 +HOSTNAME=127.0.0.1 +PASSWORD=root +PORT=3306 +USER=root + +# you can override default MYSQL options if you wish +# SSL_OPTIONS=--ssl-mode=DISABLED +# QUERY_OPTIONS=--batch --raw --default-character-set=utf8 +# DUMP_OPTIONS=--default-character-set=utf8 --compression-algorithms --hex-blob --routines --triggers --single-transaction --set-gtid-purged=OFF --column-statistics=0 + +# specific options during import +DB_IMPORT_OPTIONS= diff --git a/src/_binaries/Database/dbImportProfile/testsData/dsn/default.remote.env b/src/_binaries/Database/dbImportProfile/testsData/dsn/default.remote.env new file mode 100644 index 00000000..1958d45e --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/testsData/dsn/default.remote.env @@ -0,0 +1,12 @@ +HOSTNAME=127.0.0.1 +PASSWORD=root +PORT=3306 +USER=root + +# you can override default MYSQL options if you wish +# SSL_OPTIONS=--ssl-mode=DISABLED +# QUERY_OPTIONS=--batch --raw --default-character-set=utf8 +# DUMP_OPTIONS=--default-character-set=utf8 --compression-algorithms --hex-blob --routines --triggers --single-transaction --set-gtid-purged=OFF --column-statistics=0 + +# specific options during import +DB_IMPORT_OPTIONS= diff --git a/src/_binaries/Database/dbImportProfile/testsData/dsn/localhost-root.env b/src/_binaries/Database/dbImportProfile/testsData/dsn/localhost-root.env new file mode 100644 index 00000000..1958d45e --- /dev/null +++ b/src/_binaries/Database/dbImportProfile/testsData/dsn/localhost-root.env @@ -0,0 +1,12 @@ +HOSTNAME=127.0.0.1 +PASSWORD=root +PORT=3306 +USER=root + +# you can override default MYSQL options if you wish +# SSL_OPTIONS=--ssl-mode=DISABLED +# QUERY_OPTIONS=--batch --raw --default-character-set=utf8 +# DUMP_OPTIONS=--default-character-set=utf8 --compression-algorithms --hex-blob --routines --triggers --single-transaction --set-gtid-purged=OFF --column-statistics=0 + +# specific options during import +DB_IMPORT_OPTIONS= diff --git a/src/_binaries/Database/dbImport/testsData/expectedDbImportProfileTableListQuery.sql b/src/_binaries/Database/dbImportProfile/testsData/expectedDbImportProfileTableListQuery.sql similarity index 100% rename from src/_binaries/Database/dbImport/testsData/expectedDbImportProfileTableListQuery.sql rename to src/_binaries/Database/dbImportProfile/testsData/expectedDbImportProfileTableListQuery.sql diff --git a/src/_binaries/DbImport/dbImport.options.tpl b/src/_binaries/DbImport/dbImport.options.tpl deleted file mode 100644 index 680c4f31..00000000 --- a/src/_binaries/DbImport/dbImport.options.tpl +++ /dev/null @@ -1,141 +0,0 @@ -% -declare versionNumber="2.0" -declare commandFunctionName="dbImportCommand" -declare help="Import source db into target db using eventual table filter" -# shellcheck disable=SC2016 -declare longDescription=''' -${__HELP_TITLE}Default profiles directory:${__HELP_NORMAL} -${PROFILES_DIR-configuration error} - -${__HELP_TITLE}User profiles directory:${__HELP_NORMAL} -${HOME_PROFILES_DIR-configuration error} -Allows to override profiles defined in "Default profiles directory" - -${__HELP_TITLE}List of available profiles:${__HELP_NORMAL} -${profilesList} - -${__HELP_TITLE}List of available dsn:${__HELP_NORMAL} -${dsnList} - -${__HELP_TITLE}Aws s3 location:${__HELP_NORMAL} -${S3_BASE_URL} - -${__HELP_TITLE}Example 1: from one database to another one${__HELP_NORMAL} -${__HELP_EXAMPLE}TODO${__HELP_NORMAL} - -${__HELP_TITLE}Example 2: import from S3${__HELP_NORMAL} -${__HELP_EXAMPLE}TODO${__HELP_NORMAL}''' -# shellcheck disable=SC2116 -declare defaultFromDsnHelp=$'dsn to use for source database\n - this option is incompatible with -a|--from-aws option' - -% - -.INCLUDE "$(dynamicTemplateDir _binaries/options/options.base.tpl)" -.INCLUDE "$(dynamicTemplateDir _binaries/options/options.dsn.tpl)" -.INCLUDE "$(dynamicTemplateDir _binaries/options/options.profile.tpl)" -.INCLUDE "$(dynamicTemplateDir _binaries/options/options.mysql.target.tpl)" -.INCLUDE "$(dynamicTemplateDir _binaries/options/options.mysql.collationName.tpl)" - -% -# shellcheck source=/dev/null -source <( - Options::generateGroup \ - --title "FROM OPTIONS:" \ - --function-name groupSourceDbOptionsFunction - - Options::generateOption \ - --help "avoid to import the schema" \ - --group groupSourceDbOptionsFunction \ - --alt "--skip-schema" \ - --alt "-s" \ - --variable-name "optionSkipSchema" \ - --function-name optionSkipSchemaFunction - - # shellcheck disable=SC2116 - Options::generateOption \ - --help-value-name "awsFile" \ - --help "$(echo \ - "db dump will be downloaded from s3 instead of using remote db." \ - "The value is the name of the file without s3 location" \ - "(Only .gz or tar.gz file are supported)." \ - "This option is incompatible with -f|--from-dsn option" \ - )" \ - --group groupSourceDbOptionsFunction \ - --alt "--from-aws" \ - --alt "-a" \ - --variable-type "String" \ - --variable-name "optionFromAws" \ - --function-name optionFromAwsFunction - - Options::generateArg \ - --help "the name of the source/remote database" \ - --min 1 \ - --max 1 \ - --name "fromDbName" \ - --variable-name "fromDbName" \ - --function-name argumentFromDbNameFunction - - Options::generateArg \ - --help "the name of the target database, use fromDbName(without extension) if not provided" \ - --variable-name "targetDbName" \ - --min 0 \ - --max 1 \ - --name "targetDbName" \ - --function-name argumentTargetDbNameFunction -) -options+=( - optionSkipSchemaFunction - optionFromAwsFunction - argumentFromDbNameFunction - argumentTargetDbNameFunction - --callback dbImportCommandCallback -) -Options::generateCommand "${options[@]}" -% - -.INCLUDE "$(dynamicTemplateDir _includes/dbTools.requirements.tpl)" - -optionHelpCallback() { - local profilesList="" - local dsnList="" - dsnList="$(Conf::getMergedList "dsn" "env")" - profilesList="$(Conf::getMergedList "dbImportProfiles" "sh" || true)" - - <% ${commandFunctionName} %> help | envsubst - checkRequirements - exit 0 -} - -dbImportCommandCallback() { - if [[ -z "${targetDbName}" ]]; then - targetDbName="${fromDbName}" - fi - - if [[ -n "${optionFromAws}" ]]; then - Assert::commandExists aws \ - "Command ${SCRIPT_NAME} - missing aws, please check https://docs.aws.amazon.com/fr_fr/cli/latest/userguide/install-cliv2.html" || exit 1 - - if [[ -n "${optionFromDsn}" ]]; then - Log::fatal "Command ${SCRIPT_NAME} - you cannot use from-dsn and from-aws at the same time" - fi - - if [[ -z "${S3_BASE_URL}" ]]; then - Log::fatal "Command ${SCRIPT_NAME} - missing S3_BASE_URL, please provide a value in .env file" - fi - elif [[ -z "${optionFromDsn}" ]]; then - # default value for FROM_DSN if from-aws not set - optionFromDsn="<% ${defaultFromDsn} %>" - fi - - if [[ -z "${DB_IMPORT_DUMP_DIR}" ]]; then - Log::fatal "Command ${SCRIPT_NAME} -you have to specify a value for DB_IMPORT_DUMP_DIR env variable" - fi - - if [[ ! -d "${DB_IMPORT_DUMP_DIR}" ]]; then - mkdir -p "${DB_IMPORT_DUMP_DIR}" || - Log::fatal "Command ${SCRIPT_NAME} -impossible to create directory ${DB_IMPORT_DUMP_DIR} specified by DB_IMPORT_DUMP_DIR env variable" - fi -} - -<% ${commandFunctionName} %> parse "${BASH_FRAMEWORK_ARGV[@]}" diff --git a/src/_binaries/DbImport/dbImport.sh b/src/_binaries/DbImport/dbImport.sh deleted file mode 100755 index 93bf1486..00000000 --- a/src/_binaries/DbImport/dbImport.sh +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env bash -# BIN_FILE=${BASH_TOOLS_ROOT_DIR}/bin/dbImport -# VAR_RELATIVE_FRAMEWORK_DIR_TO_CURRENT_DIR=.. -# FACADE -# shellcheck disable=SC2034 - -# default values -declare optionFromAws="" -declare optionSkipSchema="0" -declare targetDbName="" -declare fromDbName="" -declare optionProfile="default" -declare optionTables="" -declare profileCommandFile="" -declare optionTargetDsn="" -declare optionCharacterSet="" -declare defaultTargetCharacterSet="" - -# other configuration -declare copyrightBeginYear="2020" -declare TIMEFORMAT='time spent : %3R' -declare DB_IMPORT_DUMP_DIR=${DB_IMPORT_DUMP_DIR%/} -declare PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" -declare HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" -declare DOWNLOAD_DUMP=0 - -# dump header/footer -read -r -d '\0' DUMP_HEADER <<-EOM - SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0; - SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, AUTOCOMMIT = 0; - SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS = 0;\0 -EOM - -read -r -d '\0' DUMP_FOOTER <<-EOM2 - COMMIT; - SET AUTOCOMMIT=@OLD_AUTOCOMMIT; - SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; - SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;\0 -EOM2 - -# @embed "${BASH_TOOLS_ROOT_DIR}/src/_binaries/DbImport/dumpSizeQuery.sql" AS dumpSizeQuery -# @require Linux::requireExecutedAsUser -run() { - # create db instances - declare -Agx dbFromInstance dbTargetDatabase - - # shellcheck disable=SC2154 - Database::newInstance dbTargetDatabase "${optionTargetDsn}" - # shellcheck disable=SC2154 - Database::setQueryOptions dbTargetDatabase "${dbTargetDatabase[QUERY_OPTIONS]} --connect-timeout=5" - Log::displayInfo "Using target dsn ${dbTargetDatabase['DSN_FILE']}" - if [[ -z "${optionFromAws}" ]]; then - # shellcheck disable=SC2154 - Database::newInstance dbFromInstance "${optionFromDsn}" - Database::setQueryOptions dbFromInstance "${dbFromInstance[QUERY_OPTIONS]} --connect-timeout=5" - Log::displayInfo "Using from dsn ${dbFromInstance['DSN_FILE']}" - fi - - local remoteDbDumpTempFile - local remoteDbStructureDumpTempFile - if [[ -n "${optionFromAws}" ]]; then - remoteDbDumpTempFile="${DB_IMPORT_DUMP_DIR}/${optionFromAws}" - else - # shellcheck disable=SC2154 - remoteDbDumpTempFile="${DB_IMPORT_DUMP_DIR}/${fromDbName}_${optionProfile}.sql.gz" - remoteDbStructureDumpTempFile="${DB_IMPORT_DUMP_DIR}/${fromDbName}_${optionProfile}_structure.sql.gz" - fi - - # check if local dump exists - local downloadDump=0 - if [[ ! -f "${remoteDbDumpTempFile}" ]]; then - Log::displayInfo "local dump does not exist" - downloadDump=1 - fi - if [[ -z "${optionFromAws}" && ! -f "${remoteDbStructureDumpTempFile}" ]]; then - Log::displayInfo "local structure dump does not exist" - downloadDump=1 - fi - if [[ "${downloadDump}" = "0" ]]; then - Log::displayInfo "local dump ${remoteDbDumpTempFile} already exists, avoid download" - fi - - Log::displayInfo "tables list will calculated using profile ${optionProfile} => ${profileCommandFile}" - SECONDS=0 - if [[ "${downloadDump}" = "1" ]]; then - Log::displayInfo "Download dump" - - if [[ -n "${optionFromAws}" ]]; then - # download dump from s3 - local s3Url="${S3_BASE_URL%/}/${optionFromAws}" - aws s3 ls --human-readable "${s3Url}" || { - Log::fatal "Command ${SCRIPT_NAME} - unable to get information on S3 object : ${s3Url}" - } - Log::displayInfo "Download dump from ${s3Url} ..." - TMPDIR="${TMDIR:-/tmp}" aws s3 cp "${s3Url}" "${remoteDbDumpTempFile}" || { - Log::fatal "Command ${SCRIPT_NAME} - unable to download dump from S3 : ${s3Url}" - } - else - # check if remote db exists - Database::ifDbExists dbFromInstance "${fromDbName}" || { - Log::fatal "Command ${SCRIPT_NAME} - Remote Database ${fromDbName} does not exist" - } - - initializeDefaultTargetMysqlOptions dbFromInstance "${fromDbName}" - - local dumpHeader - dumpHeader=$(printf "%s\nSET names '%s';\n" "${DUMP_HEADER}" "${optionCharacterSet}") - - # calculate remote db dump size - local listTables - local listTablesDumpSize - local listTablesDump - listTables="$(Database::query dbFromInstance "show tables" "${fromDbName}" | ${profileCommandFile} | sort)" - # shellcheck disable=SC2034 # used by DUMP_SIZE_QUERY - listTablesDumpSize="$(echo "${listTables}" | awk -v d="," -v q="'" '{s=(NR==1?s:s d)q $0 q}END{print s }')" - listTablesDump=$(echo "${listTables}" | awk -v d=" " -v q="" '{s=(NR==1?s:s d)q $0 q}END{print s }') - - Log::displayInfo "Calculate dump size for tables ${listTablesDump}" - local remoteDbDumpSize - # shellcheck disable=SC2154 - remoteDbDumpSize=$(envsubst <"${embed_file_dumpSizeQuery}" | Database::query dbFromInstance) - if [[ -z "${remoteDbDumpSize}" ]]; then - # could occur with the none profile - remoteDbDumpSize="0" - fi - - # dump db - Log::displayInfo "Dump the database ${fromDbName} (Size:${remoteDbDumpSize}MB) ..." - local dumpSizePvEstimation - dumpSizePvEstimation=$(awk "BEGIN {printf \"%.0f\",${remoteDbDumpSize}/1.5}") - time ( - echo "${dumpHeader}" - Database::dump dbFromInstance "${fromDbName}" "${listTablesDump}" \ - --no-create-info --skip-add-drop-table --single-transaction=TRUE | - pv --progress --size "${dumpSizePvEstimation}m" - echo "${DUMP_FOOTER}" - ) | gzip >"${remoteDbDumpTempFile}" - - Log::displayInfo "Dump structure of the database ${fromDbName} ..." - time ( - echo "${dumpHeader}" - #shellcheck disable=SC2016 - Database::dump dbFromInstance "${fromDbName}" "" \ - --no-data --skip-add-drop-table --single-transaction=TRUE | - sed 's/^CREATE TABLE `/CREATE TABLE IF NOT EXISTS `/g' - echo "${DUMP_FOOTER}" - ) | gzip >"${remoteDbStructureDumpTempFile}" - fi - Log::displayInfo "Dump done." - fi - - # mark dumps as modified now to avoid them to be garbage collected - touch -c -m "${remoteDbDumpTempFile}" || true - touch -c -m "${remoteDbStructureDumpTempFile}" || true - - # TODO Collation and character set should be retrieved from dump files if possible - # shellcheck disable=SC2154 - local targetCollationName="${optionCollationName:-${defaultTargetCollationName}}" - # shellcheck disable=SC2154 - local targetCharacterSet="${optionCharacterSet:-${defaultTargetCharacterSet}}" - - # shellcheck disable=SC2154 - Log::displayInfo "create target database ${targetDbName} if needed" - #shellcheck disable=SC2016 - Database::query dbTargetDatabase \ - "$(printf 'CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET "%s" COLLATE "%s"' "${targetDbName}" "${targetCharacterSet}" "${targetCollationName}")" - - if [[ -z "${optionFromAws}" ]]; then - Database::setQueryOptions dbTargetDatabase "${dbTargetDatabase['DB_IMPORT_OPTIONS']}" - Log::displayInfo "Importing remote db '${fromDbName}' to local db '${targetDbName}'" - # shellcheck disable=SC2154 - if [[ "${optionSkipSchema}" = "1" ]]; then - Log::displayInfo "avoid to create db structure" - else - Log::displayInfo "create db structure from ${remoteDbStructureDumpTempFile}" - # shellcheck disable=SC2034 - local status=0 - # shellcheck disable=SC2034 - local -a pipeStatus=() - time ( - pv "${remoteDbStructureDumpTempFile}" | zcat | - Database::query dbTargetDatabase "" "${targetDbName}" || Bash::handlePipelineFailure status pipeStatus - ) - fi - fi - Log::displayInfo "import remote to local from file ${remoteDbDumpTempFile}" - local -a dbImportStreamOptions=( - --profile "${optionProfile}" - --target-dsn "${optionTargetDsn}" - --character-set "${targetCharacterSet}" - ) - if [[ -n "${optionTables:-}" ]]; then - dbImportStreamOptions+=( - --tables "${optionTables}" - ) - fi - time ( - "${CURRENT_DIR}/dbImportStream" \ - "${dbImportStreamOptions[@]}" \ - "${remoteDbDumpTempFile}" \ - "${targetDbName}" - - ) - - # garbage collect db import dumps - File::garbageCollect "${DB_IMPORT_DUMP_DIR}" "${DB_IMPORT_GARBAGE_COLLECT_DAYS:-+30}" || true - - Log::displayInfo "Import database duration : $(date -u -d "@${SECONDS}" +"%T")" -} - -if [[ "${BASH_FRAMEWORK_QUIET_MODE:-0}" = "1" ]]; then - run &>/dev/null -else - run -fi diff --git a/src/_binaries/DbImport/dbImportProfile.options.tpl b/src/_binaries/DbImport/dbImportProfile.options.tpl deleted file mode 100644 index a89a6ca6..00000000 --- a/src/_binaries/DbImport/dbImportProfile.options.tpl +++ /dev/null @@ -1,110 +0,0 @@ -% -declare versionNumber="2.0" -declare commandFunctionName="dbImportProfileCommand" -declare help="generate optimized profiles to be used by dbImport" -# shellcheck disable=SC2016 -declare longDescription=''' -${__HELP_TITLE}Default profiles directory:${__HELP_NORMAL} -${PROFILES_DIR-configuration error} - -${__HELP_TITLE}User profiles directory:${__HELP_NORMAL} -${HOME_PROFILES_DIR-configuration error} -Allows to override profiles defined in "Default profiles directory" - -${__HELP_TITLE}List of available profiles:${__HELP_NORMAL} -${profilesList} - -${__HELP_TITLE}List of available dsn:${__HELP_NORMAL} -${dsnList}''' -declare defaultFromDsn="default.remote" -% - -.INCLUDE "$(dynamicTemplateDir _binaries/options/options.base.tpl)" - -% -# shellcheck source=/dev/null -source <( - # shellcheck disable=SC2116 - Options::generateOption \ - --help "$(echo \ - "the name of the profile to write in profiles directory. " \ - "If not provided, the file name pattern will be 'auto__.sh'" \ - )" \ - --variable-type "String" \ - --alt "--profile" \ - --alt "-p" \ - --variable-name "optionProfile" \ - --function-name optionProfileFunction - - # shellcheck disable=SC2116 - Options::generateOption \ - --help "$(echo \ - "dsn to use for source database (Default: ${defaultFromDsn})" \ - "if not provided, the file name pattern will be 'auto__.sh'" \ - )" \ - --variable-type "String" \ - --alt "--from-dsn" \ - --alt "-f" \ - --variable-name "optionFromDsn" \ - --function-name optionFromDsnFunction - - # shellcheck disable=SC2116 - Options::generateOption \ - --help "$(echo -e "define the ratio to use (0 to 100% - default 70). " \ - "0 means profile will filter out all the tables. " \ - "100 means profile will keep all the tables. " \ - "Eg: 70 means that tables with size(table+index) that are greater that 70% of the max table size will be excluded." \ - )" \ - --variable-type "String" \ - --alt "--ratio" \ - --alt "-r" \ - --variable-name "optionRatio" \ - --function-name optionRatioFunction - - Options::generateArg \ - --help "the name of the source/remote database" \ - --min 1 \ - --max 1 \ - --name "fromDbName" \ - --variable-name "fromDbName" \ - --function-name argumentFromDbNameFunction -) -options+=( - optionProfileFunction - optionFromDsnFunction - optionRatioFunction - argumentFromDbNameFunction - --callback dbImportProfileCommandCallback -) -Options::generateCommand "${options[@]}" -% - -optionHelpCallback() { - local profilesList="" - local dsnList="" - dsnList="$(Conf::getMergedList "dsn" "env")" - profilesList="$(Conf::getMergedList "dbImportProfiles" "sh" || true)" - - <% ${commandFunctionName} %> help | envsubst - exit 0 -} - -dbImportProfileCommandCallback() { - if [[ -z "${fromDbName}" ]]; then - Log::fatal "you must provide fromDbName" - fi - - if [[ -z "${optionProfile}" ]]; then - optionProfile="auto_${optionFromDsn}_${fromDbName}.sh" - fi - - if ! [[ "${optionRatio}" =~ ^-?[0-9]+$ ]]; then - Log::fatal "Ratio value should be a number" - fi - - if ((optionRatio < 0 || optionRatio > 100)); then - Log::fatal "Ratio value should be between 0 and 100" - fi -} - -<% ${commandFunctionName} %> parse "${BASH_FRAMEWORK_ARGV[@]}" diff --git a/src/_binaries/DbImport/dbImportProfile.sh b/src/_binaries/DbImport/dbImportProfile.sh deleted file mode 100755 index 8f8b2a60..00000000 --- a/src/_binaries/DbImport/dbImportProfile.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -# BIN_FILE=${BASH_TOOLS_ROOT_DIR}/bin/dbImportProfile -# VAR_RELATIVE_FRAMEWORK_DIR_TO_CURRENT_DIR=.. -# FACADE -# shellcheck disable=SC2034 - -# default values -declare optionProfile="" -declare fromDbName="" -declare optionFromDsn="default.remote" -declare optionRatio=70 - -# other configuration -declare copyrightBeginYear="2020" -declare PROFILES_DIR="${BASH_TOOLS_ROOT_DIR}/conf/dbImportProfiles" -declare HOME_PROFILES_DIR="${HOME}/.bash-tools/dbImportProfiles" - -.INCLUDE "$(dynamicTemplateDir _binaries/DbImport/dbImportProfile.options.tpl)" - -read -r -d '' QUERY <"${HOME_PROFILES_DIR}/${optionProfile}" - - Log::displayInfo "File saved in '${HOME_PROFILES_DIR}/${optionProfile}'" -} - -if [[ "${BASH_FRAMEWORK_QUIET_MODE:-0}" = "1" ]]; then - run &>/dev/null -else - run -fi diff --git a/src/_binaries/DbImport/dbImportStream.options.tpl b/src/_binaries/DbImport/dbImportStream.options.tpl index 90a5a648..10ea9b5e 100644 --- a/src/_binaries/DbImport/dbImportStream.options.tpl +++ b/src/_binaries/DbImport/dbImportStream.options.tpl @@ -61,7 +61,7 @@ optionHelpCallback() { profilesList="$(Conf::getMergedList "dbImportProfiles" "sh" || true)" <% ${commandFunctionName} %> help | envsubst - checkRequirements + Db::checkRequirements exit 0 } diff --git a/src/_binaries/DbImport/testsData/dbImportProfile.help.txt b/src/_binaries/DbImport/testsData/dbImportProfile.help.txt deleted file mode 100644 index ee081e13..00000000 --- a/src/_binaries/DbImport/testsData/dbImportProfile.help.txt +++ /dev/null @@ -1,89 +0,0 @@ -DESCRIPTION: generate optimized profiles to be used by dbImport -USAGE: dbImportProfile [OPTIONS] [ARGUMENTS] -USAGE: dbImportProfile [--profile|-p ] - [--from-dsn|-f ] [--ratio|-r ] - [--bash-framework-config ] [--config] [--verbose|-v] [-vv] [-vvv] - [--env-file ] [--no-color] [--theme ] [--help|-h] [--version] - [--quiet|-q] [--log-level ] [--log-file ] - [--display-level ] - -ARGUMENTS: - fromDbName {single} (mandatory) - the name of the source/remote database - -OPTIONS: - --profile, -p  {single} - the name of the profile to write in profiles directory. If not provided, th - e file name pattern will be 'auto__.sh' - --from-dsn, -f  {single} - dsn to use for source database (Default: default.remote) if not provided, th - e file name pattern will be 'auto__.sh' - --ratio, -r  {single} - define the ratio to use (0 to 100% - default 70). 0 means profile will filt - er out all the tables. 100 means profile will keep all the tables. Eg: - 70 means that tables with size(table+index) that are greater that 70% of - the max table size will be excluded. - -GLOBAL OPTIONS: - --bash-framework-config  {single} - use alternate bash framework configuration. - --config {single} - Display configuration - --verbose, -v {single} - info level verbose mode (alias of --display-level INFO) - -vv {single} - debug level verbose mode (alias of --display-level DEBUG) - -vvv {single} - trace level verbose mode (alias of --display-level TRACE) - --env-file  {list} (optional) - Load the specified env file (deprecated, please use --bash-framework-config - option instead) - --no-color {single} - Produce monochrome output. alias of --theme noColor. - --theme  {single} - choose color theme - default-force means colors will be produced even if com - mand is piped - Default value: default - Possible values: default|default-force|noColor - --help, -h {single} - Display this command help - --version {single} - Print version information and quit - --quiet, -q {single} - quiet mode, doesn't display any output - --log-level  {single} - Set log level - Possible values: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE - --log-file  {single} - Set log file - --display-level  {single} - set display level - Possible values: OFF|ERR|ERROR|WARN|WARNING|INFO|DEBUG|TRACE - -Default profiles directory: -/bash/conf/dbImportProfiles - -User profiles directory: -home/.bash-tools/dbImportProfiles -Allows to override profiles defined in Default profiles directory - -List of available profiles: - - -List of available dsn: - - default.local - - default.remote - - localhost-root - -VERSION: 2.0 - -AUTHOR: -[François Chastanet](https://github.com/fchastanet) - -SOURCE FILE: -https://github.com/fchastanet/bash-tools/tree/master/src/_binaries/DbImport/dbImportProfile.sh - -LICENSE: -MIT License - -Copyright (c) 2020-now François Chastanet diff --git a/src/_binaries/DbQueryAllDatabases/dbQueryAllDatabases.options.tpl b/src/_binaries/DbQueryAllDatabases/dbQueryAllDatabases.options.tpl index 596be118..4cba7255 100644 --- a/src/_binaries/DbQueryAllDatabases/dbQueryAllDatabases.options.tpl +++ b/src/_binaries/DbQueryAllDatabases/dbQueryAllDatabases.options.tpl @@ -80,7 +80,7 @@ optionHelpCallback() { queriesList="$(Conf::getMergedList "dbQueries" "sql" || true)" <% ${commandFunctionName} %> help | envsubst - checkRequirements + Db::checkRequirements exit 0 } diff --git a/src/_binaries/build/doc/doc-main.sh b/src/_binaries/build/doc/doc-main.sh index ea5fb2ea..9bfb7a76 100755 --- a/src/_binaries/build/doc/doc-main.sh +++ b/src/_binaries/build/doc/doc-main.sh @@ -90,7 +90,7 @@ generateDoc() { "${DOC_DIR}/Commands.md" mkdir -p "${DOC_DIR}/src/_binaries/Converters/testsData" || true - cp "${BASH_TOOLS_ROOT_DIR}/src/_binaries/Converters/testsData/mysql2puml-model.png" "${DOC_DIR}/src/_binaries/Converters/testsData" + cp "${BASH_TOOLS_ROOT_DIR}/src/_binaries/Converters/mysql2puml/testsData/mysql2puml-model.png" "${DOC_DIR}/src/_binaries/Converters/testsData" # copy other files cp "${BASH_TOOLS_ROOT_DIR}/README.md" "${DOC_DIR}/README.md" diff --git a/src/_binaries/commandDefinitions/optionsMysqlCollationName.yaml b/src/_binaries/commandDefinitions/optionsMysqlCollationName.yaml index 310bbe0c..4f449028 100644 --- a/src/_binaries/commandDefinitions/optionsMysqlCollationName.yaml +++ b/src/_binaries/commandDefinitions/optionsMysqlCollationName.yaml @@ -12,7 +12,7 @@ binData: group: groupTargetOptions type: String help: Change the collation name used during database creation. - helpValueName: + helpValueName: targetDsn alts: - --collation-name - -o diff --git a/src/_binaries/commandDefinitions/optionsMysqlSource.yaml b/src/_binaries/commandDefinitions/optionsMysqlSource.yaml index a7651717..255d4ab2 100644 --- a/src/_binaries/commandDefinitions/optionsMysqlSource.yaml +++ b/src/_binaries/commandDefinitions/optionsMysqlSource.yaml @@ -20,7 +20,7 @@ binData: group: groupSourceDbOptions type: String help: dsnHelpFunction - helpValueName: + helpValueName: dsn alts: - --from-dsn - -f @@ -34,6 +34,6 @@ binData: The value is the name of the file without s3 location (Only .gz or tar.gz file are supported). This option is incompatible with -f|--from-dsn option. - helpValueName: + helpValueName: awsFile type: String variableName: optionFromAws diff --git a/src/_binaries/commandDefinitions/optionsMysqlTarget.yaml b/src/_binaries/commandDefinitions/optionsMysqlTarget.yaml index 7d898e87..c8313238 100644 --- a/src/_binaries/commandDefinitions/optionsMysqlTarget.yaml +++ b/src/_binaries/commandDefinitions/optionsMysqlTarget.yaml @@ -12,7 +12,7 @@ binData: group: groupTargetOptions type: String help: Dsn to use for target database. - helpValueName: + helpValueName: targetDsn defaultValue: default.local alts: - --target-dsn @@ -21,7 +21,7 @@ binData: group: groupTargetOptions type: String help: Change the character set used during database creation. - helpValueName: + helpValueName: characterSet alts: - --character-set - -c diff --git a/src/_binaries/commandDefinitions/optionsProfile.yaml b/src/_binaries/commandDefinitions/optionsProfile.yaml index cfcdb104..df305689 100644 --- a/src/_binaries/commandDefinitions/optionsProfile.yaml +++ b/src/_binaries/commandDefinitions/optionsProfile.yaml @@ -17,7 +17,7 @@ binData: callbacks: - profileOptionCallback defaultValue: default - helpValueName: + helpValueName: profile alts: - --profile - -p @@ -30,6 +30,6 @@ binData: If aws mode, ignore profile option. callbacks: - optionTablesCallback - helpValueName: + helpValueName: tablesSeparatedByComma alts: - --tables