Skip to content

Commit

Permalink
stdenv substituteAll: use more robust code
Browse files Browse the repository at this point in the history
The set/env fix in #14907 wasn't very good, so let's use a null-delimited
approach. Suggested by Aszlig.
In particular, this should fix a mass-breakage on Darwin, though I was
unable to test that.
  • Loading branch information
vcunat committed May 7, 2016
1 parent 7176707 commit 9e0d042
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions pkgs/stdenv/generic/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ substitute() {
if [ "$p" = --subst-var ]; then
varName="${params[$((n + 1))]}"
# check if the used nix attribute name is a valid bash name
if ! [[ "$varName" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]]; then
if ! [[ "$varName" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
echo "substitution variables must be valid bash names, \"$varName\" isn't."
exit 1;
fi
Expand Down Expand Up @@ -439,20 +439,23 @@ substituteInPlace() {
}


# 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`.
substituteAll() {
local input="$1"
local output="$2"
local -a args=()

# Select all environment variables that start with a lowercase character.
# Will not work with nix attribute names (and thus env variables) containing '\n'.
for envVar in $(set | sed -e $'s/^\([a-z][^=]*\)=.*/\\1/; t \n d'); do
# We need to be careful due to vars with multi-line contents or weird names.
while IFS= read -r -d '' varName; do
if [ "$NIX_DEBUG" = "1" ]; then
echo "$envVar -> ${!envVar}"
echo "@varName@ -> '${varName}'"

This comment has been minimized.

Copy link
@abbradar

abbradar May 8, 2016

Member

If I understand correctly, this would yield fairly useless output: first @varName@ is literally a string "varName`.

This comment has been minimized.

Copy link
@vcunat

vcunat May 8, 2016

Author Member

Ah, right, it isn't correct. It shows lines like:

@varName@ -> 'src'

This comment has been minimized.

Copy link
@vcunat

vcunat May 8, 2016

Author Member

I meant that line to be echo "@${varName}@ -> '${!varName}'". But that's just a minor thing as long as darwin doesn't bootstrap.

fi
args="$args --subst-var $envVar"
done
args+=("--subst-var" "$varName")
done < <(env -0 | cut -z -d= -f1 | grep -z -v '^[_A-Z]')

This comment has been minimized.

Copy link
@abbradar

abbradar May 8, 2016

Member

Maybe env - 0 | ... | while IFS=... would work on Darwin? I'm not sure but think it's the same thing.

This comment has been minimized.

Copy link
@vcunat

vcunat May 8, 2016

Author Member

Hmm, there's some problem in that approach. I suppose that $args doesn't get out of the loop that way.

This comment has been minimized.

This comment has been minimized.

Copy link
@abbradar

abbradar May 8, 2016

Member

D: not nice. I see no easy way to do this without process substitution while saving nice properties of this code...

This comment has been minimized.

Copy link
@vcunat

vcunat May 8, 2016

Author Member

Yeah, I had also tried for a while.


substitute "$input" "$output" $args
substitute "$input" "$output" "${args[@]}"
}


Expand Down

0 comments on commit 9e0d042

Please sign in to comment.