-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Allow plain Nix expressions as flake inputs #5663
Comments
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/passing-options-to-flakes/7579/7 |
Another benefit over the old |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/passing-options-to-flakes/7579/8 |
I'm not convinced this is a good idea, and it could lead to a lot of anti-patterns. Conceptually, changing In addition, such inputs are global and can't be overriden outside of the flake input mechanism. So for instance, if I need a flake output for two different values of
P.S. the approach in dc4a280 was to implement |
Does dc4a280 require flakes to be in toml format for overrides to work? |
That’s right for toplevel flakes (though I’m not sure it’s the best possible choice), and that indeed makes passing
That’s also right, but it doesn’t seem like a fundamental issue to me. At least not if we don’t take {
inputs.debugMode.value = false;
inputs.foo = {
url = "...";
inputs.debugMode.follows = "debugMode";
};
} (granted it’s not utterly pretty though) |
For the record: some anti-patterns that currently work. Warning: ugly hacks. My thought is that you can currently declare a file with a Nix expression as an input and import it. It is not a big step from that to allowing a nix expression directly. The default can be declared in the flake.nix and tracked and locked in the same way that a file would be. Overriding on the CLI is like overriding an input, which disables writing the lock file anyway. The only concern is that doing this may encourage more usage of the underlying mechanism of override-input and reduce overall user experience. |
PoC that only allows string values: tomberek@a41ee9e
spaces are not allowed in urls, so can't be used here, will need to modify fetchers.cc to understand the modification of a value input.
|
Summary of the discussion as of 2022-03-10
|
Lack of arguments/options for flakes makes it impossible to use Flakes for builds of our mobile application. We have various arguments that we pass to the builds like build number, extra Gradle arguments, or architectures. The issue with architectures is that an Android APK can include multiple architectures, so using the Combined with other arguments - like build number - makes using separate build targets not feasible, since it's just a number. |
Looks great but can't figure out how to use that PoC. Seems like it adds the funtionality to nix directly so can I somehow patch it in the same nixos flake that would use it in its inputs? Any example would be really welcome. |
@tomberek this looks very promising. Did you have any plans to submit the PoC? |
I was not planning on it as it was more of a quick hack to explore design and learn about the underlying code. I'm convinced it's possible to implement in a better way, but I'm not yet convinced of what a good design would be or if it would be a net gain. |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
I think the easiest way to pass a nix expression to a flake is just to generate some files and let the flake read from the generated files. You might need |
For enumerable arguments, the best practice is to let them be attributes, similar to the |
Another approach might be to use
|
Hi, I just wanted to chime in and ask whether there are plans to progress on this issue, this is a serious backwards incompatibility with the "legacy" nix commands and I have seen several workflows breaking because of this, most recently in the ghc.nix repo. Thank you so much for consideration of this. |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/how-can-we-pass-argument-to-flake-nix/30833/3 |
Any progress related to tomberek@a41ee9e? |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flake-how-to-have-a-literal-value-input-no-url-file-path/36035/2 |
It seems like #9325 broke these changes. I need to be able to pass options to my custom LLVM flake. Edit: Upon trying to update these changes, I realized clang-format was not ran on the nix codebase, causing reformatting due to clang-format running on save in my IDE. |
I also wanted to chime in and say that allowing inputs to flake builds would be important to us. This does not work when building the website in Nix Flakes. Sure, we can depend on the current time since that's where our abstraction leaks a bit, but rebuilding an hour later will not cause a rebuild since the derivation is already cached. I think the cleanest way to fix this would be to pass the current time as an argument to a derivation function, but as we established, this is not really possible in pure flakes right now. I might try the This highlights another option for me, though. I understand the worry about invalidating the flake when allowing flake inputs to be overridden, but allowing function inputs to be passed through |
Just as a heads-up, for me this needs |
I had this same idea just a moment ago when trying to think of some way to pass All implenting this would mean is that users now have a fast and sane way to do the exact same thing in a less hacky and cumbersome way. I haven't seen it mentioned yet, but it would also allow for inputs of type {
# other inputs ...
outputs = { system ? "x86_64-linux", config ? { inherit system; }, self, ... }: {
# rest of flake
};
} |
As a reminder, there's still the idea of "configurable flakes" from @lheckemann: https://media.ccc.de/v/nixcon-2023-36413-what-flakes-needs-technically-#t=777 In contrast to allowing arbitrary Nix expressions as inputs, this provides a structured and validated input. In other words, the author of a flake doesn't need to validate a flake input on their own. In fact, letting Nix do that gives us consistent errors across all flakes. cc @NixOS/nix-team I can't recall that this proposal has been considered, so I'd be interested if there are reasons in favor/against it (short of "needs somebody to implement that"). Not sure yet, but if we come up with a useful design for that, I'd probably be open to do exactly that :) |
Would definitely solve my problem and seems rather elegant. I am not at all opinionated on how to solve this configuration problem, I just believe it should be solved because it seems there are many valid usecases |
With an over-reliance on input overriding like this, we'll have no place for actual configurations, in the sense that a configuration is an arrangement where everything is defined and no parameters are left. The |
@roberth just to avoid we're talking past each other: is this a criticism on the original suggestion or on the alternative that I've brought up? Because "It will be unclear which parameters can or should be provided" doesn't sound like an issue about something that explicitly defines options and defaults for that (i.e. configurable flakes).
But you'd still need to be able to pass arbitrary Nix values to these overridables, correct? Or how else would you pass e.g. |
Both suffer from the same issue, being flake-wide. Documentation does help, but "global" settings are not a great design, and a separation between inputs and configuration is a bit artificial or unnecessary - why not have structured docs for the inputs?
Yes, and these would be mostly normal functions (depending on caching, possibly), so that would be supported. |
We don't need the patch. We can do this right now using {
description = "A string as an input argument";
inputs.thing.url = "file+file:///dev/null";
inputs.thing.flake = false;
outputs = { self, nixpkgs, thing }: with nixpkgs.legacyPackages.x86_64-linux; {
packages.x86_64-linux.default = runCommand "something" {} ''
echo xxx
echo value is: ${builtins.readFile thing.outPath}
echo xxx
'';
};
} THING=anotherValue
nix build --override-input thing file+file://<(printf %s "$THING") |
@roberth I'm sorry, but I still have a hard time parsing this. What does I think I'll need an example here. |
I was a little bit facetious because I find Flake's reinvention of the wheel frustrating. I'm sorry that that made my message unclear. "Input" applied to both flake inputs and function arguments, as I was attempting to reconcile those two concepts. I don't know if I have a particularly actionable suggestion or great example, because whenever I try to come up with something, I have an urge to first tear a whole bunch of things down. For instance, we should really have something that reconciles
But this is basically impossible without also replacing them. Finally if we want "discoverability" in "configuration", we also need to respect the interface segregation principle, because, e.g. Again, I'm sorry that I don't have good answers, but hopefully we can begin to clarify what's even the question. |
Based on the suggestion to use the |
I also wanted to mention that passing inputs to a build is required for nix to be a viable build system for me as well. Even something as simple as setting the version number from CI needs the above hacky workaround at the moment |
This is exactly how I found this thread, trying to build a container from a flake, within a CI/CD server's configuration environment. We are currently using "impure" as our work-around here. This is a hard limitation on the usefulness of flakes, honestly. |
(This is mostly a reformulation and extension of #3843 (comment). I’ve been meaning to post this as its own issue for a long time as it’s a potential solution for a bunch of different issues)
As a possible way out of the combinatorial explosion of flake outputs required by the impossibility to pass arguments to flakes (the
system
issue, dirty things like #4996 required to accomodate everyone’s need, etc..), we could add a new type of flake inputnixExpr
which would inline a Nix expression.Motivations
Fix #3843
I’m not sure which one would be best, but this would enable several solutions to #3843:
inputs.system = { type = "nixExpr"; value = "x86_64-linux"; }
which could be changed with--override-input system nixExpr:x86_64-darwin
. Probably needs a better UX, but the gist of the mechanism would be here.packages.{system}.foo
structure, but haveinputs.allowedSystems = { type = "nixExpr"; value = [ "x86_64-linux", "x86_64-darwin" ]; }
, so that if someone wants to build the flake for another system, it’s possible to override this listMore generally, allow for parametrized matrix builds
system
approach is probably pretty limited if one wants to express all the possible cross-compilation strategies between a few different system typesinputs.stdenv.value = "stdenv"
(and define the actually used stdenv asstdenv = nixpkgs.${inputs.stdenv}
), so that ppl wanting to use clang can just do--override-input stdenv "nixExpr://clangStdenv"
(or whatever)Design proposal
(This is only a first draft, could certainly be refined).
nixExpr
.value
, which is a json-style Nix value. So not an arbitrary expression, but something arbitrarily (though finitely,rec
shouldn’t be allowed) nestedvalue:[expr]
--override-input
. Which would be similar to passing arguments to the flakeDesign considerations
--override-input foo value:xyz
to pass an argument isn’t the nicest syntax. Maybe we could have a--arg foo xyz
flag that would be syntactic sugar over thisinputs.system.value = "x86_64-linux"
, I need to do--override-input system value:\"x86_64-darwin\"
(with the escaped quotations, because it has to be a Nix string).--arg-str
flag like the old CLI had for this (arguably common) use-case--arg
do some magic that would make--arg foo xyz
equivalent to--arg foo \"xyz\"
ifxyz
is alphanumeric++ − that would work because it wouldn’t be valid otherwise asarg
can’t contain variables or keywords.Purity concerns
The main reason for not allowing arguments to flakes is that they’re supposed to be pure self-contained entities.
This doesn’t break this property as these “arguments” are just a special type of flake inputs − meaning that for example they are reflected in the lockfile and taken into account when computing the hash of the flake. Besides, this is already possible to emulate in a dirty − and arguably more impure − way using relative paths as inputs and overwriting them on the fly)
/cc @tomberek since you suggested the same idea on matrix
/cc @Mic92 @domenkozar
The text was updated successfully, but these errors were encountered: