comparison mercurial/scmutil.py @ 45826:21733e8c924f

errors: add config that lets user get more detailed exit codes This adds an experimental config that lets the user get more detailed exit codes. For example, there will be a specific error code for input/user errors. This is part of https://www.mercurial-scm.org/wiki/ErrorCategoriesPlan. I've made the config part of tweakdefaults. I've made the config enabled by default in tests. My reasoning is that we want to see that each specific error case gives the right exit code and we don't want to duplicate all error cases in the entire test suite. It also makes it easy to grep the `.t` files for `[255]` to find which cases we have left to fix. The logic for the current exit codes is quite simple, so I'm not too worried about regressions there. I've added a test case specifically for the "legacy" exit codes. I've set the detailed exit status only for the case of `InterventionRequired` and `SystemExit` for now (the cases where we currently return something other than 255), just to show that it works. Differential Revision: https://phab.mercurial-scm.org/D9238
author Martin von Zweigbergk <martinvonz@google.com>
date Wed, 21 Oct 2020 19:00:16 -0700
parents 8f07f5a9c3de
children 8d72e29ad1e0
comparison
equal deleted inserted replaced
45825:8f07f5a9c3de 45826:21733e8c924f
146 """call func() with global exception handling 146 """call func() with global exception handling
147 147
148 return func() if no exception happens. otherwise do some error handling 148 return func() if no exception happens. otherwise do some error handling
149 and return an exit code accordingly. does not handle all exceptions. 149 and return an exit code accordingly. does not handle all exceptions.
150 """ 150 """
151 coarse_exit_code = -1
152 detailed_exit_code = -1
151 try: 153 try:
152 try: 154 try:
153 return func() 155 return func()
154 except: # re-raises 156 except: # re-raises
155 ui.traceback() 157 ui.traceback()
210 ui.error(_(b"(%s)\n") % inst.hint) 212 ui.error(_(b"(%s)\n") % inst.hint)
211 except error.InterventionRequired as inst: 213 except error.InterventionRequired as inst:
212 ui.error(b"%s\n" % inst) 214 ui.error(b"%s\n" % inst)
213 if inst.hint: 215 if inst.hint:
214 ui.error(_(b"(%s)\n") % inst.hint) 216 ui.error(_(b"(%s)\n") % inst.hint)
215 return 1 217 detailed_exit_code = 240
218 coarse_exit_code = 1
216 except error.WdirUnsupported: 219 except error.WdirUnsupported:
217 ui.error(_(b"abort: working directory revision cannot be specified\n")) 220 ui.error(_(b"abort: working directory revision cannot be specified\n"))
218 except error.Abort as inst: 221 except error.Abort as inst:
219 ui.error(_(b"abort: %s\n") % inst.message) 222 ui.error(_(b"abort: %s\n") % inst.message)
220 if inst.hint: 223 if inst.hint:
264 except MemoryError: 267 except MemoryError:
265 ui.error(_(b"abort: out of memory\n")) 268 ui.error(_(b"abort: out of memory\n"))
266 except SystemExit as inst: 269 except SystemExit as inst:
267 # Commands shouldn't sys.exit directly, but give a return code. 270 # Commands shouldn't sys.exit directly, but give a return code.
268 # Just in case catch this and and pass exit code to caller. 271 # Just in case catch this and and pass exit code to caller.
269 return inst.code 272 detailed_exit_code = 254
270 273 coarse_exit_code = inst.code
271 return -1 274
275 if ui.configbool(b'ui', b'detailed-exit-code'):
276 return detailed_exit_code
277 else:
278 return coarse_exit_code
272 279
273 280
274 def checknewlabel(repo, lbl, kind): 281 def checknewlabel(repo, lbl, kind):
275 # Do not use the "kind" parameter in ui output. 282 # Do not use the "kind" parameter in ui output.
276 # It makes strings difficult to translate. 283 # It makes strings difficult to translate.