summary refs log tree commit diff
path: root/pkgs/stdenv/generic
diff options
context:
space:
mode:
authorOrivej Desh <orivej@gmx.fr>2017-08-31 14:20:51 +0000
committerOrivej Desh <orivej@gmx.fr>2017-09-03 12:57:08 +0000
commita09d9e7cd425fb589105363f59388b2cf66c3c86 (patch)
treefeee30e4dd75e31e2244ad200e1521c94c3b4990 /pkgs/stdenv/generic
parent447240b19f1fc5ee5d33950560002b9661a3d10e (diff)
downloadnixlib-a09d9e7cd425fb589105363f59388b2cf66c3c86.tar
nixlib-a09d9e7cd425fb589105363f59388b2cf66c3c86.tar.gz
nixlib-a09d9e7cd425fb589105363f59388b2cf66c3c86.tar.bz2
nixlib-a09d9e7cd425fb589105363f59388b2cf66c3c86.tar.lz
nixlib-a09d9e7cd425fb589105363f59388b2cf66c3c86.tar.xz
nixlib-a09d9e7cd425fb589105363f59388b2cf66c3c86.tar.zst
nixlib-a09d9e7cd425fb589105363f59388b2cf66c3c86.zip
stdenv-setup: fix substituteAll with set -eu
Environment variable filter in substituteAll was not precise and produced
undefined and invalid variable names.  Vladimír Čunát tried to fix that in [1],
but `env -0` did not work during Darwin bootstrap, so [2] reverted this change
and replaced an error due to invalid variables with a warning.  Recently in #28057
John Ericson added `set -u` to `setup.sh` and undefined variables made the setup
fail during e.g. `nix-build -A gnat` with `setup: line 519: !varName: unbound
variable`.

[1] https://github.com/NixOS/nixpkgs/commit/62fc8859c10dd18b005b9bcaa0b429103d7661d9
[2] https://github.com/NixOS/nixpkgs/commit/81df0354290389128077e00edfd2368eeeea0c24
Diffstat (limited to 'pkgs/stdenv/generic')
-rw-r--r--pkgs/stdenv/generic/setup.sh29
1 files changed, 17 insertions, 12 deletions
diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh
index d3fff57507c6..ff482241570c 100644
--- a/pkgs/stdenv/generic/setup.sh
+++ b/pkgs/stdenv/generic/setup.sh
@@ -473,14 +473,14 @@ substitute() {
     shift 2
 
     if [ ! -f "$input" ]; then
-      echo "${FUNCNAME[0]}(): ERROR: file '$input' does not exist" >&2
+      echo "substitute(): ERROR: file '$input' does not exist" >&2
       return 1
     fi
 
     local content
     # read returns non-0 on EOF, so we want read to fail
     if IFS='' read -r -N 0 content < "$input"; then
-        echo "${FUNCNAME[0]}(): ERROR: File \"$input\" has null bytes, won't process" >&2
+        echo "substitute(): ERROR: File \"$input\" has null bytes, won't process" >&2
         return 1
     fi
 
@@ -497,10 +497,8 @@ substitute() {
                 shift 2
                 # check if the used nix attribute name is a valid bash name
                 if ! [[ "$varName" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
-                    echo "${FUNCNAME[0]}(): WARNING: substitution variables should be valid bash names," >&2
-                    echo "  \"$varName\" isn't and therefore was skipped; it might be caused" >&2
-                    echo "  by multi-line phases in variables - see #14907 for details." >&2
-                    continue
+                    echo "substitute(): ERROR: substitution variables must be valid Bash names, \"$varName\" isn't." >&2
+                    return 1
                 fi
                 pattern="@$varName@"
                 replacement="${!varName}"
@@ -513,7 +511,7 @@ substitute() {
                 ;;
 
             *)
-                echo "${FUNCNAME[0]}(): ERROR: Invalid command line argument: $1" >&2
+                echo "substitute(): ERROR: Invalid command line argument: $1" >&2
                 return 1
                 ;;
         esac
@@ -532,17 +530,24 @@ substituteInPlace() {
     substitute "$fileName" "$fileName" "$@"
 }
 
+# List the names of the environment variables that are valid Bash names.
+listVars() {
+    # "export" prints "declare -x name=value", quoted for eval.
+    declare() {
+        echo "${2%%=*}"
+    }
+    eval "$(export)"
+    unset declare
+}
 
-# Substitute all environment variables that do not start with an upper-case
-# character or underscore. Note: other names that aren't bash-valid
-# will cause an error during `substitute --subst-var`.
+# Substitute all environment variables that start with a lowercase character and
+# are valid Bash names.
 substituteAll() {
     local input="$1"
     local output="$2"
     local -a args=()
 
-    # Select all environment variables that start with a lowercase character.
-    for varName in $(env | sed -e $'s/^\([a-z][^= \t]*\)=.*/\\1/; t \n d'); do
+    for varName in $(listVars | grep '^[a-z]'); do
         if [ "${NIX_DEBUG:-}" = "1" ]; then
             echo "@${varName}@ -> '${!varName}'"
         fi