This is an archive of the discontinued Mercurial Phabricator instance.

dispatch: adding config items for overriding flag defaults
Needs RevisionPublic

Authored by rdamazio on Mar 3 2018, 6:54 PM.

Details

Reviewers
yuja
baymax
Group Reviewers
hg-reviewers
Summary

This introduces the new defaults format "commandname.default.optionname" which
directly overrides the default of the option, instead of prepending the
command-line option. This is meant to replace the [defaults] section which is
already deprecated in a manner that's easier and safer to use than creating
aliases.

Diff Detail

Repository
rHG Mercurial
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

rdamazio created this revision.Mar 3 2018, 6:54 PM
rdamazio updated this revision to Diff 6523.Mar 3 2018, 6:58 PM

FYI this is a change I had previously sent to the list as 60b3222e01f96f91ece7eda9681a89bf3bb930a6, and Yuya reviewed . I just had never followed up on it.

yuja added a subscriber: dploch.Mar 4 2018, 9:21 AM
yuja requested changes to this revision.
yuja added inline comments.
mercurial/dispatch.py
624

Maybe this type conversion can be a fancyopt.customopt method since we've
refactored the default handling by D2090?

# no idea if _defaultopt() should be made public or the whole commands.default handling
# should be moved to fancyopts
x = fancyopts._defaultopt(olddefault)
newdefault = x.configdefault(ui, cmd, optname, ...)

@dploch, any suggestions?

mercurial/ui.py
389

Perhaps this is noop since [commands] is removed at all if ui.plain() returns True.

This revision now requires changes to proceed.Mar 4 2018, 9:21 AM
rdamazio updated this revision to Diff 6548.Mar 4 2018, 11:34 AM
rdamazio added inline comments.Mar 4 2018, 11:34 AM
mercurial/dispatch.py
624

The issue is that customopt (and all its children) assume the value type is already the correct one, and thus do not perform any conversion. Since we're parsing values from the config file, the conversion is desired to ensure they don't all end up as text - the config{bool,int,etc} methods called by configtyped perform the proper conversion. In most cases (all commands that declare default values) no conversio is needed since those already have the correct type.

mercurial/ui.py
389

You're right, I had the plain logic inverted in my head. Removed.

yuja added inline comments.Mar 4 2018, 12:15 PM
mercurial/dispatch.py
624

IIUC, an extension author may implement its own customopt subclasses, and
put them into the command table, so we can't make ui.configtyped to
support all of them.

rdamazio updated this revision to Diff 6609.Mar 4 2018, 3:36 PM
rdamazio added inline comments.Mar 4 2018, 3:39 PM
mercurial/dispatch.py
624

Ah, makes sense. See if this addresses that case satisfactorily - it still has the caveat of not being able to "reset" container types, but that's true of the command line as well (if you have a list flag with a non-empty default, there's no way to remove that default item).

dploch added inline comments.Mar 5 2018, 6:29 PM
mercurial/dispatch.py
624

I think rdamazio's response is correct. The type information for an opt exists only in the 'defaultvalue' slot in the tuple, so it needs to be extracted from there before reading the config. I don't have a strong opinion as to where this code should go - 'ui' does seem marginally more appropriate than 'fancyopts', since it keeps 'fancyopts' low-level and not depending on 'ui'.

625–626

This doesn't handle callables properly. I wonder if the something like the following would work instead:

oldopt = fancyopts._defaultopt(olddefault)
newdefault = old.opt.newstate(olddefault, ui.config("commands", cfgitem)
c[idx] = (opt[0], opt[1], fancyopts._withnewdefault(oldopt, newdefault), opt[3])

Where '_withnewdefault' is a wrapper customopt that just changes the default.

639–640

This makes me nervous. What if someone re-uses a customopt instance in multiple commands? i.e.:

DATE_FLAG = mypkg.dateopt()
...
('b', 'before', DATE_FLAG, '')
('a', 'after', 'DATE_FLAG', '')

Now, setting commands.defaults.before=2018-03-05 also silently changes the default for 'after'. I suspect we need to introduce a wrapper class like what I suggest on lines 625-625, that delegates and leaves the original default unchanged. And either way, we should probably clarify in the docs on customopts what expected use of the class is (i.e., should we just forbid reuse, is 'oldstate' safe to mutate, etc.)

rdamazio added inline comments.Mar 27 2018, 2:30 AM
mercurial/dispatch.py
625–626

I thought callables were meant to be used to generate the default default, not with overridden values?

639–640

Nobody should use the same *instance* on multiple flags. Even with the current flags, if you use e.g. the same list on many, that'll cause problems with listopt.

baymax requested changes to this revision.Jan 24 2020, 12:33 PM

There seems to have been no activities on this Diff for the past 3 Months.

By policy, we are automatically moving it out of the need-review state.

Please, move it back to need-review without hesitation if this diff should still be discussed.

:baymax:need-review-idle:

This revision now requires changes to proceed.Jan 24 2020, 12:33 PM