The current logic assumes that everything that isn't a derivation is a
store path, but it can also be something that's *coercible* to a store
path, like a flake input.
Unnecessary uses of `lib.toDerivation` result in errors in pure evaluation
mode when `builtins.storePath` is disabled.
Also document what a `package` is.
... where a bare submodule is an option that has a type like
`submoduleWith x`, as opposed to `attrsOf (submoduleWith x)`.
This makes migration unnecessary when introducing a freeform type
in an existing option tree.
Closes#146882
This type correctly merges multiple option types together while also
annotating them with file information. In a future commit this will be
used for `_module.freeformType`
Allow a \n character at the end of the string and remove it during the
merge function.
An option of this type will resolve to the value "foo" whether it is set
to "foo" or "foo\n".
This is useful when using 'builtins.readFile' or ''-strings, which might
add an unintended newline (for example, bash trim the final newline from
a subshell).
Add a new type, inheriting 'types.str' but checking whether the value
doesn't contain any newline characters.
The motivation comes from a problem with the
'users.users.${u}.openssh.authorizedKeys' option.
It is easy to unintentionally insert a newline character at the end of a
string, or even in the middle, for example:
restricted_ssh_keys = command: keys:
let
prefix = ''
command="${command}",no-pty,no-agent-forwarding,no-port-forwarding,no-X11-forwarding
'';
in map (key: "${prefix} ${key}") keys;
The 'prefix' string ends with a newline, which ends up in the middle of
a key entry after a few manipulations.
This is problematic because the key file is built by concatenating all
the keys with 'concatStringsSep "\n"', with result in two entries for
the faulty key:
''
command="...",options...
MY_KEY
''
This is hard to debug and might be dangerous. This is now caught at
build time.
This will be used to issue deprecation warnings recursively in the next
commit
In addition, this allows easily getting nested types of other options, which
is useful when you want to create an option that aliases a part of
another one.
Since shellPackage actually requires the value to be an attribute set
(i. e. an derivation in this case), we cannot re-use the package.check
type checker since it also allows strings or things that are coercible
to strings as long as they look like store paths.
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>
This reverts commit 4ff1ab5a56.
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 7ed41ff5e7e633dd64866398ee497ac02736a3a5)
I think there was a silent (i.e. semantic) merge conflict between PR #101139 and
PR #100456. This commit should fix the error, which manifests as follows:
error: undefined variable 'boolToString' at /home/kkini/src/nixpkgs/lib/types.nix:552:42
Nix can perform static scope checking, but whenever code is inside
a `with` expression, the analysis breaks down, because it can't
know statically what's in the attribute set whose attributes were
brought into scope. In those cases, Nix has to assume that
everything works out.
Except it doesnt. Removing `with` from lib/ revealed an undefined
variable in an error message.
If that doesn't convince you that we're better off without `with`,
I can tell you that this PR results in a 3% evaluation performance
improvement because Nix can look up local variables by index.
This adds up with applications like the module system.
Furthermore, removing `with` makes the binding site of each
variable obvious, which helps with comprehension.
This new type has unsurprising merge behavior: Only attribute sets are
merged together (recursively), and only if they don't conflict.
This is in contrast to the existing types:
- types.attrs is problematic because later definitions completely
override attributes of earlier definitions, and it doesn't support
mkIf and co.
- types.unspecified is very similar to types.attrs, but it has smart
merging behavior that often doesn't make sense, and it doesn't support
all types
Previously the only way to deprecate a type was using
theType = lib.warn "deprecated" (mkOptionType ...)
This caused the warning to be emitted when the type was evaluated, but
the error didn't include which option actually used that type.
With this commit, types can specify a deprecationMessage, which when
non-null, is printed along with the option that uses the type