From 7e86c1a5f525f352983077d743c2ce2f5d75f4fa Mon Sep 17 00:00:00 2001 From: Tyler Akins Date: Wed, 24 Jul 2024 12:22:03 -0500 Subject: [PATCH] Detect when variables are declared and not set It is possible to declare a variable but not assign a value to it using `export x`. When you do this, `declare -p x` shows the variable but does not show an "=" nor any value afterwards. When running another command, this variable will not be added to the environment variables even though it is flagged as exported. Most likely it's because the value is not a string and can't be easily converted to a string; this is the same behavior as arrays. Using `[[ -v x ]]` is also inadequate and I believe its because there are false positives when trying to access data, which goes on to break tests and the new braces and parenthesis indirection. Perhaps it could be reviewed and made to work. The best solution so far is to combine `declare -p` with `[[ -v` to see if the variable is declared and if a value is set. Closes #75. --- mo | 19 +++++++++++++++---- tests/help | 2 +- tests/issue-75 | 9 +++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100755 tests/issue-75 diff --git a/mo b/mo index a1d1e28..b53d48a 100755 --- a/mo +++ b/mo @@ -1002,13 +1002,24 @@ mo::isArrayIndexValid() { # Can not use logic like this in case invalid variable names are passed. # [[ "${!1-a}" == "${!1-b}" ]] # +# Using logic like this gives false positives. +# [[ -v "$a" ]] +# +# Declaring a variable is not the same as assigning the variable. +# export x +# declare -p x # Output: declare -x x +# export y="" +# declare -p y # Output: declare -x y="" +# unset z +# declare -p z # Error code 1 and output: bash: declare: z: not found +# # Returns true (0) if the variable is set, 1 if the variable is unset. mo::isVarSet() { - if ! declare -p "$1" &> /dev/null; then - return 1 + if declare -p "$1" &> /dev/null && [[ -v "$1" ]]; then + return 0 fi - return 0 + return 1 } @@ -1977,7 +1988,7 @@ mo::tokenizeTagContentsSingleQuote() { # Save the original command's path for usage later MO_ORIGINAL_COMMAND="$(cd "${BASH_SOURCE[0]%/*}" || exit 1; pwd)/${BASH_SOURCE[0]##*/}" -MO_VERSION="3.0.6" +MO_VERSION="3.0.7" # If sourced, load all functions. # If executed, perform the actions as expected. diff --git a/tests/help b/tests/help index 78e6c49..f36d213 100755 --- a/tests/help +++ b/tests/help @@ -94,7 +94,7 @@ This is open source! Please feel free to contribute. https://github.com/tests-always-included/mo -MO_VERSION=3.0.6 +MO_VERSION=3.0.7 EOF } diff --git a/tests/issue-75 b/tests/issue-75 new file mode 100755 index 0000000..6816dfd --- /dev/null +++ b/tests/issue-75 @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +cd "${0%/*}" || exit 1 +. ../run-tests + +export uv +export template='{{^uv}}OK{{/uv}}{{#uv}}FAIL{{/uv}}' +export expected='OK' + +runTest