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

Conversation

Ma27
Copy link
Member

@Ma27 Ma27 commented Oct 2, 2022

Description of changes

Personally, I think that warnings such as

warning: The option `services.redis.enable' defined in `/home/ma27/Projects/nixpkgs/test.nix@node-vm' has been renamed to `services.redis.servers..enable'.

are fairly confusing because of the .. and it's more correct to actually quote that. With this change the warning now looks like this:

warning: The option `services.redis.enable' defined in `/home/ma27/Projects/nixpkgs/test.nix@node-vm' has been renamed to `services.redis.servers."".enable'.

While implementing that I realized that you'd have a similar problem whenever you use attribute-names that aren't identifiers, e.g.

services.nginx.virtualHosts."example.org".locations."/".invalid = 23;

now results in the following error:

error: The option `interactive.nodes.vm.services.nginx.virtualHosts."example.org".locations."/".invalid' does not exist. Definition values:
       - In `/home/ma27/Projects/nixpkgs/test.nix@node-vm': 23

Of course there are some corner-cases where this won't work: when generating the manual, you display submodules like this:

services.nginx.virtualHosts.<name>

Since <name> isn't a value, but an indicator for a submodule, it must not be quoted. This also applies to the following identifiers:

  • * for listOf submodule
  • <function body> for functionTo

This might not be correct if you actually have a submodule with an attribute name called <name>, but I think it's an improvement over the current situation and for this you'd probably need to make even more complex changes to the module system.

Closes #152649

Things done
  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandbox = true set in nix.conf? (See Nix manual)
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 22.11 Release Notes (or backporting 22.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
    • (Release notes changes) Ran nixos/doc/manual/md-to-db.sh to update generated release notes
  • Fits CONTRIBUTING.md.

@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 labels Oct 2, 2022
@infinisil infinisil added the 6.topic: module system About "NixOS" module system internals label Oct 3, 2022
@roberth
Copy link
Member

roberth commented Oct 6, 2022

We shouldn't have been mixing placeholders and unescaped identifiers in the first place.
Instead, we could represent paths like [ "etc" { placeholder = "<name>"; } "mode" ]. This makes the code accurate and moves type-specific logic back to the types where it belongs.

@Ma27
Copy link
Member Author

Ma27 commented Oct 6, 2022

@roberth do you think it's possible to implement that without noticeable breaking changes? If yes, I'm happy to give it a try, but otherwise I'd say that this is the pragmatic solution to improve the situation a little bit at least :)

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.

While I do think the correct solution is feasible, I don't mind getting there in steps.

lib/options.nix Outdated Show resolved Hide resolved
lib/types.nix Show resolved Hide resolved
lib/options.nix Show resolved Hide resolved
…to indicate a function inside an option structure

The motivation is to have a single identifier for that. Useful for the
next commit where I'll try to escape option-parts correctly (options can
be any kind of strings, but unless these are Nix identifiers, they must
be quoted).

Since `<function body>` (or `<name>`/`*`) are special identifiers in
error messages and the manual, we need a unique way to mark an option
part as function call because these are not to be quoted.
@Ma27 Ma27 force-pushed the show-option-quoting branch from 671fc21 to 4cc267c Compare October 7, 2022 08:08
…fiers

Personally, I think that warnings such as

    warning: The option `services.redis.enable' defined in `/home/ma27/Projects/nixpkgs/test.nix@node-vm' has been renamed to `services.redis.servers..enable'.

are fairly confusing because of the `..` and it's more correct to
actually quote that. With this change the warning now looks like this:

    warning: The option `services.redis.enable' defined in `/home/ma27/Projects/nixpkgs/test.nix@node-vm' has been renamed to `services.redis.servers."".enable'.

While implementing that I realized that you'd have
a similar problem whenever you use attribute-names that aren't
identifiers, e.g.

    services.nginx.virtualHosts."example.org".locations."/".invalid = 23;

now results in the following error:

    error: The option `interactive.nodes.vm.services.nginx.virtualHosts."example.org".locations."/".invalid' does not exist. Definition values:
           - In `/home/ma27/Projects/nixpkgs/test.nix@node-vm': 23

Of course there are some corner-cases where this won't work: when
generating the manual, you display submodules like this:

    services.nginx.virtualHosts.<name>

Since `<name>` isn't a value, but an indicator for a submodule, it must
not be quoted. This also applies to the following identifiers:

* `*` for `listOf submodule`
* `<function body>` for `functionTo`

This might not be correct if you actually have a submodule with an
attribute name called `<name>`, but I think it's an improvement over the
current situation and for this you'd probably need to make even more
complex changes to the module system.
@Ma27 Ma27 force-pushed the show-option-quoting branch from 4cc267c to 6396482 Compare October 7, 2022 08:09
@Ma27 Ma27 requested a review from roberth October 7, 2022 08:09
@Ma27
Copy link
Member Author

Ma27 commented Oct 7, 2022

Thanks a lot for your review! I addressed all of your coments :)

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.

Looks ok to me
@infinisil please review

@bobby285271 bobby285271 added the 12.approvals: 1 This PR was reviewed and approved by one reputable person label Oct 7, 2022
Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

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

This currently breaks the manual build, since the XSLT processing relies on this in some weird way, you can check with

nix-build nixos/release.nix -A manualHTML.x86_64-linux

I previously broke the manual in almost the same way when I tried to change the implementation of showOption a bit in #82461, which was then subsequently reverted in #85241. There's also a bug report regarding showOption in #152649

Now we even have options like
`services.listmonk.database.settings."app.notify_emails"` shown
correctly (i.e. with quotes).
@Ma27 Ma27 requested a review from infinisil October 9, 2022 08:14
@github-actions github-actions bot added the 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS label Oct 9, 2022
@Ma27
Copy link
Member Author

Ma27 commented Oct 9, 2022

@infinisil I replaced the quotes within the xslt now with a _ and it appears to work fine. Options like services.listmonk.database.settings."app.notify_emails" are also shown correctly quoted in the manual now :)

'*&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.

@Ma27
Copy link
Member Author

Ma27 commented Oct 16, 2022

@roberth so is it fine to keep that as-is? And: anything else tbd here? :)

@roberth roberth merged commit 6259b29 into NixOS:master Oct 18, 2022
gador added a commit to gador/nixpkgs that referenced this pull request Oct 19, 2022
@Ma27 Ma27 deleted the show-option-quoting branch October 19, 2022 14:42
arcnmx pushed a commit to arcnmx/nmd that referenced this pull request Oct 20, 2022
It's now necessary to also escape `"` (i.e. `&quot;`) in option ids,
otherwise the build will fail because `&quot;` is not a valid part of an
XML element id.

See also NixOS/nixpkgs#196651 and the original
change in NixOS/nixpkgs#194035 (comment)
for further context.

The `translate` expression is directly taken from the nixpkgs's
`options-to-docbook.xsl`.
arcnmx pushed a commit to arcnmx/nmd that referenced this pull request Oct 20, 2022
It's now necessary to also escape `"` (i.e. `&quot;`) in option ids,
otherwise the build will fail because `&quot;` is not a valid part of an
XML element id.

See also NixOS/nixpkgs#196651 and the original
change in NixOS/nixpkgs#194035 (comment)
for further context.

The `translate` expression is directly taken from the nixpkgs's
`options-to-docbook.xsl`.
gador added a commit to gador/nixpkgs that referenced this pull request Oct 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
6.topic: module system About "NixOS" module system internals 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 1-10 12.approvals: 1 This PR was reviewed and approved by one reputable person
Projects
None yet
Development

Successfully merging this pull request may close these issues.

lib.showOption doesn't quote attributes with periods
4 participants