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

Bring back types.functionTo #110707

Merged
merged 5 commits into from Jan 27, 2021
Merged

Bring back types.functionTo #110707

merged 5 commits into from Jan 27, 2021

Conversation

infinisil
Copy link
Member

Motivation for this change

We have a bunch of NixOS options that can be assigned a function, like

{
  services.hoogle.packages = p: [ p.aeson ];
}

These options currently all have no type specified, because there is no fitting type for that. Despite that, such options still work just fine, due to the default merging strategy being used in such a case:

nixpkgs/lib/options.nix

Lines 119 to 123 in f6dcf09

mergeDefaultOption = loc: defs:
let list = getValues defs; in
if length list == 1 then head list
else if all isFunction list then x: mergeDefaultOption loc (map (f: f x) list)
else if all isList list then concatLists list

This PR (re)introduces types.functionTo, which specifies that merging behavior explicitly, with more control over it. This is a cherry-pick with some fixes from #44626.

History

In the discussions from 2018, a number of alternatives have been brought up, but the simplicity and safety of p: [ p.aeson ] is just unbeatable. This has become a pattern in nixpkgs which we can't avoid that easily anymore, even if an alternative would be more suitable.

Things done

  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

basvandijk and others added 3 commits January 24, 2021 16:56
This reverts commit 4ff1ab5.

We need this to type options like:
services.xserver.windowManager.xmonad.extraPackages that specify functions that
take an attribute set containing packages / plugins and return a list containing
a selection of the values in this set.

The reason we need a dedicated type for this is to have the correct merge
behaviour. Without the functionTo type merging multiple function option
definitions results in an evaluation error. The functionTo type merges
definitions by returning a new function that applies the functions of all the
definitions to the given input and merges the result.

(cherry picked from commit 7ed41ff)
Without this patch merging options like
services.xserver.windowManager.xmonad.extraPackages
results in the evaluation error:

  error: value is a list while a set was expected, at nixpkgs/lib/options.nix:77:23

With this patch we get the desired merging behaviour that just concatenates the
resulting package lists.

(cherry picked from commit 6e99f9f)

Co-Authored-By: Silvan Mosberger <contact@infinisil.com>
@roberth
Copy link
Member

roberth commented Jan 25, 2021

Also allowUnfreePredicate in pkgs/top-level/config.nix.

lib/types.nix Outdated Show resolved Hide resolved
@roberth roberth changed the title Bring back types.functionTo, finally Bring back types.functionTo Jan 26, 2021
@roberth
Copy link
Member

roberth commented Jan 26, 2021

Now type checks the resulting function values and allows mkMerge and co.

This should be tested.

@infinisil
Copy link
Member Author

Added a bunch more tests now

Copy link
Member

@roberth roberth left a comment

Choose a reason for hiding this comment

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

One final touch to make the error message consistent with listOf. Without it, the error message is inaccurate.

lib/types.nix Outdated Show resolved Hide resolved
lib/tests/modules.sh Outdated Show resolved Hide resolved
infinisil and others added 2 commits January 27, 2021 00:16
Now type checks the resulting function values and allows mkMerge and co.
Also indicates that the type check is done in the function body

Co-Authored-By: Robert Hensing <robert@roberthensing.nl>
@infinisil
Copy link
Member Author

Good point, now done :)

Copy link
Member

@roberth roberth left a comment

Choose a reason for hiding this comment

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

lgtm

@@ -453,6 +453,16 @@ rec {
functor = (defaultFunctor name) // { wrapped = elemType; };
};

functionTo = elemType: mkOptionType {
Copy link
Member

Choose a reason for hiding this comment

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

👍 good name, leaves room for function with a typed input, in case that becomes relevant someday.

@roberth
Copy link
Member

roberth commented Jan 27, 2021

The editor config check failure is for an unrelated file. Merging.

@roberth roberth merged commit d2a41be into NixOS:master Jan 27, 2021
@turion turion mentioned this pull request Jan 27, 2021
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants