mercurial/commands.py
changeset 4545 aea8fd7fb5e2
parent 4544 930ed513c864
child 4546 5c8130691692
equal deleted inserted replaced
4544:930ed513c864 4545:aea8fd7fb5e2
  3032 norepo = ("clone init version help debugancestor debugcomplete debugdata"
  3032 norepo = ("clone init version help debugancestor debugcomplete debugdata"
  3033           " debugindex debugindexdot debugdate debuginstall")
  3033           " debugindex debugindexdot debugdate debuginstall")
  3034 optionalrepo = ("paths serve showconfig")
  3034 optionalrepo = ("paths serve showconfig")
  3035 
  3035 
  3036 def run():
  3036 def run():
  3037     sys.exit(dispatch(sys.argv[1:]))
       
  3038 
       
  3039 def findpossible(ui, cmd):
       
  3040     """
       
  3041     Return cmd -> (aliases, command table entry)
       
  3042     for each matching command.
       
  3043     Return debug commands (or their aliases) only if no normal command matches.
       
  3044     """
       
  3045     choice = {}
       
  3046     debugchoice = {}
       
  3047     for e in table.keys():
       
  3048         aliases = e.lstrip("^").split("|")
       
  3049         found = None
       
  3050         if cmd in aliases:
       
  3051             found = cmd
       
  3052         elif not ui.config("ui", "strict"):
       
  3053             for a in aliases:
       
  3054                 if a.startswith(cmd):
       
  3055                     found = a
       
  3056                     break
       
  3057         if found is not None:
       
  3058             if aliases[0].startswith("debug") or found.startswith("debug"):
       
  3059                 debugchoice[found] = (aliases, table[e])
       
  3060             else:
       
  3061                 choice[found] = (aliases, table[e])
       
  3062 
       
  3063     if not choice and debugchoice:
       
  3064         choice = debugchoice
       
  3065 
       
  3066     return choice
       
  3067 
       
  3068 def findcmd(ui, cmd):
       
  3069     """Return (aliases, command table entry) for command string."""
       
  3070     choice = findpossible(ui, cmd)
       
  3071 
       
  3072     if choice.has_key(cmd):
       
  3073         return choice[cmd]
       
  3074 
       
  3075     if len(choice) > 1:
       
  3076         clist = choice.keys()
       
  3077         clist.sort()
       
  3078         raise AmbiguousCommand(cmd, clist)
       
  3079 
       
  3080     if choice:
       
  3081         return choice.values()[0]
       
  3082 
       
  3083     raise UnknownCommand(cmd)
       
  3084 
       
  3085 class ParseError(Exception):
       
  3086     """Exception raised on errors in parsing the command line."""
       
  3087 
       
  3088 def parse(ui, args):
       
  3089     options = {}
       
  3090     cmdoptions = {}
       
  3091 
       
  3092     try:
       
  3093         args = fancyopts.fancyopts(args, globalopts, options)
       
  3094     except fancyopts.getopt.GetoptError, inst:
       
  3095         raise ParseError(None, inst)
       
  3096 
       
  3097     if args:
       
  3098         cmd, args = args[0], args[1:]
       
  3099         aliases, i = findcmd(ui, cmd)
       
  3100         cmd = aliases[0]
       
  3101         defaults = ui.config("defaults", cmd)
       
  3102         if defaults:
       
  3103             args = shlex.split(defaults) + args
       
  3104         c = list(i[1])
       
  3105     else:
       
  3106         cmd = None
       
  3107         c = []
       
  3108 
       
  3109     # combine global options into local
       
  3110     for o in globalopts:
       
  3111         c.append((o[0], o[1], options[o[1]], o[3]))
       
  3112 
       
  3113     try:
       
  3114         args = fancyopts.fancyopts(args, c, cmdoptions)
       
  3115     except fancyopts.getopt.GetoptError, inst:
       
  3116         raise ParseError(cmd, inst)
       
  3117 
       
  3118     # separate global options back out
       
  3119     for o in globalopts:
       
  3120         n = o[1]
       
  3121         options[n] = cmdoptions[n]
       
  3122         del cmdoptions[n]
       
  3123 
       
  3124     return (cmd, cmd and i[0] or None, args, options, cmdoptions)
       
  3125 
       
  3126 def parseconfig(config):
       
  3127     """parse the --config options from the command line"""
       
  3128     parsed = []
       
  3129     for cfg in config:
       
  3130         try:
       
  3131             name, value = cfg.split('=', 1)
       
  3132             section, name = name.split('.', 1)
       
  3133             if not section or not name:
       
  3134                 raise IndexError
       
  3135             parsed.append((section, name, value))
       
  3136         except (IndexError, ValueError):
       
  3137             raise util.Abort(_('malformed --config option: %s') % cfg)
       
  3138     return parsed
       
  3139 
       
  3140 def catchterm(*args):
       
  3141     raise util.SignalInterrupt
       
  3142 
       
  3143 def dispatch(args):
       
  3144     for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
       
  3145         num = getattr(signal, name, None)
       
  3146         if num: signal.signal(num, catchterm)
       
  3147 
       
  3148     try:
  3037     try:
  3149         u = ui.ui(traceback='--traceback' in sys.argv[1:])
  3038         u = ui.ui(traceback='--traceback' in sys.argv[1:])
  3150     except util.Abort, inst:
  3039     except util.Abort, inst:
  3151         sys.stderr.write(_("abort: %s\n") % inst)
  3040         sys.stderr.write(_("abort: %s\n") % inst)
  3152         return -1
  3041         return -1
  3153 
  3042     sys.exit(runcatch(u, sys.argv[1:]))
  3154     extensions.loadall(u)
  3043 
  3155     u.addreadhook(extensions.loadall)
  3044 def runcatch(u, args):
       
  3045     def catchterm(*args):
       
  3046         raise util.SignalInterrupt
       
  3047 
       
  3048     for name in 'SIGBREAK', 'SIGHUP', 'SIGTERM':
       
  3049         num = getattr(signal, name, None)
       
  3050         if num: signal.signal(num, catchterm)
  3156 
  3051 
  3157     try:
  3052     try:
  3158         cmd, func, args, options, cmdoptions = parse(u, args)
  3053         return dispatch(u, args)
  3159         if options["encoding"]:
       
  3160             util._encoding = options["encoding"]
       
  3161         if options["encodingmode"]:
       
  3162             util._encodingmode = options["encodingmode"]
       
  3163         if options["time"]:
       
  3164             def get_times():
       
  3165                 t = os.times()
       
  3166                 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
       
  3167                     t = (t[0], t[1], t[2], t[3], time.clock())
       
  3168                 return t
       
  3169             s = get_times()
       
  3170             def print_time():
       
  3171                 t = get_times()
       
  3172                 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
       
  3173                     (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
       
  3174             atexit.register(print_time)
       
  3175 
       
  3176         # enter the debugger before command execution
       
  3177         if options['debugger']:
       
  3178             pdb.set_trace()
       
  3179 
       
  3180         try:
       
  3181             if options['cwd']:
       
  3182                 os.chdir(options['cwd'])
       
  3183 
       
  3184             u.updateopts(options["verbose"], options["debug"], options["quiet"],
       
  3185                          not options["noninteractive"], options["traceback"],
       
  3186                          parseconfig(options["config"]))
       
  3187 
       
  3188             path = u.expandpath(options["repository"]) or ""
       
  3189             repo = path and hg.repository(u, path=path) or None
       
  3190             if repo and not repo.local():
       
  3191                 raise util.Abort(_("repository '%s' is not local") % path)
       
  3192 
       
  3193             if options['help']:
       
  3194                 return help_(u, cmd, options['version'])
       
  3195             elif options['version']:
       
  3196                 return version_(u)
       
  3197             elif not cmd:
       
  3198                 return help_(u, 'shortlist')
       
  3199 
       
  3200             if cmd not in norepo.split():
       
  3201                 try:
       
  3202                     if not repo:
       
  3203                         repo = hg.repository(u, path=path)
       
  3204                     u = repo.ui
       
  3205                 except hg.RepoError:
       
  3206                     if cmd not in optionalrepo.split():
       
  3207                         raise
       
  3208                 d = lambda: func(u, repo, *args, **cmdoptions)
       
  3209             else:
       
  3210                 d = lambda: func(u, *args, **cmdoptions)
       
  3211 
       
  3212             try:
       
  3213                 if options['profile']:
       
  3214                     import hotshot, hotshot.stats
       
  3215                     prof = hotshot.Profile("hg.prof")
       
  3216                     try:
       
  3217                         try:
       
  3218                             return prof.runcall(d)
       
  3219                         except:
       
  3220                             try:
       
  3221                                 u.warn(_('exception raised - generating '
       
  3222                                          'profile anyway\n'))
       
  3223                             except:
       
  3224                                 pass
       
  3225                             raise
       
  3226                     finally:
       
  3227                         prof.close()
       
  3228                         stats = hotshot.stats.load("hg.prof")
       
  3229                         stats.strip_dirs()
       
  3230                         stats.sort_stats('time', 'calls')
       
  3231                         stats.print_stats(40)
       
  3232                 elif options['lsprof']:
       
  3233                     try:
       
  3234                         from mercurial import lsprof
       
  3235                     except ImportError:
       
  3236                         raise util.Abort(_(
       
  3237                             'lsprof not available - install from '
       
  3238                             'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
       
  3239                     p = lsprof.Profiler()
       
  3240                     p.enable(subcalls=True)
       
  3241                     try:
       
  3242                         return d()
       
  3243                     finally:
       
  3244                         p.disable()
       
  3245                         stats = lsprof.Stats(p.getstats())
       
  3246                         stats.sort()
       
  3247                         stats.pprint(top=10, file=sys.stderr, climit=5)
       
  3248                 else:
       
  3249                     return d()
       
  3250             finally:
       
  3251                 u.flush()
       
  3252         except:
       
  3253             # enter the debugger when we hit an exception
       
  3254             if options['debugger']:
       
  3255                 pdb.post_mortem(sys.exc_info()[2])
       
  3256             u.print_exc()
       
  3257             raise
       
  3258     except ParseError, inst:
       
  3259         if inst.args[0]:
       
  3260             u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
       
  3261             help_(u, inst.args[0])
       
  3262         else:
       
  3263             u.warn(_("hg: %s\n") % inst.args[1])
       
  3264             help_(u, 'shortlist')
       
  3265     except AmbiguousCommand, inst:
       
  3266         u.warn(_("hg: command '%s' is ambiguous:\n    %s\n") %
       
  3267                 (inst.args[0], " ".join(inst.args[1])))
       
  3268     except UnknownCommand, inst:
       
  3269         u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
       
  3270         help_(u, 'shortlist')
       
  3271     except hg.RepoError, inst:
  3054     except hg.RepoError, inst:
  3272         u.warn(_("abort: %s!\n") % inst)
  3055         u.warn(_("abort: %s!\n") % inst)
  3273     except lock.LockHeld, inst:
  3056     except lock.LockHeld, inst:
  3274         if inst.errno == errno.ETIMEDOUT:
  3057         if inst.errno == errno.ETIMEDOUT:
  3275             reason = _('timed out waiting for lock held by %s') % inst.locker
  3058             reason = _('timed out waiting for lock held by %s') % inst.locker
  3348         u.warn(_("** Mercurial Distributed SCM (version %s)\n")
  3131         u.warn(_("** Mercurial Distributed SCM (version %s)\n")
  3349                % version.get_version())
  3132                % version.get_version())
  3350         raise
  3133         raise
  3351 
  3134 
  3352     return -1
  3135     return -1
       
  3136 
       
  3137 def findpossible(ui, cmd):
       
  3138     """
       
  3139     Return cmd -> (aliases, command table entry)
       
  3140     for each matching command.
       
  3141     Return debug commands (or their aliases) only if no normal command matches.
       
  3142     """
       
  3143     choice = {}
       
  3144     debugchoice = {}
       
  3145     for e in table.keys():
       
  3146         aliases = e.lstrip("^").split("|")
       
  3147         found = None
       
  3148         if cmd in aliases:
       
  3149             found = cmd
       
  3150         elif not ui.config("ui", "strict"):
       
  3151             for a in aliases:
       
  3152                 if a.startswith(cmd):
       
  3153                     found = a
       
  3154                     break
       
  3155         if found is not None:
       
  3156             if aliases[0].startswith("debug") or found.startswith("debug"):
       
  3157                 debugchoice[found] = (aliases, table[e])
       
  3158             else:
       
  3159                 choice[found] = (aliases, table[e])
       
  3160 
       
  3161     if not choice and debugchoice:
       
  3162         choice = debugchoice
       
  3163 
       
  3164     return choice
       
  3165 
       
  3166 def findcmd(ui, cmd):
       
  3167     """Return (aliases, command table entry) for command string."""
       
  3168     choice = findpossible(ui, cmd)
       
  3169 
       
  3170     if choice.has_key(cmd):
       
  3171         return choice[cmd]
       
  3172 
       
  3173     if len(choice) > 1:
       
  3174         clist = choice.keys()
       
  3175         clist.sort()
       
  3176         raise AmbiguousCommand(cmd, clist)
       
  3177 
       
  3178     if choice:
       
  3179         return choice.values()[0]
       
  3180 
       
  3181     raise UnknownCommand(cmd)
       
  3182 
       
  3183 class ParseError(Exception):
       
  3184     """Exception raised on errors in parsing the command line."""
       
  3185 
       
  3186 def parse(ui, args):
       
  3187     options = {}
       
  3188     cmdoptions = {}
       
  3189 
       
  3190     try:
       
  3191         args = fancyopts.fancyopts(args, globalopts, options)
       
  3192     except fancyopts.getopt.GetoptError, inst:
       
  3193         raise ParseError(None, inst)
       
  3194 
       
  3195     if args:
       
  3196         cmd, args = args[0], args[1:]
       
  3197         aliases, i = findcmd(ui, cmd)
       
  3198         cmd = aliases[0]
       
  3199         defaults = ui.config("defaults", cmd)
       
  3200         if defaults:
       
  3201             args = shlex.split(defaults) + args
       
  3202         c = list(i[1])
       
  3203     else:
       
  3204         cmd = None
       
  3205         c = []
       
  3206 
       
  3207     # combine global options into local
       
  3208     for o in globalopts:
       
  3209         c.append((o[0], o[1], options[o[1]], o[3]))
       
  3210 
       
  3211     try:
       
  3212         args = fancyopts.fancyopts(args, c, cmdoptions)
       
  3213     except fancyopts.getopt.GetoptError, inst:
       
  3214         raise ParseError(cmd, inst)
       
  3215 
       
  3216     # separate global options back out
       
  3217     for o in globalopts:
       
  3218         n = o[1]
       
  3219         options[n] = cmdoptions[n]
       
  3220         del cmdoptions[n]
       
  3221 
       
  3222     return (cmd, cmd and i[0] or None, args, options, cmdoptions)
       
  3223 
       
  3224 def parseconfig(config):
       
  3225     """parse the --config options from the command line"""
       
  3226     parsed = []
       
  3227     for cfg in config:
       
  3228         try:
       
  3229             name, value = cfg.split('=', 1)
       
  3230             section, name = name.split('.', 1)
       
  3231             if not section or not name:
       
  3232                 raise IndexError
       
  3233             parsed.append((section, name, value))
       
  3234         except (IndexError, ValueError):
       
  3235             raise util.Abort(_('malformed --config option: %s') % cfg)
       
  3236     return parsed
       
  3237 
       
  3238 def dispatch(u, args):
       
  3239     extensions.loadall(u)
       
  3240     u.addreadhook(extensions.loadall)
       
  3241 
       
  3242     try:
       
  3243         cmd, func, args, options, cmdoptions = parse(u, args)
       
  3244         if options["encoding"]:
       
  3245             util._encoding = options["encoding"]
       
  3246         if options["encodingmode"]:
       
  3247             util._encodingmode = options["encodingmode"]
       
  3248         if options["time"]:
       
  3249             def get_times():
       
  3250                 t = os.times()
       
  3251                 if t[4] == 0.0: # Windows leaves this as zero, so use time.clock()
       
  3252                     t = (t[0], t[1], t[2], t[3], time.clock())
       
  3253                 return t
       
  3254             s = get_times()
       
  3255             def print_time():
       
  3256                 t = get_times()
       
  3257                 u.warn(_("Time: real %.3f secs (user %.3f+%.3f sys %.3f+%.3f)\n") %
       
  3258                     (t[4]-s[4], t[0]-s[0], t[2]-s[2], t[1]-s[1], t[3]-s[3]))
       
  3259             atexit.register(print_time)
       
  3260 
       
  3261         # enter the debugger before command execution
       
  3262         if options['debugger']:
       
  3263             pdb.set_trace()
       
  3264 
       
  3265         try:
       
  3266             if options['cwd']:
       
  3267                 os.chdir(options['cwd'])
       
  3268 
       
  3269             u.updateopts(options["verbose"], options["debug"], options["quiet"],
       
  3270                          not options["noninteractive"], options["traceback"],
       
  3271                          parseconfig(options["config"]))
       
  3272 
       
  3273             path = u.expandpath(options["repository"]) or ""
       
  3274             repo = path and hg.repository(u, path=path) or None
       
  3275             if repo and not repo.local():
       
  3276                 raise util.Abort(_("repository '%s' is not local") % path)
       
  3277 
       
  3278             if options['help']:
       
  3279                 return help_(u, cmd, options['version'])
       
  3280             elif options['version']:
       
  3281                 return version_(u)
       
  3282             elif not cmd:
       
  3283                 return help_(u, 'shortlist')
       
  3284 
       
  3285             if cmd not in norepo.split():
       
  3286                 try:
       
  3287                     if not repo:
       
  3288                         repo = hg.repository(u, path=path)
       
  3289                     u = repo.ui
       
  3290                 except hg.RepoError:
       
  3291                     if cmd not in optionalrepo.split():
       
  3292                         raise
       
  3293                 d = lambda: func(u, repo, *args, **cmdoptions)
       
  3294             else:
       
  3295                 d = lambda: func(u, *args, **cmdoptions)
       
  3296 
       
  3297             try:
       
  3298                 if options['profile']:
       
  3299                     import hotshot, hotshot.stats
       
  3300                     prof = hotshot.Profile("hg.prof")
       
  3301                     try:
       
  3302                         try:
       
  3303                             return prof.runcall(d)
       
  3304                         except:
       
  3305                             try:
       
  3306                                 u.warn(_('exception raised - generating '
       
  3307                                          'profile anyway\n'))
       
  3308                             except:
       
  3309                                 pass
       
  3310                             raise
       
  3311                     finally:
       
  3312                         prof.close()
       
  3313                         stats = hotshot.stats.load("hg.prof")
       
  3314                         stats.strip_dirs()
       
  3315                         stats.sort_stats('time', 'calls')
       
  3316                         stats.print_stats(40)
       
  3317                 elif options['lsprof']:
       
  3318                     try:
       
  3319                         from mercurial import lsprof
       
  3320                     except ImportError:
       
  3321                         raise util.Abort(_(
       
  3322                             'lsprof not available - install from '
       
  3323                             'http://codespeak.net/svn/user/arigo/hack/misc/lsprof/'))
       
  3324                     p = lsprof.Profiler()
       
  3325                     p.enable(subcalls=True)
       
  3326                     try:
       
  3327                         return d()
       
  3328                     finally:
       
  3329                         p.disable()
       
  3330                         stats = lsprof.Stats(p.getstats())
       
  3331                         stats.sort()
       
  3332                         stats.pprint(top=10, file=sys.stderr, climit=5)
       
  3333                 else:
       
  3334                     return d()
       
  3335             finally:
       
  3336                 u.flush()
       
  3337         except:
       
  3338             # enter the debugger when we hit an exception
       
  3339             if options['debugger']:
       
  3340                 pdb.post_mortem(sys.exc_info()[2])
       
  3341             u.print_exc()
       
  3342             raise
       
  3343     except ParseError, inst:
       
  3344         if inst.args[0]:
       
  3345             u.warn(_("hg %s: %s\n") % (inst.args[0], inst.args[1]))
       
  3346             help_(u, inst.args[0])
       
  3347         else:
       
  3348             u.warn(_("hg: %s\n") % inst.args[1])
       
  3349             help_(u, 'shortlist')
       
  3350     except AmbiguousCommand, inst:
       
  3351         u.warn(_("hg: command '%s' is ambiguous:\n    %s\n") %
       
  3352                 (inst.args[0], " ".join(inst.args[1])))
       
  3353     except UnknownCommand, inst:
       
  3354         u.warn(_("hg: unknown command '%s'\n") % inst.args[0])
       
  3355         help_(u, 'shortlist')