-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
[WIP] Add 'perSystem' and 'systems' schema attributes #6773
base: master
Are you sure you want to change the base?
[WIP] Add 'perSystem' and 'systems' schema attributes #6773
Conversation
@@ -1132,7 +1132,8 @@ struct CmdFlakeShow : FlakeCommand, MixJSON | |||
} | |||
} | |||
|
|||
else { | |||
// Ignore 'systems' and 'perSystem' attributes | |||
else if (!(attrPathS[0] == "systems" || attrPathS[0] == "perSystem")) { |
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.
If i do attrPathS[0] != "systems" && attrPathS[0] != "perSystem"
it throws compilation error:
src/nix/flake.cc:1136:68: error: no match for ‘operator!=’ (operand types are ‘__gnu_cxx::__alloc_traits<std::allocatornix::SymbolStr, nix::SymbolStr>::value_type’ {aka ‘nix::SymbolStr’} and ‘const char [10]’)
I don't think this is the right approach.
|
Yes, I did consider cross-compilation.
I disagree, having it implemented in nix allows us to easily copy-paste it over to flake-compat project. From what I noticed community wants to get rid of flake-utils and similar projects because it's bothersome and bad UX. If this is not something that you are happy about maybe we could have a compromise of sorts? How would you like such feature to get implemented? |
Any expression we hardcode in the Personally, I'd rather have a complete break from the current schema while it's experimental than an eternal migration logic that we can't get rid of. I'm just not sure if it's de facto still experimental though... The choice is between breaking a lot of experimental code now, or eventually breaking language reproducibility in the future as the compatibility logic bitrots. Perhaps the compatibility logic should be in a library? A special input named I wish it was simple... but simple will upset a lot of people after 3+ years. Quite the dilemma. See, truly simple is reducing the inputs to |
Yes, that is true but I'm sure that we will always have some sort of iterable concept of
👍
No, I think we need a design that is capable of designing a proper schema out of the box because it's causing more problems than it's worth. More info here: https://github.com/gytis-ivaskevicius/nix-patterns
Yeah, I was playing around with this idea in the back of my mind, but could not come up with anything with actual nice UX |
FWIW this is my biggest let down with flakes so far, there has basically been 0 experimentation with the flake schema since the day they were released despite the various gripes from different corners of the community. I would really like to see something materialize before it reaches stable, and I don't mind refactoring all my companies code by hand (I mean it really wouldn't be super hard honestly) if it means a better product in the end, rather than one we will be "working around" for years to come. Although it is still always possible to have a clean break at some point in the future, I guess it might even be a little late to complain since stabilization looks like it's coming. |
We're not late to complain. The issue was raised two years ago #3843, one and a half year before flakes were first released experimentally in 2.4, reminded and raised by others on numerous occasions. I believe the issue has been ignored by the maintainers initially because some of the initial proposals weren't improvements. The original premise of the linked issue was "builtins.currentSystem as a input to flakes", which is not the right approach, but the subsequent thread has made abundantly clear that there's an underlying problem that needs to be solved, and that it can be solved.
In nix-pattern you argue for using overlays, which are known to interfere with each other. It's good for overriding, but not for composition. Usually what we need is composition.
I would work towards something like this. Here's how a "legacy" flake would look: outputs = args@{ flake-wiring, ... }:
flake-wiring.lib.inject args (
# inputs processed by flake-wiring to equal what call-flake.nix offers
{ nixpkgs, ... }: {
# same as the current flake format
packages.x86_64-linux.hello = ...
}
); I admit that imported.outputs // { inherit (node) outPath sourceInfo; }
I haven't implemented this, but it seems feasible. Crucially, it allows a lot of flexibility without causing too much UX "damage". Almost every flake already uses some sort of framework for creating per-system outputs. These frameworks can absorb the I have zero confidence that we can hardcode a good dependency injection solution into Nix, so we should leave this to the ecosystem, where it can be pinned and where it can be collaborated on more easily. I agree that there's a UX cost when we don't hardcode a solution in Nix, but let's stay in the realm of what's actually feasible. Perhaps the general form of the invocation can be hardcoded, going from # flake.nix
{
outputs = args@{ flake-wiring, ... }:
flake-wiring.lib.inject args <<f>>;
} to # flake.nix
{
wiring = flake-wiring;
definitions = <<f>>;
} |
No, I am arguing for using nixpkgs independent data structure. At the current time overlays is the only official structure that fits the bill. At its core its just a function that we can call without any interference. https://github.com/gytis-ivaskevicius/nix-patterns/blob/master/02-packages-producer-with-dev-deps/develop/flake.nix#L15= Since by now I talked with several peeps that unreasonably hate overlays even if you treat them as a functions - a new data structure was proposed https://github.com/gytis-ivaskevicius/nix-patterns/tree/master/blueprints
It involves unnecessary dependency -> dependencies cause problems -> lets remove need for dependencies -> idea behind nix-patterns.
We should never need to do that. We should not treat About hardcoding, I was chatting with @nrdxp and basically this copy-paste more or less summarizes my opinion:
Recently @edolstra stated that we are not going to be changing schema anytime soon
eachSystem = systems: f:
let
op = attrs: system:
let
ret = f system;
in
builtins.foldl'
(attrs: key: attrs // { ${key} = (attrs.${key} or { }) // { ${system} = ret.${key}; }; })
attrs
(builtins.attrNames ret);
in
builtins.foldl' op { } systems; |
I don't understand how you can then argue to hardcode dependencies into Nix.
It seems that we agree on the simplification of
True, but we need some interface between commands such as For
I don't think this is the right perspective. First off, Nix doesn't need to know about targetSystem at all, as that's a Nixpkgs internal affair. What remains seems to be a general configurability problem and ambiguity I described before.
Let's focus on the semantics, shall we. Sure
More hardcoded junk we won't ever get rid of? It's not like we can let users pin Nix, evolve it and let users catch up with the breaking changes. Even if we could, that destroys one of the unique selling points for Nix: being able to build any old expression.
Boilerplate isn't boilerplate anymore when you can put it in a library. A library dependency is good, because it can be pinned, it can evolve, and it can be replaced entirely. If you think a single dependency and a single call are "boilerplate", you need to reconsider what boilerplate means. |
I just don't see it as a hardcoded dependency. It's more of a
I honestly don't care if nix knows about it or not, I am just strongly against limiting users and thus not covering use cases like cross-compiling or overwriting. Currently, users tend to consume the
I have not played around with it but I bet with help of this operator we might be able to build some clean approach to defining system-dependent attributes.
We introduce extra builtins to speed up evaluation. If we can think of a builtin that speeds up evaluation and helps us to express
The moment you put it into the library we return to step 1. Sometimes using a library is a great idea just because of convenience, but that is not the case for 95% of flakes since it's not necessary. |
Anyways, @roberth lets agree to disagree. This is going nowhere |
This attitude is sometimes known as "success at all costs" and it leads to bad design that ultimately holds the system back. Yes, we should fix UX issues, but not by compromising the design, or compromising features like reproducibility, or compromising our ability to evolve the system.
Yes, we have a fundamental disagreement about simple vs easy. Easy should follow from simple. The other way around is hard to sustain and hard to adapt to new use cases. Unless we can agree on this, I don't see a point in continuing this discussion either. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-01-06-nix-team-meeting-minutes-21/24573/1 |
Discussed on the Nix team meeting 2023-01-16:
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-01-13-nix-team-meeting-minutes-23/24644/1 |
Discussed in the Nix team meeting: This appears like high effort and needs more discussion, but given our current effort with regard to RFC 136 it is low priority. We're not tracking this PR any more for now. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-04-14-nix-team-meeting-minutes-48/27358/1 |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
Very minimal POC and resolution to #3843, mostly copied merging logic from flake-utils-plus since we already merge schema without depending on nixpkgs.
TODO:
systems
should be always a list,perSystem
should always be a function)If anyone wants to play around with this please use
flake.nix
as a usage reference