Mercurial > public > mercurial-scm > hg
diff mercurial/cmdutil.py @ 45827:8d72e29ad1e0
errors: introduce InputError and use it from commands and cmdutil
This patch introduces a `InputError` class and replaces many uses of
`error.Abort` by it in `commands` and `cmdutil`. This is a part of
https://www.mercurial-scm.org/wiki/ErrorCategoriesPlan. There will
later be a different class for state errors (to raise e.g. when
there's an unfinished operation). It's not always clear when one
should report an input error and when it should be a state error. We
can always adjust later if I got something wrong in this patch (but
feel free to point out any you notice now).
Differential Revision: https://phab.mercurial-scm.org/D9167
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Tue, 06 Oct 2020 22:36:15 -0700 |
parents | 976b26bdd0d8 |
children | 527ce85c2e60 |
line wrap: on
line diff
--- a/mercurial/cmdutil.py Wed Oct 21 19:00:16 2020 -0700 +++ b/mercurial/cmdutil.py Tue Oct 06 22:36:15 2020 -0700 @@ -279,7 +279,7 @@ for x in args: if opts.get(x): if previous: - raise error.Abort( + raise error.InputError( _(b'cannot specify both --%s and --%s') % (to_display(previous), to_display(x)) ) @@ -332,9 +332,9 @@ return if len(note) > 255: - raise error.Abort(_(b"cannot store a note of more than 255 bytes")) + raise error.InputError(_(b"cannot store a note of more than 255 bytes")) if b'\n' in note: - raise error.Abort(_(b"note cannot contain a newline")) + raise error.InputError(_(b"note cannot contain a newline")) def ishunk(x): @@ -426,7 +426,7 @@ msg = _(b'running non-interactively, use %s instead') % cmdsuggest else: msg = _(b'running non-interactively') - raise error.Abort(msg) + raise error.InputError(msg) # make sure username is set before going interactive if not opts.get(b'user'): @@ -451,7 +451,7 @@ wctx = repo[None] merge = len(wctx.parents()) > 1 if merge: - raise error.Abort( + raise error.InputError( _( b'cannot partially commit a merge ' b'(use "hg commit" instead)' @@ -510,7 +510,7 @@ try: chunks, newopts = filterfn(ui, originalchunks, match) except error.PatchError as err: - raise error.Abort(_(b'error parsing patch: %s') % err) + raise error.InputError(_(b'error parsing patch: %s') % err) opts.update(newopts) # We need to keep a backup of files that have been newly added and @@ -600,7 +600,7 @@ ui.debug(fp.getvalue()) patch.internalpatch(ui, repo, fp, 1, eolmode=None) except error.PatchError as err: - raise error.Abort(pycompat.bytestr(err)) + raise error.InputError(pycompat.bytestr(err)) del fp # 4. We prepared working directory according to filtered @@ -762,7 +762,7 @@ # checking the argument validity for s in pycompat.bytestr(terseargs): if s not in allst: - raise error.Abort(_(b"'%s' not recognized") % s) + raise error.InputError(_(b"'%s' not recognized") % s) # creating a dirnode object for the root of the repo rootobj = dirnode(b'') @@ -968,10 +968,10 @@ bailifchanged(repo) revs = scmutil.revrange(repo, revs) if not revs: - raise error.Abort(b"empty revision set") + raise error.InputError(b"empty revision set") roots = repo.revs(b'roots(%ld)', revs) if len(roots) > 1: - raise error.Abort( + raise error.InputError( _(b"cannot change branch of non-linear revisions") ) rewriteutil.precheck(repo, revs, b'change branch of') @@ -983,16 +983,20 @@ and label not in rpb and label in repo.branchmap() ): - raise error.Abort(_(b"a branch of the same name already exists")) + raise error.InputError( + _(b"a branch of the same name already exists") + ) if repo.revs(b'obsolete() and %ld', revs): - raise error.Abort( + raise error.InputError( _(b"cannot change branch of a obsolete changeset") ) # make sure only topological heads if repo.revs(b'heads(%ld) - head()', revs): - raise error.Abort(_(b"cannot change branch in middle of a stack")) + raise error.InputError( + _(b"cannot change branch in middle of a stack") + ) replacements = {} # avoid import cycle mercurial.cmdutil -> mercurial.context -> @@ -1373,7 +1377,7 @@ b'without a repository' ) if msg: - raise error.Abort(msg) + raise error.InputError(msg) r = None if repo: @@ -1381,7 +1385,7 @@ r = repo.unfiltered().changelog elif dir: if not scmutil.istreemanifest(repo): - raise error.Abort( + raise error.InputError( _( b"--dir can only be used on repos with " b"treemanifest enabled" @@ -1407,16 +1411,18 @@ elif util.safehasattr(r, b'_revlog'): r = r._revlog # pytype: disable=attribute-error elif r is not None: - raise error.Abort(_(b'%r does not appear to be a revlog') % r) + raise error.InputError( + _(b'%r does not appear to be a revlog') % r + ) if not r: if not returnrevlog: - raise error.Abort(_(b'cannot give path to non-revlog')) + raise error.InputError(_(b'cannot give path to non-revlog')) if not file_: raise error.CommandError(cmd, _(b'invalid arguments')) if not os.path.isfile(file_): - raise error.Abort(_(b"revlog '%s' not found") % file_) + raise error.InputError(_(b"revlog '%s' not found") % file_) r = revlog.revlog( vfsmod.vfs(encoding.getcwd(), audit=False), file_[:-2] + b".i" ) @@ -1453,10 +1459,12 @@ if not forget and not after: # TODO: Remove this restriction and make it also create the copy # targets (and remove the rename source if rename==True). - raise error.Abort(_(b'--at-rev requires --after')) + raise error.InputError(_(b'--at-rev requires --after')) ctx = scmutil.revsingle(repo, rev) if len(ctx.parents()) > 1: - raise error.Abort(_(b'cannot mark/unmark copy in merge commit')) + raise error.InputError( + _(b'cannot mark/unmark copy in merge commit') + ) else: ctx = repo[None] @@ -1469,7 +1477,7 @@ new_ctx = ctx else: if len(ctx.parents()) > 1: - raise error.Abort(_(b'cannot unmark copy in merge commit')) + raise error.InputError(_(b'cannot unmark copy in merge commit')) # avoid cycle context -> subrepo -> cmdutil from . import context @@ -1512,9 +1520,9 @@ pats = scmutil.expandpats(pats) if not pats: - raise error.Abort(_(b'no source or destination specified')) + raise error.InputError(_(b'no source or destination specified')) if len(pats) == 1: - raise error.Abort(_(b'no destination specified')) + raise error.InputError(_(b'no destination specified')) dest = pats.pop() def walkpat(pat): @@ -1554,12 +1562,12 @@ rewriteutil.precheck(repo, [ctx.rev()], b'uncopy') absdest = pathutil.canonpath(repo.root, cwd, dest) if ctx.hasdir(absdest): - raise error.Abort( + raise error.InputError( _(b'%s: --at-rev does not support a directory as destination') % uipathfn(absdest) ) if absdest not in ctx: - raise error.Abort( + raise error.InputError( _(b'%s: copy destination does not exist in %s') % (uipathfn(absdest), ctx) ) @@ -1576,12 +1584,12 @@ copylist.append(abs) if not copylist: - raise error.Abort(_(b'no files to copy')) + raise error.InputError(_(b'no files to copy')) # TODO: Add support for `hg cp --at-rev . foo bar dir` and # `hg cp --at-rev . dir1 dir2`, preferably unifying the code with the # existing functions below. if len(copylist) != 1: - raise error.Abort(_(b'--at-rev requires a single source')) + raise error.InputError(_(b'--at-rev requires a single source')) new_ctx = context.overlayworkingctx(repo) new_ctx.setbase(ctx.p1()) @@ -1809,14 +1817,16 @@ destdirexists = os.path.isdir(dest) and not os.path.islink(dest) if not destdirexists: if len(pats) > 1 or matchmod.patkind(pats[0]): - raise error.Abort( + raise error.InputError( _( b'with multiple sources, destination must be an ' b'existing directory' ) ) if util.endswithsep(dest): - raise error.Abort(_(b'destination %s is not a directory') % dest) + raise error.InputError( + _(b'destination %s is not a directory') % dest + ) tfn = targetpathfn if after: @@ -1828,7 +1838,7 @@ continue copylist.append((tfn(pat, dest, srcs), srcs)) if not copylist: - raise error.Abort(_(b'no files to copy')) + raise error.InputError(_(b'no files to copy')) errors = 0 for targetpath, srcs in copylist: @@ -1919,7 +1929,7 @@ parents.append(repo[nullid]) if opts.get(b'exact'): if not nodeid or not p1: - raise error.Abort(_(b'not a Mercurial patch')) + raise error.InputError(_(b'not a Mercurial patch')) p1 = repo[p1] p2 = repo[p2 or nullid] elif p2: @@ -2255,7 +2265,7 @@ try: rev = mrevs.max() except ValueError: - raise error.Abort(_(b"revision matching date not found")) + raise error.InputError(_(b"revision matching date not found")) ui.status( _(b"found revision %d from %s\n") @@ -2338,7 +2348,9 @@ ui, repo, match, prefix, uipathfn, explicitonly, dryrun, interactive ): if dryrun and interactive: - raise error.Abort(_(b"cannot specify both --dry-run and --interactive")) + raise error.InputError( + _(b"cannot specify both --dry-run and --interactive") + ) bad = [] badfn = lambda x, y: bad.append(x) or match.bad(x, y) wctx = repo[None] @@ -3050,9 +3062,9 @@ if finishdesc: text = finishdesc(text) if not text.strip(): - raise error.Abort(_(b"empty commit message")) + raise error.InputError(_(b"empty commit message")) if unchangedmessagedetection and editortext == templatetext: - raise error.Abort(_(b"commit message unchanged")) + raise error.InputError(_(b"commit message unchanged")) return text