diff options
Diffstat (limited to 'subcmds/upload.py')
-rw-r--r-- | subcmds/upload.py | 112 |
1 files changed, 63 insertions, 49 deletions
diff --git a/subcmds/upload.py b/subcmds/upload.py index 50dccc52..c48deab6 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py | |||
@@ -13,10 +13,12 @@ | |||
13 | # limitations under the License. | 13 | # limitations under the License. |
14 | 14 | ||
15 | import copy | 15 | import copy |
16 | import functools | ||
17 | import optparse | ||
16 | import re | 18 | import re |
17 | import sys | 19 | import sys |
18 | 20 | ||
19 | from command import InteractiveCommand | 21 | from command import DEFAULT_LOCAL_JOBS, InteractiveCommand |
20 | from editor import Editor | 22 | from editor import Editor |
21 | from error import UploadError | 23 | from error import UploadError |
22 | from git_command import GitCommand | 24 | from git_command import GitCommand |
@@ -53,7 +55,7 @@ def _SplitEmails(values): | |||
53 | 55 | ||
54 | 56 | ||
55 | class Upload(InteractiveCommand): | 57 | class Upload(InteractiveCommand): |
56 | common = True | 58 | COMMON = True |
57 | helpSummary = "Upload changes for code review" | 59 | helpSummary = "Upload changes for code review" |
58 | helpUsage = """ | 60 | helpUsage = """ |
59 | %prog [--re --cc] [<project>]... | 61 | %prog [--re --cc] [<project>]... |
@@ -145,58 +147,66 @@ https://gerrit-review.googlesource.com/Documentation/user-upload.html#notify | |||
145 | Gerrit Code Review: https://www.gerritcodereview.com/ | 147 | Gerrit Code Review: https://www.gerritcodereview.com/ |
146 | 148 | ||
147 | """ | 149 | """ |
150 | PARALLEL_JOBS = DEFAULT_LOCAL_JOBS | ||
148 | 151 | ||
149 | def _Options(self, p): | 152 | def _Options(self, p): |
150 | p.add_option('-t', | 153 | p.add_option('-t', |
151 | dest='auto_topic', action='store_true', | 154 | dest='auto_topic', action='store_true', |
152 | help='Send local branch name to Gerrit Code Review') | 155 | help='send local branch name to Gerrit Code Review') |
153 | p.add_option('--hashtag', '--ht', | 156 | p.add_option('--hashtag', '--ht', |
154 | dest='hashtags', action='append', default=[], | 157 | dest='hashtags', action='append', default=[], |
155 | help='Add hashtags (comma delimited) to the review.') | 158 | help='add hashtags (comma delimited) to the review') |
156 | p.add_option('--hashtag-branch', '--htb', | 159 | p.add_option('--hashtag-branch', '--htb', |
157 | action='store_true', | 160 | action='store_true', |
158 | help='Add local branch name as a hashtag.') | 161 | help='add local branch name as a hashtag') |
159 | p.add_option('-l', '--label', | 162 | p.add_option('-l', '--label', |
160 | dest='labels', action='append', default=[], | 163 | dest='labels', action='append', default=[], |
161 | help='Add a label when uploading.') | 164 | help='add a label when uploading') |
162 | p.add_option('--re', '--reviewers', | 165 | p.add_option('--re', '--reviewers', |
163 | type='string', action='append', dest='reviewers', | 166 | type='string', action='append', dest='reviewers', |
164 | help='Request reviews from these people.') | 167 | help='request reviews from these people') |
165 | p.add_option('--cc', | 168 | p.add_option('--cc', |
166 | type='string', action='append', dest='cc', | 169 | type='string', action='append', dest='cc', |
167 | help='Also send email to these email addresses.') | 170 | help='also send email to these email addresses') |
168 | p.add_option('--br', | 171 | p.add_option('--br', '--branch', |
169 | type='string', action='store', dest='branch', | 172 | type='string', action='store', dest='branch', |
170 | help='Branch to upload.') | 173 | help='(local) branch to upload') |
171 | p.add_option('--cbr', '--current-branch', | 174 | p.add_option('-c', '--current-branch', |
172 | dest='current_branch', action='store_true', | 175 | dest='current_branch', action='store_true', |
173 | help='Upload current git branch.') | 176 | help='upload current git branch') |
177 | p.add_option('--no-current-branch', | ||
178 | dest='current_branch', action='store_false', | ||
179 | help='upload all git branches') | ||
180 | # Turn this into a warning & remove this someday. | ||
181 | p.add_option('--cbr', | ||
182 | dest='current_branch', action='store_true', | ||
183 | help=optparse.SUPPRESS_HELP) | ||
174 | p.add_option('--ne', '--no-emails', | 184 | p.add_option('--ne', '--no-emails', |
175 | action='store_false', dest='notify', default=True, | 185 | action='store_false', dest='notify', default=True, |
176 | help='If specified, do not send emails on upload.') | 186 | help='do not send e-mails on upload') |
177 | p.add_option('-p', '--private', | 187 | p.add_option('-p', '--private', |
178 | action='store_true', dest='private', default=False, | 188 | action='store_true', dest='private', default=False, |
179 | help='If specified, upload as a private change.') | 189 | help='upload as a private change (deprecated; use --wip)') |
180 | p.add_option('-w', '--wip', | 190 | p.add_option('-w', '--wip', |
181 | action='store_true', dest='wip', default=False, | 191 | action='store_true', dest='wip', default=False, |
182 | help='If specified, upload as a work-in-progress change.') | 192 | help='upload as a work-in-progress change') |
183 | p.add_option('-o', '--push-option', | 193 | p.add_option('-o', '--push-option', |
184 | type='string', action='append', dest='push_options', | 194 | type='string', action='append', dest='push_options', |
185 | default=[], | 195 | default=[], |
186 | help='Additional push options to transmit') | 196 | help='additional push options to transmit') |
187 | p.add_option('-D', '--destination', '--dest', | 197 | p.add_option('-D', '--destination', '--dest', |
188 | type='string', action='store', dest='dest_branch', | 198 | type='string', action='store', dest='dest_branch', |
189 | metavar='BRANCH', | 199 | metavar='BRANCH', |
190 | help='Submit for review on this target branch.') | 200 | help='submit for review on this target branch') |
191 | p.add_option('-n', '--dry-run', | 201 | p.add_option('-n', '--dry-run', |
192 | dest='dryrun', default=False, action='store_true', | 202 | dest='dryrun', default=False, action='store_true', |
193 | help='Do everything except actually upload the CL.') | 203 | help='do everything except actually upload the CL') |
194 | p.add_option('-y', '--yes', | 204 | p.add_option('-y', '--yes', |
195 | default=False, action='store_true', | 205 | default=False, action='store_true', |
196 | help='Answer yes to all safe prompts.') | 206 | help='answer yes to all safe prompts') |
197 | p.add_option('--no-cert-checks', | 207 | p.add_option('--no-cert-checks', |
198 | dest='validate_certs', action='store_false', default=True, | 208 | dest='validate_certs', action='store_false', default=True, |
199 | help='Disable verifying ssl certs (unsafe).') | 209 | help='disable verifying ssl certs (unsafe)') |
200 | RepoHook.AddOptionGroup(p, 'pre-upload') | 210 | RepoHook.AddOptionGroup(p, 'pre-upload') |
201 | 211 | ||
202 | def _SingleBranch(self, opt, branch, people): | 212 | def _SingleBranch(self, opt, branch, people): |
@@ -502,40 +512,46 @@ Gerrit Code Review: https://www.gerritcodereview.com/ | |||
502 | merge_branch = p.stdout.strip() | 512 | merge_branch = p.stdout.strip() |
503 | return merge_branch | 513 | return merge_branch |
504 | 514 | ||
515 | @staticmethod | ||
516 | def _GatherOne(opt, project): | ||
517 | """Figure out the upload status for |project|.""" | ||
518 | if opt.current_branch: | ||
519 | cbr = project.CurrentBranch | ||
520 | up_branch = project.GetUploadableBranch(cbr) | ||
521 | avail = [up_branch] if up_branch else None | ||
522 | else: | ||
523 | avail = project.GetUploadableBranches(opt.branch) | ||
524 | return (project, avail) | ||
525 | |||
505 | def Execute(self, opt, args): | 526 | def Execute(self, opt, args): |
506 | project_list = self.GetProjects(args) | 527 | projects = self.GetProjects(args) |
507 | pending = [] | 528 | |
508 | reviewers = [] | 529 | def _ProcessResults(_pool, _out, results): |
509 | cc = [] | 530 | pending = [] |
510 | branch = None | 531 | for result in results: |
511 | 532 | project, avail = result | |
512 | if opt.branch: | 533 | if avail is None: |
513 | branch = opt.branch | 534 | print('repo: error: %s: Unable to upload branch "%s". ' |
514 | |||
515 | for project in project_list: | ||
516 | if opt.current_branch: | ||
517 | cbr = project.CurrentBranch | ||
518 | up_branch = project.GetUploadableBranch(cbr) | ||
519 | if up_branch: | ||
520 | avail = [up_branch] | ||
521 | else: | ||
522 | avail = None | ||
523 | print('repo: error: Unable to upload branch "%s". ' | ||
524 | 'You might be able to fix the branch by running:\n' | 535 | 'You might be able to fix the branch by running:\n' |
525 | ' git branch --set-upstream-to m/%s' % | 536 | ' git branch --set-upstream-to m/%s' % |
526 | (str(cbr), self.manifest.branch), | 537 | (project.relpath, project.CurrentBranch, self.manifest.branch), |
527 | file=sys.stderr) | 538 | file=sys.stderr) |
528 | else: | 539 | elif avail: |
529 | avail = project.GetUploadableBranches(branch) | 540 | pending.append(result) |
530 | if avail: | 541 | return pending |
531 | pending.append((project, avail)) | 542 | |
543 | pending = self.ExecuteInParallel( | ||
544 | opt.jobs, | ||
545 | functools.partial(self._GatherOne, opt), | ||
546 | projects, | ||
547 | callback=_ProcessResults) | ||
532 | 548 | ||
533 | if not pending: | 549 | if not pending: |
534 | if branch is None: | 550 | if opt.branch is None: |
535 | print('repo: error: no branches ready for upload', file=sys.stderr) | 551 | print('repo: error: no branches ready for upload', file=sys.stderr) |
536 | else: | 552 | else: |
537 | print('repo: error: no branches named "%s" ready for upload' % | 553 | print('repo: error: no branches named "%s" ready for upload' % |
538 | (branch,), file=sys.stderr) | 554 | (opt.branch,), file=sys.stderr) |
539 | return 1 | 555 | return 1 |
540 | 556 | ||
541 | pending_proj_names = [project.name for (project, available) in pending] | 557 | pending_proj_names = [project.name for (project, available) in pending] |
@@ -548,10 +564,8 @@ Gerrit Code Review: https://www.gerritcodereview.com/ | |||
548 | worktree_list=pending_worktrees): | 564 | worktree_list=pending_worktrees): |
549 | return 1 | 565 | return 1 |
550 | 566 | ||
551 | if opt.reviewers: | 567 | reviewers = _SplitEmails(opt.reviewers) if opt.reviewers else [] |
552 | reviewers = _SplitEmails(opt.reviewers) | 568 | cc = _SplitEmails(opt.cc) if opt.cc else [] |
553 | if opt.cc: | ||
554 | cc = _SplitEmails(opt.cc) | ||
555 | people = (reviewers, cc) | 569 | people = (reviewers, cc) |
556 | 570 | ||
557 | if len(pending) == 1 and len(pending[0][1]) == 1: | 571 | if len(pending) == 1 and len(pending[0][1]) == 1: |