Show More
@@ -102,6 +102,10 b' globalopts = [' | |||||
102 | _("when to paginate (boolean, always, auto, or never)"), _('TYPE')), |
|
102 | _("when to paginate (boolean, always, auto, or never)"), _('TYPE')), | |
103 | ] |
|
103 | ] | |
104 |
|
104 | |||
|
105 | # options which must be pre-parsed before loading configs and extensions | |||
|
106 | # TODO: perhaps --debugger should be included | |||
|
107 | earlyoptflags = ("--cwd", "-R", "--repository", "--repo", "--config") | |||
|
108 | ||||
105 | dryrunopts = cmdutil.dryrunopts |
|
109 | dryrunopts = cmdutil.dryrunopts | |
106 | remoteopts = cmdutil.remoteopts |
|
110 | remoteopts = cmdutil.remoteopts | |
107 | walkopts = cmdutil.walkopts |
|
111 | walkopts = cmdutil.walkopts |
@@ -264,7 +264,8 b' def _runcatch(req):' | |||||
264 |
|
264 | |||
265 | # read --config before doing anything else |
|
265 | # read --config before doing anything else | |
266 | # (e.g. to change trust settings for reading .hg/hgrc) |
|
266 | # (e.g. to change trust settings for reading .hg/hgrc) | |
267 |
cfgs = _parseconfig(req.ui, |
|
267 | cfgs = _parseconfig(req.ui, | |
|
268 | _earlyreqopt(req, 'config', ['--config'])) | |||
268 |
|
269 | |||
269 | if req.repo: |
|
270 | if req.repo: | |
270 | # copy configs that were passed on the cmdline (--config) to |
|
271 | # copy configs that were passed on the cmdline (--config) to | |
@@ -468,7 +469,7 b' class cmdalias(object):' | |||||
468 | self.cmdname = cmd = args.pop(0) |
|
469 | self.cmdname = cmd = args.pop(0) | |
469 | self.givenargs = args |
|
470 | self.givenargs = args | |
470 |
|
471 | |||
471 | for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"): |
|
472 | for invalidarg in commands.earlyoptflags: | |
472 | if _earlygetopt([invalidarg], args): |
|
473 | if _earlygetopt([invalidarg], args): | |
473 | self.badalias = (_("error in definition for alias '%s': %s may " |
|
474 | self.badalias = (_("error in definition for alias '%s': %s may " | |
474 | "only be given on the command line") |
|
475 | "only be given on the command line") | |
@@ -729,6 +730,18 b' def _earlygetopt(aliases, args, strip=Tr' | |||||
729 | pos += 1 |
|
730 | pos += 1 | |
730 | return values |
|
731 | return values | |
731 |
|
732 | |||
|
733 | def _earlyreqopt(req, name, aliases): | |||
|
734 | """Peek a list option without using a full options table""" | |||
|
735 | values = _earlygetopt(aliases, req.args, strip=False) | |||
|
736 | req.earlyoptions[name] = values | |||
|
737 | return values | |||
|
738 | ||||
|
739 | def _earlyreqoptstr(req, name, aliases): | |||
|
740 | """Peek a string option without using a full options table""" | |||
|
741 | value = (_earlygetopt(aliases, req.args, strip=False) or [''])[-1] | |||
|
742 | req.earlyoptions[name] = value | |||
|
743 | return value | |||
|
744 | ||||
732 | def _earlyreqoptbool(req, name, aliases): |
|
745 | def _earlyreqoptbool(req, name, aliases): | |
733 | """Peek a boolean option without using a full options table |
|
746 | """Peek a boolean option without using a full options table | |
734 |
|
747 | |||
@@ -819,6 +832,9 b' def _checkshellalias(lui, ui, args):' | |||||
819 | fn = entry[0] |
|
832 | fn = entry[0] | |
820 |
|
833 | |||
821 | if cmd and util.safehasattr(fn, 'shell'): |
|
834 | if cmd and util.safehasattr(fn, 'shell'): | |
|
835 | # shell alias shouldn't receive early options which are consumed by hg | |||
|
836 | args = args[:] | |||
|
837 | _earlygetopt(commands.earlyoptflags, args, strip=True) | |||
822 | d = lambda: fn(ui, *args[1:]) |
|
838 | d = lambda: fn(ui, *args[1:]) | |
823 | return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, |
|
839 | return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, | |
824 | [], {}) |
|
840 | [], {}) | |
@@ -828,13 +844,11 b' def _dispatch(req):' | |||||
828 | ui = req.ui |
|
844 | ui = req.ui | |
829 |
|
845 | |||
830 | # check for cwd |
|
846 | # check for cwd | |
831 |
cwd = _early |
|
847 | cwd = _earlyreqoptstr(req, 'cwd', ['--cwd']) | |
832 | cwd = cwd and cwd[-1] or '' |
|
|||
833 | if cwd: |
|
848 | if cwd: | |
834 | os.chdir(cwd) |
|
849 | os.chdir(cwd) | |
835 |
|
850 | |||
836 |
rpath = _early |
|
851 | rpath = _earlyreqoptstr(req, 'repository', ["-R", "--repository", "--repo"]) | |
837 | rpath = rpath and rpath[-1] or '' |
|
|||
838 | path, lui = _getlocal(ui, rpath) |
|
852 | path, lui = _getlocal(ui, rpath) | |
839 |
|
853 | |||
840 | uis = {ui, lui} |
|
854 | uis = {ui, lui} | |
@@ -874,11 +888,11 b' def _dispatch(req):' | |||||
874 | fullargs = args |
|
888 | fullargs = args | |
875 | cmd, func, args, options, cmdoptions = _parse(lui, args) |
|
889 | cmd, func, args, options, cmdoptions = _parse(lui, args) | |
876 |
|
890 | |||
877 | if options["config"]: |
|
891 | if options["config"] != req.earlyoptions["config"]: | |
878 | raise error.Abort(_("option --config may not be abbreviated!")) |
|
892 | raise error.Abort(_("option --config may not be abbreviated!")) | |
879 | if options["cwd"]: |
|
893 | if options["cwd"] != req.earlyoptions["cwd"]: | |
880 | raise error.Abort(_("option --cwd may not be abbreviated!")) |
|
894 | raise error.Abort(_("option --cwd may not be abbreviated!")) | |
881 | if options["repository"]: |
|
895 | if options["repository"] != req.earlyoptions["repository"]: | |
882 | raise error.Abort(_( |
|
896 | raise error.Abort(_( | |
883 | "option -R has to be separated from other options (e.g. not " |
|
897 | "option -R has to be separated from other options (e.g. not " | |
884 | "-qR) and --repository may only be abbreviated as --repo!")) |
|
898 | "-qR) and --repository may only be abbreviated as --repo!")) |
@@ -19,7 +19,7 b' command, exit codes, and duration' | |||||
19 | 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest exited 0 after * seconds (glob) |
|
19 | 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest exited 0 after * seconds (glob) | |
20 | 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a |
|
20 | 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a | |
21 | 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a exited 0 after * seconds (glob) |
|
21 | 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a exited 0 after * seconds (glob) | |
22 | 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000+ (5000)> blackbox |
|
22 | 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000+ (5000)> blackbox --config *blackbox.dirty=True* (glob) | |
23 |
|
23 | |||
24 | alias expansion is logged |
|
24 | alias expansion is logged | |
25 | $ rm ./.hg/blackbox.log |
|
25 | $ rm ./.hg/blackbox.log |
@@ -57,6 +57,62 b' Unparsable form of early options:' | |||||
57 | abort: option --debugger may not be abbreviated! |
|
57 | abort: option --debugger may not be abbreviated! | |
58 | [255] |
|
58 | [255] | |
59 |
|
59 | |||
|
60 | Parsing failure of early options should be detected before executing the | |||
|
61 | command: | |||
|
62 | ||||
|
63 | $ hg log -b '--config=hooks.pre-log=false' default | |||
|
64 | abort: option --config may not be abbreviated! | |||
|
65 | [255] | |||
|
66 | $ hg log -b -R. default | |||
|
67 | abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo! | |||
|
68 | [255] | |||
|
69 | $ hg log --cwd .. -b --cwd=. default | |||
|
70 | abort: option --cwd may not be abbreviated! | |||
|
71 | [255] | |||
|
72 | ||||
|
73 | However, we can't prevent it from loading extensions and configs: | |||
|
74 | ||||
|
75 | $ cat <<EOF > bad.py | |||
|
76 | > raise Exception('bad') | |||
|
77 | > EOF | |||
|
78 | $ hg log -b '--config=extensions.bad=bad.py' default | |||
|
79 | *** failed to import extension bad from bad.py: bad | |||
|
80 | abort: option --config may not be abbreviated! | |||
|
81 | [255] | |||
|
82 | ||||
|
83 | $ mkdir -p badrepo/.hg | |||
|
84 | $ echo 'invalid-syntax' > badrepo/.hg/hgrc | |||
|
85 | $ hg log -b -Rbadrepo default | |||
|
86 | hg: parse error at badrepo/.hg/hgrc:1: invalid-syntax | |||
|
87 | [255] | |||
|
88 | ||||
|
89 | $ hg log -b --cwd=inexistent default | |||
|
90 | abort: No such file or directory: 'inexistent' | |||
|
91 | [255] | |||
|
92 | ||||
|
93 | $ hg log -b '--config=ui.traceback=yes' 2>&1 | grep '^Traceback' | |||
|
94 | Traceback (most recent call last): | |||
|
95 | $ hg log -b '--config=profiling.enabled=yes' 2>&1 | grep -i sample | |||
|
96 | Sample count: .*|No samples recorded\. (re) | |||
|
97 | ||||
|
98 | Early options can't be specified in [aliases] and [defaults] because they are | |||
|
99 | applied before the command name is resolved: | |||
|
100 | ||||
|
101 | $ hg log -b '--config=alias.log=log --config=hooks.pre-log=false' | |||
|
102 | hg log: option -b not recognized | |||
|
103 | error in definition for alias 'log': --config may only be given on the command | |||
|
104 | line | |||
|
105 | [255] | |||
|
106 | ||||
|
107 | $ hg log -b '--config=defaults.log=--config=hooks.pre-log=false' | |||
|
108 | abort: option --config may not be abbreviated! | |||
|
109 | [255] | |||
|
110 | ||||
|
111 | Shell aliases bypass any command parsing rules but for the early one: | |||
|
112 | ||||
|
113 | $ hg log -b '--config=alias.log=!echo howdy' | |||
|
114 | howdy | |||
|
115 | ||||
60 | [defaults] |
|
116 | [defaults] | |
61 |
|
117 | |||
62 | $ hg cat a |
|
118 | $ hg cat a |
@@ -61,7 +61,7 b' A deleted subrepo file is flagged as dir' | |||||
61 | 9bfe45a197d7+ tip |
|
61 | 9bfe45a197d7+ tip | |
62 | $ cat .hg/blackbox.log |
|
62 | $ cat .hg/blackbox.log | |
63 | * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> serve --cmdserver chgunix * (glob) (chg !) |
|
63 | * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> serve --cmdserver chgunix * (glob) (chg !) | |
64 | * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> id (glob) |
|
64 | * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> id --config *extensions.blackbox=* --config *blackbox.dirty=True* (glob) | |
65 | * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> id --config *extensions.blackbox=* --config *blackbox.dirty=True* exited 0 * (glob) |
|
65 | * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> id --config *extensions.blackbox=* --config *blackbox.dirty=True* exited 0 * (glob) | |
66 |
|
66 | |||
67 | TODO: a deleted file should be listed as such, like the top level repo |
|
67 | TODO: a deleted file should be listed as such, like the top level repo |
@@ -406,8 +406,8 b' fixed in 86c35b7ae300:' | |||||
406 | 101 102 103 104 105 106 107 108 109 110 (no-eol) |
|
406 | 101 102 103 104 105 106 107 108 109 110 (no-eol) | |
407 | $ hg -R r1 --config extensions.blackbox= blackbox |
|
407 | $ hg -R r1 --config extensions.blackbox= blackbox | |
408 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> serve --cmdserver chgunix * (glob) (chg !) |
|
408 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> serve --cmdserver chgunix * (glob) (chg !) | |
409 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> outgoing r2 *-T{rev} * (glob) |
|
409 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* (glob) | |
410 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> found 101 common and 1 unknown server heads, 2 roundtrips in *.????s (glob) |
|
410 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> found 101 common and 1 unknown server heads, 2 roundtrips in *.????s (glob) | |
411 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* exited 0 after *.?? seconds (glob) |
|
411 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* exited 0 after *.?? seconds (glob) | |
412 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> blackbox (glob) |
|
412 | * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 --config *extensions.blackbox=* blackbox (glob) | |
413 | $ cd .. |
|
413 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now