D3376: registrar: replace "cmdtype" with an intent-based mechanism (API)
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Mon Apr 16 19:10:07 EDT 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGdfc51a482031: registrar: replace "cmdtype" with an intent-based mechanism (API) (authored by indygreg, committed by ).
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D3376?vs=8288&id=8319
REVISION DETAIL
https://phab.mercurial-scm.org/D3376
AFFECTED FILES
mercurial/commands.py
mercurial/dispatch.py
mercurial/registrar.py
tests/test-directaccess.t
CHANGE DETAILS
diff --git a/tests/test-directaccess.t b/tests/test-directaccess.t
--- a/tests/test-directaccess.t
+++ b/tests/test-directaccess.t
@@ -192,7 +192,7 @@
$ hg log -qr 'null:wdir() & 2147483647'
2147483647:ffffffffffff
-Commands with undefined cmdtype should not work right now
+Commands with undefined intent should not work right now
$ hg phase -r 28ad74
abort: hidden revision '28ad74' was rewritten as: 2443a0e66469!
diff --git a/mercurial/registrar.py b/mercurial/registrar.py
--- a/mercurial/registrar.py
+++ b/mercurial/registrar.py
@@ -138,15 +138,18 @@
potential repository locations. See ``findrepo()``. If a repository is
found, it will be used and passed to the decorated function.
- There are three constants in the class which tells what type of the command
- that is. That information will be helpful at various places. It will be also
- be used to decide what level of access the command has on hidden commits.
- The constants are:
+ The `intents` argument defines a set of intended actions or capabilities
+ the command is taking. These intents can be used to affect the construction
+ of the repository object passed to the command. For example, commands
+ declaring that they are read-only could receive a repository that doesn't
+ have any methods allowing repository mutation. Other intents could be used
+ to prevent the command from running if the requested intent could not be
+ fulfilled.
- `unrecoverablewrite` is for those write commands which can't be recovered
- like push.
- `recoverablewrite` is for write commands which can be recovered like commit.
- `readonly` is for commands which are read only.
+ The following intents are defined:
+
+ readonly
+ The command is read-only
The signature of the decorated function looks like this:
def cmd(ui[, repo] [, <args>] [, <options>])
@@ -161,29 +164,22 @@
descriptions and examples.
"""
- unrecoverablewrite = "unrecoverable"
- recoverablewrite = "recoverable"
- readonly = "readonly"
-
- possiblecmdtypes = {unrecoverablewrite, recoverablewrite, readonly}
-
def _doregister(self, func, name, options=(), synopsis=None,
norepo=False, optionalrepo=False, inferrepo=False,
- cmdtype=unrecoverablewrite):
+ intents=None):
- if cmdtype not in self.possiblecmdtypes:
- raise error.ProgrammingError("unknown cmdtype value '%s' for "
- "'%s' command" % (cmdtype, name))
func.norepo = norepo
func.optionalrepo = optionalrepo
func.inferrepo = inferrepo
- func.cmdtype = cmdtype
+ func.intents = intents or set()
if synopsis:
self._table[name] = func, list(options), synopsis
else:
self._table[name] = func, list(options)
return func
+INTENT_READONLY = b'readonly'
+
class revsetpredicate(_funcregistrarbase):
"""Decorator to register revset predicate
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -35,7 +35,6 @@
hook,
profiling,
pycompat,
- registrar,
scmutil,
ui as uimod,
util,
@@ -46,8 +45,6 @@
stringutil,
)
-unrecoverablewrite = registrar.command.unrecoverablewrite
-
class request(object):
def __init__(self, args, ui=None, repo=None, fin=None, fout=None,
ferr=None, prereposetups=None):
@@ -562,7 +559,7 @@
return aliasargs(self.fn, args)
def __getattr__(self, name):
- adefaults = {r'norepo': True, r'cmdtype': unrecoverablewrite,
+ adefaults = {r'norepo': True, r'intents': set(),
r'optionalrepo': False, r'inferrepo': False}
if name not in adefaults:
raise AttributeError(name)
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -73,7 +73,7 @@
table.update(debugcommandsmod.command._table)
command = registrar.command(table)
-readonly = registrar.command.readonly
+INTENT_READONLY = registrar.INTENT_READONLY
# common command options
@@ -1083,7 +1083,8 @@
_('show only branches that have unmerged heads (DEPRECATED)')),
('c', 'closed', False, _('show normal and closed branches')),
] + formatteropts,
- _('[-c]'), cmdtype=readonly)
+ _('[-c]'),
+ intents={INTENT_READONLY})
def branches(ui, repo, active=False, closed=False, **opts):
"""list repository named branches
@@ -1282,7 +1283,8 @@
('', 'decode', None, _('apply any matching decode filter')),
] + walkopts + formatteropts,
_('[OPTION]... FILE...'),
- inferrepo=True, cmdtype=readonly)
+ inferrepo=True,
+ intents={INTENT_READONLY})
def cat(ui, repo, file1, *pats, **opts):
"""output the current or given revision of files
@@ -1633,7 +1635,8 @@
('l', 'local', None, _('edit repository config')),
('g', 'global', None, _('edit global config'))] + formatteropts,
_('[-u] [NAME]...'),
- optionalrepo=True, cmdtype=readonly)
+ optionalrepo=True,
+ intents={INTENT_READONLY})
def config(ui, repo, *values, **opts):
"""show combined config settings from all hgrc files
@@ -1802,7 +1805,8 @@
('c', 'change', '', _('change made by revision'), _('REV'))
] + diffopts + diffopts2 + walkopts + subrepoopts,
_('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
- inferrepo=True, cmdtype=readonly)
+ inferrepo=True,
+ intents={INTENT_READONLY})
def diff(ui, repo, *pats, **opts):
"""diff repository (or selected files)
@@ -1895,7 +1899,8 @@
('', 'switch-parent', None, _('diff against the second parent')),
('r', 'rev', [], _('revisions to export'), _('REV')),
] + diffopts + formatteropts,
- _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'), cmdtype=readonly)
+ _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
+ intents={INTENT_READONLY})
def export(ui, repo, *changesets, **opts):
"""dump the header and diffs for one or more changesets
@@ -1990,7 +1995,8 @@
[('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
] + walkopts + formatteropts + subrepoopts,
- _('[OPTION]... [FILE]...'), cmdtype=readonly)
+ _('[OPTION]... [FILE]...'),
+ intents={INTENT_READONLY})
def files(ui, repo, *pats, **opts):
"""list tracked files
@@ -2371,7 +2377,8 @@
('d', 'date', None, _('list the date (short with -q)')),
] + formatteropts + walkopts,
_('[OPTION]... PATTERN [FILE]...'),
- inferrepo=True, cmdtype=readonly)
+ inferrepo=True,
+ intents={INTENT_READONLY})
def grep(ui, repo, pattern, *pats, **opts):
"""search revision history for a pattern in specified files
@@ -2617,7 +2624,8 @@
('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
('c', 'closed', False, _('show normal and closed branch heads')),
] + templateopts,
- _('[-ct] [-r STARTREV] [REV]...'), cmdtype=readonly)
+ _('[-ct] [-r STARTREV] [REV]...'),
+ intents={INTENT_READONLY})
def heads(ui, repo, *branchrevs, **opts):
"""show branch heads
@@ -2693,7 +2701,8 @@
('s', 'system', [], _('show help for specific platform(s)')),
],
_('[-ecks] [TOPIC]'),
- norepo=True, cmdtype=readonly)
+ norepo=True,
+ intents={INTENT_READONLY})
def help_(ui, name=None, **opts):
"""show help for a given topic or a help overview
@@ -2735,7 +2744,8 @@
('B', 'bookmarks', None, _('show bookmarks')),
] + remoteopts + formatteropts,
_('[-nibtB] [-r REV] [SOURCE]'),
- optionalrepo=True, cmdtype=readonly)
+ optionalrepo=True,
+ intents={INTENT_READONLY})
def identify(ui, repo, source=None, rev=None,
num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
"""identify the working directory or specified revision
@@ -3312,7 +3322,8 @@
_('do not display revision or any of its ancestors'), _('REV')),
] + logopts + walkopts,
_('[OPTION]... [FILE]'),
- inferrepo=True, cmdtype=readonly)
+ inferrepo=True,
+ intents={INTENT_READONLY})
def log(ui, repo, *pats, **opts):
"""show revision history of entire repository or files
@@ -3480,7 +3491,8 @@
[('r', 'rev', '', _('revision to display'), _('REV')),
('', 'all', False, _("list files from all revisions"))]
+ formatteropts,
- _('[-r REV]'), cmdtype=readonly)
+ _('[-r REV]'),
+ intents={INTENT_READONLY})
def manifest(ui, repo, node=None, rev=None, **opts):
"""output the current or given revision of the project manifest
@@ -3758,7 +3770,7 @@
displayer.close()
@command('paths', formatteropts, _('[NAME]'), optionalrepo=True,
- cmdtype=readonly)
+ intents={INTENT_READONLY})
def paths(ui, repo, search=None, **opts):
"""show aliases for remote repositories
@@ -4696,7 +4708,7 @@
return repo.rollback(dryrun=opts.get(r'dry_run'),
force=opts.get(r'force'))
- at command('root', [], cmdtype=readonly)
+ at command('root', [], intents={INTENT_READONLY})
def root(ui, repo):
"""print the root (top) of the current working directory
@@ -4790,7 +4802,8 @@
('', 'change', '', _('list the changed files of a revision'), _('REV')),
] + walkopts + subrepoopts + formatteropts,
_('[OPTION]... [FILE]...'),
- inferrepo=True, cmdtype=readonly)
+ inferrepo=True,
+ intents={INTENT_READONLY})
def status(ui, repo, *pats, **opts):
"""show changed files in the working directory
@@ -4958,7 +4971,8 @@
@command('^summary|sum',
[('', 'remote', None, _('check for push and pull'))],
- '[--remote]', cmdtype=readonly)
+ '[--remote]',
+ intents={INTENT_READONLY})
def summary(ui, repo, **opts):
"""summarize working directory state
@@ -5359,7 +5373,7 @@
finally:
release(lock, wlock)
- at command('tags', formatteropts, '', cmdtype=readonly)
+ at command('tags', formatteropts, '', intents={INTENT_READONLY})
def tags(ui, repo, **opts):
"""list repository tags
@@ -5596,7 +5610,8 @@
"""
return hg.verify(repo)
- at command('version', [] + formatteropts, norepo=True, cmdtype=readonly)
+ at command('version', [] + formatteropts, norepo=True,
+ intents={INTENT_READONLY})
def version_(ui, **opts):
"""output version and copyright information"""
opts = pycompat.byteskwargs(opts)
To: indygreg, #hg-reviewers, durin42
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list