Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ rec {
# support for that, in turn it's lazy in its values. This means e.g.
# a `_module.args.pkgs = import (fetchTarball { ... }) {}` won't
# start a download when `pkgs` wasn't evaluated.
type = types.lazyAttrsOf types.unspecified;
type = types.lazyAttrsOf types.raw;
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is the right trade-off. It's already lazy and when you do access an attr value, like that of pkgs, you'll force it anyway. Checking its type attr before returning it is a cheap and one-time operation.

Copy link
Member

@roberth roberth Feb 17, 2022

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

So I don't think we should trade the ability to mkForce in _module.args for arguably no benefit.

Copy link
Member Author

Choose a reason for hiding this comment

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

See #160489 (comment), mkForce and co. still work on the spine

Copy link
Member

Choose a reason for hiding this comment

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

I must have read too much into "raw".
The tests demonstrate it clearly.

Perhaps the docs can clarify that it's not entirely raw?

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess the confusion comes from #132448 where types.raw originally worked like that, not doing any processing at all, but I changed that after discussing it with you :)

I think mentioning that in the docs is a good idea

internal = true;
description = "Arguments passed to each module.";
};
Expand Down
6 changes: 6 additions & 0 deletions lib/tests/modules.sh
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,12 @@ checkConfigOutput "{ }" config.submodule.a ./emptyValues.nix
checkConfigError 'The option .int.a. is used but not defined' config.int.a ./emptyValues.nix
checkConfigError 'The option .nonEmptyList.a. is used but not defined' config.nonEmptyList.a ./emptyValues.nix

## types.raw
checkConfigOutput "{ foo = <CODE>; }" config.unprocessedNesting ./raw.nix
checkConfigOutput "10" config.processedToplevel ./raw.nix
checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix
checkConfigOutput "bar" config.priorities ./raw.nix

cat <<EOF
====== module tests ======
$pass Pass
Expand Down
30 changes: 30 additions & 0 deletions lib/tests/modules/raw.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{ lib, ... }: {

options = {
processedToplevel = lib.mkOption {
type = lib.types.raw;
};
unprocessedNesting = lib.mkOption {
type = lib.types.raw;
};
multiple = lib.mkOption {
type = lib.types.raw;
};
priorities = lib.mkOption {
type = lib.types.raw;
};
};

config = {
processedToplevel = lib.mkIf true 10;
unprocessedNesting.foo = throw "foo";
multiple = lib.mkMerge [
"foo"
"foo"
];
priorities = lib.mkMerge [
"foo"
(lib.mkForce "bar")
];
};
}
7 changes: 7 additions & 0 deletions lib/types.nix
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,13 @@ rec {
# nixos/doc/manual/development/option-types.xml!
types = rec {

raw = mkOptionType rec {
name = "raw";
description = "raw value";
check = value: true;
merge = mergeOneOption;
};

anything = mkOptionType {
name = "anything";
description = "anything";
Expand Down
11 changes: 11 additions & 0 deletions nixos/doc/manual/development/option-types.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ merging is handled.
```
:::

`types.raw`

: A type which doesn't do any checking, merging or nested evaluation. It
accepts a single arbitrary value that is not recursed into, making it
useful for values coming from outside the module system, such as package
sets or arbitrary data. Options of this type are still evaluated according
to priorities and conditionals, so `mkForce`, `mkIf` and co. still work on
the option value itself, but not for any value nested within it. This type
should only be used when checking, merging and nested evaluation are not
desirable.
Comment on lines +68 to +75
Copy link
Member Author

Choose a reason for hiding this comment

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

@roberth Does this sound good?


`types.attrs`

: A free-form attribute set.
Expand Down
19 changes: 19 additions & 0 deletions nixos/doc/manual/from_md/development/option-types.section.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,25 @@
</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>types.raw</literal>
</term>
<listitem>
<para>
A type which doesn’t do any checking, merging or nested
evaluation. It accepts a single arbitrary value that is not
recursed into, making it useful for values coming from
outside the module system, such as package sets or arbitrary
data. Options of this type are still evaluated according to
priorities and conditionals, so <literal>mkForce</literal>,
<literal>mkIf</literal> and co. still work on the option
value itself, but not for any value nested within it. This
type should only be used when checking, merging and nested
evaluation are not desirable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>types.attrs</literal>
Expand Down