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

lib/options/showOption: fix quoting of attr-names that are not identifiers #194035

Merged
merged 3 commits into from
Oct 18, 2022
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
12 changes: 9 additions & 3 deletions lib/options.nix
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 +322,16 @@ rec {
showOption = parts: let
escapeOptionPart = part:
let
escaped = lib.strings.escapeNixString part;
in if escaped == "\"${part}\""
# We assume that these are "special values" and not real configuration data.
# If it is real configuration data, it is rendered incorrectly.
specialIdentifiers = [
Ma27 marked this conversation as resolved.
Show resolved Hide resolved
"<name>" # attrsOf (submodule {})
"*" # listOf (submodule {})
"<function body>" # functionTo
];
in if builtins.elem part specialIdentifiers
then part
else escaped;
else lib.strings.escapeNixIdentifier part;
in (concatStringsSep ".") (map escapeOptionPart parts);
showFiles = files: concatStringsSep " and " (map (f: "`${f}'") files);

Expand Down
4 changes: 2 additions & 2 deletions lib/tests/modules.sh
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,11 @@ checkConfigOutput '^"baz"$' config.value.nested.bar.baz ./types-anything/mk-mods
## types.functionTo
checkConfigOutput '^"input is input"$' config.result ./functionTo/trivial.nix
checkConfigOutput '^"a b"$' config.result ./functionTo/merging-list.nix
checkConfigError 'A definition for option .fun.\[function body\]. is not of type .string.. Definition values:\n\s*- In .*wrong-type.nix' config.result ./functionTo/wrong-type.nix
checkConfigError 'A definition for option .fun.<function body>. is not of type .string.. Definition values:\n\s*- In .*wrong-type.nix' config.result ./functionTo/wrong-type.nix
checkConfigOutput '^"b a"$' config.result ./functionTo/list-order.nix
checkConfigOutput '^"a c"$' config.result ./functionTo/merging-attrs.nix
checkConfigOutput '^"a bee"$' config.result ./functionTo/submodule-options.nix
checkConfigOutput '^"fun.\[function body\].a fun.\[function body\].b"$' config.optionsResult ./functionTo/submodule-options.nix
checkConfigOutput '^"fun.<function body>.a fun.<function body>.b"$' config.optionsResult ./functionTo/submodule-options.nix

# moduleType
checkConfigOutput '^"a b"$' config.resultFoo ./declare-variants.nix ./define-variant.nix
Expand Down
4 changes: 2 additions & 2 deletions lib/types.nix
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,8 @@ rec {
descriptionClass = "composite";
check = isFunction;
merge = loc: defs:
fnArgs: (mergeDefinitions (loc ++ [ "[function body]" ]) elemType (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs)).mergedValue;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "[function body]" ]);
fnArgs: (mergeDefinitions (loc ++ [ "<function body>" ]) elemType (map (fn: { inherit (fn) file; value = fn.value fnArgs; }) defs)).mergedValue;
getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "<function body>" ]);
Ma27 marked this conversation as resolved.
Show resolved Hide resolved
getSubModules = elemType.getSubModules;
substSubModules = m: functionTo (elemType.substSubModules m);
functor = (defaultFunctor "functionTo") // { wrapped = elemType; };
Expand Down
4 changes: 2 additions & 2 deletions nixos/lib/make-options-doc/options-to-docbook.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
concat('opt-',
translate(
attr[@name = 'name']/string/@value,
'*&lt; >[]:',
'_______'
'*&lt; >[]:&quot;',
'________'
Copy link
Member

Choose a reason for hiding this comment

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

This changes the identifiers, breaking inbound links. Could you remove the quotes instead of replacing them with underscores?

Copy link
Member Author

Choose a reason for hiding this comment

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

Shouldn't that throw an error if <xref linkend="" /> points to an unknown location?

Copy link
Member

Choose a reason for hiding this comment

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

Then that would have been a problem before.
You'd have to define options."" = mkOption ... at the top level, which I don't think is something we have to worry about.

Copy link
Member Author

Choose a reason for hiding this comment

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

Then that would have been a problem before.

Yes. But considering that I can build the manual locally, doesn't that mean that there are no breaking links?

You'd have to define options."" = mkOption ... at the top level, which I don't think is something we have to worry about.

Even though it's just a theoretical problem, having e.g. settings."foo.bar" and settings.foo.bar defined would cause a conflict when removing the quotes, that's why I kept them.

Or am I misunderstanding your point? :)

Copy link
Member Author

Choose a reason for hiding this comment

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

ping @roberth

Copy link
Member

Choose a reason for hiding this comment

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

I was more concerned about links from the web to the manual. Passing the internal validation will not detect such broken links.
It does appear that the impact is quite limited:

({+_+} is git word diff syntax for "add underscore")

  • 138 ids relating to sr.ht such as opt-services.sourcehut.settings.{+_+}sr.ht{+_+}.owner-name
  • opt-services.listmonk.database.settings.{+_+}app.notify_emails{+_+}
  • opt-services.listmonk.database.settings.{+_+}bounce.mailboxes{+_+}
  • opt-services.listmonk.database.settings.{+_+}privacy.domain_blocklist{+_+}
  • opt-services.listmonk.database.settings.{+_+}privacy.exportable{+_+}
  • opt-services.xserver.windowManager.{+_+}2bwm{+_+}.enable

This seems like a small price to pay for a simpler and more injective id generating function.

))" />
<varlistentry>
<term xlink:href="#{$id}">
Expand Down