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

Add setting handlers (side effects when settings are changed) #9922

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

9999years
Copy link
Contributor

@9999years 9999years commented Feb 3, 2024

Motivation

One of the biggest differences between command-line arguments and settings is that command-line arguments have handlers, arbitrary functions that are run when the command-line argument is set, which may perform arbitrary side-effects. This is used by arguments like --log-format and --print-build-logs to make changes to global state in response to argument values.

This PR adds simple handler functions to settings, to gain parity with command-line arguments.

(Note: The use of global state in handlers for --log-format and similar arguments is unnerving and error prone. I believe this design will scale if we try to reduce global state in Nix — in the future, we can add parameters like EvalState to handler functions to make data flow explicit.)

I intend to use this functionality to implement two features:

  1. Settings with side-effects, like log-format and print-build-logs (to close tickets like Nix.conf for print-build-logs and verbose #5858 and allow settings log-format in nix.conf #5561).

    I have a PR which adds log-format and log-format-legacy settings written already, building on this PR: Convert --log-format to a setting #9923

  2. Settings that change at runtime, to support commands like :set print-build-logs in the REPL/debugger (see nix repl should be able to change settings #9944)

This PR also combines BaseSetting and Setting (there were no usages of BaseSetting on its own).

Priorities and Process

Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

`BaseSetting` is never used on its own, so it's fairly trivial to
remove.
@github-actions github-actions bot added the new-cli Relating to the "nix" command label Feb 3, 2024
Copy link
Member

@thufschmitt thufschmitt left a comment

Choose a reason for hiding this comment

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

A bunch of small nitpicks, but I think that makes sense overall. Thanks!

src/libutil/config.hh Outdated Show resolved Hide resolved
src/libutil/config.hh Outdated Show resolved Hide resolved
src/libutil/config.hh Outdated Show resolved Hide resolved
src/libutil/config.hh Outdated Show resolved Hide resolved
@edolstra
Copy link
Member

edolstra commented Feb 9, 2024

The idea of adding arbitrary side effects to configuration settings is scary to me. It makes it hard to reason about the configuration system. E.g. currently a configuration foo = 1\nfoo = 2 is equivalent to foo = 2, but if you can attach arbitrary side effects, that's no longer the case.

@thufschmitt
Copy link
Member

@edolstra wouldn't that be OK as long as we are in control of the side effects we want to have?
I think the only property we'll want to require is that handler(foo); handler(bar) is equivalent to handler(bar) (for some definition of equivalent of course), which is a reasonable-enough property. And we in indeed probably need that for things like #5561 or #9944

@Ericson2314
Copy link
Member

I just glanced at this, but I am also skeptical. I think we should have a larger conversation about what the direction of travel should be with the settings. My highest priority is still getting rid of the global variables #5638 and supporting nested settings with JSON #8373.

`fun` has a default value, so we no longer need to be able to convert
`SettingHandler` to `bool`.
@9999years
Copy link
Contributor Author

My highest priority is still getting rid of the global variables #5638

Yeah, I was thinking about that. I think it would be pretty easy to replace the setting values with thunks, and then it would be easier to make the config values non-static.

@pennae
Copy link
Contributor

pennae commented Feb 20, 2024

not sure why this is controversial. we already have the facility to add arbitrary side effects, it's just less convenient (requiring an explicit template instantiation and an implementation of parse or set). seems like codifying this on a per-setting basis would be more readable and clear than with custom settings types, and in any case a good first step towards refactoring to get rid of globals?

@Ericson2314
Copy link
Member

Ericson2314 commented Feb 20, 2024

I have given this more thought, and do think as part of the translation / compat layer we will end up needing something like this. But I want to work on what we are translating to first.

In particular, I would like to migrate the store settings off the current config.hh, and to something which the fetchers can also use.

Once that is done, I'll be more more comfortable adding bells and whistles like this to config.hh because it won't "pollute" the brave new world in the making.

Conversely, if we don't do things this way, I am afraid getting stuck half-way through with an even-more-complicated config.hh that everything is still closely tied to. Getting stuck halfway-through with some things already off the old system completely feels much safer to me.

@Ericson2314
Copy link
Member

#10562 reminds me I want the global variables gone, which reminds me that we're gonna need this as part of the transition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-cli Relating to the "nix" command
Projects
Status: ⚖ To discuss
Development

Successfully merging this pull request may close these issues.

5 participants