buildEnv: support fixed-point arguments#432957
buildEnv: support fixed-point arguments#432957ShamrockLee wants to merge 16 commits intoNixOS:stagingfrom
Conversation
bb27fcf to
09aa8ad
Compare
<pkg>.overrideAttrs|
@ofborg build nixpkgs-vet |
|
I don't know why the CI complains that Update: Rerun. They are now green. |
|
Taking a look. Is there a version of these that doesn't rebuild everything? |
|
Would take a look. But it is first time reviewing the core of the Nix builtin function, are there any ways that I can test with this change? Would building derivations with the change be helpful? |
philiptaron
left a comment
There was a problem hiding this comment.
My sense is that the rebuilds come about because of the switch from runCommand to stdenvNoCC.mkDerivation. Is that right?
The order of the merge operations (derivationArgs first, then applying the functions arguments) gives me some heartburn. It's always odd to have something set in derivationArgs which then doesn't take effect. It's sort of a bug factory. The other way is also perilous however, as certain derivationArgs are actually invalid for this build helper.
My preferred way to handle this is to use something like intersectAttrs to forbid a few things in derivationAttrs that would malform the resulting derivation. See replaceVarsWith for an example of that. Thanks to @wolfgangwalther for the pattern.
|
I'm also interested in how we deprecate and remove the |
It might be doable by excluding some arguments, but excluding
It's not the main reason of the mass rebuild. The gap between |
9b0afe2 to
aa291a2
Compare
We can support structured attributes while keeping Cc: @wolfgangwalther |
Thank you for helping out! To be precise,
Maybe we could build some packages given For example, and compare its output contents with that of I have little idea how to test it thoroughly, either. I tried to write some test cases when working on |
wolfgangwalther
left a comment
There was a problem hiding this comment.
We can support structured attributes while keeping
<pkg>.overrideAttrsunchanged by refactoringbuildenv/builder.plto get variables from the JSON file whose path is inside the environment variableNIX_ATTRS_JSON_FILEif such environment variable is available and nonempty, and falling back to the old behaviour of getting from environment variables of the same names.
Sounds like the right approach. But since you're mentioning overrideAttrs explicitly, it sounds like there is another way of fixing structuredAttrs support which would not keep overrideAttrs the same? Which way would that be?
| # We currently still rely on this custom overrider `<env-pkg>.override`, | ||
| # as fixing the structured attribute support would change the `<pkg>.overrideAttrs` interface. |
There was a problem hiding this comment.
Why is "changing the overrideAttrs interface" considered to be a problem?
In which way would this interface change?
There was a problem hiding this comment.
The approaches I considered includes:
-
Moving under
envthe variables to pass to the builder. This way we don't need to change the Perl build script. -
Enforce
__structuredAttrs = truefor all constructed packages and pass everythong consistently viaNIX_ATTRS_JSON_FILE. This way we avoid the manual serialization of[ { paths = ; priority = ; } ]completely.
There was a problem hiding this comment.
I looked into the builder a bit, and I think I'd prefer this:
2. Enforce
__structuredAttrs = truefor all constructed packages and pass everythong consistently viaNIX_ATTRS_JSON_FILE. This way we avoid the manual serialization of[ { paths = ; priority = ; } ]completely.
This would not change the overrideAttrs interface either, right?
There was a problem hiding this comment.
This would not change the overrideAttrs interface either, right?
Yes, it won't change the overriding interface. (I personally feel like replacing env.pkgs with a structual env.pathSpecs and make it part of the public interface, so that people could add paths with custom priority.)
Nevertheless, it's a tree-wide backward-incompatible change whose impact spreads across several language- and framework-specific toolchain. Python's python3Packagrs.buildEnv is currently a pkgs.buildEnv-constructed package, and python3.withPackabes is implemented by overriding python3Packages.buildEnv. In addition, it provides postBuild to allow appending custom commands. In the worst case scenario, we'll have to test dependent packages and frameworks one by one and do our best to inform users about the breakage.
There was a problem hiding this comment.
Nevertheless, it's a tree-wide backward-incompatible change
Wait, which one? Enforcing structured attrs or the pathSpecs you brought into play?
I think enforcing structuredAttrs should not be breaking, right?
There was a problem hiding this comment.
Since we set buildCommand, the phases will not be run. I think this means that setup hooks won't be run at all.
So we just need to deal with postBuild, which is manually ran in the buildCommand.
So the breaking change would be, because the structured attrs file is not additionally loaded as bash variables?
I think this would actually already happen through stdenv/setup.sh.
So I don't see the breaking part, yet.
There was a problem hiding this comment.
It just came to me that we usually don't provide bavkward compatibility for pre- or post- stuff. Maybe we could try it on the master branch, whose users are expected to tolerate breakage, and fix things that break.
There was a problem hiding this comment.
Since we set
buildCommand, the phases will not be run. I think this means that setup hooks won't be run at all.So we just need to deal with
postBuild, which is manually ran in the buildCommand.So the breaking change would be, because the structured attrs file is not additionally loaded as bash variables?
I think this would actually already happen through
stdenv/setup.sh.So I don't see the breaking part, yet.
Ah, i see.
I thought that a user might pass some random attributes and expects them to be passed to buildCommand as environment variables, but that is not possible without the derivationArgs argument introduced in this PR or overrideAttrs. Since both are not currently supported, there shouldn't be backward incompatibility issues.
There was a problem hiding this comment.
As for the setup hooks that still fail to support structual attrs, let's consider such failure their bugs.
There was a problem hiding this comment.
As for the setup hooks that still fail to support structural attrs, let's consider such failures to be their bugs.
Quite so. I agree with both you and Wolfgang this is the direction the PR ought to go.
84b1c5a to
75428e1
Compare
|
I fixed the evaluation by fixing the check-meta defaultCPEParts with PR #458529 |
RossSmyth
left a comment
There was a problem hiding this comment.
Very nice PR, would be cool to see it.
| eval "$postBuild" | ||
| '' | ||
| ++ lib.optional (lib.stringLength finalAttrs.pkgs >= 128 * 1024) "pkgs" | ||
| ++ derivationArgs.passAsFile or [ ]; |
There was a problem hiding this comment.
I will note that passAsFile is not very compatible with structuredAttrs, so the the goal is to move buildEnv to structuredAttrs, this should probably be removed.
- When
__structuredAttrs = false, one can find values via$myAttrPathset in the environment, while$myAttris unset - When
__structuredAttrs = true,$myAttrPathis unset, andmyAttrcontains the value that would be in the file
So I would not recommend exposing that to users.
philiptaron
left a comment
There was a problem hiding this comment.
I added a bunch of tests. Please take a look.
Add an eval-time test harness for buildEnv following the pattern established by `tests.overriding`. Uses `lib.runTests` to compare expr/expected pairs, and the buildCommand reports pass/fail. No tests yet; subsequent commits add them individually.
Verify that: - `name` argument is used directly as the derivation name - `pname` + `version` composes into the derivation name - Omitting all three triggers the buildEnv-specific assertion The assertion test uses `builtins.tryEval` + `builtins.seq` to force evaluation of .drvPath and confirm it throws.
Specify `extraPathsFrom` as a string using `lib.optionalString` instead of a singleton list using `lib.optional` to align with the current behavior of the Perl build script.
Merge derivationArgs.passthru into the passthru chain so that passthru attributes passed via derivationArgs are not silently dropped.
- includeClosure -> includeClosures (matching the actual argument name) - extraPrefix default: [ ] -> "" (matching the actual default) - Fix broken sentence about ignoreSingleFileOutputs
buildEnv stashes `paths` into `passthru.paths` (rather than passing it directly as a derivation attribute) to prevent unexpected string context pollution. Verify that: - paths are accessible via passthru.paths - passthru.paths can be overridden with overrideAttrs
This is the core new capability of the PR: `buildEnv` now accepts a function `(finalAttrs: { ... })` enabling self-referencing attributes.
Verify that finalAttrs.name is accessible from within the argument function.
Verify that overrideAttrs on a buildEnv result: - Can modify passthru attributes - Preserves the derivation name - Produces a different derivation when a build-affecting attribute (postBuild) is changed
buildEnv merges passthru from three sources:
`{ inherit paths; } // derivationArgs.passthru // passthru`
Verify that:
- Auto-injected paths are present in passthru
- derivationArgs.passthru attributes are preserved
- Direct passthru attributes are preserved
- Direct passthru takes precedence over derivationArgs.passthru
Verify that: - derivationArgs attributes reach the underlying mkDerivation (tested via allowSubstitutes overriding the default false) - The backward-compat layer for top-level nativeBuildInputs still works (these are forwarded through compatArgs)
Add derivations that actually build a buildEnv and verify the output tree. Exposed as passthru.buildTests so they can be built individually or all at once. - basic-symlinking: single package produces correct symlink structure - pathsToLink: only specified subdirectories appear in output - extraPrefix: output is rooted under the specified prefix - postBuild: shell commands execute after the symlink tree - ignoreCollisions: duplicate paths succeed when ignoreCollisions=true
There was a problem hiding this comment.
This file does not look like it belongs in here.
There was a problem hiding this comment.
I guess it is a leftover during some git-rebase.
There was a problem hiding this comment.
Noticed that the commit is authored by @philiptaron. As I have too much on my plate to catch up on these changes , I'll keep it as is.
There was a problem hiding this comment.
Yeah, this is my mistake… I am occasionally a noob with git worktrees, and this is me reusing one that I shouldn't have.
|
I'm tided up with my research and thesis. Sorry for leaving halfway. Many thanks to @philiptaron for pushing this PR. |
buildEnvwithlib.extendMkDerivation,stdenvNoCC.mkDerivation, andbuildCommand.buildEnvcan now take fixed-point arguments (finalAttrs: { }).We still rely on the custom overrider<env-pkg>.override, as fixing the__structuredAttrs = truesupport might change the<pkg>.overrideAttrsinterface.PR buildEnv: use structured attribute and support
<pkg>.overrideAttrs#434815 proves that the argument overriding is mostly the same after adopting structured attributes. Let's deprecate the custom overrider<env-pkg>.overrideright away, but keep it until tree-wide transition to<pkg>.overrideAttrs.derivationArgsargument forbuildEnvso that we won't have to exhaustively list all thestdenv.mkDerivationarguments users might wish to pass.This PR depends on:
Things done
passthru.tests.nixpkgs-reviewon this PR. See nixpkgs-review usage../result/bin/.Add a 👍 reaction to pull requests you find important.