comparison mercurial/dispatch.py @ 35224:6e6d0a5b88e6

dispatch: replace _earlyreq*() with new fancyopts-based parser
author Yuya Nishihara <yuya@tcha.org>
date Thu, 23 Nov 2017 22:23:59 +0900
parents 4edd2202f7d7
children 7ce0ba3a1c32
comparison
equal deleted inserted replaced
35223:4edd2202f7d7 35224:6e6d0a5b88e6
53 # input/output/error streams 53 # input/output/error streams
54 self.fin = fin 54 self.fin = fin
55 self.fout = fout 55 self.fout = fout
56 self.ferr = ferr 56 self.ferr = ferr
57 57
58 # remember options pre-parsed by _earlyreqopt*() 58 # remember options pre-parsed by _earlyparseopts()
59 self.earlyoptions = {} 59 self.earlyoptions = {}
60 60
61 # reposetups which run before extensions, useful for chg to pre-fill 61 # reposetups which run before extensions, useful for chg to pre-fill
62 # low-level repo state (for example, changelog) before extensions. 62 # low-level repo state (for example, changelog) before extensions.
63 self.prereposetups = prereposetups or [] 63 self.prereposetups = prereposetups or []
148 ferr = util.stderr 148 ferr = util.stderr
149 149
150 try: 150 try:
151 if not req.ui: 151 if not req.ui:
152 req.ui = uimod.ui.load() 152 req.ui = uimod.ui.load()
153 if req.ui.plain('strictflags'): 153 req.earlyoptions.update(_earlyparseopts(req.ui, req.args))
154 req.earlyoptions.update(_earlyparseopts(req.args)) 154 if req.earlyoptions['traceback']:
155 if _earlyreqoptbool(req, 'traceback', ['--traceback']):
156 req.ui.setconfig('ui', 'traceback', 'on', '--traceback') 155 req.ui.setconfig('ui', 'traceback', 'on', '--traceback')
157 156
158 # set ui streams from the request 157 # set ui streams from the request
159 if req.fin: 158 if req.fin:
160 req.ui.fin = req.fin 159 req.ui.fin = req.fin
264 'pdb': pdb.post_mortem 263 'pdb': pdb.post_mortem
265 } 264 }
266 265
267 # read --config before doing anything else 266 # read --config before doing anything else
268 # (e.g. to change trust settings for reading .hg/hgrc) 267 # (e.g. to change trust settings for reading .hg/hgrc)
269 cfgs = _parseconfig(req.ui, 268 cfgs = _parseconfig(req.ui, req.earlyoptions['config'])
270 _earlyreqopt(req, 'config', ['--config']))
271 269
272 if req.repo: 270 if req.repo:
273 # copy configs that were passed on the cmdline (--config) to 271 # copy configs that were passed on the cmdline (--config) to
274 # the repo ui 272 # the repo ui
275 for sec, name, val in cfgs: 273 for sec, name, val in cfgs:
279 debugger = ui.config("ui", "debugger") 277 debugger = ui.config("ui", "debugger")
280 debugmod = pdb 278 debugmod = pdb
281 if not debugger or ui.plain(): 279 if not debugger or ui.plain():
282 # if we are in HGPLAIN mode, then disable custom debugging 280 # if we are in HGPLAIN mode, then disable custom debugging
283 debugger = 'pdb' 281 debugger = 'pdb'
284 elif _earlyreqoptbool(req, 'debugger', ['--debugger']): 282 elif req.earlyoptions['debugger']:
285 # This import can be slow for fancy debuggers, so only 283 # This import can be slow for fancy debuggers, so only
286 # do it when absolutely necessary, i.e. when actual 284 # do it when absolutely necessary, i.e. when actual
287 # debugging has been requested 285 # debugging has been requested
288 with demandimport.deactivated(): 286 with demandimport.deactivated():
289 try: 287 try:
293 291
294 debugtrace[debugger] = debugmod.set_trace 292 debugtrace[debugger] = debugmod.set_trace
295 debugmortem[debugger] = debugmod.post_mortem 293 debugmortem[debugger] = debugmod.post_mortem
296 294
297 # enter the debugger before command execution 295 # enter the debugger before command execution
298 if _earlyreqoptbool(req, 'debugger', ['--debugger']): 296 if req.earlyoptions['debugger']:
299 ui.warn(_("entering debugger - " 297 ui.warn(_("entering debugger - "
300 "type c to continue starting hg or h for help\n")) 298 "type c to continue starting hg or h for help\n"))
301 299
302 if (debugger != 'pdb' and 300 if (debugger != 'pdb' and
303 debugtrace[debugger] == debugtrace['pdb']): 301 debugtrace[debugger] == debugtrace['pdb']):
309 return _dispatch(req) 307 return _dispatch(req)
310 finally: 308 finally:
311 ui.flush() 309 ui.flush()
312 except: # re-raises 310 except: # re-raises
313 # enter the debugger when we hit an exception 311 # enter the debugger when we hit an exception
314 if _earlyreqoptbool(req, 'debugger', ['--debugger']): 312 if req.earlyoptions['debugger']:
315 traceback.print_exc() 313 traceback.print_exc()
316 debugmortem[debugger](sys.exc_info()[2]) 314 debugmortem[debugger](sys.exc_info()[2])
317 raise 315 raise
318 316
319 return _callcatch(ui, _runcatchfunc) 317 return _callcatch(ui, _runcatchfunc)
644 raise error.Abort(_('malformed --config option: %r ' 642 raise error.Abort(_('malformed --config option: %r '
645 '(use --config section.name=value)') % cfg) 643 '(use --config section.name=value)') % cfg)
646 644
647 return configs 645 return configs
648 646
649 def _earlyparseopts(args): 647 def _earlyparseopts(ui, args):
650 options = {} 648 options = {}
651 fancyopts.fancyopts(args, commands.globalopts, options, 649 fancyopts.fancyopts(args, commands.globalopts, options,
652 gnu=False, early=True, 650 gnu=not ui.plain('strictflags'), early=True,
653 optaliases={'repository': ['repo']}) 651 optaliases={'repository': ['repo']})
654 return options 652 return options
655 653
656 def _earlygetopt(aliases, args, strip=True): 654 def _earlygetopt(aliases, args, strip=True):
657 """Return list of values for an option (or aliases). 655 """Return list of values for an option (or aliases).
737 pos += 1 735 pos += 1
738 else: 736 else:
739 pos += 1 737 pos += 1
740 return values 738 return values
741 739
742 def _earlyreqopt(req, name, aliases):
743 """Peek a list option without using a full options table"""
744 if req.ui.plain('strictflags'):
745 return req.earlyoptions[name]
746 values = _earlygetopt(aliases, req.args, strip=False)
747 req.earlyoptions[name] = values
748 return values
749
750 def _earlyreqoptstr(req, name, aliases):
751 """Peek a string option without using a full options table"""
752 if req.ui.plain('strictflags'):
753 return req.earlyoptions[name]
754 value = (_earlygetopt(aliases, req.args, strip=False) or [''])[-1]
755 req.earlyoptions[name] = value
756 return value
757
758 def _earlyreqoptbool(req, name, aliases):
759 """Peek a boolean option without using a full options table
760
761 >>> req = request([b'x', b'--debugger'], uimod.ui())
762 >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
763 True
764
765 >>> req = request([b'x', b'--', b'--debugger'], uimod.ui())
766 >>> _earlyreqoptbool(req, b'debugger', [b'--debugger'])
767 """
768 if req.ui.plain('strictflags'):
769 return req.earlyoptions[name]
770 try:
771 argcount = req.args.index("--")
772 except ValueError:
773 argcount = len(req.args)
774 value = None
775 pos = 0
776 while pos < argcount:
777 arg = req.args[pos]
778 if arg in aliases:
779 value = True
780 pos += 1
781 req.earlyoptions[name] = value
782 return value
783
784 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions): 740 def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions):
785 # run pre-hook, and abort if it fails 741 # run pre-hook, and abort if it fails
786 hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs), 742 hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs),
787 pats=cmdpats, opts=cmdoptions) 743 pats=cmdpats, opts=cmdoptions)
788 try: 744 try:
857 def _dispatch(req): 813 def _dispatch(req):
858 args = req.args 814 args = req.args
859 ui = req.ui 815 ui = req.ui
860 816
861 # check for cwd 817 # check for cwd
862 cwd = _earlyreqoptstr(req, 'cwd', ['--cwd']) 818 cwd = req.earlyoptions['cwd']
863 if cwd: 819 if cwd:
864 os.chdir(cwd) 820 os.chdir(cwd)
865 821
866 rpath = _earlyreqoptstr(req, 'repository', ["-R", "--repository", "--repo"]) 822 rpath = req.earlyoptions['repository']
867 path, lui = _getlocal(ui, rpath) 823 path, lui = _getlocal(ui, rpath)
868 824
869 uis = {ui, lui} 825 uis = {ui, lui}
870 826
871 if req.repo: 827 if req.repo:
872 uis.add(req.repo.ui) 828 uis.add(req.repo.ui)
873 829
874 if _earlyreqoptbool(req, 'profile', ['--profile']): 830 if req.earlyoptions['profile']:
875 for ui_ in uis: 831 for ui_ in uis:
876 ui_.setconfig('profiling', 'enabled', 'true', '--profile') 832 ui_.setconfig('profiling', 'enabled', 'true', '--profile')
877 833
878 profile = lui.configbool('profiling', 'enabled') 834 profile = lui.configbool('profiling', 'enabled')
879 with profiling.profile(lui, enabled=profile) as profiler: 835 with profiling.profile(lui, enabled=profile) as profiler:
1009 # try to infer -R from command args 965 # try to infer -R from command args
1010 repos = pycompat.maplist(cmdutil.findrepo, args) 966 repos = pycompat.maplist(cmdutil.findrepo, args)
1011 guess = repos[0] 967 guess = repos[0]
1012 if guess and repos.count(guess) == len(repos): 968 if guess and repos.count(guess) == len(repos):
1013 req.args = ['--repository', guess] + fullargs 969 req.args = ['--repository', guess] + fullargs
970 req.earlyoptions['repository'] = guess
1014 return _dispatch(req) 971 return _dispatch(req)
1015 if not path: 972 if not path:
1016 raise error.RepoError(_("no repository found in" 973 raise error.RepoError(_("no repository found in"
1017 " '%s' (.hg not found)") 974 " '%s' (.hg not found)")
1018 % pycompat.getcwd()) 975 % pycompat.getcwd())