From ad58c9c5c25fad6432a167ffa39b77936b3d199a Mon Sep 17 00:00:00 2001 From: Julien Caillon Date: Wed, 29 Jan 2025 18:19:47 +0100 Subject: [PATCH] :recycle: finishing huge refactoring --- commands.d/self-add-command.sh | 2 +- commands.d/self-build.sh | 8 +- commands.d/self-document.sh | 4 +- commands.d/self-extend.sh | 12 +- commands.d/self-install.sh | 4 +- commands.d/self-release.sh | 10 +- commands.d/self-test.sh | 8 +- docs/content/docs/300.libraries/_index.md | 29 +- docs/content/docs/300.libraries/curl.md | 8 +- docs/content/docs/300.libraries/io.md | 16 +- docs/content/docs/300.libraries/string.md | 20 +- docs/content/docs/300.libraries/system.md | 24 +- docs/content/docs/800.roadmap/_index.md | 13 +- extras/lib-valet | 134 ++-- extras/lib-valet.md | 92 +-- extras/valet.code-snippets | 256 ++++---- libraries.d/core | 69 +- libraries.d/lib-bash | 197 +++++- libraries.d/lib-benchmark | 24 +- libraries.d/lib-curl | 26 +- libraries.d/lib-exe | 92 +-- libraries.d/lib-interactive | 4 +- libraries.d/lib-progress | 10 +- libraries.d/lib-prompt | 10 +- libraries.d/lib-regex | 33 + libraries.d/lib-sfzf | 2 +- libraries.d/lib-string | 132 +--- libraries.d/lib-system | 149 +---- libraries.d/lib-time | 112 ++++ libraries.d/lib-tui | 42 +- libraries.d/lib-windows | 26 +- libraries.d/main | 14 +- tests.d/.commands.d/self-mock.sh | 6 +- tests.d/cli-features/results.approved.md | 4 +- tests.d/cli-profiler/results.approved.md | 92 +-- tests.d/lib-bash/00.tests.sh | 54 ++ tests.d/lib-bash/results.approved.md | 89 +++ tests.d/lib-benchmark/00.tests.sh | 4 +- tests.d/lib-curl/00.curl.sh | 34 +- tests.d/lib-curl/results.approved.md | 22 +- tests.d/lib-exe/00.tests.sh | 29 +- tests.d/lib-exe/results.approved.md | 768 +--------------------- tests.d/lib-fs/results.approved.md | 553 +++------------- tests.d/lib-regex/00.tests.sh | 16 + tests.d/lib-regex/results.approved.md | 14 + tests.d/lib-string/00.tests.sh | 84 +-- tests.d/lib-string/results.approved.md | 104 +-- tests.d/lib-system/00.tests.sh | 57 +- tests.d/lib-system/results.approved.md | 132 +--- tests.d/lib-time/00.tests.sh | 44 ++ tests.d/lib-time/results.approved.md | 82 +++ tests.d/lib-windows/00.tests.sh | 5 +- tests.d/lib-windows/results.approved.md | 198 ++++++ tests.d/self-export/results.approved.md | 6 +- tests.d/self-release/01.self-release.sh | 8 +- tests.d/self-release/results.approved.md | 286 +++----- version | 2 +- 57 files changed, 1668 insertions(+), 2607 deletions(-) create mode 100644 libraries.d/lib-regex create mode 100644 libraries.d/lib-time create mode 100644 tests.d/lib-regex/00.tests.sh create mode 100644 tests.d/lib-regex/results.approved.md create mode 100644 tests.d/lib-time/00.tests.sh create mode 100644 tests.d/lib-time/results.approved.md create mode 100644 tests.d/lib-windows/results.approved.md diff --git a/commands.d/self-add-command.sh b/commands.d/self-add-command.sh index 1832a2b4..b78df2b3 100644 --- a/commands.d/self-add-command.sh +++ b/commands.d/self-add-command.sh @@ -65,7 +65,7 @@ function selfAddCommand() { fi local fileName="${commandName// /-}" - string::kebabCaseToCamelCase "${fileName}" + string::convertKebabCaseToCamelCase "${fileName}" local functionName="${RETURNED_VALUE}" local newCommandFilePath="${PWD}/commands.d/${fileName}.sh" local commandTemplateFile="${GLOBAL_INSTALLATION_DIRECTORY}/extras/template-command-${templateFlavor}.sh" diff --git a/commands.d/self-build.sh b/commands.d/self-build.sh index 7088b595..62f02beb 100644 --- a/commands.d/self-build.sh +++ b/commands.d/self-build.sh @@ -453,7 +453,7 @@ function declareFinalCommandDefinitionHelpVariables() { optionValue="${TEMP_CMD_BUILD_options_name[index]}" if [[ ${optionValue} == *"<"* ]]; then optionValue="<${optionValue##*<}"; else optionValue="true"; fi selfBuild_extractFirstLongNameFromOptionString "${TEMP_CMD_BUILD_options_name[index]}" - string::kebabCaseToSnakeCase "${RETURNED_VALUE}" + string::convertKebabCaseToSnakeCase "${RETURNED_VALUE}" TEMP_CMD_BUILD_options_description[index]+=$'\n'"This option can be set by exporting the variable VALET_${RETURNED_VALUE}='${optionValue}'." fi done @@ -509,9 +509,9 @@ function declareFinalCommandDefinitionParserVariables() { option="${option//,/ }" string::trimAll "${option}" && option="${RETURNED_VALUE}" selfBuild_extractFirstLongNameFromOptionString "${option}" && optionName="${RETURNED_VALUE}" - string::kebabCaseToCamelCase "${optionName}" && optionNameCc="${RETURNED_VALUE}" + string::convertKebabCaseToCamelCase "${optionName}" && optionNameCc="${RETURNED_VALUE}" if [[ "${optionNoEnvVar}" != "true" ]]; then - string::kebabCaseToSnakeCase "${optionName}" && optionNameSc="VALET_${RETURNED_VALUE}" + string::convertKebabCaseToSnakeCase "${optionName}" && optionNameSc="VALET_${RETURNED_VALUE}" else optionNameSc="" fi @@ -537,7 +537,7 @@ function declareFinalCommandDefinitionParserVariables() { argument="${argument//\?/}" nbOptionalArguments+=1 fi - string::kebabCaseToCamelCase "${argument}" && argumentNameCc="${RETURNED_VALUE}" + string::convertKebabCaseToCamelCase "${argument}" && argumentNameCc="${RETURNED_VALUE}" eval "CMD_ARGS_NAME_${function}+=(\"${argumentNameCc}\")" done diff --git a/commands.d/self-document.sh b/commands.d/self-document.sh index e6541544..fc52b261 100644 --- a/commands.d/self-document.sh +++ b/commands.d/self-document.sh @@ -19,6 +19,8 @@ source system source array # shellcheck source=../libraries.d/lib-fs source fs +# shellcheck source=../libraries.d/lib-time +source time #=============================================================== # >>> command: self document @@ -94,7 +96,7 @@ function selfDocument::getFooter() { core::getVersion local version="${RETURNED_VALUE}" - system::date "%(%F)T" + time::getDate "%(%F)T" local currentDate="${RETURNED_VALUE}" RETURNED_VALUE="Documentation generated for the version ${version} (${currentDate})." } diff --git a/commands.d/self-extend.sh b/commands.d/self-extend.sh index 4b7829da..5a0c6d35 100644 --- a/commands.d/self-extend.sh +++ b/commands.d/self-extend.sh @@ -25,6 +25,8 @@ source interactive source progress # shellcheck source=../libraries.d/lib-curl source curl +# shellcheck source=../libraries.d/lib-bash +source bash #=============================================================== # >>> command: self extend @@ -144,7 +146,7 @@ function selfExtend() { # if Git is not installed, we download the source tarball and extract it # We will only be able to do that for a few git servers however log::info "Git is not installed, we will attempt to download the source tarball for the extension ⌜${extensionName}⌝." - if system::getNotExistingCommands curl tar; then + if bash::getMissingCommands curl tar; then local IFS=$'\n' core::fail "The following tools are required for this command but are not installed:"$'\n'"${RETURNED_ARRAY[*]}" fi @@ -217,7 +219,7 @@ function selfExtend_createExtension() { selfDocument fi - system::os + system::getOs local os="${RETURNED_VALUE}" if [[ ${os} == "windows" ]]; then # shellcheck source=../libraries.d/lib-windows @@ -303,7 +305,7 @@ function selfExtend_downloadTarball() { # download the tarball log::info "Downloading the extension from the URL ⌜${tarballUrl}⌝ for sha1 ⌜${sha1}⌝." progress::start "#spinner Download in progress, please wait..." - curl::toFile true 200,302 "${tempDirectory}/${sha1}.tar.gz" "${tarballUrl}" + curl::download true 200,302 "${tempDirectory}/${sha1}.tar.gz" "${tarballUrl}" progress::stop # untar @@ -348,9 +350,9 @@ function selfExtend_getSha1() { RETURNED_VALUE="" progress::start "#spinner Fetching reference information from GitHub..." local url="https://api.github.com/repos/${owner}/${repo}/git/refs/heads/${reference}" - if ! curl::toVar false '200' -H "Accept: application/vnd.github.v3+json" "${url}"; then + if ! curl::request false '200' -H "Accept: application/vnd.github.v3+json" "${url}"; then url="https://api.github.com/repos/${owner}/${repo}/git/refs/tags/${reference}" - curl::toVar false '200' -H "Accept: application/vnd.github.v3+json" "${url}" || : + curl::request false '200' -H "Accept: application/vnd.github.v3+json" "${url}" || : fi local response="${RETURNED_VALUE}" local error="${RETURNED_VALUE2}" diff --git a/commands.d/self-install.sh b/commands.d/self-install.sh index 961e57ca..7c10fdd0 100644 --- a/commands.d/self-install.sh +++ b/commands.d/self-install.sh @@ -188,7 +188,7 @@ function selfUpdate() { fi # get the os - system::os + system::getOs local os="${RETURNED_VALUE}" log::debug "The current OS is ⌜${os}⌝." @@ -724,7 +724,7 @@ if [[ -z "${GLOBAL_CORE_INCLUDED:-}" ]]; then " "${EPOCHSECONDS}" "ERROR" "$*" exit 1 } - function system::os() { + function system::getOs() { case "${OSTYPE:-}" in darwin*) RETURNED_VALUE="darwin" ;; linux*) RETURNED_VALUE="linux" ;; diff --git a/commands.d/self-release.sh b/commands.d/self-release.sh index 17c6d4cd..934015cd 100644 --- a/commands.d/self-release.sh +++ b/commands.d/self-release.sh @@ -27,6 +27,8 @@ source version source exe # shellcheck source=../libraries.d/lib-fs source fs +# shellcheck source=../libraries.d/lib-regex +source regex #=============================================================== # >>> self release valet @@ -79,7 +81,7 @@ function selfRelease() { # get the latest release local latestReleaseVersion - curl::toVar true '200' -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/jcaillon/valet/releases/latest" + curl::request true '200' -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/jcaillon/valet/releases/latest" lastReleaseJson="${RETURNED_VALUE}" if [[ ${lastReleaseJson} =~ "tag_name\":"([ ]?)"\"v"([^\"]+)"\"" ]]; then latestReleaseVersion="v${BASH_REMATCH[2]}" @@ -245,7 +247,7 @@ function selfRelease::createRelease() { local uploadUrl local createdReleaseJson if [[ "${dryRun:-}" != "true" ]]; then - curl::toVar true '201,422' -X POST \ + curl::request true '201,422' -X POST \ -H "Authorization: token ${githubReleaseToken:-}" \ -H "Accept: application/vnd.github.v3+json" \ -H "Content-type: application/json; charset=utf-8" \ @@ -286,7 +288,7 @@ function selfRelease::uploadArtifact() { # upload the artifact if [[ "${dryRun:-}" != "true" && -n "${uploadUrl}" ]]; then log::info "Uploading the artifact ⌜${artifactPath}⌝ to ⌜${uploadUrl}⌝." - curl::toVar true '' -X POST \ + curl::request true '' -X POST \ -H "Authorization: token ${githubReleaseToken:-}" \ -H "Content-Type: application/tar+gzip" \ --data-binary "@${artifactPath}" \ @@ -400,7 +402,7 @@ function selfRelease::writeAllFunctionsDocumentation() { local key for key in "${SORTED_FUNCTION_NAMES[@]}"; do local functionName="${key}" - string::regexGetFirst "${functionName}" '([[:alnum:]]+)::' + regex::getFirstGroup "${functionName}" '([[:alnum:]]+)::' local packageName="${RETURNED_VALUE}" if [[ -z "${packageName}" ]]; then # case for "source" function diff --git a/commands.d/self-test.sh b/commands.d/self-test.sh index 5f6f43b1..5f8b6315 100644 --- a/commands.d/self-test.sh +++ b/commands.d/self-test.sh @@ -21,6 +21,8 @@ source progress source bash # shellcheck source=../libraries.d/lib-fs source fs +# shellcheck source=../libraries.d/lib-time +source time #=============================================================== # >>> command: self test @@ -82,7 +84,7 @@ function selfTest() { command::parseArguments "$@" && eval "${RETURNED_VALUE}" command::checkParsedResults - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds local startTimeInMicroSeconds="${RETURNED_VALUE}" # check what will be used to display the diff between received and approved files @@ -161,8 +163,8 @@ function selfTest() { fi fi - core::getProgramElapsedMicroseconds - string::microsecondsToHuman $((RETURNED_VALUE - startTimeInMicroSeconds)) "%S seconds and %l ms" + time::getProgramElapsedMicroseconds + time::convertMicrosecondsToHuman $((RETURNED_VALUE - startTimeInMicroSeconds)) "%S seconds and %l ms" log::info "Total time running tests: ⌜${RETURNED_VALUE}⌝." if ((${#_TEST_FAILED_TEST_SUITES[@]} > 0)); then diff --git a/docs/content/docs/300.libraries/_index.md b/docs/content/docs/300.libraries/_index.md index da6a3d50..e7880cbc 100644 --- a/docs/content/docs/300.libraries/_index.md +++ b/docs/content/docs/300.libraries/_index.md @@ -23,20 +23,31 @@ The bash built-in `source` is overridden by a function in Valet. This allows to ## 🎀 Available core libraries + For more details, please check the documentation on each library: - {{< cards >}} - {{< card link="ansi-codes" icon="code" title="ansi-code" subtitle="This library exports variables containing ASCII escape codes, enabling interactive programs." >}} - {{< card link="array" icon="clipboard-list" title="array" subtitle="Functions to manipulate bash arrays." >}} - {{< card link="benchmark" icon="trending-up" title="benchmark" subtitle="Functions to benchmark bash functions." >}} + {{< card link="ansi-codes" icon="annotation" title="ansi-code" subtitle="Declares variables containing ASCII escape codes, enabling interactive programs." >}} + {{< card link="array" icon="table" title="array" subtitle="Manipulate bash arrays." >}} + {{< card link="bash" icon="code" title="bash" subtitle="Extend bash capabilities." >}} + {{< card link="benchmark" icon="trending-up" title="benchmark" subtitle="Benchmark bash functions." >}} + {{< card link="command" icon="ticket" title="command" subtitle="Functions to be used in your commands." >}} {{< card link="core" icon="star" title="core" subtitle="The core functions of Valet." >}} - {{< card link="fsfs" icon="table" title="fsfs" subtitle="Functions to display a full screen fuzzy search, which is used for the Valet menus." >}} - {{< card link="interactive" icon="cursor-click" title="interactive" subtitle="Functions to make your program interactive." >}} - {{< card link="io" icon="lightning-bolt" title="io" subtitle="Functions for file manipulation, command execution..." >}} {{< card link="curl" icon="cloud-download" title="curl" subtitle="Wrapper functions around curl." >}} + {{< card link="exe" icon="star" title="exe" subtitle="Run commands and executables." >}} + {{< card link="fs" icon="document" title="fs" subtitle="Manipulate the files and directories." >}} + {{< card link="http" icon="cloud-download" title="http" subtitle="Naive http implementation." >}} + {{< card link="interactive" icon="cursor-click" title="interactive" subtitle="Make your command interactive." >}} {{< card link="log" icon="pencil-alt" title="log" subtitle="Logging functions." >}} - {{< card link="profiler" icon="finger-print" title="profiler" subtitle="Functions enable and disable the bash profiler." >}} - {{< card link="string" icon="menu-alt-2" title="string" subtitle="Functions for string manipulation." >}} + {{< card link="profiler" icon="finger-print" title="profiler" subtitle="Enable and disable the bash profiler." >}} + {{< card link="progress" icon="dots-horizontal" title="progress" subtitle="Display a progress bar or a spinner." >}} + {{< card link="prompt" icon="chevron-right" title="prompt" subtitle="Prompt the user for input." >}} + {{< card link="regex" icon="tag" title="regex" subtitle="Use regular expressions." >}} + {{< card link="sfzf" icon="template" title="sfzf" subtitle="Simple fuzzy search interface, similar to fzf." >}} + {{< card link="string" icon="scissors" title="string" subtitle="Functions for string manipulation." >}} {{< card link="system" icon="desktop-computer" title="system" subtitle="Functions to get system/user information." >}} {{< card link="test" icon="badge-check" title="test" subtitle="Functions usable in your test scripts." >}} + {{< card link="time" icon="clock" title="time" subtitle="Functions related to time." >}} + {{< card link="tui" icon="terminal" title="tui" subtitle="Built terminal UI apps with these helper functions." >}} + {{< card link="version" icon="calculator" title="version" subtitle="Compare and manipulate semantic versions." >}} + {{< card link="windows" icon="view-grid" title="windows" subtitle="Functions specific to windows systems." >}} {{< /cards >}} diff --git a/docs/content/docs/300.libraries/curl.md b/docs/content/docs/300.libraries/curl.md index 504bb397..9ad5860b 100644 --- a/docs/content/docs/300.libraries/curl.md +++ b/docs/content/docs/300.libraries/curl.md @@ -5,7 +5,7 @@ cascade: url: /docs/libraries/curl --- -## curl::toFile +## curl::download This function is a wrapper around curl. It allows you to check the http status code and return 1 if it is not acceptable. @@ -30,11 +30,11 @@ Returns: - `RETURNED_VALUE2`: the http status code ```bash -curl::toFile "true" "200,201" "/filePath" "https://example.com" || core::fail "The curl command failed." +curl::download "true" "200,201" "/filePath" "https://example.com" || core::fail "The curl command failed." ``` -## curl::toVar +## curl::request This function is a wrapper around curl. It allows you to check the http status code and return 1 if it is not acceptable. @@ -58,7 +58,7 @@ Returns: - `RETURNED_VALUE3`: the http status code ```bash -curl::toVar false 200,201 https://example.com || core::fail "The curl command failed." +curl::request false 200,201 https://example.com || core::fail "The curl command failed." ``` diff --git a/docs/content/docs/300.libraries/io.md b/docs/content/docs/300.libraries/io.md index 08459d3e..896f8add 100644 --- a/docs/content/docs/300.libraries/io.md +++ b/docs/content/docs/300.libraries/io.md @@ -95,16 +95,16 @@ windows::convertPathFromUnix "/path/to/file" > Handles paths starting with `/mnt/x/` or `/x/`. -## exe::countArgs +## bash::countArgs Returns the number of arguments passed. A convenient function that can be used to: - count the files/directories in a directory - `exe::countArgs "${PWD}"/* && local numberOfFiles="${RETURNED_VALUE}"` + `bash::countArgs "${PWD}"/* && local numberOfFiles="${RETURNED_VALUE}"` - count the number of variables starting with VALET_ - `exe::countArgs "${!VALET_@}" && local numberOfVariables="${RETURNED_VALUE}"` + `bash::countArgs "${!VALET_@}" && local numberOfVariables="${RETURNED_VALUE}"` - $@: **arguments** _as any_: the arguments to count @@ -114,7 +114,7 @@ Returns: - `RETURNED_VALUE`: The number of arguments passed. ```bash -exe::countArgs 1 2 3 +bash::countArgs 1 2 3 ``` @@ -556,7 +556,7 @@ fs::readFile "/path/to/file" 500 && local fileContent="${RETURNED_VALUE}" ``` -## exe::readStdIn +## bash::readStdIn Read the content of the standard input. Will immediately return if the standard input is empty. @@ -566,11 +566,11 @@ Returns: - `RETURNED_VALUE`: The content of the standard input. ```bash -exe::readStdIn && local stdIn="${RETURNED_VALUE}" +bash::readStdIn && local stdIn="${RETURNED_VALUE}" ``` -## exe::sleep +## bash::sleep Sleep for the given amount of time. This is a pure bash replacement of sleep. @@ -579,7 +579,7 @@ This is a pure bash replacement of sleep. the time to sleep in seconds (can be a float) ```bash -io:sleep 1.5 +bash::sleep 1.5 ``` > The sleep command is not a built-in command in bash, but a separate executable. When you use sleep, you are creating a new process. diff --git a/docs/content/docs/300.libraries/string.md b/docs/content/docs/300.libraries/string.md index e6b55c59..8c24ba58 100644 --- a/docs/content/docs/300.libraries/string.md +++ b/docs/content/docs/300.libraries/string.md @@ -28,7 +28,7 @@ local newVersion="${RETURNED_VALUE}" ``` -## string::camelCaseToSnakeCase +## string::convertCamelCaseToSnakeCase This function convert a camelCase string to a SNAKE_CASE string. It uses pure bash. @@ -42,7 +42,7 @@ Returns: - `RETURNED_VALUE`: The SNAKE_CASE string. ```bash -string::camelCaseToSnakeCase "myCamelCaseString" && local mySnakeCaseString="${RETURNED_VALUE}" +string::convertCamelCaseToSnakeCase "myCamelCaseString" && local mySnakeCaseString="${RETURNED_VALUE}" ``` @@ -169,7 +169,7 @@ string::indexOf "This is a long text" "long" 10 && local index="${RETURNED_VALUE ``` -## string::kebabCaseToCamelCase +## string::convertKebabCaseToCamelCase This function convert a kebab-case string to a camelCase string. It uses pure bash. @@ -183,11 +183,11 @@ Returns: - `RETURNED_VALUE`: The camelCase string. ```bash -string::kebabCaseToCamelCase "my-kebab-case-string" && local myCamelCaseString="${RETURNED_VALUE}" +string::convertKebabCaseToCamelCase "my-kebab-case-string" && local myCamelCaseString="${RETURNED_VALUE}" ``` -## string::kebabCaseToSnakeCase +## string::convertKebabCaseToSnakeCase This function convert a kebab-case string to a SNAKE_CASE string. It uses pure bash. @@ -201,11 +201,11 @@ Returns: - `RETURNED_VALUE`: The SNAKE_CASE string. ```bash -string::kebabCaseToSnakeCase "my-kebab-case-string" && local mySnakeCaseString="${RETURNED_VALUE}" +string::convertKebabCaseToSnakeCase "my-kebab-case-string" && local mySnakeCaseString="${RETURNED_VALUE}" ``` -## string::microsecondsToHuman +## time::convertMicrosecondsToHuman Convert microseconds to human readable format. @@ -233,12 +233,12 @@ Returns: - `RETURNED_VALUE`: the human readable format ```bash -string::microsecondsToHuman 123456789 +time::convertMicrosecondsToHuman 123456789 echo "${RETURNED_VALUE}" ``` -## string::regexGetFirst +## regex::getFirstGroup Matches a string against a regex and returns the first capture group of the matched string. @@ -253,7 +253,7 @@ Returns: Empty if no match. ```bash -string::regexGetFirst "name: julien" "name:(.*)" +regex::getFirstGroup "name: julien" "name:(.*)" echo "${RETURNED_VALUE}" ``` diff --git a/docs/content/docs/300.libraries/system.md b/docs/content/docs/300.libraries/system.md index 4816635b..ad4047d6 100644 --- a/docs/content/docs/300.libraries/system.md +++ b/docs/content/docs/300.libraries/system.md @@ -20,7 +20,7 @@ system::addToPath "/path/to/bin" ``` -## system::commandExists +## bash::isCommand Check if the given command exists. @@ -34,13 +34,13 @@ Returns: - 1 otherwise. ```bash -if system::commandExists "command1"; then +if bash::isCommand "command1"; then printf 'The command exists.' fi ``` -## system::date +## time::getDate Get the current date in the given format. @@ -53,14 +53,14 @@ Returns: - `RETURNED_VALUE`: the current date in the given format. ```bash -system::date +time::getDate local date="${RETURNED_VALUE}" ``` > This function avoid to call $(date) in a subshell (date is a an external executable). -## system::env +## system::getEnvVars Get the list of all the environment variables. In pure bash, no need for env or printenv. @@ -70,7 +70,7 @@ Returns: - `RETURNED_ARRAY`: An array with the list of all the environment variables. ```bash -system::env +system::getEnvVars for var in "${RETURNED_ARRAY[@]}"; do printf '%s=%s\n' "${var}" "${!var}" done @@ -94,7 +94,7 @@ printf '%s\n' "The terminal has ⌜${GLOBAL_COLUMNS}⌝ columns and ⌜${GLOBAL_ ``` -## system::getNotExistingCommands +## bash::getMissingCommands This function returns the list of not existing commands for the given names. @@ -109,13 +109,13 @@ Returns: - `RETURNED_ARRAY`: the list of not existing commands. ```bash -if system::getNotExistingCommands "command1" "command2"; then +if bash::getMissingCommands "command1" "command2"; then printf 'The following commands do not exist: %s' "${RETURNED_ARRAY[*]}" fi ``` -## system::getUndeclaredVariables +## bash::getMissingVariables This function returns the list of undeclared variables for the given names. @@ -130,7 +130,7 @@ Returns: - `RETURNED_ARRAY`: the list of undeclared variables. ```bash -if system::getUndeclaredVariables "var1" "var2"; then +if bash::getMissingVariables "var1" "var2"; then printf 'The following variables are not declared: %s' "${RETURNED_ARRAY[*]}" fi ``` @@ -153,7 +153,7 @@ fi ``` -## system::os +## system::getOs Returns the name of the current OS. @@ -162,7 +162,7 @@ Returns: - `RETURNED_VALUE`: the name of the current OS: "darwin", "linux" or "windows". ```bash -system::os +system::getOs local osName="${RETURNED_VALUE}" ``` diff --git a/docs/content/docs/800.roadmap/_index.md b/docs/content/docs/800.roadmap/_index.md index af66b559..00cb6222 100644 --- a/docs/content/docs/800.roadmap/_index.md +++ b/docs/content/docs/800.roadmap/_index.md @@ -8,15 +8,15 @@ url: /docs/roadmap This page lists the features that I would like to implement in Valet. They come in addition to new features described in the [issues][valet-issues]. +- make `source` able to source multiple libraries that are called the same. Improve the function to quickly return for sourced lib (anything not starting with / or .) +- all interactive functions must write to stderr not stdout! - prompt: - since we add the possibility to load the prompt items from a file, migth as well rewrite another array fuzzy sort that loads from a file - prompt: add the possibility to position the autocompletion box (top/left/width/height) - prompt improvement ideas: do not filter from the original array if the new search string is starting with previous search string, we can search from the current array instead ! -- fzf: draw in a given rectangle, we handle full screen or not before calling sfzf -- refacto: move func from string/io lib to regex, path, fs libs -- make `source` able to source multiple libraries that are called the same. Improve the function to quickly return for sourced lib (anything not starting with / or .) +- fzf: + - draw in a given rectangle, we handle full screen or not before calling sfzf - the config file should define everything, leave all def commented. When we self config we define only those already defined. We have an associative array of each var and description to handle this -- all interactive functions must write to stderr not stdout! - add info of the extension from which a command comes from - we split the commands file into several one, per extension, so we don't have to load everything immediately - in the menu we can filter by extension (and we see the extension of a command) @@ -24,8 +24,9 @@ This page lists the features that I would like to implement in Valet. They come - test the "sudo" feature: it runs the command by forking. We could add an option to instead rerun valet with sudo. - document the test; use the lib-test test as an example, and also link to the test:: lib. - test the new bash:: lib -- refacto progress bar; use signal to tell the bg job to redraw the progress bar after displaying a log. +handle the terminal size to display the progress bar! -- after logging, if progress bar is in progress, we need to redraw it immediately. +- progress: + - refacto progress bar; use signal to tell the bg job to redraw the progress bar after displaying a log. +handle the terminal size to display the progress bar! + - after logging, if progress bar is in progress, we need to redraw it immediately. - for interactive mode, a first iteration is to prompt the user in the scrolling terminal. Then we add an option to instead open a full screen editor. - might be able to improve the quicksort if we use direct statements instead of functions. - for the log functions, we can optionally display the function name and the line number of the caller + pid + shlvl. +ISO8601 time `printf "%(%FT%H:%M:%S%z)T" "${EPOCHSECONDS}"`. Let user customize the log format with a var? `[%t] %-5level %36logger %msg`. Show them how to output as json! diff --git a/extras/lib-valet b/extras/lib-valet index 032b61a2..ac792750 100644 --- a/extras/lib-valet +++ b/extras/lib-valet @@ -494,7 +494,7 @@ function core::getConfigurationDirectory() { :; } # function core::getLocalStateDirectory() { :; } -# ## core::getProgramElapsedMicroseconds +# ## time::getProgramElapsedMicroseconds # # Get the elapsed time in µs since the program started. # @@ -505,7 +505,7 @@ function core::getLocalStateDirectory() { :; } # ```bash # core::getElapsedProgramTime # echo "${RETURNED_VALUE}" -# string::microsecondsToHuman "${RETURNED_VALUE}" +# time::convertMicrosecondsToHuman "${RETURNED_VALUE}" # echo "Human time: ${RETURNED_VALUE}" # ``` # @@ -513,7 +513,7 @@ function core::getLocalStateDirectory() { :; } # > The 10# forces the base 10 conversion to avoid issues with leading zeros. # > Fun fact: this function will fail in 2038 on 32-bit systems because the number of seconds will overflow. # -function core::getProgramElapsedMicroseconds() { :; } +function time::getProgramElapsedMicroseconds() { :; } # ## core::getUserDirectory # @@ -558,7 +558,7 @@ function core::getVersion() { :; } # function core::resetIncludedFiles() { :; } -# ## curl::toFile +# ## curl::download # # This function is a wrapper around curl. # It allows you to check the http status code and return 1 if it is not acceptable. @@ -583,12 +583,12 @@ function core::resetIncludedFiles() { :; } # - `RETURNED_VALUE2`: the http status code # # ```bash -# curl::toFile "true" "200,201" "/filePath" "https://example.com" || core::fail "The curl command failed." +# curl::download "true" "200,201" "/filePath" "https://example.com" || core::fail "The curl command failed." # ``` # -function curl::toFile() { :; } +function curl::download() { :; } -# ## curl::toVar +# ## curl::request # # This function is a wrapper around curl. # It allows you to check the http status code and return 1 if it is not acceptable. @@ -612,10 +612,10 @@ function curl::toFile() { :; } # - `RETURNED_VALUE3`: the http status code # # ```bash -# curl::toVar false 200,201 https://example.com || core::fail "The curl command failed." +# curl::request false 200,201 https://example.com || core::fail "The curl command failed." # ``` # -function curl::toVar() { :; } +function curl::request() { :; } # ## fsfs::itemSelector # @@ -934,16 +934,16 @@ function windows::convertPathToUnix() { :; } # function windows::convertPathFromUnix() { :; } -# ## exe::countArgs +# ## bash::countArgs # # Returns the number of arguments passed. # # A convenient function that can be used to: # # - count the files/directories in a directory -# `exe::countArgs "${PWD}"/* && local numberOfFiles="${RETURNED_VALUE}"` +# `bash::countArgs "${PWD}"/* && local numberOfFiles="${RETURNED_VALUE}"` # - count the number of variables starting with VALET_ -# `exe::countArgs "${!VALET_@}" && local numberOfVariables="${RETURNED_VALUE}"` +# `bash::countArgs "${!VALET_@}" && local numberOfVariables="${RETURNED_VALUE}"` # # - $@: **arguments** _as any_: # the arguments to count @@ -953,10 +953,10 @@ function windows::convertPathFromUnix() { :; } # - `RETURNED_VALUE`: The number of arguments passed. # # ```bash -# exe::countArgs 1 2 3 +# bash::countArgs 1 2 3 # ``` # -function exe::countArgs() { :; } +function bash::countArgs() { :; } # ## fs::createDirectoryIfNeeded # @@ -1472,7 +1472,7 @@ function fs::listPaths() { :; } # function fs::readFile() { :; } -# ## exe::readStdIn +# ## bash::readStdIn # # Read the content of the standard input. # Will immediately return if the standard input is empty. @@ -1482,12 +1482,12 @@ function fs::readFile() { :; } # - `RETURNED_VALUE`: The content of the standard input. # # ```bash -# exe::readStdIn && local stdIn="${RETURNED_VALUE}" +# bash::readStdIn && local stdIn="${RETURNED_VALUE}" # ``` # -function exe::readStdIn() { :; } +function bash::readStdIn() { :; } -# ## exe::sleep +# ## bash::sleep # # Sleep for the given amount of time. # This is a pure bash replacement of sleep. @@ -1496,12 +1496,12 @@ function exe::readStdIn() { :; } # the time to sleep in seconds (can be a float) # # ```bash -# io:sleep 1.5 +# bash::sleep 1.5 # ``` # # > The sleep command is not a built-in command in bash, but a separate executable. When you use sleep, you are creating a new process. # -function exe::sleep() { :; } +function bash::sleep() { :; } # ## fs::tail # @@ -2082,7 +2082,7 @@ function prompt_getDisplayedPromptString() { :; } # function source() { :; } -# ## string::camelCaseToSnakeCase +# ## string::convertCamelCaseToSnakeCase # # This function convert a camelCase string to a SNAKE_CASE string. # It uses pure bash. @@ -2096,10 +2096,10 @@ function source() { :; } # - `RETURNED_VALUE`: The SNAKE_CASE string. # # ```bash -# string::camelCaseToSnakeCase "myCamelCaseString" && local mySnakeCaseString="${RETURNED_VALUE}" +# string::convertCamelCaseToSnakeCase "myCamelCaseString" && local mySnakeCaseString="${RETURNED_VALUE}" # ``` # -function string::camelCaseToSnakeCase() { :; } +function string::convertCamelCaseToSnakeCase() { :; } # ## string::count # @@ -2254,7 +2254,7 @@ function string::highlight() { :; } # function string::indexOf() { :; } -# ## string::kebabCaseToCamelCase +# ## string::convertKebabCaseToCamelCase # # This function convert a kebab-case string to a camelCase string. # It uses pure bash. @@ -2268,12 +2268,12 @@ function string::indexOf() { :; } # - `RETURNED_VALUE`: The camelCase string. # # ```bash -# string::kebabCaseToCamelCase "my-kebab-case-string" && local myCamelCaseString="${RETURNED_VALUE}" +# string::convertKebabCaseToCamelCase "my-kebab-case-string" && local myCamelCaseString="${RETURNED_VALUE}" # ``` # -function string::kebabCaseToCamelCase() { :; } +function string::convertKebabCaseToCamelCase() { :; } -# ## string::kebabCaseToSnakeCase +# ## string::convertKebabCaseToSnakeCase # # This function convert a kebab-case string to a SNAKE_CASE string. # It uses pure bash. @@ -2287,12 +2287,12 @@ function string::kebabCaseToCamelCase() { :; } # - `RETURNED_VALUE`: The SNAKE_CASE string. # # ```bash -# string::kebabCaseToSnakeCase "my-kebab-case-string" && local mySnakeCaseString="${RETURNED_VALUE}" +# string::convertKebabCaseToSnakeCase "my-kebab-case-string" && local mySnakeCaseString="${RETURNED_VALUE}" # ``` # -function string::kebabCaseToSnakeCase() { :; } +function string::convertKebabCaseToSnakeCase() { :; } -# ## string::microsecondsToHuman +# ## time::convertMicrosecondsToHuman # # Convert microseconds to human readable format. # @@ -2321,13 +2321,13 @@ function string::kebabCaseToSnakeCase() { :; } # - `RETURNED_VALUE`: the human readable format # # ```bash -# string::microsecondsToHuman 123456789 +# time::convertMicrosecondsToHuman 123456789 # echo "${RETURNED_VALUE}" # ``` # -function string::microsecondsToHuman() { :; } +function time::convertMicrosecondsToHuman() { :; } -# ## string::regexGetFirst +# ## regex::getFirstGroup # # Matches a string against a regex and returns the first capture group of the matched string. # @@ -2342,13 +2342,13 @@ function string::microsecondsToHuman() { :; } # Empty if no match. # # ```bash -# string::regexGetFirst "name: julien" "name:(.*)" +# regex::getFirstGroup "name: julien" "name:(.*)" # echo "${RETURNED_VALUE}" # ``` # # > Regex wiki: https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions # -function string::regexGetFirst() { :; } +function regex::getFirstGroup() { :; } # ## string::split # @@ -2445,7 +2445,7 @@ function string::trimAll() { :; } # function string::wrapCharacters() { :; } -# ## string::wrapText +# ## string::wrapWords # # Allows to soft wrap the given text at the given width. # Wrapping is done at word boundaries. @@ -2474,7 +2474,7 @@ function string::wrapCharacters() { :; } # - `RETURNED_VALUE`: the wrapped text # # ```bash -# string::wrapText "This is a long text that should be wrapped at 20 characters." 20 ' ' 5 +# string::wrapWords "This is a long text that should be wrapped at 20 characters." 20 ' ' 5 # echo "${RETURNED_VALUE}" # ``` # @@ -2482,7 +2482,7 @@ function string::wrapCharacters() { :; } # > - This function effectively trims all the extra spaces in the text (leading, trailing but also in the middle). # > - It considers escape sequence for text formatting and does not count them as visible characters. # -function string::wrapText() { :; } +function string::wrapWords() { :; } # ## system::addToPath # @@ -2500,7 +2500,7 @@ function string::wrapText() { :; } # function system::addToPath() { :; } -# ## system::commandExists +# ## bash::isCommand # # Check if the given command exists. # @@ -2514,14 +2514,14 @@ function system::addToPath() { :; } # - 1 otherwise. # # ```bash -# if system::commandExists "command1"; then +# if bash::isCommand "command1"; then # printf 'The command exists.' # fi # ``` # -function system::commandExists() { :; } +function bash::isCommand() { :; } -# ## system::date +# ## time::getDate # # Get the current date in the given format. # @@ -2534,15 +2534,15 @@ function system::commandExists() { :; } # - `RETURNED_VALUE`: the current date in the given format. # # ```bash -# system::date +# time::getDate # local date="${RETURNED_VALUE}" # ``` # # > This function avoid to call $(date) in a subshell (date is a an external executable). # -function system::date() { :; } +function time::getDate() { :; } -# ## system::env +# ## system::getEnvVars # # Get the list of all the environment variables. # In pure bash, no need for env or printenv. @@ -2552,7 +2552,7 @@ function system::date() { :; } # - `RETURNED_ARRAY`: An array with the list of all the environment variables. # # ```bash -# system::env +# system::getEnvVars # for var in "${RETURNED_ARRAY[@]}"; do # printf '%s=%s\n' "${var}" "${!var}" # done @@ -2560,9 +2560,9 @@ function system::date() { :; } # # > This is faster than using mapfile on <(compgen -v). # -function system::env() { :; } +function system::getEnvVars() { :; } -# ## system::getNotExistingCommands +# ## bash::getMissingCommands # # This function returns the list of not existing commands for the given names. # @@ -2577,14 +2577,14 @@ function system::env() { :; } # - `RETURNED_ARRAY`: the list of not existing commands. # # ```bash -# if system::getNotExistingCommands "command1" "command2"; then +# if bash::getMissingCommands "command1" "command2"; then # printf 'The following commands do not exist: %s' "${RETURNED_ARRAY[*]}" # fi # ``` # -function system::getNotExistingCommands() { :; } +function bash::getMissingCommands() { :; } -# ## system::getUndeclaredVariables +# ## bash::getMissingVariables # # This function returns the list of undeclared variables for the given names. # @@ -2599,12 +2599,12 @@ function system::getNotExistingCommands() { :; } # - `RETURNED_ARRAY`: the list of undeclared variables. # # ```bash -# if system::getUndeclaredVariables "var1" "var2"; then +# if bash::getMissingVariables "var1" "var2"; then # printf 'The following variables are not declared: %s' "${RETURNED_ARRAY[*]}" # fi # ``` # -function system::getUndeclaredVariables() { :; } +function bash::getMissingVariables() { :; } # ## system::isRoot # @@ -2624,7 +2624,7 @@ function system::getUndeclaredVariables() { :; } # function system::isRoot() { :; } -# ## system::os +# ## system::getOs # # Returns the name of the current OS. # @@ -2633,11 +2633,11 @@ function system::isRoot() { :; } # - `RETURNED_VALUE`: the name of the current OS: "darwin", "linux" or "windows". # # ```bash -# system::os +# system::getOs # local osName="${RETURNED_VALUE}" # ``` # -function system::os() { :; } +function system::getOs() { :; } # ## windows::addToPath # @@ -3063,7 +3063,7 @@ function tui::getTerminalSize() { :; } # # This function should be called before using tui::waitForKeyPress. # -# You can call `tui::resetBindings` to restore the default bindings. However, this is not +# You can call `tui::restoreBindings` to restore the default bindings. However, this is not # necessary as the bindings are local to the script. # # ```bash @@ -3074,15 +3074,15 @@ function tui::getTerminalSize() { :; } # function tui::rebindKeymap() { :; } -# ## tui::resetBindings +# ## tui::restoreBindings # # Reset the key bindings to the default ones. # # ```bash -# tui::resetBindings +# tui::restoreBindings # ``` # -function tui::resetBindings() { :; } +function tui::restoreBindings() { :; } # ## tui::restoreInterruptTrap # @@ -3106,17 +3106,17 @@ function tui::restoreInterruptTrap() { :; } # function tui::setInterruptTrap() { :; } -# ## tui::sttyInit +# ## tui::setTerminalOptions # # Disable the echo of the tty. Will no longer display the characters typed by the user. # # ```bash -# tui::sttyInit +# tui::setTerminalOptions # ``` # -function tui::sttyInit() { :; } +function tui::setTerminalOptions() { :; } -# ## tui::sttyRestore +# ## tui::restoreTerminalOptions # # Enable the echo of the tty. Will display the characters typed by the user. # @@ -3126,11 +3126,11 @@ function tui::sttyInit() { :; } # (defaults to false) # # ```bash -# tui::sttyRestore +# tui::restoreTerminalOptions # ``` # shellcheck disable=SC2120 # -function tui::sttyRestore() { :; } +function tui::restoreTerminalOptions() { :; } # ## tui::switchBackFromFullScreen # @@ -3233,7 +3233,7 @@ function tui::waitForChar() { :; } # This means we can detect more key combinations but all keys needs to be bound first... # Special keys (CTRL+, ALT+, F1-F12, arrows, etc.) are intercepted using binding. # -# You must call `tui::rebindKeymap` and `tui::sttyInit` before using this function. +# You must call `tui::rebindKeymap` and `tui::setTerminalOptions` before using this function. # # - $@: **read parameters** _as any_: # additional parameters to pass to the read command diff --git a/extras/lib-valet.md b/extras/lib-valet.md index 24f5f313..6b789051 100644 --- a/extras/lib-valet.md +++ b/extras/lib-valet.md @@ -471,7 +471,7 @@ local directory="${RETURNED_VALUE}" ``` -## core::getProgramElapsedMicroseconds +## time::getProgramElapsedMicroseconds Get the elapsed time in µs since the program started. @@ -482,7 +482,7 @@ Returns: ```bash core::getElapsedProgramTime echo "${RETURNED_VALUE}" -string::microsecondsToHuman "${RETURNED_VALUE}" +time::convertMicrosecondsToHuman "${RETURNED_VALUE}" echo "Human time: ${RETURNED_VALUE}" ``` @@ -531,7 +531,7 @@ core::resetIncludedFiles ``` -## curl::toFile +## curl::download This function is a wrapper around curl. It allows you to check the http status code and return 1 if it is not acceptable. @@ -556,11 +556,11 @@ Returns: - `RETURNED_VALUE2`: the http status code ```bash -curl::toFile "true" "200,201" "/filePath" "https://example.com" || core::fail "The curl command failed." +curl::download "true" "200,201" "/filePath" "https://example.com" || core::fail "The curl command failed." ``` -## curl::toVar +## curl::request This function is a wrapper around curl. It allows you to check the http status code and return 1 if it is not acceptable. @@ -584,7 +584,7 @@ Returns: - `RETURNED_VALUE3`: the http status code ```bash -curl::toVar false 200,201 https://example.com || core::fail "The curl command failed." +curl::request false 200,201 https://example.com || core::fail "The curl command failed." ``` @@ -890,16 +890,16 @@ windows::convertPathFromUnix "/path/to/file" > Handles paths starting with `/mnt/x/` or `/x/`. -## exe::countArgs +## bash::countArgs Returns the number of arguments passed. A convenient function that can be used to: - count the files/directories in a directory - `exe::countArgs "${PWD}"/* && local numberOfFiles="${RETURNED_VALUE}"` + `bash::countArgs "${PWD}"/* && local numberOfFiles="${RETURNED_VALUE}"` - count the number of variables starting with VALET_ - `exe::countArgs "${!VALET_@}" && local numberOfVariables="${RETURNED_VALUE}"` + `bash::countArgs "${!VALET_@}" && local numberOfVariables="${RETURNED_VALUE}"` - $@: **arguments** _as any_: the arguments to count @@ -909,7 +909,7 @@ Returns: - `RETURNED_VALUE`: The number of arguments passed. ```bash -exe::countArgs 1 2 3 +bash::countArgs 1 2 3 ``` @@ -1409,7 +1409,7 @@ fs::readFile "/path/to/file" 500 && local fileContent="${RETURNED_VALUE}" ``` -## exe::readStdIn +## bash::readStdIn Read the content of the standard input. Will immediately return if the standard input is empty. @@ -1419,11 +1419,11 @@ Returns: - `RETURNED_VALUE`: The content of the standard input. ```bash -exe::readStdIn && local stdIn="${RETURNED_VALUE}" +bash::readStdIn && local stdIn="${RETURNED_VALUE}" ``` -## exe::sleep +## bash::sleep Sleep for the given amount of time. This is a pure bash replacement of sleep. @@ -1432,7 +1432,7 @@ This is a pure bash replacement of sleep. the time to sleep in seconds (can be a float) ```bash -io:sleep 1.5 +bash::sleep 1.5 ``` > The sleep command is not a built-in command in bash, but a separate executable. When you use sleep, you are creating a new process. @@ -1987,7 +1987,7 @@ specify the included file for spellcheck. > - Use `builtin source` if you want to include the file even if it was already included. -## string::camelCaseToSnakeCase +## string::convertCamelCaseToSnakeCase This function convert a camelCase string to a SNAKE_CASE string. It uses pure bash. @@ -2001,7 +2001,7 @@ Returns: - `RETURNED_VALUE`: The SNAKE_CASE string. ```bash -string::camelCaseToSnakeCase "myCamelCaseString" && local mySnakeCaseString="${RETURNED_VALUE}" +string::convertCamelCaseToSnakeCase "myCamelCaseString" && local mySnakeCaseString="${RETURNED_VALUE}" ``` @@ -2152,7 +2152,7 @@ string::indexOf "This is a long text" "long" 10 && local index="${RETURNED_VALUE ``` -## string::kebabCaseToCamelCase +## string::convertKebabCaseToCamelCase This function convert a kebab-case string to a camelCase string. It uses pure bash. @@ -2166,11 +2166,11 @@ Returns: - `RETURNED_VALUE`: The camelCase string. ```bash -string::kebabCaseToCamelCase "my-kebab-case-string" && local myCamelCaseString="${RETURNED_VALUE}" +string::convertKebabCaseToCamelCase "my-kebab-case-string" && local myCamelCaseString="${RETURNED_VALUE}" ``` -## string::kebabCaseToSnakeCase +## string::convertKebabCaseToSnakeCase This function convert a kebab-case string to a SNAKE_CASE string. It uses pure bash. @@ -2184,11 +2184,11 @@ Returns: - `RETURNED_VALUE`: The SNAKE_CASE string. ```bash -string::kebabCaseToSnakeCase "my-kebab-case-string" && local mySnakeCaseString="${RETURNED_VALUE}" +string::convertKebabCaseToSnakeCase "my-kebab-case-string" && local mySnakeCaseString="${RETURNED_VALUE}" ``` -## string::microsecondsToHuman +## time::convertMicrosecondsToHuman Convert microseconds to human readable format. @@ -2217,12 +2217,12 @@ Returns: - `RETURNED_VALUE`: the human readable format ```bash -string::microsecondsToHuman 123456789 +time::convertMicrosecondsToHuman 123456789 echo "${RETURNED_VALUE}" ``` -## string::regexGetFirst +## regex::getFirstGroup Matches a string against a regex and returns the first capture group of the matched string. @@ -2237,7 +2237,7 @@ Returns: Empty if no match. ```bash -string::regexGetFirst "name: julien" "name:(.*)" +regex::getFirstGroup "name: julien" "name:(.*)" echo "${RETURNED_VALUE}" ``` @@ -2335,7 +2335,7 @@ echo "${RETURNED_VALUE}" > - Leading spaces after a newly wrapped line are removed. -## string::wrapText +## string::wrapWords Allows to soft wrap the given text at the given width. Wrapping is done at word boundaries. @@ -2364,7 +2364,7 @@ Returns: - `RETURNED_VALUE`: the wrapped text ```bash -string::wrapText "This is a long text that should be wrapped at 20 characters." 20 ' ' 5 +string::wrapWords "This is a long text that should be wrapped at 20 characters." 20 ' ' 5 echo "${RETURNED_VALUE}" ``` @@ -2388,7 +2388,7 @@ system::addToPath "/path/to/bin" ``` -## system::commandExists +## bash::isCommand Check if the given command exists. @@ -2402,13 +2402,13 @@ Returns: - 1 otherwise. ```bash -if system::commandExists "command1"; then +if bash::isCommand "command1"; then printf 'The command exists.' fi ``` -## system::date +## time::getDate Get the current date in the given format. @@ -2421,14 +2421,14 @@ Returns: - `RETURNED_VALUE`: the current date in the given format. ```bash -system::date +time::getDate local date="${RETURNED_VALUE}" ``` > This function avoid to call $(date) in a subshell (date is a an external executable). -## system::env +## system::getEnvVars Get the list of all the environment variables. In pure bash, no need for env or printenv. @@ -2438,7 +2438,7 @@ Returns: - `RETURNED_ARRAY`: An array with the list of all the environment variables. ```bash -system::env +system::getEnvVars for var in "${RETURNED_ARRAY[@]}"; do printf '%s=%s\n' "${var}" "${!var}" done @@ -2447,7 +2447,7 @@ done > This is faster than using mapfile on <(compgen -v). -## system::getNotExistingCommands +## bash::getMissingCommands This function returns the list of not existing commands for the given names. @@ -2462,13 +2462,13 @@ Returns: - `RETURNED_ARRAY`: the list of not existing commands. ```bash -if system::getNotExistingCommands "command1" "command2"; then +if bash::getMissingCommands "command1" "command2"; then printf 'The following commands do not exist: %s' "${RETURNED_ARRAY[*]}" fi ``` -## system::getUndeclaredVariables +## bash::getMissingVariables This function returns the list of undeclared variables for the given names. @@ -2483,7 +2483,7 @@ Returns: - `RETURNED_ARRAY`: the list of undeclared variables. ```bash -if system::getUndeclaredVariables "var1" "var2"; then +if bash::getMissingVariables "var1" "var2"; then printf 'The following variables are not declared: %s' "${RETURNED_ARRAY[*]}" fi ``` @@ -2506,7 +2506,7 @@ fi ``` -## system::os +## system::getOs Returns the name of the current OS. @@ -2515,7 +2515,7 @@ Returns: - `RETURNED_VALUE`: the name of the current OS: "darwin", "linux" or "windows". ```bash -system::os +system::getOs local osName="${RETURNED_VALUE}" ``` @@ -2919,7 +2919,7 @@ the `tuiRebindOverride` function. This function should be called before using tui::waitForKeyPress. -You can call `tui::resetBindings` to restore the default bindings. However, this is not +You can call `tui::restoreBindings` to restore the default bindings. However, this is not necessary as the bindings are local to the script. ```bash @@ -2929,12 +2929,12 @@ tui::rebindKeymap > `showkey -a` is a good program to see the sequence of characters sent by the terminal. -## tui::resetBindings +## tui::restoreBindings Reset the key bindings to the default ones. ```bash -tui::resetBindings +tui::restoreBindings ``` @@ -2958,16 +2958,16 @@ tui::setInterruptTrap ``` -## tui::sttyInit +## tui::setTerminalOptions Disable the echo of the tty. Will no longer display the characters typed by the user. ```bash -tui::sttyInit +tui::setTerminalOptions ``` -## tui::sttyRestore +## tui::restoreTerminalOptions Enable the echo of the tty. Will display the characters typed by the user. @@ -2977,7 +2977,7 @@ Enable the echo of the tty. Will display the characters typed by the user. (defaults to false) ```bash -tui::sttyRestore +tui::restoreTerminalOptions ``` shellcheck disable=SC2120 @@ -3078,7 +3078,7 @@ It uses the read builtin command with the option `-e` to use readline behind the This means we can detect more key combinations but all keys needs to be bound first... Special keys (CTRL+, ALT+, F1-F12, arrows, etc.) are intercepted using binding. -You must call `tui::rebindKeymap` and `tui::sttyInit` before using this function. +You must call `tui::rebindKeymap` and `tui::setTerminalOptions` before using this function. - $@: **read parameters** _as any_: additional parameters to pass to the read command diff --git a/extras/valet.code-snippets b/extras/valet.code-snippets index 282e1c06..7d5b6124 100644 --- a/extras/valet.code-snippets +++ b/extras/valet.code-snippets @@ -295,18 +295,18 @@ "body": [ "# ## core::getLocalStateDirectory\n# \n# Returns the path to the valet local state directory.\n# The base directory relative to which user-specific state files should be stored.\n# Creates it if missing.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the path to the valet local state directory\n# \n# ```bash\n# core::getLocalStateDirectory\n# local directory=\"\\${RETURNED_VALUE}\"\n# ```\n# \ncore::getLocalStateDirectory$0" ] }, -"core::getProgramElapsedMicroseconds": { - "prefix": "core::getProgramElapsedMicroseconds", +"time::getProgramElapsedMicroseconds": { + "prefix": "time::getProgramElapsedMicroseconds", "description": "Get the elapsed time in µs since the program started...", "scope": "", - "body": [ "core::getProgramElapsedMicroseconds$0" ] + "body": [ "time::getProgramElapsedMicroseconds$0" ] }, -"core::getProgramElapsedMicroseconds#withdoc": { - "prefix": "core::getProgramElapsedMicroseconds#withdoc", +"time::getProgramElapsedMicroseconds#withdoc": { + "prefix": "time::getProgramElapsedMicroseconds#withdoc", "description": "Get the elapsed time in µs since the program started...", "scope": "", - "body": [ "# ## core::getProgramElapsedMicroseconds\n# \n# Get the elapsed time in µs since the program started.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the elapsed time in µs since the program started.\n# \n# ```bash\n# core::getElapsedProgramTime\n# echo \"\\${RETURNED_VALUE}\"\n# string::microsecondsToHuman \"\\${RETURNED_VALUE}\"\n# echo \"Human time: \\${RETURNED_VALUE}\"\n# ```\n# \n# > We split the computation in seconds and milliseconds to avoid overflow on 32-bit systems.\n# > The 10# forces the base 10 conversion to avoid issues with leading zeros.\n# > Fun fact: this function will fail in 2038 on 32-bit systems because the number of seconds will overflow.\n# \ncore::getProgramElapsedMicroseconds$0" ] + "body": [ "# ## time::getProgramElapsedMicroseconds\n# \n# Get the elapsed time in µs since the program started.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the elapsed time in µs since the program started.\n# \n# ```bash\n# core::getElapsedProgramTime\n# echo \"\\${RETURNED_VALUE}\"\n# time::convertMicrosecondsToHuman \"\\${RETURNED_VALUE}\"\n# echo \"Human time: \\${RETURNED_VALUE}\"\n# ```\n# \n# > We split the computation in seconds and milliseconds to avoid overflow on 32-bit systems.\n# > The 10# forces the base 10 conversion to avoid issues with leading zeros.\n# > Fun fact: this function will fail in 2038 on 32-bit systems because the number of seconds will overflow.\n# \ntime::getProgramElapsedMicroseconds$0" ] }, "core::getUserDirectory": { @@ -351,32 +351,32 @@ "body": [ "# ## core::resetIncludedFiles\n# \n# Allows to reset the included files.\n# When calling the source function, it will source all the files again.\n# This is useful when we want to reload the libraries.\n# \n# ```bash\n# core::resetIncludedFiles\n# ```\n# \ncore::resetIncludedFiles$0" ] }, -"curl::toFile": { - "prefix": "curl::toFile", +"curl::download": { + "prefix": "curl::download", "description": "This function is a wrapper around curl...", "scope": "", - "body": [ "curl::toFile \"${1:**fail**}\" \"${2:**acceptable codes**}\" \"${3:**path**}\" \"${99:**curl arguments**}\"$0" ] + "body": [ "curl::download \"${1:**fail**}\" \"${2:**acceptable codes**}\" \"${3:**path**}\" \"${99:**curl arguments**}\"$0" ] }, -"curl::toFile#withdoc": { - "prefix": "curl::toFile#withdoc", +"curl::download#withdoc": { + "prefix": "curl::download#withdoc", "description": "This function is a wrapper around curl...", "scope": "", - "body": [ "# ## curl::toFile\n# \n# This function is a wrapper around curl.\n# It allows you to check the http status code and return 1 if it is not acceptable.\n# It exe::invokes curl with the following options (do not repeat them): -sSL -w \"%{response_code}\" -o \\${2}.\n# \n# - \\$1: **fail** _as bool_:\n# true/false to indicate if the function should fail in case the execution fails\n# - \\$2: **acceptable codes** _as string_:\n# list of http status codes that are acceptable, comma separated\n# (defaults to 200,201,202,204,301,304,308 if left empty)\n# - \\$3: **path** _as string_:\n# the file in which to save the output of curl\n# - \\$@: **curl arguments** _as any_:\n# options for curl\n# \n# Returns:\n# \n# - `\\$?`:\n# - 0 if the http status code is acceptable\n# - 1 otherwise\n# - `RETURNED_VALUE`: the content of stderr\n# - `RETURNED_VALUE2`: the http status code\n# \n# ```bash\n# curl::toFile \"true\" \"200,201\" \"/filePath\" \"https://example.com\" || core::fail \"The curl command failed.\"\n# ```\n# \ncurl::toFile \"${1:**fail**}\" \"${2:**acceptable codes**}\" \"${3:**path**}\" \"${99:**curl arguments**}\"$0" ] + "body": [ "# ## curl::download\n# \n# This function is a wrapper around curl.\n# It allows you to check the http status code and return 1 if it is not acceptable.\n# It exe::invokes curl with the following options (do not repeat them): -sSL -w \"%{response_code}\" -o \\${2}.\n# \n# - \\$1: **fail** _as bool_:\n# true/false to indicate if the function should fail in case the execution fails\n# - \\$2: **acceptable codes** _as string_:\n# list of http status codes that are acceptable, comma separated\n# (defaults to 200,201,202,204,301,304,308 if left empty)\n# - \\$3: **path** _as string_:\n# the file in which to save the output of curl\n# - \\$@: **curl arguments** _as any_:\n# options for curl\n# \n# Returns:\n# \n# - `\\$?`:\n# - 0 if the http status code is acceptable\n# - 1 otherwise\n# - `RETURNED_VALUE`: the content of stderr\n# - `RETURNED_VALUE2`: the http status code\n# \n# ```bash\n# curl::download \"true\" \"200,201\" \"/filePath\" \"https://example.com\" || core::fail \"The curl command failed.\"\n# ```\n# \ncurl::download \"${1:**fail**}\" \"${2:**acceptable codes**}\" \"${3:**path**}\" \"${99:**curl arguments**}\"$0" ] }, -"curl::toVar": { - "prefix": "curl::toVar", +"curl::request": { + "prefix": "curl::request", "description": "This function is a wrapper around curl...", "scope": "", - "body": [ "curl::toVar \"${1:**fail**}\" \"${2:**acceptable codes**}\" \"${99:**curl arguments**}\"$0" ] + "body": [ "curl::request \"${1:**fail**}\" \"${2:**acceptable codes**}\" \"${99:**curl arguments**}\"$0" ] }, -"curl::toVar#withdoc": { - "prefix": "curl::toVar#withdoc", +"curl::request#withdoc": { + "prefix": "curl::request#withdoc", "description": "This function is a wrapper around curl...", "scope": "", - "body": [ "# ## curl::toVar\n# \n# This function is a wrapper around curl.\n# It allows you to check the http status code and return 1 if it is not acceptable.\n# It exe::invokes curl with the following options (do not repeat them): -sSL -w \"%{response_code}\" -o \"tempfile\".\n# \n# - \\$1: **fail** _as bool_:\n# true/false to indicate if the function should fail in case the execution fails\n# - \\$2: **acceptable codes** _as string_:\n# list of http status codes that are acceptable, comma separated\n# (defaults to 200,201,202,204,301,304,308 if left empty)\n# - \\$@: **curl arguments** _as any_:\n# options for curl\n# \n# Returns:\n# \n# - `\\$?`:\n# - 0 if the http status code is acceptable\n# - 1 otherwise\n# - `RETURNED_VALUE`: the content of the request\n# - `RETURNED_VALUE2`: the content of stderr\n# - `RETURNED_VALUE3`: the http status code\n# \n# ```bash\n# curl::toVar false 200,201 https://example.com || core::fail \"The curl command failed.\"\n# ```\n# \ncurl::toVar \"${1:**fail**}\" \"${2:**acceptable codes**}\" \"${99:**curl arguments**}\"$0" ] + "body": [ "# ## curl::request\n# \n# This function is a wrapper around curl.\n# It allows you to check the http status code and return 1 if it is not acceptable.\n# It exe::invokes curl with the following options (do not repeat them): -sSL -w \"%{response_code}\" -o \"tempfile\".\n# \n# - \\$1: **fail** _as bool_:\n# true/false to indicate if the function should fail in case the execution fails\n# - \\$2: **acceptable codes** _as string_:\n# list of http status codes that are acceptable, comma separated\n# (defaults to 200,201,202,204,301,304,308 if left empty)\n# - \\$@: **curl arguments** _as any_:\n# options for curl\n# \n# Returns:\n# \n# - `\\$?`:\n# - 0 if the http status code is acceptable\n# - 1 otherwise\n# - `RETURNED_VALUE`: the content of the request\n# - `RETURNED_VALUE2`: the content of stderr\n# - `RETURNED_VALUE3`: the http status code\n# \n# ```bash\n# curl::request false 200,201 https://example.com || core::fail \"The curl command failed.\"\n# ```\n# \ncurl::request \"${1:**fail**}\" \"${2:**acceptable codes**}\" \"${99:**curl arguments**}\"$0" ] }, "fsfs::itemSelector": { @@ -589,18 +589,18 @@ "body": [ "# ## windows::convertPathFromUnix\n# \n# Convert a unix path to a Windows path.\n# \n# - \\$1: **path** _as string_:\n# the path to convert\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The Windows path.\n# \n# ```bash\n# windows::convertPathFromUnix \"/path/to/file\"\n# ```\n# \n# > Handles paths starting with `/mnt/x/` or `/x/`.\n# \nwindows::convertPathFromUnix \"${1:**path**}\"$0" ] }, -"exe::countArgs": { - "prefix": "exe::countArgs", +"bash::countArgs": { + "prefix": "bash::countArgs", "description": "Returns the number of arguments passed...", "scope": "", - "body": [ "exe::countArgs \"${99:**arguments**}\"$0" ] + "body": [ "bash::countArgs \"${99:**arguments**}\"$0" ] }, -"exe::countArgs#withdoc": { - "prefix": "exe::countArgs#withdoc", +"bash::countArgs#withdoc": { + "prefix": "bash::countArgs#withdoc", "description": "Returns the number of arguments passed...", "scope": "", - "body": [ "# ## exe::countArgs\n# \n# Returns the number of arguments passed.\n# \n# A convenient function that can be used to:\n# \n# - count the files/directories in a directory\n# `exe::countArgs \"\\${PWD}\"/* && local numberOfFiles=\"\\${RETURNED_VALUE}\"`\n# - count the number of variables starting with VALET_\n# `exe::countArgs \"\\${!VALET_@}\" && local numberOfVariables=\"\\${RETURNED_VALUE}\"`\n# \n# - \\$@: **arguments** _as any_:\n# the arguments to count\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The number of arguments passed.\n# \n# ```bash\n# exe::countArgs 1 2 3\n# ```\n# \nexe::countArgs \"${99:**arguments**}\"$0" ] + "body": [ "# ## bash::countArgs\n# \n# Returns the number of arguments passed.\n# \n# A convenient function that can be used to:\n# \n# - count the files/directories in a directory\n# `bash::countArgs \"\\${PWD}\"/* && local numberOfFiles=\"\\${RETURNED_VALUE}\"`\n# - count the number of variables starting with VALET_\n# `bash::countArgs \"\\${!VALET_@}\" && local numberOfVariables=\"\\${RETURNED_VALUE}\"`\n# \n# - \\$@: **arguments** _as any_:\n# the arguments to count\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The number of arguments passed.\n# \n# ```bash\n# bash::countArgs 1 2 3\n# ```\n# \nbash::countArgs \"${99:**arguments**}\"$0" ] }, "fs::createDirectoryIfNeeded": { @@ -855,32 +855,32 @@ "body": [ "# ## fs::readFile\n# \n# Reads the content of a file and returns it in the global variable RETURNED_VALUE.\n# Uses pure bash.\n# \n# - \\$1: **path** _as string_:\n# the file path to read\n# - \\$2: max char _as int_:\n# (optional) the maximum number of characters to read\n# (defaults to 0, which means read the whole file)\n# \n# > If the file does not exist, the function will return an empty string instead of failing.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The content of the file.\n# \n# ```bash\n# fs::readFile \"/path/to/file\" && local fileContent=\"\\${RETURNED_VALUE}\"\n# fs::readFile \"/path/to/file\" 500 && local fileContent=\"\\${RETURNED_VALUE}\"\n# ```\n# \nfs::readFile \"${1:**path**}\" \"${2:max char}\"$0" ] }, -"exe::readStdIn": { - "prefix": "exe::readStdIn", +"bash::readStdIn": { + "prefix": "bash::readStdIn", "description": "Read the content of the standard input...", "scope": "", - "body": [ "exe::readStdIn$0" ] + "body": [ "bash::readStdIn$0" ] }, -"exe::readStdIn#withdoc": { - "prefix": "exe::readStdIn#withdoc", +"bash::readStdIn#withdoc": { + "prefix": "bash::readStdIn#withdoc", "description": "Read the content of the standard input...", "scope": "", - "body": [ "# ## exe::readStdIn\n# \n# Read the content of the standard input.\n# Will immediately return if the standard input is empty.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The content of the standard input.\n# \n# ```bash\n# exe::readStdIn && local stdIn=\"\\${RETURNED_VALUE}\"\n# ```\n# \nexe::readStdIn$0" ] + "body": [ "# ## bash::readStdIn\n# \n# Read the content of the standard input.\n# Will immediately return if the standard input is empty.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The content of the standard input.\n# \n# ```bash\n# bash::readStdIn && local stdIn=\"\\${RETURNED_VALUE}\"\n# ```\n# \nbash::readStdIn$0" ] }, -"exe::sleep": { - "prefix": "exe::sleep", +"bash::sleep": { + "prefix": "bash::sleep", "description": "Sleep for the given amount of time...", "scope": "", - "body": [ "exe::sleep \"${1:**time**}\"$0" ] + "body": [ "bash::sleep \"${1:**time**}\"$0" ] }, -"exe::sleep#withdoc": { - "prefix": "exe::sleep#withdoc", +"bash::sleep#withdoc": { + "prefix": "bash::sleep#withdoc", "description": "Sleep for the given amount of time...", "scope": "", - "body": [ "# ## exe::sleep\n# \n# Sleep for the given amount of time.\n# This is a pure bash replacement of sleep.\n# \n# - \\$1: **time** _as float_:\n# the time to sleep in seconds (can be a float)\n# \n# ```bash\n# io:sleep 1.5\n# ```\n# \n# > The sleep command is not a built-in command in bash, but a separate executable. When you use sleep, you are creating a new process.\n# \nexe::sleep \"${1:**time**}\"$0" ] + "body": [ "# ## bash::sleep\n# \n# Sleep for the given amount of time.\n# This is a pure bash replacement of sleep.\n# \n# - \\$1: **time** _as float_:\n# the time to sleep in seconds (can be a float)\n# \n# ```bash\n# bash::sleep 1.5\n# ```\n# \n# > The sleep command is not a built-in command in bash, but a separate executable. When you use sleep, you are creating a new process.\n# \nbash::sleep \"${1:**time**}\"$0" ] }, "fs::tail": { @@ -1303,18 +1303,18 @@ "body": [ "# ## source\n# \n# Allows to include a library file or sources a file.\n# \n# It replaces the builtin source command to make sure that we do not include the same file twice.\n# We replace source instead of creating a new function to allow us to\n# specify the included file for spellcheck.\n# \n# - \\$1: **library name** _as string_:\n# the name of the library (array, interactive, string...) or the file path to include.\n# - \\$@: arguments _as any_:\n# (optional) the arguments to pass to the included file (mimics the builtin source command).\n# \n# ```bash\n# source string array system\n# source ./my/path my/other/path\n# ```\n# \n# > - The file can be relative to the current script (script that calls this function).\n# > - This function makes sure that we do not include the same file twice.\n# > - Use `builtin source` if you want to include the file even if it was already included.\n# \nsource \"${1:**library name**}\" \"${99:arguments}\"$0" ] }, -"string::camelCaseToSnakeCase": { - "prefix": "string::camelCaseToSnakeCase", +"string::convertCamelCaseToSnakeCase": { + "prefix": "string::convertCamelCaseToSnakeCase", "description": "This function convert a camelCase string to a SNAKE_CASE string...", "scope": "", - "body": [ "string::camelCaseToSnakeCase \"${1:**camelCase string**}\"$0" ] + "body": [ "string::convertCamelCaseToSnakeCase \"${1:**camelCase string**}\"$0" ] }, -"string::camelCaseToSnakeCase#withdoc": { - "prefix": "string::camelCaseToSnakeCase#withdoc", +"string::convertCamelCaseToSnakeCase#withdoc": { + "prefix": "string::convertCamelCaseToSnakeCase#withdoc", "description": "This function convert a camelCase string to a SNAKE_CASE string...", "scope": "", - "body": [ "# ## string::camelCaseToSnakeCase\n# \n# This function convert a camelCase string to a SNAKE_CASE string.\n# It uses pure bash.\n# Removes all leading underscores.\n# \n# - \\$1: **camelCase string** _as string_:\n# The camelCase string to convert.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The SNAKE_CASE string.\n# \n# ```bash\n# string::camelCaseToSnakeCase \"myCamelCaseString\" && local mySnakeCaseString=\"\\${RETURNED_VALUE}\"\n# ```\n# \nstring::camelCaseToSnakeCase \"${1:**camelCase string**}\"$0" ] + "body": [ "# ## string::convertCamelCaseToSnakeCase\n# \n# This function convert a camelCase string to a SNAKE_CASE string.\n# It uses pure bash.\n# Removes all leading underscores.\n# \n# - \\$1: **camelCase string** _as string_:\n# The camelCase string to convert.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The SNAKE_CASE string.\n# \n# ```bash\n# string::convertCamelCaseToSnakeCase \"myCamelCaseString\" && local mySnakeCaseString=\"\\${RETURNED_VALUE}\"\n# ```\n# \nstring::convertCamelCaseToSnakeCase \"${1:**camelCase string**}\"$0" ] }, "string::count": { @@ -1401,60 +1401,60 @@ "body": [ "# ## string::indexOf\n# \n# Find the first index of a string within another string.\n# \n# - \\$1: **string** _as string_:\n# the string in which to search\n# - \\$2: **search** _as string_:\n# the string to search\n# - \\$3: start index _as int_:\n# (optional) the starting index\n# (defaults to 0)\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the index of the substring in the string or -1 if not found.\n# \n# ```bash\n# string::indexOf \"This is a long text\" \"long\" && local index=\"\\${RETURNED_VALUE}\"\n# string::indexOf \"This is a long text\" \"long\" 10 && local index=\"\\${RETURNED_VALUE}\"\n# ```\n# \nstring::indexOf \"${1:**string**}\" \"${2:**search**}\" \"${3:start index}\"$0" ] }, -"string::kebabCaseToCamelCase": { - "prefix": "string::kebabCaseToCamelCase", +"string::convertKebabCaseToCamelCase": { + "prefix": "string::convertKebabCaseToCamelCase", "description": "This function convert a kebab-case string to a camelCase string...", "scope": "", - "body": [ "string::kebabCaseToCamelCase \"${1:**kebab-case string**}\"$0" ] + "body": [ "string::convertKebabCaseToCamelCase \"${1:**kebab-case string**}\"$0" ] }, -"string::kebabCaseToCamelCase#withdoc": { - "prefix": "string::kebabCaseToCamelCase#withdoc", +"string::convertKebabCaseToCamelCase#withdoc": { + "prefix": "string::convertKebabCaseToCamelCase#withdoc", "description": "This function convert a kebab-case string to a camelCase string...", "scope": "", - "body": [ "# ## string::kebabCaseToCamelCase\n# \n# This function convert a kebab-case string to a camelCase string.\n# It uses pure bash.\n# Removes all leading dashes.\n# \n# - \\$1: **kebab-case string** _as string_:\n# The kebab-case string to convert.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The camelCase string.\n# \n# ```bash\n# string::kebabCaseToCamelCase \"my-kebab-case-string\" && local myCamelCaseString=\"\\${RETURNED_VALUE}\"\n# ```\n# \nstring::kebabCaseToCamelCase \"${1:**kebab-case string**}\"$0" ] + "body": [ "# ## string::convertKebabCaseToCamelCase\n# \n# This function convert a kebab-case string to a camelCase string.\n# It uses pure bash.\n# Removes all leading dashes.\n# \n# - \\$1: **kebab-case string** _as string_:\n# The kebab-case string to convert.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The camelCase string.\n# \n# ```bash\n# string::convertKebabCaseToCamelCase \"my-kebab-case-string\" && local myCamelCaseString=\"\\${RETURNED_VALUE}\"\n# ```\n# \nstring::convertKebabCaseToCamelCase \"${1:**kebab-case string**}\"$0" ] }, -"string::kebabCaseToSnakeCase": { - "prefix": "string::kebabCaseToSnakeCase", +"string::convertKebabCaseToSnakeCase": { + "prefix": "string::convertKebabCaseToSnakeCase", "description": "This function convert a kebab-case string to a SNAKE_CASE string...", "scope": "", - "body": [ "string::kebabCaseToSnakeCase \"${1:**kebab-case string**}\"$0" ] + "body": [ "string::convertKebabCaseToSnakeCase \"${1:**kebab-case string**}\"$0" ] }, -"string::kebabCaseToSnakeCase#withdoc": { - "prefix": "string::kebabCaseToSnakeCase#withdoc", +"string::convertKebabCaseToSnakeCase#withdoc": { + "prefix": "string::convertKebabCaseToSnakeCase#withdoc", "description": "This function convert a kebab-case string to a SNAKE_CASE string...", "scope": "", - "body": [ "# ## string::kebabCaseToSnakeCase\n# \n# This function convert a kebab-case string to a SNAKE_CASE string.\n# It uses pure bash.\n# Removes all leading dashes.\n# \n# - \\$1: **kebab-case string** _as string_:\n# The kebab-case string to convert.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The SNAKE_CASE string.\n# \n# ```bash\n# string::kebabCaseToSnakeCase \"my-kebab-case-string\" && local mySnakeCaseString=\"\\${RETURNED_VALUE}\"\n# ```\n# \nstring::kebabCaseToSnakeCase \"${1:**kebab-case string**}\"$0" ] + "body": [ "# ## string::convertKebabCaseToSnakeCase\n# \n# This function convert a kebab-case string to a SNAKE_CASE string.\n# It uses pure bash.\n# Removes all leading dashes.\n# \n# - \\$1: **kebab-case string** _as string_:\n# The kebab-case string to convert.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: The SNAKE_CASE string.\n# \n# ```bash\n# string::convertKebabCaseToSnakeCase \"my-kebab-case-string\" && local mySnakeCaseString=\"\\${RETURNED_VALUE}\"\n# ```\n# \nstring::convertKebabCaseToSnakeCase \"${1:**kebab-case string**}\"$0" ] }, -"string::microsecondsToHuman": { - "prefix": "string::microsecondsToHuman", +"time::convertMicrosecondsToHuman": { + "prefix": "time::convertMicrosecondsToHuman", "description": "Convert microseconds to human readable format...", "scope": "", - "body": [ "string::microsecondsToHuman \"${1:**microseconds**}\" \"${2:format}\"$0" ] + "body": [ "time::convertMicrosecondsToHuman \"${1:**microseconds**}\" \"${2:format}\"$0" ] }, -"string::microsecondsToHuman#withdoc": { - "prefix": "string::microsecondsToHuman#withdoc", +"time::convertMicrosecondsToHuman#withdoc": { + "prefix": "time::convertMicrosecondsToHuman#withdoc", "description": "Convert microseconds to human readable format...", "scope": "", - "body": [ "# ## string::microsecondsToHuman\n# \n# Convert microseconds to human readable format.\n# \n# - \\$1: **microseconds** _as int_:\n# the microseconds to convert\n# - \\$2: format _as string_:\n# (optional) Can be set using the variable `_OPTION_FORMAT`.\n# the format to use (defaults to \"%HH:%MM:%SS\")\n# Usable formats:\n# - %HH: hours\n# - %MM: minutes\n# - %SS: seconds\n# - %LL: milliseconds\n# - %h: hours without leading zero\n# - %m: minutes without leading zero\n# - %s: seconds without leading zero\n# - %l: milliseconds without leading zero\n# - %u: microseconds without leading zero\n# - %M: total minutes\n# - %S: total seconds\n# - %L: total milliseconds\n# - %U: total microseconds\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the human readable format\n# \n# ```bash\n# string::microsecondsToHuman 123456789\n# echo \"\\${RETURNED_VALUE}\"\n# ```\n# \nstring::microsecondsToHuman \"${1:**microseconds**}\" \"${2:format}\"$0" ] + "body": [ "# ## time::convertMicrosecondsToHuman\n# \n# Convert microseconds to human readable format.\n# \n# - \\$1: **microseconds** _as int_:\n# the microseconds to convert\n# - \\$2: format _as string_:\n# (optional) Can be set using the variable `_OPTION_FORMAT`.\n# the format to use (defaults to \"%HH:%MM:%SS\")\n# Usable formats:\n# - %HH: hours\n# - %MM: minutes\n# - %SS: seconds\n# - %LL: milliseconds\n# - %h: hours without leading zero\n# - %m: minutes without leading zero\n# - %s: seconds without leading zero\n# - %l: milliseconds without leading zero\n# - %u: microseconds without leading zero\n# - %M: total minutes\n# - %S: total seconds\n# - %L: total milliseconds\n# - %U: total microseconds\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the human readable format\n# \n# ```bash\n# time::convertMicrosecondsToHuman 123456789\n# echo \"\\${RETURNED_VALUE}\"\n# ```\n# \ntime::convertMicrosecondsToHuman \"${1:**microseconds**}\" \"${2:format}\"$0" ] }, -"string::regexGetFirst": { - "prefix": "string::regexGetFirst", +"regex::getFirstGroup": { + "prefix": "regex::getFirstGroup", "description": "Matches a string against a regex and returns the first capture group of the matched string...", "scope": "", - "body": [ "string::regexGetFirst \"${1:**string**}\" \"${2:**regex**}\"$0" ] + "body": [ "regex::getFirstGroup \"${1:**string**}\" \"${2:**regex**}\"$0" ] }, -"string::regexGetFirst#withdoc": { - "prefix": "string::regexGetFirst#withdoc", +"regex::getFirstGroup#withdoc": { + "prefix": "regex::getFirstGroup#withdoc", "description": "Matches a string against a regex and returns the first capture group of the matched string...", "scope": "", - "body": [ "# ## string::regexGetFirst\n# \n# Matches a string against a regex and returns the first capture group of the matched string.\n# \n# - \\$1: **string** _as string_:\n# the string to match\n# - \\$2: **regex** _as string_:\n# the regex\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the first capture group in the matched string.\n# Empty if no match.\n# \n# ```bash\n# string::regexGetFirst \"name: julien\" \"name:(.*)\"\n# echo \"\\${RETURNED_VALUE}\"\n# ```\n# \n# > Regex wiki: https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions\n# \nstring::regexGetFirst \"${1:**string**}\" \"${2:**regex**}\"$0" ] + "body": [ "# ## regex::getFirstGroup\n# \n# Matches a string against a regex and returns the first capture group of the matched string.\n# \n# - \\$1: **string** _as string_:\n# the string to match\n# - \\$2: **regex** _as string_:\n# the regex\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the first capture group in the matched string.\n# Empty if no match.\n# \n# ```bash\n# regex::getFirstGroup \"name: julien\" \"name:(.*)\"\n# echo \"\\${RETURNED_VALUE}\"\n# ```\n# \n# > Regex wiki: https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions\n# \nregex::getFirstGroup \"${1:**string**}\" \"${2:**regex**}\"$0" ] }, "string::split": { @@ -1513,18 +1513,18 @@ "body": [ "# ## string::wrapCharacters\n# \n# Allows to hard wrap the given string at the given width.\n# Wrapping is done at character boundaries, see string::warpText for word wrapping.\n# Optionally appends padding characters on each new line.\n# \n# - \\$1: **text** _as string_:\n# The text to wrap.\n# - \\$2: wrap width _as string_:\n# (optional) Can be set using the variable `_OPTION_WRAP_WIDTH`.\n# The width to wrap the text at.\n# Note that length of the optional padding characters are subtracted from the\n# width to make sure the text fits in the given width.\n# (defaults to GLOBAL_COLUMNS)\n# - \\$3: padding characters _as string_:\n# (optional) Can be set using the variable `_OPTION_PADDING_CHARS`.\n# The characters to apply as padding on the left of each new line.\n# E.g. ' ' will add 2 spaces on the left of each new line.\n# (defaults to 0)\n# - \\$4: first line width _as int_:\n# (optional) Can be set using the variable `_OPTION_FIRST_LINE_WIDTH`.\n# The width to use for the first line.\n# (defaults to the width)\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the wrapped string\n# - `RETURNED_VALUE2`: the length taken on the last line\n# \n# ```bash\n# string::wrapCharacters \"This is a long text that should be wrapped at 20 characters.\" 20 --- 5\n# echo \"\\${RETURNED_VALUE}\"\n# ```\n# \n# > - This function is written in pure bash and is faster than calling the fold command.\n# > - It considers escape sequence for text formatting and does not count them as visible characters.\n# > - Leading spaces after a newly wrapped line are removed.\n# \nstring::wrapCharacters \"${1:**text**}\" \"${2:wrap width}\" \"${3:padding characters}\" \"${4:first line width}\"$0" ] }, -"string::wrapText": { - "prefix": "string::wrapText", +"string::wrapWords": { + "prefix": "string::wrapWords", "description": "Allows to soft wrap the given text at the given width...", "scope": "", - "body": [ "string::wrapText \"${1:**text**}\" \"${2:wrap width}\" \"${3:padding characters}\" \"${4:first line width}\"$0" ] + "body": [ "string::wrapWords \"${1:**text**}\" \"${2:wrap width}\" \"${3:padding characters}\" \"${4:first line width}\"$0" ] }, -"string::wrapText#withdoc": { - "prefix": "string::wrapText#withdoc", +"string::wrapWords#withdoc": { + "prefix": "string::wrapWords#withdoc", "description": "Allows to soft wrap the given text at the given width...", "scope": "", - "body": [ "# ## string::wrapText\n# \n# Allows to soft wrap the given text at the given width.\n# Wrapping is done at word boundaries.\n# Optionally appends padding characters on each new line.\n# \n# - \\$1: **text** _as string_:\n# The text to wrap.\n# - \\$2: wrap width _as string_:\n# (optional) Can be set using the variable `_OPTION_WRAP_WIDTH`.\n# The width to wrap the text at.\n# Note that length of the optional padding characters are subtracted from the\n# width to make sure the text fits in the given width.\n# (defaults to GLOBAL_COLUMNS)\n# - \\$3: padding characters _as string_:\n# (optional) Can be set using the variable `_OPTION_PADDING_CHARS`.\n# The characters to apply as padding on the left of each new line.\n# E.g. ' ' will add 2 spaces on the left of each new line.\n# (defaults to 0)\n# - \\$4: first line width _as int_:\n# (optional) Can be set using the variable `_OPTION_FIRST_LINE_WIDTH`.\n# The width to use for the first line.\n# (defaults to the width)\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the wrapped text\n# \n# ```bash\n# string::wrapText \"This is a long text that should be wrapped at 20 characters.\" 20 ' ' 5\n# echo \"\\${RETURNED_VALUE}\"\n# ```\n# \n# > - This function is written in pure bash and is faster than calling the fold command.\n# > - This function effectively trims all the extra spaces in the text (leading, trailing but also in the middle).\n# > - It considers escape sequence for text formatting and does not count them as visible characters.\n# \nstring::wrapText \"${1:**text**}\" \"${2:wrap width}\" \"${3:padding characters}\" \"${4:first line width}\"$0" ] + "body": [ "# ## string::wrapWords\n# \n# Allows to soft wrap the given text at the given width.\n# Wrapping is done at word boundaries.\n# Optionally appends padding characters on each new line.\n# \n# - \\$1: **text** _as string_:\n# The text to wrap.\n# - \\$2: wrap width _as string_:\n# (optional) Can be set using the variable `_OPTION_WRAP_WIDTH`.\n# The width to wrap the text at.\n# Note that length of the optional padding characters are subtracted from the\n# width to make sure the text fits in the given width.\n# (defaults to GLOBAL_COLUMNS)\n# - \\$3: padding characters _as string_:\n# (optional) Can be set using the variable `_OPTION_PADDING_CHARS`.\n# The characters to apply as padding on the left of each new line.\n# E.g. ' ' will add 2 spaces on the left of each new line.\n# (defaults to 0)\n# - \\$4: first line width _as int_:\n# (optional) Can be set using the variable `_OPTION_FIRST_LINE_WIDTH`.\n# The width to use for the first line.\n# (defaults to the width)\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the wrapped text\n# \n# ```bash\n# string::wrapWords \"This is a long text that should be wrapped at 20 characters.\" 20 ' ' 5\n# echo \"\\${RETURNED_VALUE}\"\n# ```\n# \n# > - This function is written in pure bash and is faster than calling the fold command.\n# > - This function effectively trims all the extra spaces in the text (leading, trailing but also in the middle).\n# > - It considers escape sequence for text formatting and does not count them as visible characters.\n# \nstring::wrapWords \"${1:**text**}\" \"${2:wrap width}\" \"${3:padding characters}\" \"${4:first line width}\"$0" ] }, "system::addToPath": { @@ -1541,74 +1541,74 @@ "body": [ "# ## system::addToPath\n# \n# Add the given path to the PATH environment variable for various shells,\n# by adding the appropriate export command to the appropriate file.\n# \n# Will also export the PATH variable in the current bash.\n# \n# - \\$1: **path** _as string_:\n# the path to add to the PATH environment variable.\n# \n# ```bash\n# system::addToPath \"/path/to/bin\"\n# ```\n# \nsystem::addToPath \"${1:**path**}\"$0" ] }, -"system::commandExists": { - "prefix": "system::commandExists", +"bash::isCommand": { + "prefix": "bash::isCommand", "description": "Check if the given command exists...", "scope": "", - "body": [ "system::commandExists \"${1:**command name**}\"$0" ] + "body": [ "bash::isCommand \"${1:**command name**}\"$0" ] }, -"system::commandExists#withdoc": { - "prefix": "system::commandExists#withdoc", +"bash::isCommand#withdoc": { + "prefix": "bash::isCommand#withdoc", "description": "Check if the given command exists...", "scope": "", - "body": [ "# ## system::commandExists\n# \n# Check if the given command exists.\n# \n# - \\$1: **command name** _as string_:\n# the command name to check.\n# \n# Returns:\n# \n# - \\$?\n# - 0 if the command exists\n# - 1 otherwise.\n# \n# ```bash\n# if system::commandExists \"command1\"; then\n# printf 'The command exists.'\n# fi\n# ```\n# \nsystem::commandExists \"${1:**command name**}\"$0" ] + "body": [ "# ## bash::isCommand\n# \n# Check if the given command exists.\n# \n# - \\$1: **command name** _as string_:\n# the command name to check.\n# \n# Returns:\n# \n# - \\$?\n# - 0 if the command exists\n# - 1 otherwise.\n# \n# ```bash\n# if bash::isCommand \"command1\"; then\n# printf 'The command exists.'\n# fi\n# ```\n# \nbash::isCommand \"${1:**command name**}\"$0" ] }, -"system::date": { - "prefix": "system::date", +"time::getDate": { + "prefix": "time::getDate", "description": "Get the current date in the given format...", "scope": "", - "body": [ "system::date \"${1:format}\"$0" ] + "body": [ "time::getDate \"${1:format}\"$0" ] }, -"system::date#withdoc": { - "prefix": "system::date#withdoc", +"time::getDate#withdoc": { + "prefix": "time::getDate#withdoc", "description": "Get the current date in the given format...", "scope": "", - "body": [ "# ## system::date\n# \n# Get the current date in the given format.\n# \n# - \\$1: format _as string_:\n# (optional) the format of the date to return\n# (defaults to %(%F_%Hh%Mm%Ss)T).\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the current date in the given format.\n# \n# ```bash\n# system::date\n# local date=\"\\${RETURNED_VALUE}\"\n# ```\n# \n# > This function avoid to call \\$(date) in a subshell (date is a an external executable).\n# \nsystem::date \"${1:format}\"$0" ] + "body": [ "# ## time::getDate\n# \n# Get the current date in the given format.\n# \n# - \\$1: format _as string_:\n# (optional) the format of the date to return\n# (defaults to %(%F_%Hh%Mm%Ss)T).\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the current date in the given format.\n# \n# ```bash\n# time::getDate\n# local date=\"\\${RETURNED_VALUE}\"\n# ```\n# \n# > This function avoid to call \\$(date) in a subshell (date is a an external executable).\n# \ntime::getDate \"${1:format}\"$0" ] }, -"system::env": { - "prefix": "system::env", +"system::getEnvVars": { + "prefix": "system::getEnvVars", "description": "Get the list of all the environment variables...", "scope": "", - "body": [ "system::env$0" ] + "body": [ "system::getEnvVars$0" ] }, -"system::env#withdoc": { - "prefix": "system::env#withdoc", +"system::getEnvVars#withdoc": { + "prefix": "system::getEnvVars#withdoc", "description": "Get the list of all the environment variables...", "scope": "", - "body": [ "# ## system::env\n# \n# Get the list of all the environment variables.\n# In pure bash, no need for env or printenv.\n# \n# Returns:\n# \n# - `RETURNED_ARRAY`: An array with the list of all the environment variables.\n# \n# ```bash\n# system::env\n# for var in \"\\${RETURNED_ARRAY[@]}\"; do\n# printf '%s=%s\\n' \"\\${var}\" \"\\${!var}\"\n# done\n# ```\n# \n# > This is faster than using mapfile on <(compgen -v).\n# \nsystem::env$0" ] + "body": [ "# ## system::getEnvVars\n# \n# Get the list of all the environment variables.\n# In pure bash, no need for env or printenv.\n# \n# Returns:\n# \n# - `RETURNED_ARRAY`: An array with the list of all the environment variables.\n# \n# ```bash\n# system::getEnvVars\n# for var in \"\\${RETURNED_ARRAY[@]}\"; do\n# printf '%s=%s\\n' \"\\${var}\" \"\\${!var}\"\n# done\n# ```\n# \n# > This is faster than using mapfile on <(compgen -v).\n# \nsystem::getEnvVars$0" ] }, -"system::getNotExistingCommands": { - "prefix": "system::getNotExistingCommands", +"bash::getMissingCommands": { + "prefix": "bash::getMissingCommands", "description": "This function returns the list of not existing commands for the given names...", "scope": "", - "body": [ "system::getNotExistingCommands \"${99:**command names**}\"$0" ] + "body": [ "bash::getMissingCommands \"${99:**command names**}\"$0" ] }, -"system::getNotExistingCommands#withdoc": { - "prefix": "system::getNotExistingCommands#withdoc", +"bash::getMissingCommands#withdoc": { + "prefix": "bash::getMissingCommands#withdoc", "description": "This function returns the list of not existing commands for the given names...", "scope": "", - "body": [ "# ## system::getNotExistingCommands\n# \n# This function returns the list of not existing commands for the given names.\n# \n# - \\$@: **command names** _as string_:\n# the list of command names to check.\n# \n# Returns:\n# \n# - \\$?\n# - 0 if there are not existing commands\n# - 1 otherwise.\n# - `RETURNED_ARRAY`: the list of not existing commands.\n# \n# ```bash\n# if system::getNotExistingCommands \"command1\" \"command2\"; then\n# printf 'The following commands do not exist: %s' \"\\${RETURNED_ARRAY[*]}\"\n# fi\n# ```\n# \nsystem::getNotExistingCommands \"${99:**command names**}\"$0" ] + "body": [ "# ## bash::getMissingCommands\n# \n# This function returns the list of not existing commands for the given names.\n# \n# - \\$@: **command names** _as string_:\n# the list of command names to check.\n# \n# Returns:\n# \n# - \\$?\n# - 0 if there are not existing commands\n# - 1 otherwise.\n# - `RETURNED_ARRAY`: the list of not existing commands.\n# \n# ```bash\n# if bash::getMissingCommands \"command1\" \"command2\"; then\n# printf 'The following commands do not exist: %s' \"\\${RETURNED_ARRAY[*]}\"\n# fi\n# ```\n# \nbash::getMissingCommands \"${99:**command names**}\"$0" ] }, -"system::getUndeclaredVariables": { - "prefix": "system::getUndeclaredVariables", +"bash::getMissingVariables": { + "prefix": "bash::getMissingVariables", "description": "This function returns the list of undeclared variables for the given names...", "scope": "", - "body": [ "system::getUndeclaredVariables \"${99:**variable names**}\"$0" ] + "body": [ "bash::getMissingVariables \"${99:**variable names**}\"$0" ] }, -"system::getUndeclaredVariables#withdoc": { - "prefix": "system::getUndeclaredVariables#withdoc", +"bash::getMissingVariables#withdoc": { + "prefix": "bash::getMissingVariables#withdoc", "description": "This function returns the list of undeclared variables for the given names...", "scope": "", - "body": [ "# ## system::getUndeclaredVariables\n# \n# This function returns the list of undeclared variables for the given names.\n# \n# - \\$@: **variable names** _as string_:\n# the list of variable names to check.\n# \n# Returns:\n# \n# - \\$?\n# - 0 if there are variable undeclared\n# - 1 otherwise.\n# - `RETURNED_ARRAY`: the list of undeclared variables.\n# \n# ```bash\n# if system::getUndeclaredVariables \"var1\" \"var2\"; then\n# printf 'The following variables are not declared: %s' \"\\${RETURNED_ARRAY[*]}\"\n# fi\n# ```\n# \nsystem::getUndeclaredVariables \"${99:**variable names**}\"$0" ] + "body": [ "# ## bash::getMissingVariables\n# \n# This function returns the list of undeclared variables for the given names.\n# \n# - \\$@: **variable names** _as string_:\n# the list of variable names to check.\n# \n# Returns:\n# \n# - \\$?\n# - 0 if there are variable undeclared\n# - 1 otherwise.\n# - `RETURNED_ARRAY`: the list of undeclared variables.\n# \n# ```bash\n# if bash::getMissingVariables \"var1\" \"var2\"; then\n# printf 'The following variables are not declared: %s' \"\\${RETURNED_ARRAY[*]}\"\n# fi\n# ```\n# \nbash::getMissingVariables \"${99:**variable names**}\"$0" ] }, "system::isRoot": { @@ -1625,18 +1625,18 @@ "body": [ "# ## system::isRoot\n# \n# Check if the script is running as root.\n# \n# Returns:\n# \n# - \\$?\n# - 0 if the script is running as root\n# - 1 otherwise.\n# \n# ```bash\n# if system::isRoot; then\n# printf 'The script is running as root.'\n# fi\n# ```\n# \nsystem::isRoot$0" ] }, -"system::os": { - "prefix": "system::os", +"system::getOs": { + "prefix": "system::getOs", "description": "Returns the name of the current OS...", "scope": "", - "body": [ "system::os$0" ] + "body": [ "system::getOs$0" ] }, -"system::os#withdoc": { - "prefix": "system::os#withdoc", +"system::getOs#withdoc": { + "prefix": "system::getOs#withdoc", "description": "Returns the name of the current OS...", "scope": "", - "body": [ "# ## system::os\n# \n# Returns the name of the current OS.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the name of the current OS: \"darwin\", \"linux\" or \"windows\".\n# \n# ```bash\n# system::os\n# local osName=\"\\${RETURNED_VALUE}\"\n# ```\n# \nsystem::os$0" ] + "body": [ "# ## system::getOs\n# \n# Returns the name of the current OS.\n# \n# Returns:\n# \n# - `RETURNED_VALUE`: the name of the current OS: \"darwin\", \"linux\" or \"windows\".\n# \n# ```bash\n# system::getOs\n# local osName=\"\\${RETURNED_VALUE}\"\n# ```\n# \nsystem::getOs$0" ] }, "windows::addToPath": { @@ -2000,21 +2000,21 @@ "prefix": "tui::rebindKeymap#withdoc", "description": "Rebinds all special keys to call a given callback function...", "scope": "", - "body": [ "# ## tui::rebindKeymap\n# \n# Rebinds all special keys to call a given callback function.\n# See @tui::testWaitForKeyPress for an implementation example.\n# \n# This allows to use the `-e` option with the read command and receive events for special key press.\n# \n# Key binding is a mess because binding is based on the sequence of characters that gets\n# generated by the terminal when a key is pressed and this is not standard across all terminals.\n# We do our best here to cover most cases but it is by no mean perfect.\n# A good base documentation was .\n# \n# Users of this function can completely change the bindings afterward by implementing\n# the `tuiRebindOverride` function.\n# \n# This function should be called before using tui::waitForKeyPress.\n# \n# You can call `tui::resetBindings` to restore the default bindings. However, this is not\n# necessary as the bindings are local to the script.\n# \n# ```bash\n# tui::rebindKeymap\n# ```\n# \n# > `showkey -a` is a good program to see the sequence of characters sent by the terminal.\n# \ntui::rebindKeymap$0" ] + "body": [ "# ## tui::rebindKeymap\n# \n# Rebinds all special keys to call a given callback function.\n# See @tui::testWaitForKeyPress for an implementation example.\n# \n# This allows to use the `-e` option with the read command and receive events for special key press.\n# \n# Key binding is a mess because binding is based on the sequence of characters that gets\n# generated by the terminal when a key is pressed and this is not standard across all terminals.\n# We do our best here to cover most cases but it is by no mean perfect.\n# A good base documentation was .\n# \n# Users of this function can completely change the bindings afterward by implementing\n# the `tuiRebindOverride` function.\n# \n# This function should be called before using tui::waitForKeyPress.\n# \n# You can call `tui::restoreBindings` to restore the default bindings. However, this is not\n# necessary as the bindings are local to the script.\n# \n# ```bash\n# tui::rebindKeymap\n# ```\n# \n# > `showkey -a` is a good program to see the sequence of characters sent by the terminal.\n# \ntui::rebindKeymap$0" ] }, -"tui::resetBindings": { - "prefix": "tui::resetBindings", +"tui::restoreBindings": { + "prefix": "tui::restoreBindings", "description": "Reset the key bindings to the default ones...", "scope": "", - "body": [ "tui::resetBindings$0" ] + "body": [ "tui::restoreBindings$0" ] }, -"tui::resetBindings#withdoc": { - "prefix": "tui::resetBindings#withdoc", +"tui::restoreBindings#withdoc": { + "prefix": "tui::restoreBindings#withdoc", "description": "Reset the key bindings to the default ones...", "scope": "", - "body": [ "# ## tui::resetBindings\n# \n# Reset the key bindings to the default ones.\n# \n# ```bash\n# tui::resetBindings\n# ```\n# \ntui::resetBindings$0" ] + "body": [ "# ## tui::restoreBindings\n# \n# Reset the key bindings to the default ones.\n# \n# ```bash\n# tui::restoreBindings\n# ```\n# \ntui::restoreBindings$0" ] }, "tui::restoreInterruptTrap": { @@ -2045,32 +2045,32 @@ "body": [ "# ## tui::setInterruptTrap\n# \n# Set a trap to catch the interrupt signal (SIGINT).\n# When the user presses Ctrl+C, the GLOBAL_SESSION_INTERRUPTED variable will be set to true.\n# \n# ```bash\n# tui::setInterruptTrap\n# ```\n# \ntui::setInterruptTrap$0" ] }, -"tui::sttyInit": { - "prefix": "tui::sttyInit", +"tui::setTerminalOptions": { + "prefix": "tui::setTerminalOptions", "description": "Disable the echo of the tty...", "scope": "", - "body": [ "tui::sttyInit$0" ] + "body": [ "tui::setTerminalOptions$0" ] }, -"tui::sttyInit#withdoc": { - "prefix": "tui::sttyInit#withdoc", +"tui::setTerminalOptions#withdoc": { + "prefix": "tui::setTerminalOptions#withdoc", "description": "Disable the echo of the tty...", "scope": "", - "body": [ "# ## tui::sttyInit\n# \n# Disable the echo of the tty. Will no longer display the characters typed by the user.\n# \n# ```bash\n# tui::sttyInit\n# ```\n# \ntui::sttyInit$0" ] + "body": [ "# ## tui::setTerminalOptions\n# \n# Disable the echo of the tty. Will no longer display the characters typed by the user.\n# \n# ```bash\n# tui::setTerminalOptions\n# ```\n# \ntui::setTerminalOptions$0" ] }, -"tui::sttyRestore": { - "prefix": "tui::sttyRestore", +"tui::restoreTerminalOptions": { + "prefix": "tui::restoreTerminalOptions", "description": "Enable the echo of the tty...", "scope": "", - "body": [ "tui::sttyRestore \"${1:**force**}\"$0" ] + "body": [ "tui::restoreTerminalOptions \"${1:**force**}\"$0" ] }, -"tui::sttyRestore#withdoc": { - "prefix": "tui::sttyRestore#withdoc", +"tui::restoreTerminalOptions#withdoc": { + "prefix": "tui::restoreTerminalOptions#withdoc", "description": "Enable the echo of the tty...", "scope": "", - "body": [ "# ## tui::sttyRestore\n# \n# Enable the echo of the tty. Will display the characters typed by the user.\n# \n# - \\$1: **force** _as bool_:\n# (optional) force the restoration of the stty configuration\n# stty state will not be restored if\n# (defaults to false)\n# \n# ```bash\n# tui::sttyRestore\n# ```\n# shellcheck disable=SC2120\n# \ntui::sttyRestore \"${1:**force**}\"$0" ] + "body": [ "# ## tui::restoreTerminalOptions\n# \n# Enable the echo of the tty. Will display the characters typed by the user.\n# \n# - \\$1: **force** _as bool_:\n# (optional) force the restoration of the stty configuration\n# stty state will not be restored if\n# (defaults to false)\n# \n# ```bash\n# tui::restoreTerminalOptions\n# ```\n# shellcheck disable=SC2120\n# \ntui::restoreTerminalOptions \"${1:**force**}\"$0" ] }, "tui::switchBackFromFullScreen": { @@ -2154,7 +2154,7 @@ "prefix": "tui::waitForKeyPress#withdoc", "description": "Wait for a key press (single key)...", "scope": "", - "body": [ "# ## tui::waitForKeyPress\n# \n# Wait for a key press (single key).\n# You can pass additional parameters to the read command (e.g. to wait for a set amount of time).\n# \n# It uses the read builtin command with the option `-e` to use readline behind the scene.\n# This means we can detect more key combinations but all keys needs to be bound first...\n# Special keys (CTRL+, ALT+, F1-F12, arrows, etc.) are intercepted using binding.\n# \n# You must call `tui::rebindKeymap` and `tui::sttyInit` before using this function.\n# \n# - \\$@: **read parameters** _as any_:\n# additional parameters to pass to the read command\n# \n# Returns:\n# \n# - `\\$?`:\n# - 0 if a key was pressed\n# - 1 otherwise\n# - `LAST_KEY_PRESSED`: the key pressed.\n# \n# ```bash\n# tui::waitForKeyPress\n# tui::waitForKeyPress -t 0.1\n# ```\n# \n# > Due to a bug in bash, if the cursor is at the end of the screen, it will make the screen scroll\n# > even when nothing is read... Make sure to not position the cursor at the end of the screen.\n# \ntui::waitForKeyPress \"${99:**read parameters**}\"$0" ] + "body": [ "# ## tui::waitForKeyPress\n# \n# Wait for a key press (single key).\n# You can pass additional parameters to the read command (e.g. to wait for a set amount of time).\n# \n# It uses the read builtin command with the option `-e` to use readline behind the scene.\n# This means we can detect more key combinations but all keys needs to be bound first...\n# Special keys (CTRL+, ALT+, F1-F12, arrows, etc.) are intercepted using binding.\n# \n# You must call `tui::rebindKeymap` and `tui::setTerminalOptions` before using this function.\n# \n# - \\$@: **read parameters** _as any_:\n# additional parameters to pass to the read command\n# \n# Returns:\n# \n# - `\\$?`:\n# - 0 if a key was pressed\n# - 1 otherwise\n# - `LAST_KEY_PRESSED`: the key pressed.\n# \n# ```bash\n# tui::waitForKeyPress\n# tui::waitForKeyPress -t 0.1\n# ```\n# \n# > Due to a bug in bash, if the cursor is at the end of the screen, it will make the screen scroll\n# > even when nothing is read... Make sure to not position the cursor at the end of the screen.\n# \ntui::waitForKeyPress \"${99:**read parameters**}\"$0" ] }, "version::bump": { diff --git a/libraries.d/core b/libraries.d/core index 66a47c0b..494175eb 100644 --- a/libraries.d/core +++ b/libraries.d/core @@ -206,6 +206,10 @@ function fs::cleanTempFiles() { log::debug "Deleting temporary directory." rm -Rf "${GLOBAL_TEMPORARY_DIRECTORY}" 1>/dev/null || : fi + if [[ -n ${GLOBAL_WINDOWS_TEMPORARY_DIRECTORY:-} && -d ${GLOBAL_WINDOWS_TEMPORARY_DIRECTORY} ]]; then + log::debug "Deleting temporary windows directory." + rm -Rf "${GLOBAL_WINDOWS_TEMPORARY_DIRECTORY}" 1>/dev/null || : + fi rm -f "${GLOBAL_TEMPORARY_FILE_PREFIX}"* 1>/dev/null || : unset TEMPORARY_FILE_NUMBER TEMPORARY_DIRECTORY_NUMBER } @@ -447,7 +451,7 @@ function log::createPrintFunction() { done wrapStatement=' - string::wrapText "${RETURNED_VALUE}" '"${wrapTextColumns}"' '"'${wrapPaddingCharacters}'"' '"$((wrapTextColumns - wrapPaddingLength))"'' + string::wrapWords "${RETURNED_VALUE}" '"${wrapTextColumns}"' '"'${wrapPaddingCharacters}'"' '"$((wrapTextColumns - wrapPaddingLength))"'' else wrapPaddingLength=0 fi @@ -853,7 +857,7 @@ function log::printCallStack() { # >>> String utilities #=============================================================== -# ## string::wrapText +# ## string::wrapWords # # Allows to soft wrap the given text at the given width. # Wrapping is done at word boundaries. @@ -882,14 +886,14 @@ function log::printCallStack() { # - `RETURNED_VALUE`: the wrapped text # # ```bash -# string::wrapText "This is a long text that should be wrapped at 20 characters." 20 ' ' 5 +# string::wrapWords "This is a long text that should be wrapped at 20 characters." 20 ' ' 5 # echo "${RETURNED_VALUE}" # ``` # # > - This function is written in pure bash and is faster than calling the fold command. # > - This function effectively trims all the extra spaces in the text (leading, trailing but also in the middle). # > - It considers escape sequence for text formatting and does not count them as visible characters. -function string::wrapText() { +function string::wrapWords() { local text="${1}" local -i width="${2:-${_OPTION_WRAP_WIDTH:-${GLOBAL_COLUMNS}}}" local leftPaddingChars="${3:-${_OPTION_PADDING_CHARS:-}}" @@ -1292,9 +1296,12 @@ function array::fuzzyFilterSortQuicksort() { # - 0 if the function was successfully re-exported # - 1 if the function does not exist # - `RETURNED_VALUE`: the modified function definition +# - `RETURNED_VALUE2`: the original function # # ```bash # bash::getFunctionDefinitionWithGlobalVars "myFunction" "myFunctionWithGlobalVars" "MY_VAR1" "MY_VAR2" +# eval "${RETURNED_VALUE}" +# myFunctionWithGlobalVars # ``` function bash::getFunctionDefinitionWithGlobalVars() { local functionName="${1}" @@ -1302,10 +1309,10 @@ function bash::getFunctionDefinitionWithGlobalVars() { shift 2 local IFS='' - local functionDefinition declare -f "${functionName}" 1>"${GLOBAL_TEMPORARY_STDOUT_FILE}" || return 1 - read -rd '' functionDefinition <"${GLOBAL_TEMPORARY_STDOUT_FILE}" || [[ -n ${functionDefinition} ]] - functionDefinition="${functionDefinition/"${functionName}"/"${newFunctionName}"}" + read -rd '' RETURNED_VALUE2 <"${GLOBAL_TEMPORARY_STDOUT_FILE}" || [[ -n ${RETURNED_VALUE2} ]] + local functionDefinition + functionDefinition="${RETURNED_VALUE2/"${functionName}"/"${newFunctionName}"}" # find the mapping between the positional parameters and the new global variable names local -A globalVars=() @@ -1336,6 +1343,32 @@ function bash::getFunctionDefinitionWithGlobalVars() { RETURNED_VALUE="${modifiedFunctionDefinition}" } +#=============================================================== +# >>> Time utilities +#=============================================================== + +# ## time::getProgramElapsedMicroseconds +# +# Get the elapsed time in µs since the program started. +# +# Returns: +# +# - `RETURNED_VALUE`: the elapsed time in µs since the program started. +# +# ```bash +# core::getElapsedProgramTime +# echo "${RETURNED_VALUE}" +# time::convertMicrosecondsToHuman "${RETURNED_VALUE}" +# echo "Human time: ${RETURNED_VALUE}" +# ``` +# +# > We split the computation in seconds and milliseconds to avoid overflow on 32-bit systems. +# > The 10# forces the base 10 conversion to avoid issues with leading zeros. +# > Fun fact: this function will fail in 2038 on 32-bit systems because the number of seconds will overflow. +function time::getProgramElapsedMicroseconds() { + RETURNED_VALUE=$(((${EPOCHREALTIME%%\.*} - GLOBAL_PROGRAM_STARTED_AT_SECOND) * 1000000 + (10#${EPOCHREALTIME##*\.} - 10#${GLOBAL_PROGRAM_STARTED_AT_MICROSECOND}))) +} + #=============================================================== # >>> Core utilities #=============================================================== @@ -1541,28 +1574,6 @@ function core::getVersion() { fs::readFile "${GLOBAL_INSTALLATION_DIRECTORY}/version" } -# ## core::getProgramElapsedMicroseconds -# -# Get the elapsed time in µs since the program started. -# -# Returns: -# -# - `RETURNED_VALUE`: the elapsed time in µs since the program started. -# -# ```bash -# core::getElapsedProgramTime -# echo "${RETURNED_VALUE}" -# string::microsecondsToHuman "${RETURNED_VALUE}" -# echo "Human time: ${RETURNED_VALUE}" -# ``` -# -# > We split the computation in seconds and milliseconds to avoid overflow on 32-bit systems. -# > The 10# forces the base 10 conversion to avoid issues with leading zeros. -# > Fun fact: this function will fail in 2038 on 32-bit systems because the number of seconds will overflow. -function core::getProgramElapsedMicroseconds() { - RETURNED_VALUE=$(((${EPOCHREALTIME%%\.*} - GLOBAL_PROGRAM_STARTED_AT_SECOND) * 1000000 + (10#${EPOCHREALTIME##*\.} - 10#${GLOBAL_PROGRAM_STARTED_AT_MICROSECOND}))) -} - #=============================================================== # >>> Valet files and directories #=============================================================== diff --git a/libraries.d/lib-bash b/libraries.d/lib-bash index 7e41c1ff..c796ed41 100644 --- a/libraries.d/lib-bash +++ b/libraries.d/lib-bash @@ -137,7 +137,7 @@ function bash::runInParallel() { done if ((nbJobsCompleted == 0)); then - exe::sleep "${timeoutBetweenChecks}" + bash::sleep "${timeoutBetweenChecks}" fi if ((${#exitCodes[@]} == ${#jobNames[@]})); then @@ -220,4 +220,199 @@ function bash::injectCodeInFunction() { RETURNED_VALUE="${modifiedFunctionDefinition}" RETURNED_VALUE2="${functionDefinition:-}" +} + +# ## bash::sleep +# +# Sleep for the given amount of time. +# This is a pure bash replacement of sleep. +# +# - $1: **time** _as float_: +# the time to sleep in seconds (can be a float) +# +# ```bash +# bash::sleep 1.5 +# ``` +# +# > The sleep command is not a built-in command in bash, but a separate executable. When you use sleep, you are creating a new process. +function bash::sleep() { + local timeout="${1}" + # when connected to a terminal, we can just read the stdout + # which will never be written to, and use a timeout on read + if [[ -t 2 ]]; then + read -rt "${timeout}" -u 2 || : + return 0 + elif command -v mkfifo 1>/dev/null; then + if [[ -z ${IO_SLEEP_FIFO:-} ]]; then + fs::createTempFile && IO_SLEEP_FIFO="${RETURNED_VALUE}" + rm "${IO_SLEEP_FIFO}" + mkfifo -m 700 "${IO_SLEEP_FIFO}" + exec 6<>"${IO_SLEEP_FIFO}" + rm "${IO_SLEEP_FIFO}" + fi + read -rt "${timeout}" -u 6 || : + else + # when everything else failed... + sleep "${timeout}" + fi +} + +# ## bash::readStdIn +# +# Read the content of the standard input. +# Will immediately return if the standard input is empty. +# +# Returns: +# +# - `RETURNED_VALUE`: The content of the standard input. +# +# ```bash +# bash::readStdIn && local stdIn="${RETURNED_VALUE}" +# ``` +function bash::readStdIn() { + RETURNED_VALUE="" + local IFS='' + if read -t 0 -u 0 -rd ''; then + read -u 0 -rd '' RETURNED_VALUE || [[ -n ${RETURNED_VALUE} ]] || RETURNED_VALUE="" + else + RETURNED_VALUE="" + fi +} + +# ## bash::countArgs +# +# Returns the number of arguments passed. +# +# A convenient function that can be used to: +# +# - count the files/directories in a directory +# `bash::countArgs "${PWD}"/* && local numberOfFiles="${RETURNED_VALUE}"` +# - count the number of variables starting with VALET_ +# `bash::countArgs "${!VALET_@}" && local numberOfVariables="${RETURNED_VALUE}"` +# +# - $@: **arguments** _as any_: +# the arguments to count +# +# Returns: +# +# - `RETURNED_VALUE`: The number of arguments passed. +# +# ```bash +# bash::countArgs 1 2 3 +# ``` +function bash::countArgs() { + RETURNED_VALUE="$#" +} + +# ## bash::getMissingVariables +# +# This function returns the list of undeclared variables for the given names. +# +# - $@: **variable names** _as string_: +# the list of variable names to check. +# +# Returns: +# +# - $? +# - 0 if there are variable undeclared +# - 1 otherwise. +# - `RETURNED_ARRAY`: the list of undeclared variables. +# +# ```bash +# if bash::getMissingVariables "var1" "var2"; then +# printf 'The following variables are not declared: %s' "${RETURNED_ARRAY[*]}" +# fi +# ``` +function bash::getMissingVariables() { + RETURNED_ARRAY=() + local var + for var in "$@"; do + if [[ ! -v "${var}" ]]; then + RETURNED_ARRAY+=("${var}") + fi + done + if [[ ${#RETURNED_ARRAY[@]} -gt 0 ]]; then + return 0 + fi + return 1 +} + +# ## bash::getMissingCommands +# +# This function returns the list of not existing commands for the given names. +# +# - $@: **command names** _as string_: +# the list of command names to check. +# +# Returns: +# +# - $? +# - 0 if there are not existing commands +# - 1 otherwise. +# - `RETURNED_ARRAY`: the list of not existing commands. +# +# ```bash +# if bash::getMissingCommands "command1" "command2"; then +# printf 'The following commands do not exist: %s' "${RETURNED_ARRAY[*]}" +# fi +# ``` +function bash::getMissingCommands() { + RETURNED_ARRAY=() + local cmd + for cmd in "$@"; do + if ! command -v "${cmd}" &>/dev/null; then + RETURNED_ARRAY+=("${cmd}") + fi + done + if [[ ${#RETURNED_ARRAY[@]} -gt 0 ]]; then + return 0 + fi + return 1 +} + +# ## bash::isCommand +# +# Check if the given command exists. +# +# - $1: **command name** _as string_: +# the command name to check. +# +# Returns: +# +# - $? +# - 0 if the command exists +# - 1 otherwise. +# +# ```bash +# if bash::isCommand "command1"; then +# printf 'The command exists.' +# fi +# ``` +function bash::isCommand() { + if command -v "${1:-}" &>/dev/null; then + return 0 + fi + return 1 +} + +# ## system::isRoot +# +# Check if the script is running as root. +# +# Returns: +# +# - $? +# - 0 if the script is running as root +# - 1 otherwise. +# +# ```bash +# if system::isRoot; then +# printf 'The script is running as root.' +# fi +# ``` +function system::isRoot() { + if [[ ${EUID:-${UID}} -eq 0 ]]; then + return 0 + fi + return 1 } \ No newline at end of file diff --git a/libraries.d/lib-benchmark b/libraries.d/lib-benchmark index 247af3fe..7a4efb04 100644 --- a/libraries.d/lib-benchmark +++ b/libraries.d/lib-benchmark @@ -10,6 +10,8 @@ source string source ansi-codes # shellcheck source=lib-progress source progress +# shellcheck source=lib-time +source time # ## benchmark::run @@ -69,7 +71,7 @@ function benchmark::run() { # Run the baseline progress::start "#spinner Running the baseline ⌜${baseline}⌝ for ⌜${time}s⌝." - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds local startTimeInUs="${RETURNED_VALUE}" local -i baselineRuns @@ -77,7 +79,7 @@ function benchmark::run() { # ^(this is to avoid a bug in the syntax coloration) for ((baselineRuns = 1; (baselineRuns <= maxRuns || maxRuns == -1); baselineRuns++)); do "${baseline}" - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds if (( RETURNED_VALUE - startTimeInUs > time * 1000000 )); then break fi @@ -85,9 +87,9 @@ function benchmark::run() { progress::stop - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds local elapsedTimeInUs=$((RETURNED_VALUE - startTimeInUs)) - string::microsecondsToHuman "${elapsedTimeInUs}" '%S.%LL' + time::convertMicrosecondsToHuman "${elapsedTimeInUs}" '%S.%LL' log::info "The baseline ⌜${baseline}⌝ was initially run ⌜${baselineRuns}⌝ times in ⌜${RETURNED_VALUE}s⌝." # Run the other functions @@ -95,17 +97,17 @@ function benchmark::run() { for function in ${functions}; do progress::start "#spinner Running the function ⌜${function}⌝ ⌜${baselineRuns}⌝ times." - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds startTimeInUs="${RETURNED_VALUE}" local -i runs for ((runs = 0; runs < baselineRuns; runs++)); do "${function}" done - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds local elapsedTimeInUs=$((RETURNED_VALUE - startTimeInUs)) functionsElapsed["${function}"]="${elapsedTimeInUs}" - string::microsecondsToHuman "${elapsedTimeInUs}" %S.%LL + time::convertMicrosecondsToHuman "${elapsedTimeInUs}" %S.%LL log::info "The function ⌜${function}⌝ was run ⌜${runs}⌝ times in ⌜${RETURNED_VALUE}s⌝." progress::stop @@ -115,16 +117,16 @@ function benchmark::run() { # Re run the baseline to get the average time progress::start "#spinner Running the baseline ⌜${baseline}⌝ ⌜${baselineRuns}⌝ times." - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds startTimeInUs="${RETURNED_VALUE}" local -i runs for ((runs = 0; runs < baselineRuns; runs++)); do "${baseline}" done - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds local elapsedTimeInUs=$((RETURNED_VALUE - startTimeInUs)) functionsElapsed["${baseline}"]="${elapsedTimeInUs}" - string::microsecondsToHuman "${elapsedTimeInUs}" %S.%LL + time::convertMicrosecondsToHuman "${elapsedTimeInUs}" %S.%LL log::info "The function ⌜${baseline}⌝ was run ⌜${runs}⌝ times in ⌜${RETURNED_VALUE}s⌝." progress::stop @@ -144,7 +146,7 @@ function benchmark::run() { for function in "${_BENCHMARK_FUNCTIONS[@]}"; do local averageTime="$((functionsElapsed[${function}] / baselineRuns))" local percentSlowerThanFastest="+$(( (functionsElapsed[${function}] - fastestElapsed) * 100 / fastestElapsed ))%" - string::microsecondsToHuman "${averageTime}" "%S.%LLs %UUµs" + time::convertMicrosecondsToHuman "${averageTime}" "%S.%LLs %UUµs" if (( index == 0 )); then percentSlowerThanFastest="N/A" fi diff --git a/libraries.d/lib-curl b/libraries.d/lib-curl index d526deff..59ca2378 100644 --- a/libraries.d/lib-curl +++ b/libraries.d/lib-curl @@ -7,11 +7,11 @@ source exe # shellcheck source=lib-fs source fs -# ## curl::toFile +# ## curl::download # -# This function is a wrapper around curl. +# This function is a wrapper around curl to save a request result in a file. # It allows you to check the http status code and return 1 if it is not acceptable. -# It exe::invokes curl with the following options (do not repeat them): -sSL -w "%{response_code}" -o ${2}. +# It invokes curl with the following options (do not repeat them): -sSL -w "%{response_code}" -o ${2}. # # - $1: **fail** _as bool_: # true/false to indicate if the function should fail in case the execution fails @@ -32,10 +32,10 @@ source fs # - `RETURNED_VALUE2`: the http status code # # ```bash -# curl::toFile true 200,201 "/filePath" "https://example.com" -# curl::toFile false 200 "/filePath2" "https://example2.com" || core::fail "The curl command failed." +# curl::download true 200,201 "/filePath" "https://example.com" +# curl::download false 200 "/filePath2" "https://example2.com" || core::fail "The curl command failed." # ``` -function curl::toFile() { +function curl::download() { local failIfFails="${1:-false}" local acceptableStatusCodes="${2:-200,201,202,204,301,304,308}" local outputFile="${3}" @@ -90,11 +90,11 @@ function curl::toFile() { return ${exitCode} } -# ## curl::toVar +# ## curl::request # -# This function is a wrapper around curl. +# This function is a wrapper around curl to save the content of a request in a variable. # It allows you to check the http status code and return 1 if it is not acceptable. -# It exe::invokes curl with the following options (do not repeat them): -sSL -w "%{response_code}" -o "tempfile". +# It invokes curl with the following options (do not repeat them): -sSL -w "%{response_code}" -o "tempfile". # # - $1: **fail** _as bool_: # true/false to indicate if the function should fail in case the execution fails @@ -114,10 +114,10 @@ function curl::toFile() { # - `RETURNED_VALUE3`: the http status code # # ```bash -# curl::toVar true 200 https://example.com -X POST -H 'Authorization: token' -# curl::toVar false 200,201 https://example.com || core::fail "The curl command failed." +# curl::request true 200 https://example.com -X POST -H 'Authorization: token' +# curl::request false 200,201 https://example.com || core::fail "The curl command failed." # ``` -function curl::toVar() { +function curl::request() { local failIfFails="${1:-false}" local acceptableStatusCodes="${2:-}" shift 2 @@ -127,7 +127,7 @@ function curl::toVar() { local -i exitCode=0 local errors httpStatusCode - curl::toFile "${failIfFails}" "${acceptableStatusCodes}" "${GLOBAL_TEMPORARY_WORK_FILE}" "$@" || exitCode=$? + curl::download "${failIfFails}" "${acceptableStatusCodes}" "${GLOBAL_TEMPORARY_WORK_FILE}" "$@" || exitCode=$? errors="${RETURNED_VALUE}" httpStatusCode="${RETURNED_VALUE2}" diff --git a/libraries.d/lib-exe b/libraries.d/lib-exe index cb6ae6d4..e03f3186 100644 --- a/libraries.d/lib-exe +++ b/libraries.d/lib-exe @@ -185,7 +185,7 @@ function exe::invoke5() { # # This function call an executable and its arguments. # It redirects the stdout and stderr to temporary files. -# Equivalent to exe::invokef5 "${1}" 0 "" "" "${@:2}" +# Equivalent to `exe::invokef5 "${1}" 0 "" "" "${@:2}"` # # - $1: **fail** _as bool_: # true/false to indicate if the function should fail in case the execution fails. @@ -218,7 +218,7 @@ function exe::invokef2() { # # This function call an executable and its arguments. # It redirects the stdout and stderr to environment variables. -# Equivalent to exe::invoke5 "${1}" 0 "" "" "${@:2}" +# Equivalent to `exe::invoke5 "${1}" 0 "" "" "${@:2}"` # # - $1: **fail** _as bool_: # true/false to indicate if the function should fail in case the execution fails. @@ -251,7 +251,7 @@ function exe::invoke2() { # # This function call an executable and its arguments and input a given string as stdin. # It redirects the stdout and stderr to temporary files. -# Equivalent to exe::invokef5 "${1}" 0 false "${2}" "${@:3}" +# Equivalent to `exe::invokef5 "${1}" 0 false "${2}" "${@:3}"` # # - $1: **fail** _as bool_: # true/false to indicate if the function should fail in case the execution fails. @@ -291,7 +291,7 @@ function exe::invokef2piped() { # # This function call an executable and its arguments and input a given string as stdin. # It redirects the stdout and stderr to environment variables. -# Equivalent to exe::invoke5 "${1}" 0 false "${2}" "${@:3}" +# Equivalent to `exe::invoke5 "${1}" 0 false "${2}" "${@:3}"` # # - $1: **fail** _as bool_: # true/false to indicate if the function should fail in case the execution fails. @@ -334,7 +334,7 @@ function exe::invoke2piped() { # Otherwise it hides both streams, effectively rendering the execution silent unless it fails. # # It redirects the stdout and stderr to environment variables. -# Equivalent to exe::invoke5 true 0 '' '' "${@}" +# Equivalent to `exe::invoke5 true 0 '' '' "${@}"` # # - $1: **executable** _as string_: # the executable or command @@ -385,85 +385,3 @@ function exe::captureOutput() { RETURNED_VALUE="" IFS='' read -rd '' RETURNED_VALUE <"${GLOBAL_TEMPORARY_STDOUT_FILE}" || : } - -# ## exe::sleep -# -# Sleep for the given amount of time. -# This is a pure bash replacement of sleep. -# -# - $1: **time** _as float_: -# the time to sleep in seconds (can be a float) -# -# ```bash -# io:sleep 1.5 -# ``` -# -# > The sleep command is not a built-in command in bash, but a separate executable. When you use sleep, you are creating a new process. -function exe::sleep() { - local timeout="${1}" - # when connected to a terminal, we can just read the stdout - # which will never be written to, and use a timeout on read - if [[ -t 2 ]]; then - read -rt "${timeout}" -u 2 || : - return 0 - elif command -v mkfifo 1>/dev/null; then - if [[ -z ${IO_SLEEP_FIFO:-} ]]; then - fs::createTempFile && IO_SLEEP_FIFO="${RETURNED_VALUE}" - rm "${IO_SLEEP_FIFO}" - mkfifo -m 700 "${IO_SLEEP_FIFO}" - exec 6<>"${IO_SLEEP_FIFO}" - rm "${IO_SLEEP_FIFO}" - fi - read -rt "${timeout}" -u 6 || : - else - # when everything else failed... - sleep "${timeout}" - fi -} - -# ## exe::readStdIn -# -# Read the content of the standard input. -# Will immediately return if the standard input is empty. -# -# Returns: -# -# - `RETURNED_VALUE`: The content of the standard input. -# -# ```bash -# exe::readStdIn && local stdIn="${RETURNED_VALUE}" -# ``` -function exe::readStdIn() { - RETURNED_VALUE="" - local IFS='' - if read -t 0 -u 0 -rd ''; then - read -u 0 -rd '' RETURNED_VALUE || [[ -n ${RETURNED_VALUE} ]] || RETURNED_VALUE="" - else - RETURNED_VALUE="" - fi -} - -# ## exe::countArgs -# -# Returns the number of arguments passed. -# -# A convenient function that can be used to: -# -# - count the files/directories in a directory -# `exe::countArgs "${PWD}"/* && local numberOfFiles="${RETURNED_VALUE}"` -# - count the number of variables starting with VALET_ -# `exe::countArgs "${!VALET_@}" && local numberOfVariables="${RETURNED_VALUE}"` -# -# - $@: **arguments** _as any_: -# the arguments to count -# -# Returns: -# -# - `RETURNED_VALUE`: The number of arguments passed. -# -# ```bash -# exe::countArgs 1 2 3 -# ``` -function exe::countArgs() { - RETURNED_VALUE="$#" -} \ No newline at end of file diff --git a/libraries.d/lib-interactive b/libraries.d/lib-interactive index 78259741..cd666b53 100644 --- a/libraries.d/lib-interactive +++ b/libraries.d/lib-interactive @@ -95,6 +95,8 @@ function interactive::askForConfirmationRaw() { # - The user can validate the choice with the enter key. # - The user can also validate immediately with the y or n key. # +# Dialog boxes are displayed for the question and answer. +# # - $1: **prompt** _as string_: # the prompt to display # - $2: default _as bool_: @@ -304,7 +306,7 @@ interactive::displayDialogBox() { textWidth=${#text} fi - string::wrapText "${text}" "${textWidth}" + string::wrapWords "${text}" "${textWidth}" local wrappedText="${RETURNED_VALUE}" local finalString line sideString diff --git a/libraries.d/lib-progress b/libraries.d/lib-progress index d96bf782..84759003 100644 --- a/libraries.d/lib-progress +++ b/libraries.d/lib-progress @@ -6,8 +6,8 @@ source ansi-codes # shellcheck source=lib-fs source fs -# shellcheck source=lib-exe -source exe +# shellcheck source=lib-bash +source bash # shellcheck source=lib-tui source tui @@ -114,7 +114,7 @@ function progress_runAnimationInBackground() { spinnerIndex=$((spinnerIndex >= ${#spinner} - 1 ? 0 : spinnerIndex + 1)) loop+=1 - exe::sleep "${frameDelay}" + bash::sleep "${frameDelay}" done } @@ -185,7 +185,7 @@ function progress::start() { printf '%s' "${AC__CURSOR_HIDE}" # disable echoing when we type something - tui::sttyInit + tui::setTerminalOptions fs::createTempFile _PROGRESS_BAR_UPDATE_FILE="${RETURNED_VALUE}" @@ -266,5 +266,5 @@ function progress::stop() { printf "%s" "${AC__ERASE_LINE}${AC__CURSOR_SHOW}" # restore the key echoing - tui::sttyRestore + tui::restoreTerminalOptions } diff --git a/libraries.d/lib-prompt b/libraries.d/lib-prompt index b80a2d56..2e505a27 100644 --- a/libraries.d/lib-prompt +++ b/libraries.d/lib-prompt @@ -337,7 +337,7 @@ function prompt::input() { # before starting to wait for inputs, we clear up the key pressed tui::clearKeyPressed # setup the terminal to be ready for readline - tui::sttyInit + tui::setTerminalOptions # rebind some keys to call the callback function prompt_onKeyBindingPress tui::rebindKeymap prompt_onKeyBindingPress @@ -394,7 +394,7 @@ function prompt::input() { prompt_clearErrorBox prompt_clearItemsBox prompt_clearPrompt - tui::sttyRestore + tui::restoreTerminalOptions tui::restoreInterruptTrap shopt -u nocasematch @@ -760,7 +760,7 @@ function prompt_onKeyPressed() { prompt_onTextChanged # here we handle the case where the user pastes a string (or spam a key) - core::getProgramElapsedMicroseconds + time::getProgramElapsedMicroseconds if ((RETURNED_VALUE - _PROMPT_LAST_KEY_PRESSED_TIME < 300000)); then # key pressed under 100ms of the last _PROMPT_NB_SUCCESSIVE_RAPID_KEY_PRESSED=$((_PROMPT_NB_SUCCESSIVE_RAPID_KEY_PRESSED + 1)) @@ -1223,7 +1223,7 @@ function prompt_showError() { prompt_clearItemsBox prompt_clearErrorBox - string::wrapText "${message}" $((_PROMPT_WIDTH - ${#_PROMPT_ERROR_BOX_SYMBOL})) + string::wrapWords "${message}" $((_PROMPT_WIDTH - ${#_PROMPT_ERROR_BOX_SYMBOL})) local IFS=$'\n' local text="${RETURNED_VALUE}" local -i errorLinesNeeded=0 @@ -1470,7 +1470,7 @@ function prompt_getCurrentInitialItemsIndex() { RETURNED_VALUE=-1 } -# ## prompt_getDisplayedPromptString +# ## prompt_getDisplayedPromptString (private) # # This function return a string that can be printed in a terminal in order to display a text # and position the cursor at a given index in the input text. diff --git a/libraries.d/lib-regex b/libraries.d/lib-regex new file mode 100644 index 00000000..076acee4 --- /dev/null +++ b/libraries.d/lib-regex @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# author: github.com/jcaillon +# description: This script can be sourced by commands to provide convenient functions. + +# ## regex::getFirstGroup +# +# Matches a string against a regex and returns the first capture group of the matched string. +# +# - $1: **string** _as string_: +# the string to match +# - $2: **regex** _as string_: +# the regex +# +# Returns: +# +# - `RETURNED_VALUE`: the first capture group in the matched string. +# Empty if no match. +# +# ```bash +# regex::getFirstGroup "name: julien" "name:(.*)" +# echo "${RETURNED_VALUE}" +# ``` +# +# > Regex wiki: https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions +function regex::getFirstGroup() { + # Usage: regex "string" "regex" + if [[ ${1} =~ ${2} ]]; then + RETURNED_VALUE="${BASH_REMATCH[1]:-}" + else + # shellcheck disable=SC2034 + RETURNED_VALUE="" + fi +} diff --git a/libraries.d/lib-sfzf b/libraries.d/lib-sfzf index 84195aed..e23678d4 100644 --- a/libraries.d/lib-sfzf +++ b/libraries.d/lib-sfzf @@ -217,7 +217,7 @@ function sfzfDrawScreen() { # - compute the number of content lines for the pane # 1. draw the prompt string - string::wrapText "${prompt}" "$((SFZF_LEFT_PANE_WIDTH - 1))" + string::wrapWords "${prompt}" "$((SFZF_LEFT_PANE_WIDTH - 1))" prompt="${RETURNED_VALUE}" SFZF_LEFT_PANE_FIRST_LINE=1 local IFS line diff --git a/libraries.d/lib-string b/libraries.d/lib-string index 75a06bcc..a8ad6421 100644 --- a/libraries.d/lib-string +++ b/libraries.d/lib-string @@ -47,7 +47,7 @@ function string::cutField() { RETURNED_VALUE="" } -# ## string::camelCaseToSnakeCase +# ## string::convertCamelCaseToSnakeCase # # This function convert a camelCase string to a SNAKE_CASE string. # It uses pure bash. @@ -61,9 +61,9 @@ function string::cutField() { # - `RETURNED_VALUE`: The SNAKE_CASE string. # # ```bash -# string::camelCaseToSnakeCase "myCamelCaseString" && local mySnakeCaseString="${RETURNED_VALUE}" +# string::convertCamelCaseToSnakeCase "myCamelCaseString" && local mySnakeCaseString="${RETURNED_VALUE}" # ``` -function string::camelCaseToSnakeCase() { +function string::convertCamelCaseToSnakeCase() { local camelCase="${1}" local snakeCase="" local -i charIndex strLength=${#camelCase} @@ -82,7 +82,7 @@ function string::camelCaseToSnakeCase() { RETURNED_VALUE="${snakeCase}" } -# ## string::kebabCaseToSnakeCase +# ## string::convertKebabCaseToSnakeCase # # This function convert a kebab-case string to a SNAKE_CASE string. # It uses pure bash. @@ -96,9 +96,9 @@ function string::camelCaseToSnakeCase() { # - `RETURNED_VALUE`: The SNAKE_CASE string. # # ```bash -# string::kebabCaseToSnakeCase "my-kebab-case-string" && local mySnakeCaseString="${RETURNED_VALUE}" +# string::convertKebabCaseToSnakeCase "my-kebab-case-string" && local mySnakeCaseString="${RETURNED_VALUE}" # ``` -function string::kebabCaseToSnakeCase() { +function string::convertKebabCaseToSnakeCase() { local kebabCase="${1}" local snakeCase="" local -i charIndex strLength=${#kebabCase} @@ -117,7 +117,7 @@ function string::kebabCaseToSnakeCase() { RETURNED_VALUE="${snakeCase}" } -# ## string::kebabCaseToCamelCase +# ## string::convertKebabCaseToCamelCase # # This function convert a kebab-case string to a camelCase string. # It uses pure bash. @@ -131,9 +131,9 @@ function string::kebabCaseToSnakeCase() { # - `RETURNED_VALUE`: The camelCase string. # # ```bash -# string::kebabCaseToCamelCase "my-kebab-case-string" && local myCamelCaseString="${RETURNED_VALUE}" +# string::convertKebabCaseToCamelCase "my-kebab-case-string" && local myCamelCaseString="${RETURNED_VALUE}" # ``` -function string::kebabCaseToCamelCase() { +function string::convertKebabCaseToCamelCase() { local kebabCase="${1}" local camelCase="" local -i charIndex strLength=${#kebabCase} @@ -369,120 +369,6 @@ function string::split() { RETURNED_ARRAY=(${1}) } -# ## string::regexGetFirst -# -# Matches a string against a regex and returns the first capture group of the matched string. -# -# - $1: **string** _as string_: -# the string to match -# - $2: **regex** _as string_: -# the regex -# -# Returns: -# -# - `RETURNED_VALUE`: the first capture group in the matched string. -# Empty if no match. -# -# ```bash -# string::regexGetFirst "name: julien" "name:(.*)" -# echo "${RETURNED_VALUE}" -# ``` -# -# > Regex wiki: https://en.wikibooks.org/wiki/Regular_Expressions/POSIX-Extended_Regular_Expressions -function string::regexGetFirst() { - # Usage: regex "string" "regex" - if [[ ${1} =~ ${2} ]]; then - RETURNED_VALUE="${BASH_REMATCH[1]:-}" - else - RETURNED_VALUE="" - fi -} - -# ## string::microsecondsToHuman -# -# Convert microseconds to human readable format. -# -# - $1: **microseconds** _as int_: -# the microseconds to convert -# - $2: format _as string_: -# (optional) Can be set using the variable `_OPTION_FORMAT`. -# the format to use (defaults to "%HH:%MM:%SS") -# Usable formats: -# - %HH: hours -# - %MM: minutes -# - %SS: seconds -# - %LL: milliseconds -# - %h: hours without leading zero -# - %m: minutes without leading zero -# - %s: seconds without leading zero -# - %l: milliseconds without leading zero -# - %u: microseconds without leading zero -# - %M: total minutes -# - %S: total seconds -# - %L: total milliseconds -# - %U: total microseconds -# -# Returns: -# -# - `RETURNED_VALUE`: the human readable format -# -# ```bash -# string::microsecondsToHuman 123456789 -# echo "${RETURNED_VALUE}" -# ``` -function string::microsecondsToHuman() { - local -i ms="${1}" - local format="${2:-${_OPTION_FORMAT:-"%HH:%MM:%SS"}}" - - local -i hours=$((ms / 3600 / 1000000)) - local -i minutes=$(((ms / 60 / 1000000) % 60)) - local -i seconds=$(((ms / 1000000) % 60)) - local -i milliseconds=$((ms / 1000 % 1000)) - local -i microseconds=$((ms % 1000)) - - local humanFormat="${format}" - if [[ ${hours} -lt 10 ]]; then - humanFormat="${humanFormat//%HH/0${hours}}" - else - humanFormat="${humanFormat//%HH/${hours}}" - fi - if [[ ${minutes} -lt 10 ]]; then - humanFormat="${humanFormat//%MM/0${minutes}}" - else - humanFormat="${humanFormat//%MM/${minutes}}" - fi - if [[ ${seconds} -lt 10 ]]; then - humanFormat="${humanFormat//%SS/0${seconds}}" - else - humanFormat="${humanFormat//%SS/${seconds}}" - fi - if [[ ${milliseconds} -lt 10 ]]; then - humanFormat="${humanFormat//%LL/00${milliseconds}}" - elif [[ ${milliseconds} -lt 100 ]]; then - humanFormat="${humanFormat//%LL/0${milliseconds}}" - else - humanFormat="${humanFormat//%LL/${milliseconds}}" - fi - if [[ ${microseconds} -lt 10 ]]; then - humanFormat="${humanFormat//%UU/00${microseconds}}" - elif [[ ${microseconds} -lt 100 ]]; then - humanFormat="${humanFormat//%UU/0${microseconds}}" - else - humanFormat="${humanFormat//%UU/${microseconds}}" - fi - humanFormat="${humanFormat//%h/${hours}}" - humanFormat="${humanFormat//%m/${minutes}}" - humanFormat="${humanFormat//%s/${seconds}}" - humanFormat="${humanFormat//%l/${milliseconds}}" - humanFormat="${humanFormat//%u/${microseconds}}" - humanFormat="${humanFormat//%M/$((hours * 60 + minutes))}" - humanFormat="${humanFormat//%S/$((hours * 3600 + minutes * 60 + seconds))}" - humanFormat="${humanFormat//%L/$(((hours * 3600 * + minutes * 60 + seconds) * 1000 + milliseconds))}" - humanFormat="${humanFormat//%U/$((ms))}" - - RETURNED_VALUE="${humanFormat}" -} - # ## string::head # # Get the first n lines of a string. diff --git a/libraries.d/lib-system b/libraries.d/lib-system index 0e6fd856..47314612 100644 --- a/libraries.d/lib-system +++ b/libraries.d/lib-system @@ -5,7 +5,7 @@ # shellcheck source=lib-fs source fs -# ## system::os +# ## system::getOs # # Returns the name of the current OS. # @@ -14,10 +14,10 @@ source fs # - `RETURNED_VALUE`: the name of the current OS: "darwin", "linux" or "windows". # # ```bash -# system::os +# system::getOs # local osName="${RETURNED_VALUE}" # ``` -function system::os() { +function system::getOs() { local osName case "${OSTYPE:-}" in darwin*) osName="darwin";; @@ -28,7 +28,7 @@ function system::os() { RETURNED_VALUE="${osName}" } -# ## system::env +# ## system::getEnvVars # # Get the list of all the environment variables. # In pure bash, no need for env or printenv. @@ -38,157 +38,20 @@ function system::os() { # - `RETURNED_ARRAY`: An array with the list of all the environment variables. # # ```bash -# system::env +# system::getEnvVars # for var in "${RETURNED_ARRAY[@]}"; do # printf '%s=%s\n' "${var}" "${!var}" # done # ``` # # > This is faster than using mapfile on <(compgen -v). -function system::env() { +function system::getEnvVars() { RETURNED_ARRAY=() for i in $(compgen -v); do RETURNED_ARRAY+=("${i}") done } -# ## system::date -# -# Get the current date in the given format. -# -# - $1: format _as string_: -# (optional) the format of the date to return -# (defaults to %(%F_%Hh%Mm%Ss)T). -# -# Returns: -# -# - `RETURNED_VALUE`: the current date in the given format. -# -# ```bash -# system::date -# local date="${RETURNED_VALUE}" -# ``` -# -# > This function avoid to call $(date) in a subshell (date is a an external executable). -function system::date() { - local format="${1:-"%(%F_%Hh%Mm%Ss)T"}" - # shellcheck disable=SC2059 - printf -v RETURNED_VALUE "${format}" "${EPOCHSECONDS}" -} - -# ## system::getUndeclaredVariables -# -# This function returns the list of undeclared variables for the given names. -# -# - $@: **variable names** _as string_: -# the list of variable names to check. -# -# Returns: -# -# - $? -# - 0 if there are variable undeclared -# - 1 otherwise. -# - `RETURNED_ARRAY`: the list of undeclared variables. -# -# ```bash -# if system::getUndeclaredVariables "var1" "var2"; then -# printf 'The following variables are not declared: %s' "${RETURNED_ARRAY[*]}" -# fi -# ``` -function system::getUndeclaredVariables() { - RETURNED_ARRAY=() - local var - for var in "$@"; do - if [[ ! -v "${var}" ]]; then - RETURNED_ARRAY+=("${var}") - fi - done - if [[ ${#RETURNED_ARRAY[@]} -gt 0 ]]; then - return 0 - fi - return 1 -} - -# ## system::getNotExistingCommands -# -# This function returns the list of not existing commands for the given names. -# -# - $@: **command names** _as string_: -# the list of command names to check. -# -# Returns: -# -# - $? -# - 0 if there are not existing commands -# - 1 otherwise. -# - `RETURNED_ARRAY`: the list of not existing commands. -# -# ```bash -# if system::getNotExistingCommands "command1" "command2"; then -# printf 'The following commands do not exist: %s' "${RETURNED_ARRAY[*]}" -# fi -# ``` -function system::getNotExistingCommands() { - RETURNED_ARRAY=() - local cmd - for cmd in "$@"; do - if ! command -v "${cmd}" &>/dev/null; then - RETURNED_ARRAY+=("${cmd}") - fi - done - if [[ ${#RETURNED_ARRAY[@]} -gt 0 ]]; then - return 0 - fi - return 1 -} - -# ## system::commandExists -# -# Check if the given command exists. -# -# - $1: **command name** _as string_: -# the command name to check. -# -# Returns: -# -# - $? -# - 0 if the command exists -# - 1 otherwise. -# -# ```bash -# if system::commandExists "command1"; then -# printf 'The command exists.' -# fi -# ``` -function system::commandExists() { - if command -v "${1:-}" &>/dev/null; then - return 0 - fi - return 1 -} - -# ## system::isRoot -# -# Check if the script is running as root. -# -# Returns: -# -# - $? -# - 0 if the script is running as root -# - 1 otherwise. -# -# ```bash -# if system::isRoot; then -# printf 'The script is running as root.' -# fi -# ``` -function system::isRoot() { - if [[ ${EUID:-${UID}} -eq 0 ]]; then - return 0 - fi - return 1 -} - # ## system::addToPath # # Add the given path to the PATH environment variable for various shells, diff --git a/libraries.d/lib-time b/libraries.d/lib-time new file mode 100644 index 00000000..f9b90e1e --- /dev/null +++ b/libraries.d/lib-time @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +# author: github.com/jcaillon +# description: This script can be sourced by commands to provide convenient functions. + +# ## time::getDate +# +# Get the current date in the given format. +# +# - $1: format _as string_: +# (optional) the format of the date to return +# (defaults to %(%F_%Hh%Mm%Ss)T). +# +# Returns: +# +# - `RETURNED_VALUE`: the current date in the given format. +# +# ```bash +# time::getDate +# local date="${RETURNED_VALUE}" +# ``` +# +# > This function avoid to call $(date) in a subshell (date is a an external executable). +function time::getDate() { + local format="${1:-"%(%F_%Hh%Mm%Ss)T"}" + # shellcheck disable=SC2059 + printf -v RETURNED_VALUE "${format}" "${EPOCHSECONDS}" +} + +# ## time::convertMicrosecondsToHuman +# +# Convert microseconds to human readable format. +# +# - $1: **microseconds** _as int_: +# the microseconds to convert +# - $2: format _as string_: +# (optional) Can be set using the variable `_OPTION_FORMAT`. +# the format to use (defaults to "%HH:%MM:%SS") +# Usable formats: +# - %HH: hours +# - %MM: minutes +# - %SS: seconds +# - %LL: milliseconds +# - %h: hours without leading zero +# - %m: minutes without leading zero +# - %s: seconds without leading zero +# - %l: milliseconds without leading zero +# - %u: microseconds without leading zero +# - %M: total minutes +# - %S: total seconds +# - %L: total milliseconds +# - %U: total microseconds +# +# Returns: +# +# - `RETURNED_VALUE`: the human readable format +# +# ```bash +# time::convertMicrosecondsToHuman 123456789 +# echo "${RETURNED_VALUE}" +# ``` +function time::convertMicrosecondsToHuman() { + local -i ms="${1}" + local format="${2:-${_OPTION_FORMAT:-"%HH:%MM:%SS"}}" + + local -i hours=$((ms / 3600 / 1000000)) + local -i minutes=$(((ms / 60 / 1000000) % 60)) + local -i seconds=$(((ms / 1000000) % 60)) + local -i milliseconds=$((ms / 1000 % 1000)) + local -i microseconds=$((ms % 1000)) + + local humanFormat="${format}" + if [[ ${hours} -lt 10 ]]; then + humanFormat="${humanFormat//%HH/0${hours}}" + else + humanFormat="${humanFormat//%HH/${hours}}" + fi + if [[ ${minutes} -lt 10 ]]; then + humanFormat="${humanFormat//%MM/0${minutes}}" + else + humanFormat="${humanFormat//%MM/${minutes}}" + fi + if [[ ${seconds} -lt 10 ]]; then + humanFormat="${humanFormat//%SS/0${seconds}}" + else + humanFormat="${humanFormat//%SS/${seconds}}" + fi + if [[ ${milliseconds} -lt 10 ]]; then + humanFormat="${humanFormat//%LL/00${milliseconds}}" + elif [[ ${milliseconds} -lt 100 ]]; then + humanFormat="${humanFormat//%LL/0${milliseconds}}" + else + humanFormat="${humanFormat//%LL/${milliseconds}}" + fi + if [[ ${microseconds} -lt 10 ]]; then + humanFormat="${humanFormat//%UU/00${microseconds}}" + elif [[ ${microseconds} -lt 100 ]]; then + humanFormat="${humanFormat//%UU/0${microseconds}}" + else + humanFormat="${humanFormat//%UU/${microseconds}}" + fi + humanFormat="${humanFormat//%h/${hours}}" + humanFormat="${humanFormat//%m/${minutes}}" + humanFormat="${humanFormat//%s/${seconds}}" + humanFormat="${humanFormat//%l/${milliseconds}}" + humanFormat="${humanFormat//%u/${microseconds}}" + humanFormat="${humanFormat//%M/$((hours * 60 + minutes))}" + humanFormat="${humanFormat//%S/$((hours * 3600 + minutes * 60 + seconds))}" + humanFormat="${humanFormat//%L/$(((hours * 3600 * + minutes * 60 + seconds) * 1000 + milliseconds))}" + humanFormat="${humanFormat//%U/$((ms))}" + + RETURNED_VALUE="${humanFormat}" +} diff --git a/libraries.d/lib-tui b/libraries.d/lib-tui index 0da9a44d..825973e7 100644 --- a/libraries.d/lib-tui +++ b/libraries.d/lib-tui @@ -82,7 +82,7 @@ function tui::switchToFullScreen() { _INTERACTIVE_FULL_SCREEN_MODE=true # disable echoing when we type something - tui::sttyInit + tui::setTerminalOptions # switch to the alternate screen, hide the cursor and clear the screen printf '%s' "${AC__ENABLE_ALTERNATE_BUFFER_SCREEN}${AC__CURSOR_HIDE}${AC__ERASE_SCREEN}" @@ -116,7 +116,7 @@ function tui::switchBackFromFullScreen() { printf '%s' "${AC__CURSOR_SHOW}${AC__TEXT_RESET}${AC__DISABLE_ALTERNATE_BUFFER_SCREEN}" # restore stty - tui::sttyRestore + tui::restoreTerminalOptions # restore the error output and display them if any exec 2>&4 4>&- @@ -126,14 +126,16 @@ function tui::switchBackFromFullScreen() { fi } -# ## tui::sttyInit +# ## tui::setTerminalOptions # -# Disable the echo of the tty. Will no longer display the characters typed by the user. +# Set the terminal options to enable a satisfying and consistent behavior +# for the GNU readline library. +# Disable the echo of the terminal, no longer display the characters typed by the user. # # ```bash -# tui::sttyInit +# tui::setTerminalOptions # ``` -function tui::sttyInit() { +function tui::setTerminalOptions() { if command -v stty &>/dev/null; then if [[ -z ${_INTERACTIVE_STTY_SAVED_CONFIG:-} ]]; then exe::invoke "stty" "-g" @@ -146,9 +148,10 @@ function tui::sttyInit() { fi } -# ## tui::sttyRestore +# ## tui::restoreTerminalOptions # -# Enable the echo of the tty. Will display the characters typed by the user. +# Restore the terminal options to their original state. +# Should be called after `tui::setTerminalOptions`. # # - $1: **force** _as bool_: # (optional) force the restoration of the stty configuration @@ -156,10 +159,10 @@ function tui::sttyInit() { # (defaults to false) # # ```bash -# tui::sttyRestore +# tui::restoreTerminalOptions # ``` # shellcheck disable=SC2120 -function tui::sttyRestore() { +function tui::restoreTerminalOptions() { if [[ ${_INTERACTIVE_FULL_SCREEN_MODE:-} == "true" && ${1:-} != "true" ]]; then return 0 fi @@ -380,8 +383,9 @@ function tui::testWaitForChar() { # It uses the read builtin command. This will not detect all key combinations. # The output will depend on the terminal used and the character sequences it sends on each key press. # -# For more advanced use cases, you can use tui::waitForKeyPress. -# This simple implementation does not rely on GNU readline and does not require stty to be initialized. +# For more advanced use cases, you can use `tui::waitForKeyPress`. +# This simple implementation does not rely on GNU readline and does not require terminal options +# to be set using `tui::setTerminalOptions`. # # Some special keys are translated into more readable strings: # UP, DOWN, RIGHT, LEFT, BACKSPACE, DEL, PAGE_UP, PAGE_DOWN, HOME, END, ESC, F1-F12, ALT+... @@ -464,7 +468,7 @@ function tui::waitForChar() { # ``` function tui::testWaitForKeyPress() { # setup the terminal before anything else - tui::sttyInit + tui::setTerminalOptions # define the callback function called when a special key is pressed # shellcheck disable=SC2317 function interactiveOnKeyBindingPressTestFunction() { @@ -484,7 +488,7 @@ function tui::testWaitForKeyPress() { if [[ ! -t 0 ]]; then break; fi done - tui::sttyRestore + tui::restoreTerminalOptions } # ## tui::waitForKeyPress @@ -496,7 +500,7 @@ function tui::testWaitForKeyPress() { # This means we can detect more key combinations but all keys needs to be bound first... # Special keys (CTRL+, ALT+, F1-F12, arrows, etc.) are intercepted using binding. # -# You must call `tui::rebindKeymap` and `tui::sttyInit` before using this function. +# You must call `tui::rebindKeymap` and `tui::setTerminalOptions` before using this function. # # - $@: **read parameters** _as any_: # additional parameters to pass to the read command @@ -549,7 +553,7 @@ function tui::waitForKeyPress() { # # This function should be called before using tui::waitForKeyPress. # -# You can call `tui::resetBindings` to restore the default bindings. However, this is not +# You can call `tui::restoreBindings` to restore the default bindings. However, this is not # necessary as the bindings are local to the script. # # ```bash @@ -742,14 +746,14 @@ function tui::rebindKeymap() { fi } -# ## tui::resetBindings +# ## tui::restoreBindings # # Reset the key bindings to the default ones. # # ```bash -# tui::resetBindings +# tui::restoreBindings # ``` -function tui::resetBindings() { +function tui::restoreBindings() { if [[ -z ${_INTERACTIVE_SAVED_BINDINGS_FILE:-} ]]; then return 0 fi diff --git a/libraries.d/lib-windows b/libraries.d/lib-windows index 8651342c..25cfed31 100644 --- a/libraries.d/lib-windows +++ b/libraries.d/lib-windows @@ -182,7 +182,8 @@ function windows::endPs1Batch() { # (defaults to false) # - $4: force _as boolean_: # (optional) true to overwrite the link or file if it already exists. -# Otherwise, the function will fail on an existing link. +# Otherwise, the function will not on an existing link not pointing to the +# target path. # (defaults to true) # # ```bash @@ -336,9 +337,9 @@ function windows::convertPathToUnix() { function windows::createTempFile() { local windowsTemporaryDirectory="${LOCALAPPDATA:-"C:\\Users\\${USERNAME}\\AppData\\Local"}\\Temp\\${GLOBAL_TEMPORARY_DIRECTORY##*/}-windows" - if [[ -z ${_IO_WINDOWS_TEMPORARY_DIRECTORY:-} ]]; then + if [[ -z ${GLOBAL_WINDOWS_TEMPORARY_DIRECTORY:-} ]]; then windows::convertPathToUnix "${windowsTemporaryDirectory}" - _IO_WINDOWS_TEMPORARY_DIRECTORY="${RETURNED_VALUE}" + GLOBAL_WINDOWS_TEMPORARY_DIRECTORY="${RETURNED_VALUE}" fi local windowsPath linuxPath @@ -378,9 +379,9 @@ function windows::createTempFile() { function windows::createTempDirectory() { local windowsTemporaryDirectory="${LOCALAPPDATA:-"C:\\Users\\${USERNAME}\\AppData\\Local"}\\Temp\\${GLOBAL_TEMPORARY_DIRECTORY##*/}-windows" - if [[ -z ${_IO_WINDOWS_TEMPORARY_DIRECTORY:-} ]]; then + if [[ -z ${GLOBAL_WINDOWS_TEMPORARY_DIRECTORY:-} ]]; then windows::convertPathToUnix "${windowsTemporaryDirectory}" - _IO_WINDOWS_TEMPORARY_DIRECTORY="${RETURNED_VALUE}" + GLOBAL_WINDOWS_TEMPORARY_DIRECTORY="${RETURNED_VALUE}" fi local windowsPath linuxPath @@ -420,11 +421,6 @@ function windows::setEnvVar() { local varName="${1:-}" local varValue="${2:-}" - system::os - if [[ "${RETURNED_VALUE}" != "windows" ]]; then - core::fail "This function is only available on Windows." - fi - if [[ -z ${varName} ]]; then core::fail "The variable name is missing." fi @@ -459,11 +455,6 @@ function windows::setEnvVar() { function windows::getEnvVar() { local varName="${1:-}" - system::os - if [[ "${RETURNED_VALUE}" != "windows" ]]; then - core::fail "This function is only available on Windows." - fi - if [[ -z ${varName} ]]; then core::fail "The variable name is missing." fi @@ -498,11 +489,6 @@ function windows::getEnvVar() { function windows::addToPath() { local pathToAdd="${1:-}" - system::os - if [[ "${RETURNED_VALUE}" != "windows" ]]; then - core::fail "This function is only available on Windows." - fi - log::debug "Adding directory ⌜${pathToAdd}⌝ to the PATH." if [[ -z ${pathToAdd} ]]; then diff --git a/libraries.d/main b/libraries.d/main index 952b6026..6c94bbf2 100644 --- a/libraries.d/main +++ b/libraries.d/main @@ -49,7 +49,7 @@ function main::onExitInternal() { } function main::onInterruptInternal() { - if ! command -v tui::sttyRestore &>/dev/null; then + if ! command -v tui::restoreTerminalOptions &>/dev/null; then printf '\n' # Set cursor to the next line of '^C' (only if stty echo is on) fi log::print "WARNING" "${VALET_CONFIG_ICON_STOPPED:-$'\uf256'}" "STOPPED" "Program interrupted by the user." @@ -125,8 +125,8 @@ function main::onCleanUpInternal() { fi # restore tty settings if needed - if command -v tui::sttyRestore &>/dev/null; then - tui::sttyRestore true + if command -v tui::restoreTerminalOptions &>/dev/null; then + tui::restoreTerminalOptions true fi } @@ -244,7 +244,7 @@ function main::getHelpText() { local -n functionExamples="CMD_EXAMPLES_NAME_${functionName}" # description - string::wrapText "${description}" "${helpWidth}" " " "$((helpWidth - 2))" + string::wrapWords "${description}" "${helpWidth}" " " "$((helpWidth - 2))" local wrappedDescription=" ${RETURNED_VALUE}" # usage @@ -276,7 +276,7 @@ function main::getHelpText() { fi fi RETURNED_VALUE2="${usage}" - string::wrapText "${usage}" "${helpWidth}" " " "$((helpWidth - 2))" + string::wrapWords "${usage}" "${helpWidth}" " " "$((helpWidth - 2))" usage=" ${RETURNED_VALUE}" # global options @@ -355,10 +355,10 @@ function mainWriteAsTable() { output="" for index in "${!names[@]}"; do - string::wrapText "${names[${index}]}" "${width}" " " "$((width - 2))" + string::wrapWords "${names[${index}]}" "${width}" " " "$((width - 2))" output+=" ${color}${RETURNED_VALUE}${cDefault:-}"$'\n' - string::wrapText "${descriptions[${index}]}" "${width}" " " "$((width - 6))" + string::wrapWords "${descriptions[${index}]}" "${width}" " " "$((width - 6))" output+=" ${RETURNED_VALUE}"$'\n' done diff --git a/tests.d/.commands.d/self-mock.sh b/tests.d/.commands.d/self-mock.sh index bd2f2c27..504af9d8 100644 --- a/tests.d/.commands.d/self-mock.sh +++ b/tests.d/.commands.d/self-mock.sh @@ -13,8 +13,8 @@ fi # shellcheck source=../../libraries.d/lib-fs source fs -# shellcheck source=../../libraries.d/lib-exe -source exe +# shellcheck source=../../libraries.d/lib-bash +source bash #=============================================================== # >>> command: self mock1 @@ -104,7 +104,7 @@ function selfMock1() { ;; wait-indefinitely) log::info "This is for testing valet core functions, waiting indefinitely." - exe::sleep 999 + bash::sleep 999 ;; show-help) command::showHelp diff --git a/tests.d/cli-features/results.approved.md b/tests.d/cli-features/results.approved.md index 9441bae6..7dc77b0a 100644 --- a/tests.d/cli-features/results.approved.md +++ b/tests.d/cli-features/results.approved.md @@ -43,7 +43,7 @@ Returned code: `1` ```text WARNING This is for testing valet core functions, the next statement will return 1 and create an error. ERROR Error code 1 in selfMock1(), stack: -├─ in selfMock1() at $GLOBAL_INSTALLATION_DIRECTORY/tests.d/.commands.d/self-mock.sh:52 +├─ in selfMock1() at $GLOBAL_INSTALLATION_DIRECTORY/tests.d/.commands.d/self-mock.sh:54 ├─ in main::runFunction() at $GLOBAL_INSTALLATION_DIRECTORY/libraries.d/main:565 ├─ in main::parseMainArguments() at $GLOBAL_INSTALLATION_DIRECTORY/libraries.d/main:423 └─ in main() at valet:110 @@ -104,7 +104,7 @@ WARNING This is for testing valet core functions, the next statement will call ERROR Command not found: ⌜thisIsAnUnknownCommandForTesting⌝. Please check your ⌜PATH⌝ variable. ERROR Error code 1 in selfMock1(), stack: -├─ in selfMock1() at $GLOBAL_INSTALLATION_DIRECTORY/tests.d/.commands.d/self-mock.sh:70 +├─ in selfMock1() at $GLOBAL_INSTALLATION_DIRECTORY/tests.d/.commands.d/self-mock.sh:72 ├─ in main::runFunction() at $GLOBAL_INSTALLATION_DIRECTORY/libraries.d/main:565 ├─ in main::parseMainArguments() at $GLOBAL_INSTALLATION_DIRECTORY/libraries.d/main:423 └─ in main() at valet:110 diff --git a/tests.d/cli-profiler/results.approved.md b/tests.d/cli-profiler/results.approved.md index ad0f2919..d281a02a 100644 --- a/tests.d/cli-profiler/results.approved.md +++ b/tests.d/cli-profiler/results.approved.md @@ -44,9 +44,9 @@ INFO Disabling profiler. (D=function depth, I=level of indirection, S=subshell level, timer=elapsed time in seconds, delta=delta between the last command in seconds, caller source:line=the source file and line number of the caller of the function, function=the name of the function in which the command is executed, command=the executed command) D I S timer delta source:line function → command -00 00 00 0.0XXX 0.0XXX self-mock.sh:164 selfMock2() → local -a more -00 00 00 0.0XXX 0.0XXX self-mock.sh:165 selfMock2() → command::parseArguments arg1 arg2 -00 00 00 0.0XXX 0.0XXX self-mock.sh:165 selfMock2() → eval 'local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +00 00 00 0.0XXX 0.0XXX self-mock.sh:166 selfMock2() → local -a more +00 00 00 0.0XXX 0.0XXX self-mock.sh:167 selfMock2() → command::parseArguments arg1 arg2 +00 00 00 0.0XXX 0.0XXX self-mock.sh:167 selfMock2() → eval 'local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg local -a more option1="" thisIsOption2="${VALET_THIS_IS_OPTION2:-}" @@ -58,26 +58,26 @@ D I S timer delta source:line function more=( "arg2" )' -00 00 00 0.0XXX 0.0XXX self-mock.sh:165 selfMock2() → local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -00 00 00 0.0XXX 0.0XXX self-mock.sh:166 selfMock2() → local -a more -00 00 00 0.0XXX 0.0XXX self-mock.sh:167 selfMock2() → option1= -00 00 00 0.0XXX 0.0XXX self-mock.sh:168 selfMock2() → thisIsOption2= -00 00 00 0.0XXX 0.0XXX self-mock.sh:169 selfMock2() → flag3= -00 00 00 0.0XXX 0.0XXX self-mock.sh:170 selfMock2() → withDefault=cool -00 00 00 0.0XXX 0.0XXX self-mock.sh:171 selfMock2() → help= -00 00 00 0.0XXX 0.0XXX self-mock.sh:172 selfMock2() → parsingErrors= -00 00 00 0.0XXX 0.0XXX self-mock.sh:173 selfMock2() → firstArg=arg1 -00 00 00 0.0XXX 0.0XXX self-mock.sh:176 selfMock2() → more=("arg2") -00 00 00 0.0XXX 0.0XXX self-mock.sh:166 selfMock2() → command::checkParsedResults -00 00 00 0.0XXX 0.0XXX self-mock.sh:168 selfMock2() → log::info 'Option 1 (option1): .' -00 00 00 0.0XXX 0.0XXX self-mock.sh:169 selfMock2() → log::info 'Option 2 (thisIsOption2): .' -00 00 00 0.0XXX 0.0XXX self-mock.sh:170 selfMock2() → log::info 'Option 3 (flag3): .' -00 00 00 0.0XXX 0.0XXX self-mock.sh:171 selfMock2() → log::info 'Option 4 (withDefault): cool.' -00 00 00 0.0XXX 0.0XXX self-mock.sh:172 selfMock2() → log::info 'First argument: arg1.' -00 00 00 0.0XXX 0.0XXX self-mock.sh:173 selfMock2() → log::info 'More: arg2.' -00 00 00 0.0XXX 0.0XXX self-mock.sh:175 selfMock2() → aSubFunctionInselfMock2 -00 00 00 0.0XXX 0.0XXX self-mock.sh:182 aSubFunctionInselfMock2() → log::debug 'This is a sub function.' -00 00 00 0.0XXX 0.0XXX self-mock.sh:177 selfMock2() → printf '%s\n' 'That'\''s it!' +00 00 00 0.0XXX 0.0XXX self-mock.sh:167 selfMock2() → local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +00 00 00 0.0XXX 0.0XXX self-mock.sh:168 selfMock2() → local -a more +00 00 00 0.0XXX 0.0XXX self-mock.sh:169 selfMock2() → option1= +00 00 00 0.0XXX 0.0XXX self-mock.sh:170 selfMock2() → thisIsOption2= +00 00 00 0.0XXX 0.0XXX self-mock.sh:171 selfMock2() → flag3= +00 00 00 0.0XXX 0.0XXX self-mock.sh:172 selfMock2() → withDefault=cool +00 00 00 0.0XXX 0.0XXX self-mock.sh:173 selfMock2() → help= +00 00 00 0.0XXX 0.0XXX self-mock.sh:174 selfMock2() → parsingErrors= +00 00 00 0.0XXX 0.0XXX self-mock.sh:175 selfMock2() → firstArg=arg1 +00 00 00 0.0XXX 0.0XXX self-mock.sh:178 selfMock2() → more=("arg2") +00 00 00 0.0XXX 0.0XXX self-mock.sh:168 selfMock2() → command::checkParsedResults +00 00 00 0.0XXX 0.0XXX self-mock.sh:170 selfMock2() → log::info 'Option 1 (option1): .' +00 00 00 0.0XXX 0.0XXX self-mock.sh:171 selfMock2() → log::info 'Option 2 (thisIsOption2): .' +00 00 00 0.0XXX 0.0XXX self-mock.sh:172 selfMock2() → log::info 'Option 3 (flag3): .' +00 00 00 0.0XXX 0.0XXX self-mock.sh:173 selfMock2() → log::info 'Option 4 (withDefault): cool.' +00 00 00 0.0XXX 0.0XXX self-mock.sh:174 selfMock2() → log::info 'First argument: arg1.' +00 00 00 0.0XXX 0.0XXX self-mock.sh:175 selfMock2() → log::info 'More: arg2.' +00 00 00 0.0XXX 0.0XXX self-mock.sh:177 selfMock2() → aSubFunctionInselfMock2 +00 00 00 0.0XXX 0.0XXX self-mock.sh:184 aSubFunctionInselfMock2() → log::debug 'This is a sub function.' +00 00 00 0.0XXX 0.0XXX self-mock.sh:179 selfMock2() → printf '%s\n' 'That'\''s it!' ``` @@ -112,9 +112,9 @@ INFO Disabling profiler. (D=function depth, I=level of indirection, S=subshell level, timer=elapsed time in seconds, delta=delta between the last command in seconds, caller source:line=the source file and line number of the caller of the function, function=the name of the function in which the command is executed, command=the executed command) D I S timer delta source:line function → command -00 00 00 0.0XXX 0.0XXX self-mock.sh:164 selfMock2() → local -a more -00 00 00 0.0XXX 0.0XXX self-mock.sh:165 selfMock2() → command::parseArguments arg1 arg2 -00 00 00 0.0XXX 0.0XXX self-mock.sh:165 selfMock2() → eval 'local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +00 00 00 0.0XXX 0.0XXX self-mock.sh:166 selfMock2() → local -a more +00 00 00 0.0XXX 0.0XXX self-mock.sh:167 selfMock2() → command::parseArguments arg1 arg2 +00 00 00 0.0XXX 0.0XXX self-mock.sh:167 selfMock2() → eval 'local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg local -a more option1="" thisIsOption2="${VALET_THIS_IS_OPTION2:-}" @@ -126,26 +126,26 @@ D I S timer delta source:line function more=( "arg2" )' -00 00 00 0.0XXX 0.0XXX self-mock.sh:165 selfMock2() → local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg -00 00 00 0.0XXX 0.0XXX self-mock.sh:166 selfMock2() → local -a more -00 00 00 0.0XXX 0.0XXX self-mock.sh:167 selfMock2() → option1= -00 00 00 0.0XXX 0.0XXX self-mock.sh:168 selfMock2() → thisIsOption2= -00 00 00 0.0XXX 0.0XXX self-mock.sh:169 selfMock2() → flag3= -00 00 00 0.0XXX 0.0XXX self-mock.sh:170 selfMock2() → withDefault=cool -00 00 00 0.0XXX 0.0XXX self-mock.sh:171 selfMock2() → help= -00 00 00 0.0XXX 0.0XXX self-mock.sh:172 selfMock2() → parsingErrors= -00 00 00 0.0XXX 0.0XXX self-mock.sh:173 selfMock2() → firstArg=arg1 -00 00 00 0.0XXX 0.0XXX self-mock.sh:176 selfMock2() → more=("arg2") -00 00 00 0.0XXX 0.0XXX self-mock.sh:166 selfMock2() → command::checkParsedResults -00 00 00 0.0XXX 0.0XXX self-mock.sh:168 selfMock2() → log::info 'Option 1 (option1): .' -00 00 00 0.0XXX 0.0XXX self-mock.sh:169 selfMock2() → log::info 'Option 2 (thisIsOption2): .' -00 00 00 0.0XXX 0.0XXX self-mock.sh:170 selfMock2() → log::info 'Option 3 (flag3): .' -00 00 00 0.0XXX 0.0XXX self-mock.sh:171 selfMock2() → log::info 'Option 4 (withDefault): cool.' -00 00 00 0.0XXX 0.0XXX self-mock.sh:172 selfMock2() → log::info 'First argument: arg1.' -00 00 00 0.0XXX 0.0XXX self-mock.sh:173 selfMock2() → log::info 'More: arg2.' -00 00 00 0.0XXX 0.0XXX self-mock.sh:175 selfMock2() → aSubFunctionInselfMock2 -00 00 00 0.0XXX 0.0XXX self-mock.sh:182 aSubFunctionInselfMock2() → log::debug 'This is a sub function.' -00 00 00 0.0XXX 0.0XXX self-mock.sh:177 selfMock2() → printf '%s\n' 'That'\''s it!' +00 00 00 0.0XXX 0.0XXX self-mock.sh:167 selfMock2() → local parsingErrors option1 thisIsOption2 flag3 withDefault help firstArg +00 00 00 0.0XXX 0.0XXX self-mock.sh:168 selfMock2() → local -a more +00 00 00 0.0XXX 0.0XXX self-mock.sh:169 selfMock2() → option1= +00 00 00 0.0XXX 0.0XXX self-mock.sh:170 selfMock2() → thisIsOption2= +00 00 00 0.0XXX 0.0XXX self-mock.sh:171 selfMock2() → flag3= +00 00 00 0.0XXX 0.0XXX self-mock.sh:172 selfMock2() → withDefault=cool +00 00 00 0.0XXX 0.0XXX self-mock.sh:173 selfMock2() → help= +00 00 00 0.0XXX 0.0XXX self-mock.sh:174 selfMock2() → parsingErrors= +00 00 00 0.0XXX 0.0XXX self-mock.sh:175 selfMock2() → firstArg=arg1 +00 00 00 0.0XXX 0.0XXX self-mock.sh:178 selfMock2() → more=("arg2") +00 00 00 0.0XXX 0.0XXX self-mock.sh:168 selfMock2() → command::checkParsedResults +00 00 00 0.0XXX 0.0XXX self-mock.sh:170 selfMock2() → log::info 'Option 1 (option1): .' +00 00 00 0.0XXX 0.0XXX self-mock.sh:171 selfMock2() → log::info 'Option 2 (thisIsOption2): .' +00 00 00 0.0XXX 0.0XXX self-mock.sh:172 selfMock2() → log::info 'Option 3 (flag3): .' +00 00 00 0.0XXX 0.0XXX self-mock.sh:173 selfMock2() → log::info 'Option 4 (withDefault): cool.' +00 00 00 0.0XXX 0.0XXX self-mock.sh:174 selfMock2() → log::info 'First argument: arg1.' +00 00 00 0.0XXX 0.0XXX self-mock.sh:175 selfMock2() → log::info 'More: arg2.' +00 00 00 0.0XXX 0.0XXX self-mock.sh:177 selfMock2() → aSubFunctionInselfMock2 +00 00 00 0.0XXX 0.0XXX self-mock.sh:184 aSubFunctionInselfMock2() → log::debug 'This is a sub function.' +00 00 00 0.0XXX 0.0XXX self-mock.sh:179 selfMock2() → printf '%s\n' 'That'\''s it!' ``` diff --git a/tests.d/lib-bash/00.tests.sh b/tests.d/lib-bash/00.tests.sh index df49bb75..1233fa4a 100644 --- a/tests.d/lib-bash/00.tests.sh +++ b/tests.d/lib-bash/00.tests.sh @@ -4,6 +4,12 @@ function main() { test_bash::getFunctionDefinitionWithGlobalVars test_bash::countJobs test_bash::injectCodeInFunction + test_bash::sleep + test_bash::readStdIn + test_bash::countArgs + test_bash::getMissingVariables + test_bash::getMissingCommands + test_bash::isCommand } function test_bash::injectCodeInFunction() { @@ -83,4 +89,52 @@ function test_bash::getFunctionDefinitionWithGlobalVars() { test::flush } +function test_bash::sleep() { + test::title "✅ Testing bash::sleep" + + test::exec bash::sleep 0.001 +} + +function test_bash::readStdIn() { + test::title "✅ Testing bash::readStdIn" + + test::prompt "bash::readStdIn <<<'coucou'" + test::resetReturnedVars + bash::readStdIn <<<"coucou" + test::printReturnedVars + + test::func bash::readStdIn +} + +function test_bash::countArgs() { + test::title "✅ Testing bash::countArgs" + + test::func bash::countArgs 'arg1' 'arg2' 'arg3' + test::func bash::countArgs "\${PWD}/resources/*" +} + +function test_bash::getMissingVariables() { + test::title "✅ Testing bash::getMissingVariables" + + test::func bash::getMissingVariables + test::exec ABC="ok" + test::func bash::getMissingVariables GLOBAL_TEST_TEMP_FILE dfg ABC NOP +} + +function test_bash::getMissingCommands() { + test::title "✅ Testing bash::getMissingCommands" + + test::func bash::getMissingCommands + + test::func bash::getMissingCommands NONEXISTINGSTUFF bash::getMissingCommands rm YETANOTHERONEMISSING +} + +function test_bash::isCommand() { + test::title "✅ Testing bash::isCommand" + + test::exec bash::isCommand + test::exec bash::isCommand NONEXISTINGSTUFF + test::exec bash::isCommand rm +} + main \ No newline at end of file diff --git a/tests.d/lib-bash/results.approved.md b/tests.d/lib-bash/results.approved.md index 056dcef2..c43f11da 100644 --- a/tests.d/lib-bash/results.approved.md +++ b/tests.d/lib-bash/results.approved.md @@ -163,3 +163,92 @@ echo 'injected in a new function!' ``` +### ✅ Testing bash::sleep + +❯ `bash::sleep 0.001` + +### ✅ Testing bash::readStdIn + +❯ `bash::readStdIn <<<'coucou'` + +Returned variables: + +```text +RETURNED_VALUE='coucou +' +``` + +❯ `bash::readStdIn` + +Returned variables: + +```text +RETURNED_VALUE='' +``` + +### ✅ Testing bash::countArgs + +❯ `bash::countArgs arg1 arg2 arg3` + +Returned variables: + +```text +RETURNED_VALUE='3' +``` + +❯ `bash::countArgs ${PWD}/resources/*` + +Returned variables: + +```text +RETURNED_VALUE='1' +``` + +### ✅ Testing bash::getMissingVariables + +❯ `bash::getMissingVariables` + +Returned code: `1` + +❯ `ABC=ok` + +❯ `bash::getMissingVariables GLOBAL_TEST_TEMP_FILE dfg ABC NOP` + +Returned variables: + +```text +RETURNED_ARRAY=( +[0]='dfg' +[1]='NOP' +) +``` + +### ✅ Testing bash::getMissingCommands + +❯ `bash::getMissingCommands` + +Returned code: `1` + +❯ `bash::getMissingCommands NONEXISTINGSTUFF bash::getMissingCommands rm YETANOTHERONEMISSING` + +Returned variables: + +```text +RETURNED_ARRAY=( +[0]='NONEXISTINGSTUFF' +[1]='YETANOTHERONEMISSING' +) +``` + +### ✅ Testing bash::isCommand + +❯ `bash::isCommand` + +Returned code: `1` + +❯ `bash::isCommand NONEXISTINGSTUFF` + +Returned code: `1` + +❯ `bash::isCommand rm` + diff --git a/tests.d/lib-benchmark/00.tests.sh b/tests.d/lib-benchmark/00.tests.sh index ea419291..967d6808 100644 --- a/tests.d/lib-benchmark/00.tests.sh +++ b/tests.d/lib-benchmark/00.tests.sh @@ -14,8 +14,8 @@ function test_benchmark::run() { test::exec benchmark::run test_function_1 test_function_2,test_function_3 3 5 } -# override core::getProgramElapsedMicroseconds to return a fake incremental time -function core::getProgramElapsedMicroseconds() { +# override time::getProgramElapsedMicroseconds to return a fake incremental time +function time::getProgramElapsedMicroseconds() { if [[ -z ${_FAKE_TIME:-} ]]; then _FAKE_TIME=0 _TIME_FACTOR=1 diff --git a/tests.d/lib-curl/00.curl.sh b/tests.d/lib-curl/00.curl.sh index e62791ca..49e04356 100644 --- a/tests.d/lib-curl/00.curl.sh +++ b/tests.d/lib-curl/00.curl.sh @@ -6,29 +6,29 @@ source curl source fs function main() { - test_curl::toFile - test_curl::toVar + test_curl::download + test_curl::request } -function test_curl::toFile() { - test::title "✅ Testing curl::toFile" +function test_curl::download() { + test::title "✅ Testing curl::download" test::markdown "Writing to an output file:" - test::func curl::toFile true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 200 https://fuu + test::func curl::download true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 200 https://fuu test::exec fs::cat "${GLOBAL_TEST_TEMP_FILE}" test::markdown "Getting a 500 error with fail mode on:" - test::exit curl::toFile true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 500 https://fuu + test::exit curl::download true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 500 https://fuu test::markdown "Getting a 500 error with fail mode off:" - test::func curl::toFile false 200 "${GLOBAL_TEST_TEMP_FILE}" --code 500 https://fuu + test::func curl::download false 200 "${GLOBAL_TEST_TEMP_FILE}" --code 500 https://fuu test::markdown "Getting an acceptable 400 error with fail mode:" - test::func curl::toFile true '200,400,401' "${GLOBAL_TEST_TEMP_FILE}" --code 400 https://fuu + test::func curl::download true '200,400,401' "${GLOBAL_TEST_TEMP_FILE}" --code 400 https://fuu test::markdown "Getting an acceptable 201 with debug mode on" test::exec log::setLevel debug - test::func curl::toFile false \'\' "${GLOBAL_TEST_TEMP_FILE}" --code 201 https://fuu + test::func curl::download false \'\' "${GLOBAL_TEST_TEMP_FILE}" --code 201 https://fuu test::exec log::setLevel info } @@ -38,7 +38,7 @@ function echoOutputCurlToFile() { filePath="${2}" local debugMessage - debugMessage="curl::toFile false function ended with exit code ⌈${exitCode}⌉."$'\n' + debugMessage="curl::download false function ended with exit code ⌈${exitCode}⌉."$'\n' debugMessage+="http return code was ⌈${RETURNED_VALUE2}⌉"$'\n' if [[ -s "${filePath}" ]]; then debugMessage+="Content of downloaded file:"$'\n'"⌈$(<"${filePath}")⌉"$'\n' @@ -47,24 +47,24 @@ function echoOutputCurlToFile() { echo "${debugMessage}" } -function test_curl::toVar() { - test::title "✅ Testing curl::toVar" +function test_curl::request() { + test::title "✅ Testing curl::request" local -i exitCode test::markdown "Getting 200:" - test::func curl::toVar true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 200 https://fuu + test::func curl::request true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 200 https://fuu test::markdown "Getting 500 with fail mode off:" - test::exit curl::toVar false \'\' "${GLOBAL_TEST_TEMP_FILE}" --code 500 https://fuu + test::exit curl::request false \'\' "${GLOBAL_TEST_TEMP_FILE}" --code 500 https://fuu test::markdown "Getting 500 with fail mode on:" - test::exit curl::toVar true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 500 https://fuu + test::exit curl::request true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 500 https://fuu export NO_CURL_CONTENT=true test::markdown "Getting 200 with no content and debug mode on:" test::exec log::setLevel debug - test::func curl::toVar true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 200 https://fuu + test::func curl::request true 200 "${GLOBAL_TEST_TEMP_FILE}" --code 200 https://fuu test::exec log::setLevel info unset NO_CURL_CONTENT @@ -75,7 +75,7 @@ function echoOutputCurlToVar() { exitCode="${1}" local debugMessage - debugMessage="curl::toVar function ended with exit code ⌈${exitCode}⌉."$'\n' + debugMessage="curl::request function ended with exit code ⌈${exitCode}⌉."$'\n' debugMessage+="http return code was ⌈${RETURNED_VALUE3}⌉"$'\n' debugMessage+="stdout:"$'\n'"⌈${RETURNED_VALUE}⌉"$'\n' debugMessage+="stderr:"$'\n'"⌈${RETURNED_VALUE2}⌉" diff --git a/tests.d/lib-curl/results.approved.md b/tests.d/lib-curl/results.approved.md index af5e6e32..c3f9a29e 100644 --- a/tests.d/lib-curl/results.approved.md +++ b/tests.d/lib-curl/results.approved.md @@ -2,11 +2,11 @@ ## Test script 00.curl -### ✅ Testing curl::toFile +### ✅ Testing curl::download Writing to an output file: -❯ `curl::toFile true 200 /tmp/valet-temp --code 200 https://fuu` +❯ `curl::download true 200 /tmp/valet-temp --code 200 https://fuu` Returned variables: @@ -26,7 +26,7 @@ RETURNED_VALUE2='200' Getting a 500 error with fail mode on: -❯ `curl::toFile true 200 /tmp/valet-temp --code 500 https://fuu` +❯ `curl::download true 200 /tmp/valet-temp --code 500 https://fuu` Exited with code: `1` @@ -41,7 +41,7 @@ ERROR The http return code ⌜500⌝ is not acceptable for url ⌜https://fuu Getting a 500 error with fail mode off: -❯ `curl::toFile false 200 /tmp/valet-temp --code 500 https://fuu` +❯ `curl::download false 200 /tmp/valet-temp --code 500 https://fuu` Returned code: `1` @@ -55,7 +55,7 @@ RETURNED_VALUE2='500' Getting an acceptable 400 error with fail mode: -❯ `curl::toFile true 200,400,401 /tmp/valet-temp --code 400 https://fuu` +❯ `curl::download true 200,400,401 /tmp/valet-temp --code 400 https://fuu` Returned variables: @@ -76,7 +76,7 @@ DEBUG Log level set to debug. WARNING Beware that debug log level might lead to secret leak, use it only if necessary. ``` -❯ `curl::toFile false '' /tmp/valet-temp --code 201 https://fuu` +❯ `curl::download false '' /tmp/valet-temp --code 201 https://fuu` **Error output**: @@ -98,11 +98,11 @@ RETURNED_VALUE2='201' ❯ `log::setLevel info` -### ✅ Testing curl::toVar +### ✅ Testing curl::request Getting 200: -❯ `curl::toVar true 200 /tmp/valet-temp --code 200 https://fuu` +❯ `curl::request true 200 /tmp/valet-temp --code 200 https://fuu` Returned variables: @@ -115,13 +115,13 @@ RETURNED_VALUE3='200' Getting 500 with fail mode off: -❯ `curl::toVar false '' /tmp/valet-temp --code 500 https://fuu` +❯ `curl::request false '' /tmp/valet-temp --code 500 https://fuu` Exited with code: `1` Getting 500 with fail mode on: -❯ `curl::toVar true 200 /tmp/valet-temp --code 500 https://fuu` +❯ `curl::request true 200 /tmp/valet-temp --code 500 https://fuu` Exited with code: `1` @@ -145,7 +145,7 @@ DEBUG Log level set to debug. WARNING Beware that debug log level might lead to secret leak, use it only if necessary. ``` -❯ `curl::toVar true 200 /tmp/valet-temp --code 200 https://fuu` +❯ `curl::request true 200 /tmp/valet-temp --code 200 https://fuu` **Error output**: diff --git a/tests.d/lib-exe/00.tests.sh b/tests.d/lib-exe/00.tests.sh index 2d7dc2af..df20a224 100644 --- a/tests.d/lib-exe/00.tests.sh +++ b/tests.d/lib-exe/00.tests.sh @@ -13,9 +13,6 @@ function main() { test_exe::invoke2 test_exe::invoke test_exe::invoke2piped - test_exe::sleep - test_exe::readStdIn - test_exe::countArgs test_exe::captureOutput } @@ -75,30 +72,6 @@ function test_exe::invoke2piped() { test::func exe::invokef2piped true "'input_stream'" fake --std-in --option argument1 argument2 } -function test_exe::sleep() { - test::title "✅ Testing exe::sleep" - - test::exec exe::sleep 0.001 -} - -function test_exe::readStdIn() { - test::title "✅ Testing exe::readStdIn" - - test::prompt "exe::readStdIn <<<'coucou'" - test::resetReturnedVars - exe::readStdIn <<<"coucou" - test::printReturnedVars - - test::func exe::readStdIn -} - -function test_exe::countArgs() { - test::title "✅ Testing exe::countArgs" - - test::func exe::countArgs 'arg1' 'arg2' 'arg3' - test::func exe::countArgs "\${PWD}/resources/*" -} - function test_exe::captureOutput() { test::title "✅ Testing exe::captureOutput" @@ -111,7 +84,7 @@ function fake() { local inputStreamContent if [[ $* == *"--std-in"* ]]; then - exe::readStdIn + bash::readStdIn inputStreamContent="${RETURNED_VALUE}" fi diff --git a/tests.d/lib-exe/results.approved.md b/tests.d/lib-exe/results.approved.md index f51bcefa..98668ac2 100644 --- a/tests.d/lib-exe/results.approved.md +++ b/tests.d/lib-exe/results.approved.md @@ -1,509 +1,7 @@ -# Test suite lib-io +# Test suite lib-exe ## Test script 00.tests -### ✅ Testing fs::toAbsolutePath - -❯ `fs::toAbsolutePath $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.sh` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.sh' -``` - -❯ `fs::toAbsolutePath .` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io' -``` - -❯ `fs::toAbsolutePath ..` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d' -``` - -❯ `fs::toAbsolutePath 01.invoke.s` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.s' -``` - -❯ `fs::toAbsolutePath ../1004-lib-system/00.tests.sh` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/../1004-lib-system/00.tests.sh' -``` - -❯ `fs::toAbsolutePath resources` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources' -``` - -❯ `fs::toAbsolutePath ./01.invoke.sh` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.sh' -``` - -❯ `fs::toAbsolutePath ./resources` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources' -``` - -❯ `fs::toAbsolutePath missing-file` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/missing-file' -``` - -### ✅ Testing fs::readFile - -❯ `fs::readFile resources/file-to-read 22` - -Returned variables: - -```text -RETURNED_VALUE='# Explore why veganism' -``` - -❯ `fs::readFile resources/file-to-read` - -Returned variables: - -```text -RETURNED_VALUE='# Explore why veganism is kinder to animals, to people and to our planet'"'"'s future. - -Source: - -## For the animals - -Preventing the exploitation of animals is not the only reason for becoming vegan, but for many it remains the key factor in their decision to go vegan and stay vegan. Having emotional attachments with animals may form part of that reason, while many believe that all sentient creatures have a right to life and freedom. Specifics aside, avoiding animal products is one of the most obvious ways you can take a stand against animal cruelty and animal exploitation everywhere. Read a detailed overview on why being vegan demonstrates true compassion for animals. - -## For your health - -Well-planned vegan diets follow healthy eating guidelines, and contain all the nutrients that our bodies need. Both the British Dietetic Association and the American Academy of Nutrition and Dietetics recognise that they are suitable for every age and stage of life. Some research has linked that there are certain health benefits to vegan diets with lower blood pressure and cholesterol, and lower rates of heart disease, type 2 diabetes and some types of cancer. - -Going vegan is a great opportunity to learn more about nutrition and cooking, and improve your diet. Getting your nutrients from plant foods allows more room in your diet for health-promoting options like whole grains, fruit, nuts, seeds and vegetables, which are packed full of beneficial fibre, vitamins and minerals. - -## For the environment - -From recycling our household rubbish to cycling to work, we'"'"'re all aware of ways to live a greener life. One of the most effective things an individual can do to lower their carbon footprint is to avoid all animal products. This goes way beyond the problem of cow flatulence and air pollution! -Why is meat and dairy so bad for the environment? - -The production of meat and other animal derived products places a heavy burden on the environment. The vast amount of grain feed required for meat production is a significant contributor to deforestation, habitat loss and species extinction. In Brazil alone, the equivalent of 5.6 million acres of land is used to grow soya beans for animals in Europe. This land contributes to developing world malnutrition by driving impoverished populations to grow cash crops for animal feed, rather than food for themselves. On the other hand, considerably lower quantities of crops and water are required to sustain a vegan diet, making the switch to veganism one of the easiest, most enjoyable and most effective ways to reduce our impact on the environment. For more on how veganism is the way forward for the environment, see our environment section. - -## For people - -Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there'"'"'s never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it'"'"'s the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people.' -``` - -### ✅ Testing fs::createDirectoryIfNeeded - -❯ `fs::createDirectoryIfNeeded resources/dir/subdir` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subdir' -``` - -This next command will fail because the directory already exists (it is a file). - -❯ `fs::createDirectoryIfNeeded resources/dir/subdir/file1` - -Exited with code: `1` - -**Error output**: - -```text -mkdir: cannot create directory ‘$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subdir/file1’: File exists -ERROR Failed to create the directory ⌜$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subdir/file1⌝. -``` - -❯ `fs::createDirectoryIfNeeded resources/gitignored/derp` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/derp' -``` - -Directory created successfully! - -### ✅ Testing fs::createFilePathIfNeeded - -❯ `fs::createFilePathIfNeeded resources/dir/subdir/file1` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subdir/file1' -``` - -❯ `fs::createFilePathIfNeeded resources/gitignored/allo/file1` - -Returned variables: - -```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/allo/file1' -``` - -File created successfully! - -### ✅ Testing exe::sleep - -❯ `exe::sleep 0.001` - -### ✅ Testing fs::cat - -❯ `fs::cat resources/file-to-read` - -**Standard output**: - -```text -# Explore why veganism is kinder to animals, to people and to our planet's future. - -Source: - -## For the animals - -Preventing the exploitation of animals is not the only reason for becoming vegan, but for many it remains the key factor in their decision to go vegan and stay vegan. Having emotional attachments with animals may form part of that reason, while many believe that all sentient creatures have a right to life and freedom. Specifics aside, avoiding animal products is one of the most obvious ways you can take a stand against animal cruelty and animal exploitation everywhere. Read a detailed overview on why being vegan demonstrates true compassion for animals. - -## For your health - -Well-planned vegan diets follow healthy eating guidelines, and contain all the nutrients that our bodies need. Both the British Dietetic Association and the American Academy of Nutrition and Dietetics recognise that they are suitable for every age and stage of life. Some research has linked that there are certain health benefits to vegan diets with lower blood pressure and cholesterol, and lower rates of heart disease, type 2 diabetes and some types of cancer. - -Going vegan is a great opportunity to learn more about nutrition and cooking, and improve your diet. Getting your nutrients from plant foods allows more room in your diet for health-promoting options like whole grains, fruit, nuts, seeds and vegetables, which are packed full of beneficial fibre, vitamins and minerals. - -## For the environment - -From recycling our household rubbish to cycling to work, we're all aware of ways to live a greener life. One of the most effective things an individual can do to lower their carbon footprint is to avoid all animal products. This goes way beyond the problem of cow flatulence and air pollution! -Why is meat and dairy so bad for the environment? - -The production of meat and other animal derived products places a heavy burden on the environment. The vast amount of grain feed required for meat production is a significant contributor to deforestation, habitat loss and species extinction. In Brazil alone, the equivalent of 5.6 million acres of land is used to grow soya beans for animals in Europe. This land contributes to developing world malnutrition by driving impoverished populations to grow cash crops for animal feed, rather than food for themselves. On the other hand, considerably lower quantities of crops and water are required to sustain a vegan diet, making the switch to veganism one of the easiest, most enjoyable and most effective ways to reduce our impact on the environment. For more on how veganism is the way forward for the environment, see our environment section. - -## For people - -Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. -``` - -Returned variables: - -```text -RETURNED_VALUE='# Explore why veganism is kinder to animals, to people and to our planet'"'"'s future. - -Source: - -## For the animals - -Preventing the exploitation of animals is not the only reason for becoming vegan, but for many it remains the key factor in their decision to go vegan and stay vegan. Having emotional attachments with animals may form part of that reason, while many believe that all sentient creatures have a right to life and freedom. Specifics aside, avoiding animal products is one of the most obvious ways you can take a stand against animal cruelty and animal exploitation everywhere. Read a detailed overview on why being vegan demonstrates true compassion for animals. - -## For your health - -Well-planned vegan diets follow healthy eating guidelines, and contain all the nutrients that our bodies need. Both the British Dietetic Association and the American Academy of Nutrition and Dietetics recognise that they are suitable for every age and stage of life. Some research has linked that there are certain health benefits to vegan diets with lower blood pressure and cholesterol, and lower rates of heart disease, type 2 diabetes and some types of cancer. - -Going vegan is a great opportunity to learn more about nutrition and cooking, and improve your diet. Getting your nutrients from plant foods allows more room in your diet for health-promoting options like whole grains, fruit, nuts, seeds and vegetables, which are packed full of beneficial fibre, vitamins and minerals. - -## For the environment - -From recycling our household rubbish to cycling to work, we'"'"'re all aware of ways to live a greener life. One of the most effective things an individual can do to lower their carbon footprint is to avoid all animal products. This goes way beyond the problem of cow flatulence and air pollution! -Why is meat and dairy so bad for the environment? - -The production of meat and other animal derived products places a heavy burden on the environment. The vast amount of grain feed required for meat production is a significant contributor to deforestation, habitat loss and species extinction. In Brazil alone, the equivalent of 5.6 million acres of land is used to grow soya beans for animals in Europe. This land contributes to developing world malnutrition by driving impoverished populations to grow cash crops for animal feed, rather than food for themselves. On the other hand, considerably lower quantities of crops and water are required to sustain a vegan diet, making the switch to veganism one of the easiest, most enjoyable and most effective ways to reduce our impact on the environment. For more on how veganism is the way forward for the environment, see our environment section. - -## For people - -Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there'"'"'s never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it'"'"'s the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people.' -``` - -### ✅ Testing exe::readStdIn - -❯ `exe::readStdIn <<<'coucou'` - -Returned variables: - -```text -RETURNED_VALUE='coucou -' -``` - -❯ `exe::readStdIn` - -Returned variables: - -```text -RETURNED_VALUE='' -``` - -### ✅ Testing exe::countArgs - -❯ `exe::countArgs arg1 arg2 arg3` - -Returned variables: - -```text -RETURNED_VALUE='3' -``` - -❯ `exe::countArgs ${PWD}/resources/*` - -Returned variables: - -```text -RETURNED_VALUE='3' -``` - -### ✅ Testing fs::isDirectoryWritable - -❯ `fs::isDirectoryWritable /tmp && echo Writable || echo Not\ writable` - -**Standard output**: - -```text -Writable -``` - -### ✅ Testing windows::convertPathFromUnix - -❯ `windows::convertPathFromUnix /tmp/file` - -Returned variables: - -```text -RETURNED_VALUE='\tmp\file' -``` - -❯ `windows::convertPathFromUnix /mnt/d/Users/username` - -Returned variables: - -```text -RETURNED_VALUE='D:\Users\username' -``` - -❯ `windows::convertPathFromUnix /c/data/file` - -Returned variables: - -```text -RETURNED_VALUE='C:\data\file' -``` - -### ✅ Testing fs::createLink - -❯ `fs::createLink resources/gitignored/file resources/gitignored/try/file2 true` - -**Standard output**: - -```text -🙈 mocking ln: $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/file $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/try/file2 -``` - -❯ `fs::createLink resources/gitignored/try resources/gitignored/new` - -**Standard output**: - -```text -🙈 mocking ln: -s $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/try $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/new -``` - -### ✅ Testing windows::convertPathToUnix - -❯ `windows::convertPathToUnix C:\\Users\\username` - -Returned variables: - -```text -RETURNED_VALUE='/c/Users/username' -``` - -❯ `windows::convertPathToUnix D:\\data\\file` - -Returned variables: - -```text -RETURNED_VALUE='/d/data/file' -``` - -### ✅ Testing fs::head - -❯ `fs::head resources/file-to-read 10` - -**Standard output**: - -```text -# Explore why veganism is kinder to animals, to people and to our planet's future. - -Source: - -## For the animals - -Preventing the exploitation of animals is not the only reason for becoming vegan, but for many it remains the key factor in their decision to go vegan and stay vegan. Having emotional attachments with animals may form part of that reason, while many believe that all sentient creatures have a right to life and freedom. Specifics aside, avoiding animal products is one of the most obvious ways you can take a stand against animal cruelty and animal exploitation everywhere. Read a detailed overview on why being vegan demonstrates true compassion for animals. - -## For your health - -``` - -❯ `fs::head resources/file-to-read 0` - -❯ `fs::head resources/file-to-read 99` - -**Standard output**: - -```text -# Explore why veganism is kinder to animals, to people and to our planet's future. - -Source: - -## For the animals - -Preventing the exploitation of animals is not the only reason for becoming vegan, but for many it remains the key factor in their decision to go vegan and stay vegan. Having emotional attachments with animals may form part of that reason, while many believe that all sentient creatures have a right to life and freedom. Specifics aside, avoiding animal products is one of the most obvious ways you can take a stand against animal cruelty and animal exploitation everywhere. Read a detailed overview on why being vegan demonstrates true compassion for animals. - -## For your health - -Well-planned vegan diets follow healthy eating guidelines, and contain all the nutrients that our bodies need. Both the British Dietetic Association and the American Academy of Nutrition and Dietetics recognise that they are suitable for every age and stage of life. Some research has linked that there are certain health benefits to vegan diets with lower blood pressure and cholesterol, and lower rates of heart disease, type 2 diabetes and some types of cancer. - -Going vegan is a great opportunity to learn more about nutrition and cooking, and improve your diet. Getting your nutrients from plant foods allows more room in your diet for health-promoting options like whole grains, fruit, nuts, seeds and vegetables, which are packed full of beneficial fibre, vitamins and minerals. - -## For the environment - -From recycling our household rubbish to cycling to work, we're all aware of ways to live a greener life. One of the most effective things an individual can do to lower their carbon footprint is to avoid all animal products. This goes way beyond the problem of cow flatulence and air pollution! -Why is meat and dairy so bad for the environment? - -The production of meat and other animal derived products places a heavy burden on the environment. The vast amount of grain feed required for meat production is a significant contributor to deforestation, habitat loss and species extinction. In Brazil alone, the equivalent of 5.6 million acres of land is used to grow soya beans for animals in Europe. This land contributes to developing world malnutrition by driving impoverished populations to grow cash crops for animal feed, rather than food for themselves. On the other hand, considerably lower quantities of crops and water are required to sustain a vegan diet, making the switch to veganism one of the easiest, most enjoyable and most effective ways to reduce our impact on the environment. For more on how veganism is the way forward for the environment, see our environment section. - -## For people - -Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. -``` - -❯ `fs::head resources/file-to-read 3 true` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='# Explore why veganism is kinder to animals, to people and to our planet'"'"'s future.' -[1]='' -[2]='Source: ' -) -``` - -### ✅ Testing exe::captureOutput - -❯ `exe::captureOutput echo coucou` - -Returned variables: - -```text -RETURNED_VALUE='coucou -' -``` - -❯ `exe::captureOutput declare -f exe::captureOutput` - -Returned variables: - -```text -RETURNED_VALUE='exe::captureOutput () -{ - local IFS='"'"' '"'"'; - ${@} &> "${GLOBAL_TEMPORARY_STDOUT_FILE}" || return 1; - RETURNED_VALUE=""; - IFS='"'"''"'"' read -rd '"'"''"'"' RETURNED_VALUE < "${GLOBAL_TEMPORARY_STDOUT_FILE}" || : -} -' -``` - -❯ `exe::captureOutput [[ 1 -eq 0 ]]` - -Returned code: `1` - -### ✅ Testing fs::tail - -❯ `fs::tail resources/file-to-read 3` - -**Standard output**: - -```text -## For people - -Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. -``` - -❯ `fs::tail resources/file-to-read 0` - -**Standard output**: - -```text - -``` - -❯ `fs::tail resources/file-to-read 99` - -**Standard output**: - -```text -# Explore why veganism is kinder to animals, to people and to our planet's future. - -Source: - -## For the animals - -Preventing the exploitation of animals is not the only reason for becoming vegan, but for many it remains the key factor in their decision to go vegan and stay vegan. Having emotional attachments with animals may form part of that reason, while many believe that all sentient creatures have a right to life and freedom. Specifics aside, avoiding animal products is one of the most obvious ways you can take a stand against animal cruelty and animal exploitation everywhere. Read a detailed overview on why being vegan demonstrates true compassion for animals. - -## For your health - -Well-planned vegan diets follow healthy eating guidelines, and contain all the nutrients that our bodies need. Both the British Dietetic Association and the American Academy of Nutrition and Dietetics recognise that they are suitable for every age and stage of life. Some research has linked that there are certain health benefits to vegan diets with lower blood pressure and cholesterol, and lower rates of heart disease, type 2 diabetes and some types of cancer. - -Going vegan is a great opportunity to learn more about nutrition and cooking, and improve your diet. Getting your nutrients from plant foods allows more room in your diet for health-promoting options like whole grains, fruit, nuts, seeds and vegetables, which are packed full of beneficial fibre, vitamins and minerals. - -## For the environment - -From recycling our household rubbish to cycling to work, we're all aware of ways to live a greener life. One of the most effective things an individual can do to lower their carbon footprint is to avoid all animal products. This goes way beyond the problem of cow flatulence and air pollution! -Why is meat and dairy so bad for the environment? - -The production of meat and other animal derived products places a heavy burden on the environment. The vast amount of grain feed required for meat production is a significant contributor to deforestation, habitat loss and species extinction. In Brazil alone, the equivalent of 5.6 million acres of land is used to grow soya beans for animals in Europe. This land contributes to developing world malnutrition by driving impoverished populations to grow cash crops for animal feed, rather than food for themselves. On the other hand, considerably lower quantities of crops and water are required to sustain a vegan diet, making the switch to veganism one of the easiest, most enjoyable and most effective ways to reduce our impact on the environment. For more on how veganism is the way forward for the environment, see our environment section. - -## For people - -Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there's never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it's the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people. -``` - -❯ `fs::tail resources/file-to-read 3 true` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='## For people' -[1]='' -[2]='Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there'"'"'s never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it'"'"'s the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people.' -) -``` - -## Test script 01.invoke - For these tests, we will use a special command `fake` defined as such: ❯ `declare -f fake` @@ -515,7 +13,7 @@ fake () { local inputStreamContent; if [[ $* == *"--std-in"* ]]; then - exe::readStdIn; + bash::readStdIn; inputStreamContent="${RETURNED_VALUE}"; fi; local IFS=" "; @@ -730,269 +228,33 @@ RETURNED_VALUE='/tmp/valet-stdout.f' RETURNED_VALUE2='/tmp/valet-stderr.f' ``` -## Test script 02.listPaths - -### ✅ Testing fs::listPaths - -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -) -``` - -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' -) -``` - -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search false true` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -) -``` - -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3' -[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/file10' -[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4' -[7]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/.hidden-file2' -[8]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[9]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2' -[10]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' -[11]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13' -[12]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' -[13]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14' -[14]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3' -[15]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' -) -``` - -❯ `declare -f fileNamedFile` - -**Standard output**: - -```text -fileNamedFile () -{ - if [[ ${1##*/} =~ ^file[[:digit:]]+$ ]]; then - return 0; - else - return 1; - fi -} -``` - -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true fileNamedFile` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/file10' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14' -[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' -) -``` - -❯ `declare -f folderNamedHidden` - -**Standard output**: - -```text -folderNamedHidden () -{ - if [[ ${1##*/} == *hidden* ]]; then - return 0; - else - return 1; - fi -} -``` - -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true folderNamedHidden` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/.hidden-file2' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' -[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' -[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3' -) -``` - -### ✅ Testing fs::listFiles - -❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -) -``` - -❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' -) -``` - -❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/file10' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/.hidden-file2' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' -[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13' -[7]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' -[8]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14' -[9]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3' -[10]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' -) -``` - -❯ `declare -f fileNamedHidden` - -**Standard output**: - -```text -fileNamedHidden () -{ - if [[ ${1##*/} == *hidden* ]]; then - return 0; - else - return 1; - fi -} -``` - -❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true folderNamedHidden` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/file10' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13' -) -``` - -### ✅ Testing fs::listDirectories - -❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -) -``` +### ✅ Testing exe::captureOutput -❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true` +❯ `exe::captureOutput echo coucou` Returned variables: ```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2' -) +RETURNED_VALUE='coucou +' ``` -❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true` +❯ `exe::captureOutput declare -f exe::captureOutput` Returned variables: ```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2' -) -``` - -❯ `declare -f folderNamedHidden` - -**Standard output**: - -```text -folderNamedHidden () +RETURNED_VALUE='exe::captureOutput () { - if [[ ${1##*/} == *hidden* ]]; then - return 0; - else - return 1; - fi + local IFS='"'"' '"'"'; + ${@} &> "${GLOBAL_TEMPORARY_STDOUT_FILE}" || return 1; + RETURNED_VALUE=""; + IFS='"'"''"'"' read -rd '"'"''"'"' RETURNED_VALUE < "${GLOBAL_TEMPORARY_STDOUT_FILE}" || : } +' ``` -❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true folderNamedHidden` - -Returned variables: +❯ `exe::captureOutput [[ 1 -eq 0 ]]` -```text -RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4' -) -``` +Returned code: `1` diff --git a/tests.d/lib-fs/results.approved.md b/tests.d/lib-fs/results.approved.md index f51bcefa..7c54d052 100644 --- a/tests.d/lib-fs/results.approved.md +++ b/tests.d/lib-fs/results.approved.md @@ -1,15 +1,15 @@ -# Test suite lib-io +# Test suite lib-fs ## Test script 00.tests ### ✅ Testing fs::toAbsolutePath -❯ `fs::toAbsolutePath $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.sh` +❯ `fs::toAbsolutePath $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/01.invoke.sh` Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.sh' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/01.invoke.sh' ``` ❯ `fs::toAbsolutePath .` @@ -17,7 +17,7 @@ RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.sh' Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs' ``` ❯ `fs::toAbsolutePath ..` @@ -33,7 +33,7 @@ RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d' Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.s' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/01.invoke.s' ``` ❯ `fs::toAbsolutePath ../1004-lib-system/00.tests.sh` @@ -41,7 +41,7 @@ RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.s' Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/../1004-lib-system/00.tests.sh' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/../1004-lib-system/00.tests.sh' ``` ❯ `fs::toAbsolutePath resources` @@ -49,7 +49,7 @@ RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/../1004-lib-system Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources' ``` ❯ `fs::toAbsolutePath ./01.invoke.sh` @@ -57,7 +57,7 @@ RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources' Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.sh' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/01.invoke.sh' ``` ❯ `fs::toAbsolutePath ./resources` @@ -65,7 +65,7 @@ RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/01.invoke.sh' Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources' ``` ❯ `fs::toAbsolutePath missing-file` @@ -73,7 +73,7 @@ RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources' Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/missing-file' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/missing-file' ``` ### ✅ Testing fs::readFile @@ -124,7 +124,7 @@ Just like veganism is the sustainable option when it comes to looking after our Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subdir' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/dir/subdir' ``` This next command will fail because the directory already exists (it is a file). @@ -136,8 +136,8 @@ Exited with code: `1` **Error output**: ```text -mkdir: cannot create directory ‘$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subdir/file1’: File exists -ERROR Failed to create the directory ⌜$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subdir/file1⌝. +mkdir: cannot create directory ‘$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/dir/subdir/file1’: File exists +ERROR Failed to create the directory ⌜$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/dir/subdir/file1⌝. ``` ❯ `fs::createDirectoryIfNeeded resources/gitignored/derp` @@ -145,7 +145,7 @@ ERROR Failed to create the directory ⌜$GLOBAL_INSTALLATION_DIRECTORY/tests. Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/derp' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/gitignored/derp' ``` Directory created successfully! @@ -157,7 +157,7 @@ Directory created successfully! Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subdir/file1' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/dir/subdir/file1' ``` ❯ `fs::createFilePathIfNeeded resources/gitignored/allo/file1` @@ -165,15 +165,11 @@ RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/dir/subd Returned variables: ```text -RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/allo/file1' +RETURNED_VALUE='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/gitignored/allo/file1' ``` File created successfully! -### ✅ Testing exe::sleep - -❯ `exe::sleep 0.001` - ### ✅ Testing fs::cat ❯ `fs::cat resources/file-to-read` @@ -236,43 +232,6 @@ The production of meat and other animal derived products places a heavy burden o Just like veganism is the sustainable option when it comes to looking after our planet, plant-based living is also a more sustainable way of feeding the human family. A plant-based diet requires only one third of the land needed to support a meat and dairy diet. With rising global food and water insecurity due to a myriad of environmental and socio-economic problems, there'"'"'s never been a better time to adopt a more sustainable way of living. Avoiding animal products is not just one of the simplest ways an individual can reduce the strain on food as well as other resources, it'"'"'s the simplest way to take a stand against inefficient food systems which disproportionately affect the poorest people all over the world. Read more about how vegan diets can help people.' ``` -### ✅ Testing exe::readStdIn - -❯ `exe::readStdIn <<<'coucou'` - -Returned variables: - -```text -RETURNED_VALUE='coucou -' -``` - -❯ `exe::readStdIn` - -Returned variables: - -```text -RETURNED_VALUE='' -``` - -### ✅ Testing exe::countArgs - -❯ `exe::countArgs arg1 arg2 arg3` - -Returned variables: - -```text -RETURNED_VALUE='3' -``` - -❯ `exe::countArgs ${PWD}/resources/*` - -Returned variables: - -```text -RETURNED_VALUE='3' -``` - ### ✅ Testing fs::isDirectoryWritable ❯ `fs::isDirectoryWritable /tmp && echo Writable || echo Not\ writable` @@ -283,32 +242,6 @@ RETURNED_VALUE='3' Writable ``` -### ✅ Testing windows::convertPathFromUnix - -❯ `windows::convertPathFromUnix /tmp/file` - -Returned variables: - -```text -RETURNED_VALUE='\tmp\file' -``` - -❯ `windows::convertPathFromUnix /mnt/d/Users/username` - -Returned variables: - -```text -RETURNED_VALUE='D:\Users\username' -``` - -❯ `windows::convertPathFromUnix /c/data/file` - -Returned variables: - -```text -RETURNED_VALUE='C:\data\file' -``` - ### ✅ Testing fs::createLink ❯ `fs::createLink resources/gitignored/file resources/gitignored/try/file2 true` @@ -316,7 +249,7 @@ RETURNED_VALUE='C:\data\file' **Standard output**: ```text -🙈 mocking ln: $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/file $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/try/file2 +🙈 mocking ln: $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/gitignored/file $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/gitignored/try/file2 ``` ❯ `fs::createLink resources/gitignored/try resources/gitignored/new` @@ -324,25 +257,7 @@ RETURNED_VALUE='C:\data\file' **Standard output**: ```text -🙈 mocking ln: -s $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/try $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/gitignored/new -``` - -### ✅ Testing windows::convertPathToUnix - -❯ `windows::convertPathToUnix C:\\Users\\username` - -Returned variables: - -```text -RETURNED_VALUE='/c/Users/username' -``` - -❯ `windows::convertPathToUnix D:\\data\\file` - -Returned variables: - -```text -RETURNED_VALUE='/d/data/file' +🙈 mocking ln: -s $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/gitignored/try $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/gitignored/new ``` ### ✅ Testing fs::head @@ -409,36 +324,6 @@ RETURNED_ARRAY=( ) ``` -### ✅ Testing exe::captureOutput - -❯ `exe::captureOutput echo coucou` - -Returned variables: - -```text -RETURNED_VALUE='coucou -' -``` - -❯ `exe::captureOutput declare -f exe::captureOutput` - -Returned variables: - -```text -RETURNED_VALUE='exe::captureOutput () -{ - local IFS='"'"' '"'"'; - ${@} &> "${GLOBAL_TEMPORARY_STDOUT_FILE}" || return 1; - RETURNED_VALUE=""; - IFS='"'"''"'"' read -rd '"'"''"'"' RETURNED_VALUE < "${GLOBAL_TEMPORARY_STDOUT_FILE}" || : -} -' -``` - -❯ `exe::captureOutput [[ 1 -eq 0 ]]` - -Returned code: `1` - ### ✅ Testing fs::tail ❯ `fs::tail resources/file-to-read 3` @@ -502,298 +387,70 @@ RETURNED_ARRAY=( ) ``` -## Test script 01.invoke - -For these tests, we will use a special command `fake` defined as such: - -❯ `declare -f fake` - -**Standard output**: - -```text -fake () -{ - local inputStreamContent; - if [[ $* == *"--std-in"* ]]; then - exe::readStdIn; - inputStreamContent="${RETURNED_VALUE}"; - fi; - local IFS=" "; - echo "🙈 mocking fake $*"; - if [[ -n ${inputStreamContent:-} ]]; then - echo "Input stream: <${inputStreamContent}>"; - fi; - echo "INFO: log line from fake mock" 1>&2; - if [[ $* == *"--error"* ]]; then - echo "ERROR: returning error from fake" 1>&2; - return 1; - fi -} -``` - -### ✅ Testing exe::invoke5 - -Input stream from string, returns an error: - -❯ `exe::invoke5 false 0 false 'input_stream' fake --std-in --error` - -Returned code: `1` - -Returned variables: - -```text -RETURNED_VALUE='🙈 mocking fake --std-in --error -Input stream: -' -RETURNED_VALUE2='INFO: log line from fake mock -ERROR: returning error from fake -' -``` - -Input stream from string, fails (exit): - -❯ `exe::invoke5 true 0 false 'input_stream' fake --std-in --error` - -Exited with code: `1` - -**Error output**: - -```text -TRACE Fake standard output stream: - 1 ░ 🙈 mocking fake --std-in --error - 2 ░ Input stream: -TRACE Fake standard error stream: - 1 ░ INFO: log line from fake mock - 2 ░ ERROR: returning error from fake -ERROR The command ⌜fake⌝ originally ended with exit code ⌜1⌝. -``` - -Make error 1 acceptable: - -❯ `exe::invoke5 true 0,1,2 true '' fake --error` - -Returned variables: - -```text -RETURNED_VALUE='🙈 mocking fake --error -' -RETURNED_VALUE2='INFO: log line from fake mock -ERROR: returning error from fake -' -``` - -Normal, return everything as variables: - -❯ `exe::invoke5 true '' '' '' fake` - -Returned variables: - -```text -RETURNED_VALUE='🙈 mocking fake -' -RETURNED_VALUE2='INFO: log line from fake mock -' -``` - -Input stream for file, return everything as files: - -❯ `exe::invokef5 false 0 true /tmp/valet-temp fake --std-in` - -Returned variables: - -```text -RETURNED_VALUE='/tmp/valet-stdout.f' -RETURNED_VALUE2='/tmp/valet-stderr.f' -``` - -❯ `fs::cat /tmp/valet-stdout.f` - -**Standard output**: - -```text -🙈 mocking fake --std-in -Input stream: - -``` - -❯ `fs::cat /tmp/valet-stderr.f` - -**Standard output**: - -```text -INFO: log line from fake mock - -``` - -### ✅ Testing exe::invoke2 - -❯ `exe::invoke2 false fake --option argument1 argument2` - -Returned variables: - -```text -RETURNED_VALUE='🙈 mocking fake --option argument1 argument2 -' -RETURNED_VALUE2='INFO: log line from fake mock -' -``` - -❯ `exe::invoke2 false fake --error` - -Returned code: `1` - -Returned variables: - -```text -RETURNED_VALUE='🙈 mocking fake --error -' -RETURNED_VALUE2='INFO: log line from fake mock -ERROR: returning error from fake -' -``` - -❯ `exe::invoke2 true fake --error` - -Exited with code: `1` - -**Error output**: - -```text -TRACE Fake standard output stream: - 1 ░ 🙈 mocking fake --error -TRACE Fake standard error stream: - 1 ░ INFO: log line from fake mock - 2 ░ ERROR: returning error from fake -ERROR The command ⌜fake⌝ originally ended with exit code ⌜1⌝. -``` - -❯ `exe::invokef2 false fake --option argument1 argument2` - -Returned variables: - -```text -RETURNED_VALUE='/tmp/valet-stdout.f' -RETURNED_VALUE2='/tmp/valet-stderr.f' -``` - -### ✅ Testing exe::invoke - -❯ `exe::invoke fake --error` - -Exited with code: `1` - -**Error output**: - -```text -TRACE Fake standard output stream: - 1 ░ 🙈 mocking fake --error -TRACE Fake standard error stream: - 1 ░ INFO: log line from fake mock - 2 ░ ERROR: returning error from fake -ERROR The command ⌜fake⌝ originally ended with exit code ⌜1⌝. -``` - -❯ `exe::invoke fake --option argument1 argument2` - -Returned variables: - -```text -RETURNED_VALUE='🙈 mocking fake --option argument1 argument2 -' -RETURNED_VALUE2='INFO: log line from fake mock -' -``` - -### ✅ Testing exe::invoke2piped - -❯ `exe::invoke2piped true 'input_stream' fake --std-in --option argument1 argument2` - -Returned variables: - -```text -RETURNED_VALUE='🙈 mocking fake --std-in --option argument1 argument2 -Input stream: -' -RETURNED_VALUE2='INFO: log line from fake mock -' -``` - -❯ `exe::invokef2piped true 'input_stream' fake --std-in --option argument1 argument2` - -Returned variables: - -```text -RETURNED_VALUE='/tmp/valet-stdout.f' -RETURNED_VALUE2='/tmp/valet-stderr.f' -``` - -## Test script 02.listPaths +## Test script 01.listPaths ### ✅ Testing fs::listPaths -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search` +❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1' ) ``` -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true` +❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/file2' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2' +[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2/file3' ) ``` -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search false true` +❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search false true` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-file' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1' ) ``` -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true` +❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true true` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3' -[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/file10' -[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4' -[7]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/.hidden-file2' -[8]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[9]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2' -[10]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' -[11]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13' -[12]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' -[13]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14' -[14]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3' -[15]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-file' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1' +[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3' +[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/file10' +[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4' +[7]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/.hidden-file2' +[8]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/file2' +[9]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2' +[10]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' +[11]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3/file13' +[12]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' +[13]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4/file14' +[14]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2/.hidden-file3' +[15]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2/file3' ) ``` @@ -812,18 +469,18 @@ fileNamedFile () } ``` -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true fileNamedFile` +❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true true fileNamedFile` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/file10' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14' -[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/file10' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/file2' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3/file13' +[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4/file14' +[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2/file3' ) ``` @@ -842,63 +499,63 @@ folderNamedHidden () } ``` -❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true folderNamedHidden` +❯ `fs::listPaths $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true true folderNamedHidden` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/.hidden-file2' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' -[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' -[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-file' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/.hidden-file2' +[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' +[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' +[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2/.hidden-file3' ) ``` ### ✅ Testing fs::listFiles -❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search` +❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' ) ``` -❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true` +❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/file2' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2/file3' ) ``` -❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true` +❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true true` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/file10' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/.hidden-file2' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/file2' -[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' -[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13' -[7]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' -[8]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4/file14' -[9]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/.hidden-file3' -[10]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2/file3' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-file' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/file10' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/.hidden-file2' +[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/file2' +[5]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' +[6]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3/file13' +[7]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4/.hidden-file-14' +[8]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4/file14' +[9]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2/.hidden-file3' +[10]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2/file3' ) ``` @@ -917,54 +574,54 @@ fileNamedHidden () } ``` -❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true folderNamedHidden` +❯ `fs::listFiles $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true true folderNamedHidden` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-file' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/file1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/file10' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3/file13' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-file' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/file1' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/file10' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3/.hidden-file-13' +[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3/file13' ) ``` ### ✅ Testing fs::listDirectories -❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search` +❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1' ) ``` -❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true` +❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2' ) ``` -❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true` +❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true true` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4' -[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1/subfolder2' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4' +[4]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1/subfolder2' ) ``` @@ -983,16 +640,16 @@ folderNamedHidden () } ``` -❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search true true folderNamedHidden` +❯ `fs::listDirectories $GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search true true folderNamedHidden` Returned variables: ```text RETURNED_ARRAY=( -[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder' -[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/subfolder1' -[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/.hidden3' -[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-io/resources/search/.hidden-subfolder/subfolder4' +[0]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder' +[1]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/subfolder1' +[2]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/.hidden3' +[3]='$GLOBAL_INSTALLATION_DIRECTORY/tests.d/lib-fs/resources/search/.hidden-subfolder/subfolder4' ) ``` diff --git a/tests.d/lib-regex/00.tests.sh b/tests.d/lib-regex/00.tests.sh new file mode 100644 index 00000000..5c230121 --- /dev/null +++ b/tests.d/lib-regex/00.tests.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# shellcheck source=../../libraries.d/lib-regex +source regex + +function main() { + test_regex::getFirstGroup +} + +function test_regex::getFirstGroup() { + test::title "✅ Testing regex::getFirstGroup function" + + test::func regex::getFirstGroup 'name: julien' "'name:[[:space:]]*([[:alnum:]]*)'" +} + +main \ No newline at end of file diff --git a/tests.d/lib-regex/results.approved.md b/tests.d/lib-regex/results.approved.md new file mode 100644 index 00000000..49f6cf2f --- /dev/null +++ b/tests.d/lib-regex/results.approved.md @@ -0,0 +1,14 @@ +# Test suite lib-regex + +## Test script 00.tests + +### ✅ Testing regex::getFirstGroup function + +❯ `regex::getFirstGroup name:\ julien 'name:[[:space:]]*([[:alnum:]]*)'` + +Returned variables: + +```text +RETURNED_VALUE='julien' +``` + diff --git a/tests.d/lib-string/00.tests.sh b/tests.d/lib-string/00.tests.sh index d53224c2..2290c8ec 100644 --- a/tests.d/lib-string/00.tests.sh +++ b/tests.d/lib-string/00.tests.sh @@ -5,18 +5,16 @@ source string function main() { test_string::cutField - test_string::kebabCaseToSnakeCase - test_string::kebabCaseToSnakeCase - test_string::kebabCaseToCamelCase + test_string::convertKebabCaseToSnakeCase + test_string::convertKebabCaseToSnakeCase + test_string::convertKebabCaseToCamelCase test_string::trimAll test_string::trim test_string::indexOf test_string::extractBetween test_string::count test_string::split - test_string::regexGetFirst - test_string::microsecondsToHuman - test_string::wrapText + test_string::wrapWords test_string::wrapCharacters test_string::highlight test_string::head @@ -34,28 +32,28 @@ line2 does it work on lines? line3 seems so" 2 $'\n' } -function test_string::camelCaseToSnakeCase() { - test::title "✅ Testing string::camelCaseToSnakeCase" +function test_string::convertCamelCaseToSnakeCase() { + test::title "✅ Testing string::convertCamelCaseToSnakeCase" - test::func string::camelCaseToSnakeCase thisIsATest0 - test::func string::camelCaseToSnakeCase AnotherTest + test::func string::convertCamelCaseToSnakeCase thisIsATest0 + test::func string::convertCamelCaseToSnakeCase AnotherTest } -function test_string::kebabCaseToSnakeCase() { - test::title "✅ Testing string::kebabCaseToSnakeCase" +function test_string::convertKebabCaseToSnakeCase() { + test::title "✅ Testing string::convertKebabCaseToSnakeCase" - test::func string::kebabCaseToSnakeCase this-is-a-test0 - test::func string::kebabCaseToSnakeCase --another-test + test::func string::convertKebabCaseToSnakeCase this-is-a-test0 + test::func string::convertKebabCaseToSnakeCase --another-test } -function test_string::kebabCaseToCamelCase() { - test::title "✅ Testing string::kebabCaseToCamelCase" +function test_string::convertKebabCaseToCamelCase() { + test::title "✅ Testing string::convertKebabCaseToCamelCase" - test::func string::kebabCaseToCamelCase this-is-a-test0 - test::func string::kebabCaseToCamelCase --another-test - test::func string::kebabCaseToCamelCase --last-- + test::func string::convertKebabCaseToCamelCase this-is-a-test0 + test::func string::convertKebabCaseToCamelCase --another-test + test::func string::convertKebabCaseToCamelCase --last-- } function test_string::trimAll() { @@ -112,58 +110,26 @@ function test_string::split() { test::func string::split "one"$'\n'"two"$'\n'"three" $'\n' } -function test_string::regexGetFirst() { - test::title "✅ Testing string::regexGetFirst function" - - test::func string::regexGetFirst 'name: julien' "'name:[[:space:]]*([[:alnum:]]*)'" -} - -function test_string::microsecondsToHuman() { - test::title "✅ Testing string::microsecondsToHuman function" - - local -i ms=$((234 + 1000 * 2 + 1000000 * 3 + 1000000 * 60 * 4 + 1000000 * 60 * 60 * 5)) - local format="Hours: %HH -Minutes: %MM -Seconds: %SS -Milliseconds: %LL -Microseconds: %UU - -Hours: %h -Minutes: %m -Seconds: %s -Milliseconds: %l -Microseconds: %u - -Total minutes: %M -Total seconds: %S -Total milliseconds: %L -Total microseconds: %U" - test::printVars format - test::func string::microsecondsToHuman ${ms} "\"\${format}\"" - test::func string::microsecondsToHuman ${ms} - test::func _OPTION_FORMAT='%U' string::microsecondsToHuman ${ms} -} - -function test_string::wrapText() { - test::title "✅ Testing string::wrapText" +function test_string::wrapWords() { + test::title "✅ Testing string::wrapWords" test::markdown "Wrapping text at column 30 with no padding" - test::func string::wrapText "\"\${MULTI_LINES_TEXT}\"" 30 + test::func string::wrapWords "\"\${MULTI_LINES_TEXT}\"" 30 test::markdown "Wrapping text at column 50 with padding of 4 on new lines" - test::func string::wrapText "\"\${MULTI_LINES_TEXT}\"" 50 ' ' + test::func string::wrapWords "\"\${MULTI_LINES_TEXT}\"" 50 ' ' test::markdown "Wrapping text at column 20 with padding of 3 on all lines" - test::func string::wrapText "\"\${MULTI_LINES_TEXT}\"" 20 ' ' 17 + test::func string::wrapWords "\"\${MULTI_LINES_TEXT}\"" 20 ' ' 17 test::markdown "Wrapping words, shortcut because the message is a short single line" - test::func string::wrapText 'A message.' 80 + test::func string::wrapWords 'A message.' 80 test::markdown "Wrapping words, no shortcut!" - test::func string::wrapText 'A message.' 80 '' 5 + test::func string::wrapWords 'A message.' 80 '' 5 test::markdown "Wrapping words" - test::func string::wrapText 'A message.'$'\n''A new line' 13 '░░░' 10 + test::func string::wrapWords 'A message.'$'\n''A new line' 13 '░░░' 10 } function test_string::wrapCharacters() { diff --git a/tests.d/lib-string/results.approved.md b/tests.d/lib-string/results.approved.md index 5dac2705..4951d9e6 100644 --- a/tests.d/lib-string/results.approved.md +++ b/tests.d/lib-string/results.approved.md @@ -44,9 +44,9 @@ Returned variables: RETURNED_VALUE='line3 seems so' ``` -### ✅ Testing string::kebabCaseToSnakeCase +### ✅ Testing string::convertKebabCaseToSnakeCase -❯ `string::kebabCaseToSnakeCase this-is-a-test0` +❯ `string::convertKebabCaseToSnakeCase this-is-a-test0` Returned variables: @@ -54,7 +54,7 @@ Returned variables: RETURNED_VALUE='THIS_IS_A_TEST0' ``` -❯ `string::kebabCaseToSnakeCase --another-test` +❯ `string::convertKebabCaseToSnakeCase --another-test` Returned variables: @@ -62,9 +62,9 @@ Returned variables: RETURNED_VALUE='ANOTHER_TEST' ``` -### ✅ Testing string::kebabCaseToSnakeCase +### ✅ Testing string::convertKebabCaseToSnakeCase -❯ `string::kebabCaseToSnakeCase this-is-a-test0` +❯ `string::convertKebabCaseToSnakeCase this-is-a-test0` Returned variables: @@ -72,7 +72,7 @@ Returned variables: RETURNED_VALUE='THIS_IS_A_TEST0' ``` -❯ `string::kebabCaseToSnakeCase --another-test` +❯ `string::convertKebabCaseToSnakeCase --another-test` Returned variables: @@ -80,9 +80,9 @@ Returned variables: RETURNED_VALUE='ANOTHER_TEST' ``` -### ✅ Testing string::kebabCaseToCamelCase +### ✅ Testing string::convertKebabCaseToCamelCase -❯ `string::kebabCaseToCamelCase this-is-a-test0` +❯ `string::convertKebabCaseToCamelCase this-is-a-test0` Returned variables: @@ -90,7 +90,7 @@ Returned variables: RETURNED_VALUE='thisIsATest0' ``` -❯ `string::kebabCaseToCamelCase --another-test` +❯ `string::convertKebabCaseToCamelCase --another-test` Returned variables: @@ -98,7 +98,7 @@ Returned variables: RETURNED_VALUE='anotherTest' ``` -❯ `string::kebabCaseToCamelCase --last--` +❯ `string::convertKebabCaseToCamelCase --last--` Returned variables: @@ -303,81 +303,11 @@ RETURNED_ARRAY=( ) ``` -### ✅ Testing string::regexGetFirst function - -❯ `string::regexGetFirst name:\ julien 'name:[[:space:]]*([[:alnum:]]*)'` - -Returned variables: - -```text -RETURNED_VALUE='julien' -``` - -### ✅ Testing string::microsecondsToHuman function - -```text -format='Hours: %HH -Minutes: %MM -Seconds: %SS -Milliseconds: %LL -Microseconds: %UU - -Hours: %h -Minutes: %m -Seconds: %s -Milliseconds: %l -Microseconds: %u - -Total minutes: %M -Total seconds: %S -Total milliseconds: %L -Total microseconds: %U' -``` - -❯ `string::microsecondsToHuman 18243002234 "${format}"` - -Returned variables: - -```text -RETURNED_VALUE='Hours: 05 -Minutes: 04 -Seconds: 03 -Milliseconds: 002 -Microseconds: 234 - -Hours: 5 -Minutes: 4 -Seconds: 3 -Milliseconds: 2 -Microseconds: 234 - -Total minutes: 304 -Total seconds: 18243 -Total milliseconds: 4320003002 -Total microseconds: 18243002234' -``` - -❯ `string::microsecondsToHuman 18243002234` - -Returned variables: - -```text -RETURNED_VALUE='05:04:03' -``` - -❯ `_OPTION_FORMAT=%U string::microsecondsToHuman 18243002234` - -Returned variables: - -```text -RETURNED_VALUE='18243002234' -``` - -### ✅ Testing string::wrapText +### ✅ Testing string::wrapWords Wrapping text at column 30 with no padding -❯ `string::wrapText "${MULTI_LINES_TEXT}" 30` +❯ `string::wrapWords "${MULTI_LINES_TEXT}" 30` Returned variables: @@ -427,7 +357,7 @@ RETURNED_VALUE2='8' Wrapping text at column 50 with padding of 4 on new lines -❯ `string::wrapText "${MULTI_LINES_TEXT}" 50 \ \ \ \ ` +❯ `string::wrapWords "${MULTI_LINES_TEXT}" 50 \ \ \ \ ` Returned variables: @@ -462,7 +392,7 @@ RETURNED_VALUE='You don`t get better on the days w Wrapping text at column 20 with padding of 3 on all lines -❯ `string::wrapText "${MULTI_LINES_TEXT}" 20 \ \ \ 17` +❯ `string::wrapWords "${MULTI_LINES_TEXT}" 20 \ \ \ 17` Returned variables: @@ -538,7 +468,7 @@ RETURNED_VALUE2='4' Wrapping words, shortcut because the message is a short single line -❯ `string::wrapText A\ message. 80` +❯ `string::wrapWords A\ message. 80` Returned variables: @@ -548,7 +478,7 @@ RETURNED_VALUE='A message.' Wrapping words, no shortcut! -❯ `string::wrapText A\ message. 80 '' 5` +❯ `string::wrapWords A\ message. 80 '' 5` Returned variables: @@ -559,7 +489,7 @@ message.' Wrapping words -❯ `string::wrapText $'A message.\nA new line' 13 ░░░ 10` +❯ `string::wrapWords $'A message.\nA new line' 13 ░░░ 10` Returned variables: diff --git a/tests.d/lib-system/00.tests.sh b/tests.d/lib-system/00.tests.sh index 93eb5d9f..a078e94f 100644 --- a/tests.d/lib-system/00.tests.sh +++ b/tests.d/lib-system/00.tests.sh @@ -6,65 +6,30 @@ source system source fs function main() { - test_system::os - test_system::env - test_system::date - test_system::getUndeclaredVariables - test_system::getNotExistingCommands - test_system::commandExists + test_system::getOs + test_system::getEnvVars test_system::addToPath } -function test_system::os() { - test::title "✅ Testing system::os" +function test_system::getOs() { + test::title "✅ Testing system::getOs" - test::func OSTYPE=linux-bsd system::os - test::func OSTYPE=msys system::os - test::func OSTYPE=darwin-stuff system::os - test::func OSTYPE=nop system::os + test::func OSTYPE=linux-bsd system::getOs + test::func OSTYPE=msys system::getOs + test::func OSTYPE=darwin-stuff system::getOs + test::func OSTYPE=nop system::getOs } -function test_system::env() { - test::title "✅ Testing system::env" +function test_system::getEnvVars() { + test::title "✅ Testing system::getEnvVars" RETURNED_ARRAY=() - test::exec system::env + test::exec system::getEnvVars if ((${#RETURNED_ARRAY[*]} > 0)); then test::markdown "Found environment variables in RETURNED_ARRAY." fi } -function test_system::date() { - test::title "✅ Testing system::date" - - test::func system::date - test::func system::date "'%(%H:%M:%S)T'" -} - -function test_system::getUndeclaredVariables() { - test::title "✅ Testing system::getUndeclaredVariables" - - test::func system::getUndeclaredVariables - test::exec ABC="ok" - test::func system::getUndeclaredVariables GLOBAL_TEST_TEMP_FILE dfg ABC NOP -} - -function test_system::getNotExistingCommands() { - test::title "✅ Testing system::getNotExistingCommands" - - test::func system::getNotExistingCommands - - test::func system::getNotExistingCommands NONEXISTINGSTUFF system::getNotExistingCommands rm YETANOTHERONEMISSING -} - -function test_system::commandExists() { - test::title "✅ Testing system::commandExists" - - test::exec system::commandExists - test::exec system::commandExists NONEXISTINGSTUFF - test::exec system::commandExists rm -} - # shellcheck disable=SC2317 function test_system::addToPath() { test::title "✅ Testing system::addToPath" diff --git a/tests.d/lib-system/results.approved.md b/tests.d/lib-system/results.approved.md index 2006a240..06ce6350 100644 --- a/tests.d/lib-system/results.approved.md +++ b/tests.d/lib-system/results.approved.md @@ -2,9 +2,9 @@ ## Test script 00.tests -### ✅ Testing system::os +### ✅ Testing system::getOs -❯ `OSTYPE=linux-bsd system::os` +❯ `OSTYPE=linux-bsd system::getOs` Returned variables: @@ -12,7 +12,7 @@ Returned variables: RETURNED_VALUE='linux' ``` -❯ `OSTYPE=msys system::os` +❯ `OSTYPE=msys system::getOs` Returned variables: @@ -20,7 +20,7 @@ Returned variables: RETURNED_VALUE='windows' ``` -❯ `OSTYPE=darwin-stuff system::os` +❯ `OSTYPE=darwin-stuff system::getOs` Returned variables: @@ -28,7 +28,7 @@ Returned variables: RETURNED_VALUE='darwin' ``` -❯ `OSTYPE=nop system::os` +❯ `OSTYPE=nop system::getOs` Returned variables: @@ -36,78 +36,12 @@ Returned variables: RETURNED_VALUE='unknown' ``` -### ✅ Testing system::env +### ✅ Testing system::getEnvVars -❯ `system::env` +❯ `system::getEnvVars` Found environment variables in RETURNED_ARRAY. -### ✅ Testing system::date - -❯ `system::date` - -Returned variables: - -```text -RETURNED_VALUE='1987-05-25_01h00m00s' -``` - -❯ `system::date '%(%H:%M:%S)T'` - -Returned variables: - -```text -RETURNED_VALUE='01:00:00' -``` - -### ✅ Testing system::getUndeclaredVariables - -❯ `system::getUndeclaredVariables` - -Returned code: `1` - -❯ `ABC=ok` - -❯ `system::getUndeclaredVariables GLOBAL_TEST_TEMP_FILE dfg ABC NOP` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='dfg' -[1]='NOP' -) -``` - -### ✅ Testing system::getNotExistingCommands - -❯ `system::getNotExistingCommands` - -Returned code: `1` - -❯ `system::getNotExistingCommands NONEXISTINGSTUFF system::getNotExistingCommands rm YETANOTHERONEMISSING` - -Returned variables: - -```text -RETURNED_ARRAY=( -[0]='NONEXISTINGSTUFF' -[1]='YETANOTHERONEMISSING' -) -``` - -### ✅ Testing system::commandExists - -❯ `system::commandExists` - -Returned code: `1` - -❯ `system::commandExists NONEXISTINGSTUFF` - -Returned code: `1` - -❯ `system::commandExists rm` - ### ✅ Testing system::addToPath ❯ `system::addToPath /coucou` @@ -235,55 +169,3 @@ INFO The directory ⌜/coucou⌝ is already in the PATH for ⌜fish⌝ shell INFO The directory ⌜/coucou⌝ is already in the PATH for ⌜nu⌝ shell. ``` -### ✅ Testing windows::setEnvVar - -❯ `OSTYPE=msys windows::setEnvVar VAR VALUE` - -**Standard output**: - -```text -🙈 mocking windows::runPs1: $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); $key.SetValue('VAR', 'VALUE', 'ExpandString'); -``` - -❯ `OSTYPE=msys windows::setEnvVar VAR ''` - -**Standard output**: - -```text -🙈 mocking windows::runPs1: $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); $key.DeleteValue('VAR'); -``` - -### ✅ Testing windows::getEnvVar - -❯ `OSTYPE=msys windows::getEnvVar VAR` - -**Standard output**: - -```text -🙈 mocking windows::runPs1: - $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); - $value = $key.GetValue('VAR', '', 'DoNotExpandEnvironmentNames'); - $key.Dispose(); - Write-Output $value; - -``` - -### ✅ Testing windows::addToPath - -❯ `OSTYPE=msys windows::addToPath /coucou` - -**Standard output**: - -```text -🙈 mocking windows::runPs1: - $pathToAdd = '\coucou'; - $key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', $true); - $oldPath = $key.GetValue('Path', '', 'DoNotExpandEnvironmentNames').TrimEnd([IO.Path]::PathSeparator); - if ($currentPath -notlike "*$pathToAdd*") { - $newPath = '{0}{1}{2}' -f $oldPath, [IO.Path]::PathSeparator, $pathToAdd; - $key.SetValue('Path', $newPath, 'ExpandString'); - }; - $key.Dispose(); - -``` - diff --git a/tests.d/lib-time/00.tests.sh b/tests.d/lib-time/00.tests.sh new file mode 100644 index 00000000..8a4fd68a --- /dev/null +++ b/tests.d/lib-time/00.tests.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# shellcheck source=../../libraries.d/lib-time +source time + +function main() { + test_time::getDate + test_time::convertMicrosecondsToHuman +} + +function test_time::getDate() { + test::title "✅ Testing time::getDate" + + test::func time::getDate + test::func time::getDate "'%(%H:%M:%S)T'" +} + +function test_time::convertMicrosecondsToHuman() { + test::title "✅ Testing time::convertMicrosecondsToHuman function" + + local -i ms=$((234 + 1000 * 2 + 1000000 * 3 + 1000000 * 60 * 4 + 1000000 * 60 * 60 * 5)) + local format="Hours: %HH +Minutes: %MM +Seconds: %SS +Milliseconds: %LL +Microseconds: %UU + +Hours: %h +Minutes: %m +Seconds: %s +Milliseconds: %l +Microseconds: %u + +Total minutes: %M +Total seconds: %S +Total milliseconds: %L +Total microseconds: %U" + test::printVars format + test::func time::convertMicrosecondsToHuman ${ms} "\"\${format}\"" + test::func time::convertMicrosecondsToHuman ${ms} + test::func _OPTION_FORMAT='%U' time::convertMicrosecondsToHuman ${ms} +} + +main \ No newline at end of file diff --git a/tests.d/lib-time/results.approved.md b/tests.d/lib-time/results.approved.md new file mode 100644 index 00000000..fc60e636 --- /dev/null +++ b/tests.d/lib-time/results.approved.md @@ -0,0 +1,82 @@ +# Test suite lib-time + +## Test script 00.tests + +### ✅ Testing time::getDate + +❯ `time::getDate` + +Returned variables: + +```text +RETURNED_VALUE='1987-05-25_01h00m00s' +``` + +❯ `time::getDate '%(%H:%M:%S)T'` + +Returned variables: + +```text +RETURNED_VALUE='01:00:00' +``` + +### ✅ Testing time::convertMicrosecondsToHuman function + +```text +format='Hours: %HH +Minutes: %MM +Seconds: %SS +Milliseconds: %LL +Microseconds: %UU + +Hours: %h +Minutes: %m +Seconds: %s +Milliseconds: %l +Microseconds: %u + +Total minutes: %M +Total seconds: %S +Total milliseconds: %L +Total microseconds: %U' +``` + +❯ `time::convertMicrosecondsToHuman 18243002234 "${format}"` + +Returned variables: + +```text +RETURNED_VALUE='Hours: 05 +Minutes: 04 +Seconds: 03 +Milliseconds: 002 +Microseconds: 234 + +Hours: 5 +Minutes: 4 +Seconds: 3 +Milliseconds: 2 +Microseconds: 234 + +Total minutes: 304 +Total seconds: 18243 +Total milliseconds: 4320003002 +Total microseconds: 18243002234' +``` + +❯ `time::convertMicrosecondsToHuman 18243002234` + +Returned variables: + +```text +RETURNED_VALUE='05:04:03' +``` + +❯ `_OPTION_FORMAT=%U time::convertMicrosecondsToHuman 18243002234` + +Returned variables: + +```text +RETURNED_VALUE='18243002234' +``` + diff --git a/tests.d/lib-windows/00.tests.sh b/tests.d/lib-windows/00.tests.sh index b2524917..55ba8e34 100644 --- a/tests.d/lib-windows/00.tests.sh +++ b/tests.d/lib-windows/00.tests.sh @@ -63,7 +63,10 @@ function test_windows::createLink() { } function powershell() { - echo "🙈 mocking powershell: $*"; + local text="🙈 mocking powershell: $*" + text="${text//"-FilePath "*"-Encoding utf8;"/"-FilePath 'tmp' -Encoding utf8;"}" + text="${text//"\"-File\","*") -Wait"/"\"-File\",'tmp') -Wait"}" + echo "${text}"; } main \ No newline at end of file diff --git a/tests.d/lib-windows/results.approved.md b/tests.d/lib-windows/results.approved.md new file mode 100644 index 00000000..ae9aab8f --- /dev/null +++ b/tests.d/lib-windows/results.approved.md @@ -0,0 +1,198 @@ +# Test suite lib-windows + +## Test script 00.tests + +### ✅ Testing windows::convertPathFromUnix + +❯ `windows::convertPathFromUnix /tmp/file` + +Returned variables: + +```text +RETURNED_VALUE='\tmp\file' +``` + +❯ `windows::convertPathFromUnix /mnt/d/Users/username` + +Returned variables: + +```text +RETURNED_VALUE='D:\Users\username' +``` + +❯ `windows::convertPathFromUnix /c/data/file` + +Returned variables: + +```text +RETURNED_VALUE='C:\data\file' +``` + +### ✅ Testing windows::convertPathToUnix + +❯ `windows::convertPathToUnix C:\\Users\\username` + +Returned variables: + +```text +RETURNED_VALUE='/c/Users/username' +``` + +❯ `windows::convertPathToUnix D:\\data\\file` + +Returned variables: + +```text +RETURNED_VALUE='/d/data/file' +``` + +### ✅ Testing windows::setEnvVar + +❯ `OSTYPE=msys windows::setEnvVar VAR VALUE` + +**Standard output**: + +```text +🙈 mocking powershell: -NoProfile -NonInteractive -Command + $ErrorActionPreference = 'Stop'; + $processInfo = New-Object System.Diagnostics.ProcessStartInfo; + $processInfo.FileName = "powershell.exe" + $processInfo.Verb = "runas"; + $processInfo.RedirectStandardError = $true; + $processInfo.RedirectStandardOutput = $true; + $processInfo.UseShellExecute = $false; + $processInfo.CreateNoWindow = $true; + $processInfo.Arguments = @("-NoProfile","-NonInteractive","-Command","`$ErrorActionPreference = 'Stop'; `$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', `$true); `$key.SetValue('VAR', 'VALUE', 'ExpandString');; exit `$LASTEXITCODE;") + $p = New-Object System.Diagnostics.Process; + $p.StartInfo = $processInfo; + $p.Start() | Out-Null; + $stdout = $p.StandardOutput.ReadToEnd(); + $stderr = $p.StandardError.ReadToEnd(); + $p.WaitForExit(); + $stdout | Out-File -FilePath 'tmp' -Encoding utf8; + exit $p.ExitCode; + +``` + +❯ `OSTYPE=msys windows::setEnvVar VAR ''` + +**Standard output**: + +```text +🙈 mocking powershell: -NoProfile -NonInteractive -Command + $ErrorActionPreference = 'Stop'; + $processInfo = New-Object System.Diagnostics.ProcessStartInfo; + $processInfo.FileName = "powershell.exe" + $processInfo.Verb = "runas"; + $processInfo.RedirectStandardError = $true; + $processInfo.RedirectStandardOutput = $true; + $processInfo.UseShellExecute = $false; + $processInfo.CreateNoWindow = $true; + $processInfo.Arguments = @("-NoProfile","-NonInteractive","-Command","`$ErrorActionPreference = 'Stop'; `$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', `$true); `$key.DeleteValue('VAR');; exit `$LASTEXITCODE;") + $p = New-Object System.Diagnostics.Process; + $p.StartInfo = $processInfo; + $p.Start() | Out-Null; + $stdout = $p.StandardOutput.ReadToEnd(); + $stderr = $p.StandardError.ReadToEnd(); + $p.WaitForExit(); + $stdout | Out-File -FilePath 'tmp' -Encoding utf8; + exit $p.ExitCode; + +``` + +### ✅ Testing windows::getEnvVar + +❯ `OSTYPE=msys windows::getEnvVar VAR` + +**Standard output**: + +```text +🙈 mocking powershell: -NoProfile -NonInteractive -Command + $ErrorActionPreference = 'Stop'; + $processInfo = New-Object System.Diagnostics.ProcessStartInfo; + $processInfo.FileName = "powershell.exe" + $processInfo.Verb = "runas"; + $processInfo.RedirectStandardError = $true; + $processInfo.RedirectStandardOutput = $true; + $processInfo.UseShellExecute = $false; + $processInfo.CreateNoWindow = $true; + $processInfo.Arguments = @("-NoProfile","-NonInteractive","-Command","`$ErrorActionPreference = 'Stop'; + `$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', `$true); + `$value = `$key.GetValue('VAR', '', 'DoNotExpandEnvironmentNames'); + `$key.Dispose(); + Write-Output `$value; + ; exit `$LASTEXITCODE;") + $p = New-Object System.Diagnostics.Process; + $p.StartInfo = $processInfo; + $p.Start() | Out-Null; + $stdout = $p.StandardOutput.ReadToEnd(); + $stderr = $p.StandardError.ReadToEnd(); + $p.WaitForExit(); + $stdout | Out-File -FilePath 'tmp' -Encoding utf8; + exit $p.ExitCode; + +``` + +### ✅ Testing windows::addToPath + +❯ `OSTYPE=msys windows::addToPath /coucou` + +**Standard output**: + +```text +🙈 mocking powershell: -NoProfile -NonInteractive -Command + $ErrorActionPreference = 'Stop'; + $processInfo = New-Object System.Diagnostics.ProcessStartInfo; + $processInfo.FileName = "powershell.exe" + $processInfo.Verb = "runas"; + $processInfo.RedirectStandardError = $true; + $processInfo.RedirectStandardOutput = $true; + $processInfo.UseShellExecute = $false; + $processInfo.CreateNoWindow = $true; + $processInfo.Arguments = @("-NoProfile","-NonInteractive","-Command","`$ErrorActionPreference = 'Stop'; + `$pathToAdd = '\coucou'; + `$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Environment', `$true); + `$oldPath = `$key.GetValue('Path', '', 'DoNotExpandEnvironmentNames').TrimEnd([IO.Path]::PathSeparator); + if (`$currentPath -notlike `"*`$pathToAdd*`") { + `$newPath = '{0}{1}{2}' -f `$oldPath, [IO.Path]::PathSeparator, `$pathToAdd; + `$key.SetValue('Path', `$newPath, 'ExpandString'); + }; + `$key.Dispose(); + ; exit `$LASTEXITCODE;") + $p = New-Object System.Diagnostics.Process; + $p.StartInfo = $processInfo; + $p.Start() | Out-Null; + $stdout = $p.StandardOutput.ReadToEnd(); + $stderr = $p.StandardError.ReadToEnd(); + $p.WaitForExit(); + $stdout | Out-File -FilePath 'tmp' -Encoding utf8; + exit $p.ExitCode; + +``` + +### ✅ Testing windows::createLink + +❯ `windows::createLink resources/gitignored/file resources/gitignored/try/file2 true` + +**Standard output**: + +```text +🙈 mocking powershell: -NoProfile -NonInteractive -Command + $ErrorActionPreference = 'Stop'; + $process = Start-Process -FilePath powershell.exe -ArgumentList @("-NoProfile","-NonInteractive","-File",'tmp') -Wait -Verb RunAs -WindowStyle Hidden; + exit $process.ExitCode + +``` + +❯ `windows::createLink resources/gitignored/try resources/gitignored/new` + +**Standard output**: + +```text +🙈 mocking powershell: -NoProfile -NonInteractive -Command + $ErrorActionPreference = 'Stop'; + $process = Start-Process -FilePath powershell.exe -ArgumentList @("-NoProfile","-NonInteractive","-File",'tmp') -Wait -Verb RunAs -WindowStyle Hidden; + exit $process.ExitCode + +``` + diff --git a/tests.d/self-export/results.approved.md b/tests.d/self-export/results.approved.md index f1444d2b..1bd6fe0b 100644 --- a/tests.d/self-export/results.approved.md +++ b/tests.d/self-export/results.approved.md @@ -31,18 +31,22 @@ source bash source benchmark source command source curl +source exe +source fs source http source interactive -source io source profiler source progress source prompt +source regex source sfzf source string source system source test +source time source tui source version +source windows ``` diff --git a/tests.d/self-release/01.self-release.sh b/tests.d/self-release/01.self-release.sh index 0f3bd67e..c3458d83 100644 --- a/tests.d/self-release/01.self-release.sh +++ b/tests.d/self-release/01.self-release.sh @@ -42,16 +42,16 @@ function interactive::promptYesNo() { return 0 } -function curl::toVar() { - echo "🙈 mocked curl::toVar $*" 1>&2 +function curl::request() { + echo "🙈 mocked curl::request $*" 1>&2 RETURNED_VALUE='{ "upload_url": "https://uploads.github.com/repos/jcaillon/valet/releases/xxxx/assets{?name,label}", "tag_name": "v1.2.3", "browser_download_url": "https:///fake" }' RETURNED_VALUE2="" RETURNED_VALUE3=200 } -function curl::toFile() { - echo "🙈 mocked curl::toFile $*" 1>&2 +function curl::download() { + echo "🙈 mocked curl::download $*" 1>&2 RETURNED_VALUE="" RETURNED_VALUE2=200 } diff --git a/tests.d/self-release/results.approved.md b/tests.d/self-release/results.approved.md index 33062b69..b06ed3a8 100644 --- a/tests.d/self-release/results.approved.md +++ b/tests.d/self-release/results.approved.md @@ -14,7 +14,7 @@ Testing selfRelease, dry run major version INFO Dry run mode is enabled, no changes will be made. 🙈 mocked exe::invoke git tag --sort=version:refname --no-color INFO The last tag is: v1.2.3. -🙈 mocked curl::toVar true 200 -H Accept: application/vnd.github.v3+json https://api.github.com/repos/jcaillon/valet/releases/latest +🙈 mocked curl::request true 200 -H Accept: application/vnd.github.v3+json https://api.github.com/repos/jcaillon/valet/releases/latest INFO The latest release on GitHub is: v1.2.3. 🙈 mocked exe::invoke git rev-parse HEAD INFO The current version of valet is: 1.2.3. @@ -42,7 +42,7 @@ Testing selfRelease, minor version ```text 🙈 mocked exe::invoke git tag --sort=version:refname --no-color INFO The last tag is: v1.2.3. -🙈 mocked curl::toVar true 200 -H Accept: application/vnd.github.v3+json https://api.github.com/repos/jcaillon/valet/releases/latest +🙈 mocked curl::request true 200 -H Accept: application/vnd.github.v3+json https://api.github.com/repos/jcaillon/valet/releases/latest INFO The latest release on GitHub is: v1.2.3. 🙈 mocked exe::invoke git rev-parse HEAD 🙈 mocked exe::invokef5 false 0 git update-index --really-refresh @@ -80,14 +80,6 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked exe::invoke rm -f $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md 🙈 mocked exe::invoke rm -f $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/codes.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/codes.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md @@ -107,12 +99,16 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/bash.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/benchmark.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/benchmark.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/benchmark.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md @@ -121,16 +117,6 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/command.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md @@ -140,15 +126,52 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/curl.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/curl.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/curl.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/curl.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/exe.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/fs.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md @@ -156,88 +179,6 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/interactive.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/io.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md @@ -256,34 +197,17 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/log.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/profiler.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/profiler.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/profiler.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/profiler.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/progress.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/sfzf.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/regex.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/regex.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/sfzf.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/sfzf.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md @@ -298,47 +222,10 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/string.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/system.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md @@ -355,19 +242,12 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/test.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/time.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/time.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/time.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/time.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/time.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/time.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md @@ -404,22 +284,32 @@ INFO Writing the 154 functions documentation to the core libraries docs. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/tui.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/version.md -🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/version.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/version.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/version.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/version.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/version.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md +🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/windows.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/array.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/codes.md 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/docs/content/docs/300.libraries/core.md @@ -457,7 +347,7 @@ SUCCESS The new version has been tagged. SUCCESS The ⌜main⌝ branch and the new version ⌜v1.2.3⌝ has been pushed. 🙈 mocked exe::invoke git push origin -f main:latest SUCCESS The ⌜latest⌝ branch has been updated. -🙈 mocked curl::toVar true 201,422 -X POST -H Authorization: token token -H Accept: application/vnd.github.v3+json -H Content-type: application/json; charset=utf-8 -d { +🙈 mocked curl::request true 201,422 -X POST -H Authorization: token token -H Accept: application/vnd.github.v3+json -H Content-type: application/json; charset=utf-8 -d { "name": "v1.2.3", "tag_name": "v1.2.3", "body": "# Release of version 1.2.3\n\nChangelog: \n\n- ✨ feature\n- 🐞 fix\n", @@ -473,7 +363,7 @@ SUCCESS The new version has been released on GitHub. 🙈 mocked exe::invoke cp -R $GLOBAL_INSTALLATION_DIRECTORY/version . 🙈 mocked exe::invoke tar -czvf valet.tar.gz examples.d commands.d libraries.d extras valet version INFO Uploading the artifact ⌜valet.tar.gz⌝ to ⌜https://uploads.github.com/repos/jcaillon/valet/releases/xxxx/assets⌝. -🙈 mocked curl::toVar true -X POST -H Authorization: token token -H Content-Type: application/tar+gzip --data-binary @valet.tar.gz https://uploads.github.com/repos/jcaillon/valet/releases/xxxx/assets?name=valet.tar.gz +🙈 mocked curl::request true -X POST -H Authorization: token token -H Content-Type: application/tar+gzip --data-binary @valet.tar.gz https://uploads.github.com/repos/jcaillon/valet/releases/xxxx/assets?name=valet.tar.gz INFO The current version of valet is: 1.2.3. 🙈 mocked fs::writeToFile $GLOBAL_INSTALLATION_DIRECTORY/version INFO The bumped version of valet is: 1.3.0. diff --git a/version b/version index 70b644b5..02a59aa2 100644 --- a/version +++ b/version @@ -1 +1 @@ -0.28.2564 \ No newline at end of file +0.28.2606 \ No newline at end of file