diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh index ee894a260df9..7666360fb7bb 100644 --- a/pkgs/stdenv/generic/setup.sh +++ b/pkgs/stdenv/generic/setup.sh @@ -357,6 +357,36 @@ concatTo() { done } +# Concatenate a list of strings ($2) with a separator ($1) between each element. +# The list can be an indexed array of strings or a single string. A single string +# is split on spaces and then concatenated with the separator. +# +# $ flags="lorem ipsum dolor sit amet" +# $ concatStringsSep ";" flags +# lorem;ipsum;dolor;sit;amet +# +# $ flags=("lorem ipsum" "dolor" "sit amet") +# $ concatStringsSep ";" flags +# lorem ipsum;dolor;sit amet +concatStringsSep() { + local sep="$1" + local name="$2" + local type oldifs + if type=$(declare -p "$name" 2> /dev/null); then + local -n nameref="$name" + case "${type#* }" in + -A*) + echo "concatStringsSep(): ERROR: trying to use concatStringsSep on an associative array." >&2 + return 1 ;; + -a*) + local IFS="$sep" + echo -n "${nameref[*]}" ;; + *) + echo -n "${nameref// /${sep}}" ;; + esac + fi +} + # Add $1/lib* into rpaths. # The function is used in multiple-outputs.sh hook, # so it is defined here but tried after the hook. diff --git a/pkgs/test/stdenv/default.nix b/pkgs/test/stdenv/default.nix index 996087ae32be..a6885d65cea8 100644 --- a/pkgs/test/stdenv/default.nix +++ b/pkgs/test/stdenv/default.nix @@ -131,6 +131,27 @@ let ''; } // extraAttrs); + testConcatStringsSep = { name, stdenv' }: + stdenv'.mkDerivation + { + inherit name; + + passAsFile = [ "buildCommand" ]; + buildCommand = '' + declare -A associativeArray=(["X"]="Y") + [[ $(concatStringsSep ";" associativeArray 2>&1) =~ "trying to use" ]] || (echo "concatStringsSep did not throw concatenating associativeArray" && false) + + string="lorem ipsum dolor sit amet" + stringWithSep="$(concatStringsSep ";" string)" + [[ "$stringWithSep" == "lorem;ipsum;dolor;sit;amet" ]] || (echo "'\$stringWithSep' was not 'lorem;ipsum;dolor;sit;amet'" && false) + + array=("lorem ipsum" "dolor" "sit amet") + arrayWithSep="$(concatStringsSep ";" array)" + [[ "$arrayWithSep" == "lorem ipsum;dolor;sit amet" ]] || (echo "'\$arrayWithSep' was not 'lorem ipsum;dolor;sit amet'" && false) + + touch $out + ''; + }; in { @@ -236,6 +257,11 @@ in stdenv' = bootStdenv; }; + test-concat-strings-sep = testConcatStringsSep { + name = "test-concat-strings-sep"; + stdenv' = bootStdenv; + }; + test-structured-env-attrset = testEnvAttrset { name = "test-structured-env-attrset"; stdenv' = bootStdenv; @@ -313,6 +339,11 @@ in }; }; + test-concat-strings-sep = testConcatStringsSep { + name = "test-concat-strings-sep-structuredAttrsByDefault"; + stdenv' = bootStdenvStructuredAttrsByDefault; + }; + test-golden-example-structuredAttrs = let goldenSh = earlyPkgs.writeText "goldenSh" ''