Skip to content
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

Fix nested flake input overrides #6621

Merged
merged 2 commits into from
Sep 1, 2022
Merged

Conversation

Kha
Copy link
Contributor

@Kha Kha commented Jun 6, 2022

Currently, B in inputs.A.inputs.B.inputs.C... is interpreted as registry flake, discarding any of its configuration in A, leading to an unexpected "cannot find flake 'flake:B' in the flake registries". This PR implements the expected behavior:

  • input overrides (those nested inside inputs) are not defaulted to registry flakes.
  • Input overrides do not outright replace the corresponding input of the nested flake, but are recursively merged into it, meaning e.g. inputs.B.url set in A is preserved by the above config.

Fixes #5790

Comment on lines 418 to 432
// Respect the “flakeness” of the input even if we
// override it
i->second.isFlake = input2.isFlake;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this workaround could be replaced by a "proper" merge as now done with the other attributes below if isFlake had a value for "not specified", e.g. was changed to std::optional<bool>. But wanting to override the flakeness of an input does seem like an exotic use case.

@tomberek
Copy link
Contributor

Works as expected. There are a few changes in-flight to follows/overrides and the lazy-trees branch with which I'd wonder if there is any interaction or conflict.

Copy link
Member

@thufschmitt thufschmitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for that, and sorry for the delay (I'm always a bit reluctant to touch that logic 😛).

Looks good overall, just a few suggestions, mostly around the tests

@@ -90,11 +90,11 @@ static void expectType(EvalState & state, ValueType type,

static std::map<FlakeId, FlakeInput> parseFlakeInputs(
EvalState & state, Value * value, const PosIdx pos,
const std::optional<Path> & baseDir, InputPath lockRootPath);
const std::optional<Path> & baseDir, InputPath lockRootPath, bool isOverride);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind making this a proper enum (enum structeven) rather than an opaque bool?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do that, but looking at the code again, it seemed more elegant to just pass the recursion depth given that isOverride corresponds to depth > 0. Does it look sensible?

tests/flakes.sh Outdated
Comment on lines 848 to 875

# Test nested flake overrides

cat <<EOF > $flakeFollowsD/flake.nix
{ outputs = _: {}; }
EOF
cat <<EOF > $flakeFollowsC/flake.nix
{
inputs.D.url = "path:nosuchflake";
outputs = _: {};
}
EOF
cat <<EOF > $flakeFollowsB/flake.nix
{
inputs.C.url = "path:../flakeC";
outputs = _: {};
}
EOF
cat <<EOF > $flakeFollowsA/flake.nix
{
inputs.B.url = "path:./flakeB";
inputs.D.url = "path:./flakeD";
inputs.B.inputs.C.inputs.D.follows = "D";
outputs = _: {};
}
EOF

nix flake lock $flakeFollowsA
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move that to its own test file? The flakes.sh test is already infuriatingly slow (and totally sequential) and I wouldn't to expand it further

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved to the new follows.sh

tests/flakes.sh Outdated
EOF
cat <<EOF > $flakeFollowsB/flake.nix
{
inputs.C.url = "path:../flakeC";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That input doesn't seem right (flakeC is a subdir of flakeB). It's probably safer to use absolute paths (via the $flakeFollows* variables everywhere here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

tests/flakes.sh Outdated
}
EOF

nix flake lock $flakeFollowsA
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the idea of the test (the flake lock can only succeed if the override is properly taken into account), but it would be nice to have a more explicit check, if only to make the intent clearer. Maybe something like

nix flake metadata $flakeFollowsA --json | jq --exit-status '.locks.nodes.C.inputs.D == [ "D" ]'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in the same style as in the other tests in the file

@Kha
Copy link
Contributor Author

Kha commented Aug 28, 2022

I noticed and fixed a related bug, see new commit above. I added it to this PR to avoid merge conflicts in the test file, but happy to relocate.

EOF

# bug was not triggered without recreating the lockfile
nix flake lock $flakeFollowsA --recreate-lock-file
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a bit concerning that one gets an entirely different lockfile without this flag, but that's probably a different problem

Copy link
Member

@thufschmitt thufschmitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not coming back to this earlier. I'm only 95% confident that this isn't braking something (because I still couldn't wrap my head around the flake locking code), but since we're just at the beginning of a new release cycle, let's merge and revert if needs be. Thanks!

@thufschmitt thufschmitt merged commit c530cda into NixOS:master Sep 1, 2022
edolstra added a commit to edolstra/nix that referenced this pull request Sep 1, 2022
This reverts commit c530cda, reversing
changes made to 4adcdff.
edolstra added a commit that referenced this pull request Sep 1, 2022
Revert "Merge pull request #6621 from Kha/nested-follows"
Minion3665 pushed a commit to Minion3665/nix that referenced this pull request Feb 23, 2023
This reverts commit c530cda, reversing
changes made to 4adcdff.
Minion3665 pushed a commit to Minion3665/nix that referenced this pull request Feb 23, 2023
Fix nested flake input overrides
Minion3665 pushed a commit to Minion3665/nix that referenced this pull request Feb 23, 2023
Revert "Merge pull request NixOS#6621 from Kha/nested-follows"
tebowy pushed a commit to tebowy/nix that referenced this pull request Jul 11, 2024
This reverts commit a8b3d77.

This undoes the revert of PR#6621, which allows nested `follows`, i.e.

    {
      inputs = {
        foo.url = "github:bar/foo";
        foo.inputs.bar.inputs.nixpkgs = "nixpkgs";
      };
    }

does the expected thing now. This is useful to avoid the 1000 instances
of nixpkgs problem without having each flake in the dependency tree to
expose all of its transitive dependencies for modification.

This was in fact part of Nix before and the C++ changes applied w/o
conflicts. However, it got reverted then because people didn't want to
merge lazy-trees against it which was supposed to be merged soon back in
October 2022.

Fixes: https://git.lix.systems/lix-project/lix/issues/201

Change-Id: I5ddef914135b695717b2ef88862d57ced5e7aa3c
tebowy pushed a commit to tebowy/nix that referenced this pull request Jul 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Transitive inputs "not in registry"
3 participants