Skip to content

Allow plain Nix expressions as flake inputs #5663

@thufschmitt

Description

@thufschmitt

(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 input nixExpr 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:

  • Flakes could effectively take the current system as input by having 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.
  • Less invasive (and more eval-cache-friendly), we could keep the packages.{system}.foo structure, but have inputs.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 list

More generally, allow for parametrized matrix builds

  • I’m not really familiar with all the details of cross-compilation, but the system approach is probably pretty limited if one wants to express all the possible cross-compilation strategies between a few different system types
  • Restore the ability to build with clang on linux #4129 also wants to add a new dimension to the list of possible builds of the Nix flake. Currently the values of this new dimension have to be hardcoded, but with this approach, we could just have inputs.stdenv.value = "stdenv" (and define the actually used stdenv as stdenv = 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).

  • Flakes would have a new input type nixExpr.
  • This input type would take as only argument value, which is a json-style Nix value. So not an arbitrary expression, but something arbitrarily (though finitely, rec shouldn’t be allowed) nested
  • Like the other input types, it would also have a url-like form: value:[expr]
  • Like any other input, it could be overriden from the cli using --override-input. Which would be similar to passing arguments to the flake

Design considerations

  • Having to use --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 this
  • Overriding string inputs wouldn’t be very nice. If I want to override an input such as inputs.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).
    • Maybe we could also add a --arg-str flag like the old CLI had for this (arguably common) use-case
    • Alternatively, we could have --arg do some magic that would make --arg foo xyz equivalent to --arg foo \"xyz\" if xyz is alphanumeric++ − that would work because it wouldn’t be valid otherwise as arg 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No fields configured for issues without a type.

    Projects

    Status
    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions