about summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorArtturin <Artturin@artturin.com>2022-12-10 01:09:40 +0200
committerArtturin <Artturin@artturin.com>2022-12-10 04:42:36 +0200
commit11c3127e38dafdf95ca71a85b1591a29b67e0c09 (patch)
treedcd6953692543afd53d14e5b640a7c2edcd7889c /pkgs
parentbf972f18736478dad213ce2c409239af36417787 (diff)
stdenv: detect the type of variable in {prepend,append}ToVar
stdenv: error if using {prepend,append}ToVar on associative array

i don't know how to prepend to associative array
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/stdenv/generic/setup.sh50
-rw-r--r--pkgs/test/stdenv/default.nix19
2 files changed, 63 insertions, 6 deletions
diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh
index 182f849cf525d..5a64625e10d1e 100644
--- a/pkgs/stdenv/generic/setup.sh
+++ b/pkgs/stdenv/generic/setup.sh
@@ -209,8 +209,31 @@ addToSearchPath() {
 # Expressions for individual packages should simply switch to array
 # syntax when they switch to setting __structuredAttrs = true.
 prependToVar() {
-    local -n nameref="$1"; shift
+    local -n nameref="$1"
+
+    useArray=
     if [ -n "$__structuredAttrs" ]; then
+        useArray=true
+    else
+        useArray=false
+    fi
+
+    # check if variable already exist and if it does then do extra checks
+    if declare -p "$1" 2> /dev/null | grep -q '^'; then
+        type="$(declare -p "$1")"
+        if [[ "$type" =~ "declare -A" ]]; then
+            echo "prependToVar(): ERROR: trying to use prependToVar on an associative array." >&2
+            return 1
+        elif [[ "$type" =~ "declare -a" ]]; then
+            useArray=true
+        else
+            useArray=false
+        fi
+    fi
+
+    shift
+
+    if $useArray; then
         nameref=( "$@" ${nameref+"${nameref[@]}"} )
     else
         nameref="$* ${nameref-}"
@@ -219,8 +242,31 @@ prependToVar() {
 
 # Same as above
 appendToVar() {
-    local -n nameref="$1"; shift
+    local -n nameref="$1"
+
+    useArray=
     if [ -n "$__structuredAttrs" ]; then
+        useArray=true
+    else
+        useArray=false
+    fi
+
+    # check if variable already exist and if it does then do extra checks
+    if declare -p "$1" 2> /dev/null | grep -q '^'; then
+        type="$(declare -p "$1")"
+        if [[ "$type" =~ "declare -A" ]]; then
+            echo "appendToVar(): ERROR: trying to use appendToVar on an associative array, use variable+=([\"X\"]=\"Y\") instead." >&2
+            return 1
+        elif [[ "$type" =~ "declare -a" ]]; then
+            useArray=true
+        else
+            useArray=false
+        fi
+    fi
+
+    shift
+
+    if $useArray; then
         nameref=( ${nameref+"${nameref[@]}"} "$@" )
     else
         nameref="${nameref-} $*"
diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix
index c5af468655ff5..08e8eed118f98 100644
--- a/pkgs/test/stdenv/default.nix
+++ b/pkgs/test/stdenv/default.nix
@@ -60,10 +60,6 @@ let
         };
 
         passAsFile = [ "buildCommand" ] ++ lib.optionals (extraAttrs ? extraTest) [ "extraTest" ];
-        # FIXME: with structuredAttrs string is converted to a indexed array
-        # should a/pToVar check if the passed variable is a array or a string?
-        # declare -x string="testing-string"
-        # declare -ax string=([0]="world" [1]="testing-string" [2]="hello")
         buildCommand = ''
           declare -p string
           appendToVar string hello
@@ -71,8 +67,23 @@ let
           prependToVar string "world"
           declare -p string
 
+          declare -A associativeArray=(["X"]="Y")
+          [[ $(appendToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "prependToVar did not catch prepending associativeArray" && false)
+          [[ $(prependToVar associativeArray "fail" 2>&1) =~ "trying to use" ]] || (echo "prependToVar did not catch prepending associativeArray" && false)
+
           [[ $string == "world testing-string hello" ]] || (echo "'\$string' was not 'world testing-string hello'" && false)
 
+          # test appending to a unset variable
+          appendToVar nonExistant created hello
+          typeset -p nonExistant
+          if [[ -n $__structuredAttrs ]]; then
+            [[ "''${nonExistant[@]}" == "created hello" ]]
+          else
+            # there's a extra " " in front here and a extra " " in the end of prependToVar
+            # shouldn't matter because these functions will mostly be used for $*Flags and the Flag variable will in most cases already exit
+            [[ "$nonExistant" == " created hello" ]]
+          fi
+
           eval "$extraTest"
 
           touch $out