git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH/RFC] parse-options: add facility to make options configurable

From
Jeff King <peff@peff.net>
Date
Mar 28, 2017, 05:17 UTC
Message-ID
<20170328051723.h2xi2do6iclm64pi@sigill.intra.peff.net>
In-Reply-To
<CACBZZX6=_Jh-emAr=g1-VQwgA4MnDpu=zSOqPK5QHAa7uef_LQ@mail.gmail.com>
On Sat, Mar 25, 2017 at 11:32:02PM +0100, Ævar Arnfjörð Bjarmason wrote:
Show 11 quoted lines
> > So hopefully it's clear that the two are functionally equivalent, and
> > differ only in syntax (in this case we manually decided which options
> > are safe to pull from the config, but we'd have to parse the options.log
> > string, too, and we could make the same decision there).
> 
> I like the simplicity of this approach a lot. I.e. (to paraphrase it
> just to make sure we're on the same page): Skip all the complexity of
> reaching into the getopt guts, and just munge argc/argv given a config
> we can stick ahead of the getopt (struct options) spec, inject some
> options at the beginning if they're in the config, and off we go
> without any further changes to the getopt guts.
Yep, I think that's an accurate description.
Show 21 quoted lines
> There's two practical issues with this that are easy to solve with my
> current approach, but I can't find an easy solution to using this
> method.
> 
> The first is that we're replacing the semantics of:
> 
> "If you're specifying it on the command-line, we take it from there,
> otherwise we use your config, if set, regardless of how the option
> works"
> 
> with:
> 
> "We read your config, inject options implicitly at the start of the
> command line, and then append whatever command-line you give us"
> 
> These two are not the same. Consider e.g. the commit.verbose config.
> With my current patch if have commit.verbose=1 in your config and do
> "commit --verbose" you just end up with a result equivalent to not
> having it in your config, but since the --verbose option can be
> supplied multiple times to increase verbosity with the injection
> method you'd end up with the equivalent of commit.verbose=2.

Right, for anything where multiple options are meaningful, they'd have to give "--no-verbose" to reset the option. In a sense that's less friendly, because it's more manual. But it's also less magical, because the semantics are clear: the config option behaves exactly as if you gave the option on the command line. So for an OPT_STRING_LIST(), you could append to the list, or reset it to empty, etc, as you see fit.

But I do agree that it's more manual, and probably would cause some confusion.

> I can't think of a good way around that with your proposed approach
> that doesn't essentially get us back to something very similar to my
> patch, i.e. we'd need to parse the command-line using the options spec
> before applying our implicit config.

Yes, the semantics you gave require parsing the options first. I think it would be sufficient to just give each "struct option" a "seen" flag (rather than having it understand the config mechanism), having parse_options() set the flag, and then feeding the result to a separate config/cmdline mapping mechanism. That keeps the complexity out of the options code.

It does tie us back in to requiring parse-options, which not all the options use.

In a lot of cases that "seen" flag is effectively a sentinel value in whatever variable the option value is stored in. But some of the options don't have reasonable sentinel values (as you noticed with the "revert -m" handling recently).

> The second issue is related, i.e. I was going to add some flag an
> option could supply to say "if I'm provided none of these other
> maybe-from-config options get to read their config". This is needed
> for hybrid plumbing/porcelain like "git status --porcelain".

Yeah, I agree you can't make that decision until you've seen the command-line options. I think we currently do some hairy stuff where we speculatively read config into a variable, and then apply the config-based defaults only when we know we're in non-porcelain mode (see status_deferred_config in builtin/commit.c).

That came about because we didn't want to parse the config a second time. These days the deferred config should probably just be read from the cached configset, after we've read the other options.

But I think this can be done after the full option-parsing is finished by applying the mapping then. I.e., something like:

    parse_options(argc, argv, options, ...);
    if (status_format != STATUS_FORMAT_PORCELAIN)
	apply_config_mapping(status_mapping, options);
-Peff
Previous: Ævar Arnfjörð BjarmasonNext: Ævar Arnfjörð Bjarmason
Message 16 of 19 in “Add configuration options for some commonly used command-line options (Was: [RFH] GSoC 2015 application)”
  1. Duy NguyenMar 19, 2017
  2. Matthieu MoyMar 19, 2017
  3. brian m. carlsonMar 19, 2017
  4. Ævar Arnfjörð BjarmasonMar 19, 2017
  5. Duy NguyenMar 20, 2017
  6. Brandon WilliamsMar 20, 2017
  7. Jeff KingMar 20, 2017
  8. Brandon McCaigMar 31, 2017
  9. Junio C HamanoMar 20, 2017
  10. Jeff KingMar 20, 2017
  11. Ævar Arnfjörð BjarmasonMar 20, 2017
  12. parse-options: add facility to make options configurableÆvar Arnfjörð Bjarmason, Mar 24, 2017
  13. Ævar Arnfjörð BjarmasonMar 25, 2017
  14. Jeff KingMar 25, 2017
  15. Ævar Arnfjörð BjarmasonMar 25, 2017
  16. Jeff KingMar 28, 2017
  17. WIP configurable options facilityÆvar Arnfjörð Bjarmason, Mar 28, 2017
  18. brian m. carlsonMar 25, 2017
  19. Duy NguyenMar 20, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.