diff options
-rw-r--r-- | command.py | 10 | ||||
-rwxr-xr-x | main.py | 1 | ||||
-rw-r--r-- | subcmds/abandon.py | 10 | ||||
-rw-r--r-- | subcmds/checkout.py | 3 | ||||
-rw-r--r-- | subcmds/cherry_pick.py | 3 | ||||
-rw-r--r-- | subcmds/diffmanifests.py | 5 | ||||
-rw-r--r-- | subcmds/forall.py | 3 | ||||
-rw-r--r-- | subcmds/init.py | 11 | ||||
-rw-r--r-- | subcmds/list.py | 9 | ||||
-rw-r--r-- | subcmds/manifest.py | 11 | ||||
-rw-r--r-- | subcmds/start.py | 7 | ||||
-rw-r--r-- | subcmds/sync.py | 34 |
12 files changed, 55 insertions, 52 deletions
@@ -98,6 +98,16 @@ class Command(object): | |||
98 | self.OptionParser.print_usage() | 98 | self.OptionParser.print_usage() |
99 | sys.exit(1) | 99 | sys.exit(1) |
100 | 100 | ||
101 | def ValidateOptions(self, opt, args): | ||
102 | """Validate the user options & arguments before executing. | ||
103 | |||
104 | This is meant to help break the code up into logical steps. Some tips: | ||
105 | * Use self.OptionParser.error to display CLI related errors. | ||
106 | * Adjust opt member defaults as makes sense. | ||
107 | * Adjust the args list, but do so inplace so the caller sees updates. | ||
108 | * Try to avoid updating self state. Leave that to Execute. | ||
109 | """ | ||
110 | |||
101 | def Execute(self, opt, args): | 111 | def Execute(self, opt, args): |
102 | """Perform the action, after option parsing is complete. | 112 | """Perform the action, after option parsing is complete. |
103 | """ | 113 | """ |
@@ -197,6 +197,7 @@ class _Repo(object): | |||
197 | cmd_event = cmd.event_log.Add(name, event_log.TASK_COMMAND, start) | 197 | cmd_event = cmd.event_log.Add(name, event_log.TASK_COMMAND, start) |
198 | cmd.event_log.SetParent(cmd_event) | 198 | cmd.event_log.SetParent(cmd_event) |
199 | try: | 199 | try: |
200 | cmd.ValidateOptions(copts, cargs) | ||
200 | result = cmd.Execute(copts, cargs) | 201 | result = cmd.Execute(copts, cargs) |
201 | except (DownloadError, ManifestInvalidRevisionError, | 202 | except (DownloadError, ManifestInvalidRevisionError, |
202 | NoManifestException) as e: | 203 | NoManifestException) as e: |
diff --git a/subcmds/abandon.py b/subcmds/abandon.py index 319262bd..cd1d0c40 100644 --- a/subcmds/abandon.py +++ b/subcmds/abandon.py | |||
@@ -37,19 +37,19 @@ It is equivalent to "git branch -D <branchname>". | |||
37 | dest='all', action='store_true', | 37 | dest='all', action='store_true', |
38 | help='delete all branches in all projects') | 38 | help='delete all branches in all projects') |
39 | 39 | ||
40 | def Execute(self, opt, args): | 40 | def ValidateOptions(self, opt, args): |
41 | if not opt.all and not args: | 41 | if not opt.all and not args: |
42 | self.Usage() | 42 | self.Usage() |
43 | 43 | ||
44 | if not opt.all: | 44 | if not opt.all: |
45 | nb = args[0] | 45 | nb = args[0] |
46 | if not git.check_ref_format('heads/%s' % nb): | 46 | if not git.check_ref_format('heads/%s' % nb): |
47 | print("error: '%s' is not a valid name" % nb, file=sys.stderr) | 47 | self.OptionParser.error("'%s' is not a valid branch name" % nb) |
48 | sys.exit(1) | ||
49 | else: | 48 | else: |
50 | args.insert(0,None) | 49 | args.insert(0, "'All local branches'") |
51 | nb = "'All local branches'" | ||
52 | 50 | ||
51 | def Execute(self, opt, args): | ||
52 | nb = args[0] | ||
53 | err = defaultdict(list) | 53 | err = defaultdict(list) |
54 | success = defaultdict(list) | 54 | success = defaultdict(list) |
55 | all_projects = self.GetProjects(args[1:]) | 55 | all_projects = self.GetProjects(args[1:]) |
diff --git a/subcmds/checkout.py b/subcmds/checkout.py index 51ac4833..c8a09a8e 100644 --- a/subcmds/checkout.py +++ b/subcmds/checkout.py | |||
@@ -34,10 +34,11 @@ The command is equivalent to: | |||
34 | repo forall [<project>...] -c git checkout <branchname> | 34 | repo forall [<project>...] -c git checkout <branchname> |
35 | """ | 35 | """ |
36 | 36 | ||
37 | def Execute(self, opt, args): | 37 | def ValidateOptions(self, opt, args): |
38 | if not args: | 38 | if not args: |
39 | self.Usage() | 39 | self.Usage() |
40 | 40 | ||
41 | def Execute(self, opt, args): | ||
41 | nb = args[0] | 42 | nb = args[0] |
42 | err = [] | 43 | err = [] |
43 | success = [] | 44 | success = [] |
diff --git a/subcmds/cherry_pick.py b/subcmds/cherry_pick.py index 43215f91..a541a040 100644 --- a/subcmds/cherry_pick.py +++ b/subcmds/cherry_pick.py | |||
@@ -37,10 +37,11 @@ change id will be added. | |||
37 | def _Options(self, p): | 37 | def _Options(self, p): |
38 | pass | 38 | pass |
39 | 39 | ||
40 | def Execute(self, opt, args): | 40 | def ValidateOptions(self, opt, args): |
41 | if len(args) != 1: | 41 | if len(args) != 1: |
42 | self.Usage() | 42 | self.Usage() |
43 | 43 | ||
44 | def Execute(self, opt, args): | ||
44 | reference = args[0] | 45 | reference = args[0] |
45 | 46 | ||
46 | p = GitCommand(None, | 47 | p = GitCommand(None, |
diff --git a/subcmds/diffmanifests.py b/subcmds/diffmanifests.py index cae776a7..b999699e 100644 --- a/subcmds/diffmanifests.py +++ b/subcmds/diffmanifests.py | |||
@@ -176,10 +176,11 @@ synced and their revisions won't be found. | |||
176 | self.printText(log) | 176 | self.printText(log) |
177 | self.out.nl() | 177 | self.out.nl() |
178 | 178 | ||
179 | def Execute(self, opt, args): | 179 | def ValidateOptions(self, opt, args): |
180 | if not args or len(args) > 2: | 180 | if not args or len(args) > 2: |
181 | self.Usage() | 181 | self.OptionParser.error('missing manifests to diff') |
182 | 182 | ||
183 | def Execute(self, opt, args): | ||
183 | self.out = _Coloring(self.manifest.globalConfig) | 184 | self.out = _Coloring(self.manifest.globalConfig) |
184 | self.printText = self.out.nofmt_printer('text') | 185 | self.printText = self.out.nofmt_printer('text') |
185 | if opt.color: | 186 | if opt.color: |
diff --git a/subcmds/forall.py b/subcmds/forall.py index 3e6007ba..0be8d3bc 100644 --- a/subcmds/forall.py +++ b/subcmds/forall.py | |||
@@ -177,10 +177,11 @@ without iterating through the remaining projects. | |||
177 | 'worktree': project.worktree, | 177 | 'worktree': project.worktree, |
178 | } | 178 | } |
179 | 179 | ||
180 | def Execute(self, opt, args): | 180 | def ValidateOptions(self, opt, args): |
181 | if not opt.command: | 181 | if not opt.command: |
182 | self.Usage() | 182 | self.Usage() |
183 | 183 | ||
184 | def Execute(self, opt, args): | ||
184 | cmd = [opt.command[0]] | 185 | cmd = [opt.command[0]] |
185 | 186 | ||
186 | shell = True | 187 | shell = True |
diff --git a/subcmds/init.py b/subcmds/init.py index eaa6da50..32663a04 100644 --- a/subcmds/init.py +++ b/subcmds/init.py | |||
@@ -436,18 +436,17 @@ to update the working directory files. | |||
436 | print(' rm -r %s/.repo' % self.manifest.topdir) | 436 | print(' rm -r %s/.repo' % self.manifest.topdir) |
437 | print('and try again.') | 437 | print('and try again.') |
438 | 438 | ||
439 | def Execute(self, opt, args): | 439 | def ValidateOptions(self, opt, args): |
440 | git_require(MIN_GIT_VERSION, fail=True) | ||
441 | |||
442 | if opt.reference: | 440 | if opt.reference: |
443 | opt.reference = os.path.expanduser(opt.reference) | 441 | opt.reference = os.path.expanduser(opt.reference) |
444 | 442 | ||
445 | # Check this here, else manifest will be tagged "not new" and init won't be | 443 | # Check this here, else manifest will be tagged "not new" and init won't be |
446 | # possible anymore without removing the .repo/manifests directory. | 444 | # possible anymore without removing the .repo/manifests directory. |
447 | if opt.archive and opt.mirror: | 445 | if opt.archive and opt.mirror: |
448 | print('fatal: --mirror and --archive cannot be used together.', | 446 | self.OptionParser.error('--mirror and --archive cannot be used together.') |
449 | file=sys.stderr) | 447 | |
450 | sys.exit(1) | 448 | def Execute(self, opt, args): |
449 | git_require(MIN_GIT_VERSION, fail=True) | ||
451 | 450 | ||
452 | self._SyncManifest(opt) | 451 | self._SyncManifest(opt) |
453 | self._LinkManifest(opt.manifest_name) | 452 | self._LinkManifest(opt.manifest_name) |
diff --git a/subcmds/list.py b/subcmds/list.py index 961b1956..00172f0e 100644 --- a/subcmds/list.py +++ b/subcmds/list.py | |||
@@ -49,6 +49,10 @@ This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'. | |||
49 | dest='path_only', action='store_true', | 49 | dest='path_only', action='store_true', |
50 | help="Display only the path of the repository") | 50 | help="Display only the path of the repository") |
51 | 51 | ||
52 | def ValidateOptions(self, opt, args): | ||
53 | if opt.fullpath and opt.name_only: | ||
54 | self.OptionParser.error('cannot combine -f and -n') | ||
55 | |||
52 | def Execute(self, opt, args): | 56 | def Execute(self, opt, args): |
53 | """List all projects and the associated directories. | 57 | """List all projects and the associated directories. |
54 | 58 | ||
@@ -60,11 +64,6 @@ This is similar to running: repo forall -c 'echo "$REPO_PATH : $REPO_PROJECT"'. | |||
60 | opt: The options. | 64 | opt: The options. |
61 | args: Positional args. Can be a list of projects to list, or empty. | 65 | args: Positional args. Can be a list of projects to list, or empty. |
62 | """ | 66 | """ |
63 | |||
64 | if opt.fullpath and opt.name_only: | ||
65 | print('error: cannot combine -f and -n', file=sys.stderr) | ||
66 | sys.exit(1) | ||
67 | |||
68 | if not opt.regex: | 67 | if not opt.regex: |
69 | projects = self.GetProjects(args, groups=opt.groups) | 68 | projects = self.GetProjects(args, groups=opt.groups) |
70 | else: | 69 | else: |
diff --git a/subcmds/manifest.py b/subcmds/manifest.py index 07fa323a..768f072e 100644 --- a/subcmds/manifest.py +++ b/subcmds/manifest.py | |||
@@ -73,14 +73,9 @@ in a Git repository for use during future 'repo init' invocations. | |||
73 | if opt.output_file != '-': | 73 | if opt.output_file != '-': |
74 | print('Saved manifest to %s' % opt.output_file, file=sys.stderr) | 74 | print('Saved manifest to %s' % opt.output_file, file=sys.stderr) |
75 | 75 | ||
76 | def Execute(self, opt, args): | 76 | def ValidateOptions(self, opt, args): |
77 | if args: | 77 | if args: |
78 | self.Usage() | 78 | self.Usage() |
79 | 79 | ||
80 | if opt.output_file is not None: | 80 | def Execute(self, opt, args): |
81 | self._Output(opt) | 81 | self._Output(opt) |
82 | return | ||
83 | |||
84 | print('error: no operation to perform', file=sys.stderr) | ||
85 | print('error: see repo help manifest', file=sys.stderr) | ||
86 | sys.exit(1) | ||
diff --git a/subcmds/start.py b/subcmds/start.py index 0c60d78c..5d4c9c01 100644 --- a/subcmds/start.py +++ b/subcmds/start.py | |||
@@ -41,15 +41,16 @@ revision specified in the manifest. | |||
41 | dest='all', action='store_true', | 41 | dest='all', action='store_true', |
42 | help='begin branch in all projects') | 42 | help='begin branch in all projects') |
43 | 43 | ||
44 | def Execute(self, opt, args): | 44 | def ValidateOptions(self, opt, args): |
45 | if not args: | 45 | if not args: |
46 | self.Usage() | 46 | self.Usage() |
47 | 47 | ||
48 | nb = args[0] | 48 | nb = args[0] |
49 | if not git.check_ref_format('heads/%s' % nb): | 49 | if not git.check_ref_format('heads/%s' % nb): |
50 | print("error: '%s' is not a valid name" % nb, file=sys.stderr) | 50 | self.OptionParser.error("'%s' is not a valid name" % nb) |
51 | sys.exit(1) | ||
52 | 51 | ||
52 | def Execute(self, opt, args): | ||
53 | nb = args[0] | ||
53 | err = [] | 54 | err = [] |
54 | projects = [] | 55 | projects = [] |
55 | if not opt.all: | 56 | if not opt.all: |
diff --git a/subcmds/sync.py b/subcmds/sync.py index 3eab2fcf..5655a1e6 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py | |||
@@ -738,36 +738,30 @@ later is required to fix a server side protocol bug. | |||
738 | fd.close() | 738 | fd.close() |
739 | return 0 | 739 | return 0 |
740 | 740 | ||
741 | def Execute(self, opt, args): | 741 | def ValidateOptions(self, opt, args): |
742 | if opt.jobs: | ||
743 | self.jobs = opt.jobs | ||
744 | if self.jobs > 1: | ||
745 | soft_limit, _ = _rlimit_nofile() | ||
746 | self.jobs = min(self.jobs, (soft_limit - 5) // 3) | ||
747 | |||
748 | if opt.force_broken: | 742 | if opt.force_broken: |
749 | print('warning: -f/--force-broken is now the default behavior, and the ' | 743 | print('warning: -f/--force-broken is now the default behavior, and the ' |
750 | 'options are deprecated', file=sys.stderr) | 744 | 'options are deprecated', file=sys.stderr) |
751 | if opt.network_only and opt.detach_head: | 745 | if opt.network_only and opt.detach_head: |
752 | print('error: cannot combine -n and -d', file=sys.stderr) | 746 | self.OptionParser.error('cannot combine -n and -d') |
753 | sys.exit(1) | ||
754 | if opt.network_only and opt.local_only: | 747 | if opt.network_only and opt.local_only: |
755 | print('error: cannot combine -n and -l', file=sys.stderr) | 748 | self.OptionParser.error('cannot combine -n and -l') |
756 | sys.exit(1) | ||
757 | if opt.manifest_name and opt.smart_sync: | 749 | if opt.manifest_name and opt.smart_sync: |
758 | print('error: cannot combine -m and -s', file=sys.stderr) | 750 | self.OptionParser.error('cannot combine -m and -s') |
759 | sys.exit(1) | ||
760 | if opt.manifest_name and opt.smart_tag: | 751 | if opt.manifest_name and opt.smart_tag: |
761 | print('error: cannot combine -m and -t', file=sys.stderr) | 752 | self.OptionParser.error('cannot combine -m and -t') |
762 | sys.exit(1) | ||
763 | if opt.manifest_server_username or opt.manifest_server_password: | 753 | if opt.manifest_server_username or opt.manifest_server_password: |
764 | if not (opt.smart_sync or opt.smart_tag): | 754 | if not (opt.smart_sync or opt.smart_tag): |
765 | print('error: -u and -p may only be combined with -s or -t', | 755 | self.OptionParser.error('-u and -p may only be combined with -s or -t') |
766 | file=sys.stderr) | ||
767 | sys.exit(1) | ||
768 | if None in [opt.manifest_server_username, opt.manifest_server_password]: | 756 | if None in [opt.manifest_server_username, opt.manifest_server_password]: |
769 | print('error: both -u and -p must be given', file=sys.stderr) | 757 | self.OptionParser.error('both -u and -p must be given') |
770 | sys.exit(1) | 758 | |
759 | def Execute(self, opt, args): | ||
760 | if opt.jobs: | ||
761 | self.jobs = opt.jobs | ||
762 | if self.jobs > 1: | ||
763 | soft_limit, _ = _rlimit_nofile() | ||
764 | self.jobs = min(self.jobs, (soft_limit - 5) // 3) | ||
771 | 765 | ||
772 | if opt.manifest_name: | 766 | if opt.manifest_name: |
773 | self.manifest.Override(opt.manifest_name) | 767 | self.manifest.Override(opt.manifest_name) |