-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
treewide: support structuredAttrs in setup hooks (part 2) #335666
treewide: support structuredAttrs in setup hooks (part 2) #335666
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't tested it yet. Lots of questions about shellcheck; thanks for adding it in a lot of areas. The overall approach is sound.
4fdc570
to
d80cd3f
Compare
Addressed the first round of comments. |
d80cd3f
to
185ec47
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, although the changes introduce some side effects (see comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for addressing the shellcheck issues.
I like @tie's suggestion about
if [[ -v checkFlags ]]; then
concatTo flagsArray checkFlags
else
appendToVar flagsArray VERBOSE=y
fi
Is there anything that blocks this from being merged? I move we merge it, |
We can’t merge a nice‐to‐have Darwin stdenv rebuild into |
Can't contribute much to the discussion above but I read through the diffs ✅
I have some concerns over what the |
Do you mean whether I will look into the default values thread above again to make sure that it's non-leaking, even in hooks, though. |
185ec47
to
2a30acb
Compare
Tested samba4 with and without __structuredAttrs.
Tested waylock with and without __structuredAttrs.
Tested build2 itself with and without __structuredAttrs.
Tested swiften with and without __structuredAttrs.
The checkTarget variable is explicitly tested before, but not passed to scons. This was apparently missed in the initial commit for that setupHook in NixOS#50293.
Tested gmad with and without __structuredAttrs. Building it succeeded on master with structuredAttrs, but the log output showed that the configure flags were not passed correctly previously.
Tested v8 with and without __structuredAttrs.
Tested qbs with and without __structuredAttrs.
Tested perlPackages.GSSAPI with and without __structuredAttrs.
9b60c03
to
581aebc
Compare
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all looks good to me.
It treats an array with a single element that is an empty string as empty 😅 declare -a arr=( '' )
if [[ -v arr ]]; then
echo defined
fi
if [[ -z "${arr[@]}" ]]; then
echo oops
fi
# Output:
# defined
# oops What do you think about the following check? # Either variable is not declared,
! type=$(declare -p -- "$name" 2>/dev/null) ||
# or it is declared but no value is assigned (e.g. empty array),
[[ -z ${!name+x} ]] ||
# or it is not an array and is empty.
[[ ${type#* } != -[aA]* && -z ${!name} ]] That is, we’d treat empty values (empty arrays and strings) consistently by using the default value. For example, set -eu -o pipefail
concatTo() {
local -n targetref=$1
shift
local arg default name type
for arg; do
IFS='=' read -r name default <<<"$arg"
# Append the default value if $name variable is not declared. Note that
# variable attributes are separate from variable assignment. In addition
# to that, declare assigns an attribute for name but does not actually
# create the variable for empty arrays (i.e. `declare -a arr=()`).
#
# For compatibility, we treat variables with empty values as undeclared as well.
if
# Either variable is not declared,
! type=$(declare -p -- "$name" 2>/dev/null) ||
# or it is declared but no value is assigned (e.g. empty array),
[[ -z ${!name+x} ]] ||
# or it is not an array and is empty.
[[ ${type#* } != -[aA]* && -z ${!name} ]]
then
case "$default" in
'('*)
# Evaluate array expressions, i.e.
# `concatTo fooFlags barFlags='(baz)'`.
#
# Beware that, just like the regular array assignments, this
# evaluates Bash code inside the default value. E.g.
# `declare -a arr='( "$(echo element)" )' && echo "${arr[*]}"` prints
# `element`.
local -a defaultArray=$default
targetref+=("${defaultArray[@]}")
;;
'')
# Ignores both `undefinedVar=` and `undefinedVar` to avoid
# appending an empty string for the latter.
# TODO: perhaps return an error if no default is given and
# variable is not declared?
;;
*)
targetref+=("$default")
;;
esac
continue
fi
local -n nameref=$name
case "${type#* }" in
-A*)
echo "concatTo(): ERROR: trying to use concatTo on an associative array." >&2
return 1
;;
-a*)
targetref+=("${nameref[@]}")
;;
*)
if [[ $name == *"Array" ]]; then
targetref+=("${nameref[@]}")
else
# shellcheck disable=SC2206
targetref+=(${nameref-})
fi
;;
esac
done
}
declare -a definedFlags=(b c)
declare -a emptyArray=()
declare emptyString=
declare unboundString
declare string=h
concatTo flagsArray emptyArray=a definedFlags=unused undefinedWithDefaultArray='(d e)' emptyString=f unboundString=g string=unused undefinedWithoutDefault
echo "${flagsArray[@]}"
# Output:
# a b c d e f g h Note that the code above also allows using arrays as default values, e.g. concatToVar flagsArray defaultArray='( --foo --bar --baz )' |
Yes, that's on purpose to not introduce a breaking change.
Interesting. I have only found one use-case, so far, the autoreconf hook. I might look into this later (travelling this week). |
Confirmed that all commits still work and have the intended change for building with structuredAttrs. |
Perhaps a check for $ bash -e -u -c 'declare -a arr=(); echo "${arr[@]:+x}"'
$ bash -e -u -c 'declare -a arr=(""); echo "${arr[@]:+x}"'
$ bash -e -u -c 'declare -a arr=("" ""); echo "${arr[@]:+x}"'
x
$ bash -e -u -c 'declare -a arr=("" "brr"); echo "${arr[@]:+x}"'
x
$ bash -e -u -c 'declare -a arr=("brr"); echo "${arr[@]:+x}"'
x
$ bash -e -u -c 's=; echo "${s[@]:+x}"'
$ bash -e -u -c 's=brr; echo "${s[@]:+x}"'
x |
@tie, let's finesse it in follow-on PRs. Welcome to the committer team, btw! |
Description of changes
This is a follow up to #318614, which had a lot more commits initially. After merging the basic changes for stdenv's appendTo, prependTo and new concatTo functions there, I now come back to apply those in more setup hooks.
I intentionally only took a part of long tail of commits I still have for this, so there will be more after this PR. All commits in this PR have one thing in common: I was able to test each of them by building the respective package mentioned in the commit message with
__structuredAttrs
turned on, similar to how I did it in #318614: The build for this package would fail on master, but succeed on this branch.For some of the other setup hooks it's not that easy to find examples in nixpkgs, which actually fail with structuredAttrs turned on, so hard to prove the fix works. Thus I left them out for the moment and will bring them back once we have merged this set of changes, increasing the confidence in the general pattern of how the transition to
concatTo
works.CC @emilazy @philiptaron @SomeoneSerge @tie
Since the changed setup hooks won't trigger ofborg to mention the maintainers:
Quick recap for those not involved in #318614: That PR added a new function
concatTo
to allow merging of flags arrays / lists in either string or bash array format. Together with the already existingappendTo
andprependTo
, this allows to transparently support both building with and withoutstructuredAttrs
turned on, without putting checks whether structuredAttrs are enabled or not all over nixpkgs.Making all the setup hooks support structuredAttrs is the first step to making this the default eventually.
Things done
Of course I built the respective packages themselves - but since the setup hook is not a part of the derivation, those still work. As mentioned above, I built another package for each of the setup hooks, which uses that hook in the build process.
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.