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') |