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

imports preprocessing function #196584

Open
roberth opened this issue Oct 18, 2022 · 4 comments
Open

imports preprocessing function #196584

roberth opened this issue Oct 18, 2022 · 4 comments
Labels
0.kind: enhancement 6.topic: module system About "NixOS" module system internals

Comments

@roberth
Copy link
Member

roberth commented Oct 18, 2022

Project description

Modules have many different applications nowadays: NixOS, home-manager, nix-darwin, NixOS tests, (soon) NixOps networks, Arion, and the list goes on.
Each of these benefit from a standardized flake attribute, but this leads to a bit of boilerplate:

{
  imports = [
    foo.nixosModules.default
    bar.nixosModules.default
    baz.nixosModules.default
    qux.nixosModules.quxExperimental
  ];
}

This could be automated with an evalModules parameter.

{
  evalModules = {
    #...

    # A function that preprocess the raw `imports`.
    # This can be used to pick out the default module in flake.
    # The argument can be of any type. The return value must
    # be a valid imports item. It should not ignore any imports,
    # so that imports preparation is a convenience, not a liability.
    prepareImport ? x: x
  }:
  #...
NixOS
evalModules {
  inherit modules;
  prepareImport = x:
    if x?nixosModules.default && x?inputs && x.sourceInfo
    then x.nixosModules.default
    else x;
}

Afterwards: no more wall of text. Non-default modules grab more attention, but may require more knowledge to write if no example is around.

{
  imports = [
    foo
    bar
    baz
    qux.nixosModules.quxExperimental
  ];
}
@srid
Copy link
Contributor

srid commented Oct 18, 2022

A more general solution is to implement some sort of polymorphism feature to Nix's nascent type system. But can Nix get static types already? :-)

@shlevy
Copy link
Member

shlevy commented Oct 18, 2022

Why not just imports = map lib.getDefaultNixosModuleIfFlakeExceptThisFunctionNameShouldBeShorter [ foo bar baz ]?

@shlevy
Copy link
Member

shlevy commented Oct 18, 2022

e.g. hercules-ci/flake-parts@7450589

@roberth
Copy link
Member Author

roberth commented Oct 24, 2022

Why not just imports = map lib.getDefaultNixosModuleIfFlakeExceptThisFunctionNameShouldBeShorter [ foo bar baz ]?

I understand your motivation, but in this case I believe ergonomics beat simplicity.
I would agree 100% if the module system was "just a library" where it is ok to require the caller to come up with such solutions.
However, the way the module system is used is different from most libraries. Whereas a library is often something you integrate once and don't touch again, the module system is a embedded DSL where shorthand syntax makes the modules easier to read.

That all said, this issue suggested a wrong solution. @infinisil was right to point out (at NixCon) that this solution is too powerful. It allows the preprocessing function to be abused, making modules harder to understand, because a module system application could add crazy logic to the imports preprocessing function.

For this reason, I've created an alternative solution in #197547, which does not allow arbitrary transformations, but rather makes the concept of module "class" (nixos, home-manager, etc) explicit and also uses that to improve error messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: enhancement 6.topic: module system About "NixOS" module system internals
Projects
None yet
Development

No branches or pull requests

3 participants