diff options
Diffstat (limited to 'subcmds/upload.py')
| -rw-r--r-- | subcmds/upload.py | 96 |
1 files changed, 83 insertions, 13 deletions
diff --git a/subcmds/upload.py b/subcmds/upload.py index 20822096..c9312973 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py | |||
| @@ -19,7 +19,8 @@ import sys | |||
| 19 | 19 | ||
| 20 | from command import InteractiveCommand | 20 | from command import InteractiveCommand |
| 21 | from editor import Editor | 21 | from editor import Editor |
| 22 | from error import UploadError | 22 | from error import HookError, UploadError |
| 23 | from project import RepoHook | ||
| 23 | 24 | ||
| 24 | UNUSUAL_COMMIT_THRESHOLD = 5 | 25 | UNUSUAL_COMMIT_THRESHOLD = 5 |
| 25 | 26 | ||
| @@ -72,7 +73,7 @@ Configuration | |||
| 72 | 73 | ||
| 73 | review.URL.autoupload: | 74 | review.URL.autoupload: |
| 74 | 75 | ||
| 75 | To disable the "Upload ... (y/n)?" prompt, you can set a per-project | 76 | To disable the "Upload ... (y/N)?" prompt, you can set a per-project |
| 76 | or global Git configuration option. If review.URL.autoupload is set | 77 | or global Git configuration option. If review.URL.autoupload is set |
| 77 | to "true" then repo will assume you always answer "y" at the prompt, | 78 | to "true" then repo will assume you always answer "y" at the prompt, |
| 78 | and will not prompt you further. If it is set to "false" then repo | 79 | and will not prompt you further. If it is set to "false" then repo |
| @@ -102,6 +103,14 @@ or in the .git/config within the project. For example: | |||
| 102 | autoupload = true | 103 | autoupload = true |
| 103 | autocopy = johndoe@company.com,my-team-alias@company.com | 104 | autocopy = johndoe@company.com,my-team-alias@company.com |
| 104 | 105 | ||
| 106 | review.URL.uploadtopic: | ||
| 107 | |||
| 108 | To add a topic branch whenever uploading a commit, you can set a | ||
| 109 | per-project or global Git option to do so. If review.URL.uploadtopic | ||
| 110 | is set to "true" then repo will assume you always want the equivalent | ||
| 111 | of the -t option to the repo command. If unset or set to "false" then | ||
| 112 | repo will make use of only the command line option. | ||
| 113 | |||
| 105 | References | 114 | References |
| 106 | ---------- | 115 | ---------- |
| 107 | 116 | ||
| @@ -119,6 +128,38 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 119 | p.add_option('--cc', | 128 | p.add_option('--cc', |
| 120 | type='string', action='append', dest='cc', | 129 | type='string', action='append', dest='cc', |
| 121 | help='Also send email to these email addresses.') | 130 | help='Also send email to these email addresses.') |
| 131 | p.add_option('--br', | ||
| 132 | type='string', action='store', dest='branch', | ||
| 133 | help='Branch to upload.') | ||
| 134 | p.add_option('--cbr', '--current-branch', | ||
| 135 | dest='current_branch', action='store_true', | ||
| 136 | help='Upload current git branch.') | ||
| 137 | p.add_option('-d', '--draft', | ||
| 138 | action='store_true', dest='draft', default=False, | ||
| 139 | help='If specified, upload as a draft.') | ||
| 140 | |||
| 141 | # Options relating to upload hook. Note that verify and no-verify are NOT | ||
| 142 | # opposites of each other, which is why they store to different locations. | ||
| 143 | # We are using them to match 'git commit' syntax. | ||
| 144 | # | ||
| 145 | # Combinations: | ||
| 146 | # - no-verify=False, verify=False (DEFAULT): | ||
| 147 | # If stdout is a tty, can prompt about running upload hooks if needed. | ||
| 148 | # If user denies running hooks, the upload is cancelled. If stdout is | ||
| 149 | # not a tty and we would need to prompt about upload hooks, upload is | ||
| 150 | # cancelled. | ||
| 151 | # - no-verify=False, verify=True: | ||
| 152 | # Always run upload hooks with no prompt. | ||
| 153 | # - no-verify=True, verify=False: | ||
| 154 | # Never run upload hooks, but upload anyway (AKA bypass hooks). | ||
| 155 | # - no-verify=True, verify=True: | ||
| 156 | # Invalid | ||
| 157 | p.add_option('--no-verify', | ||
| 158 | dest='bypass_hooks', action='store_true', | ||
| 159 | help='Do not run the upload hook.') | ||
| 160 | p.add_option('--verify', | ||
| 161 | dest='allow_all_hooks', action='store_true', | ||
| 162 | help='Run the upload hook without prompting.') | ||
| 122 | 163 | ||
| 123 | def _SingleBranch(self, opt, branch, people): | 164 | def _SingleBranch(self, opt, branch, people): |
| 124 | project = branch.project | 165 | project = branch.project |
| @@ -135,7 +176,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 135 | date = branch.date | 176 | date = branch.date |
| 136 | list = branch.commits | 177 | list = branch.commits |
| 137 | 178 | ||
| 138 | print 'Upload project %s/:' % project.relpath | 179 | print 'Upload project %s/ to remote branch %s:' % (project.relpath, project.revisionExpr) |
| 139 | print ' branch %s (%2d commit%s, %s):' % ( | 180 | print ' branch %s (%2d commit%s, %s):' % ( |
| 140 | name, | 181 | name, |
| 141 | len(list), | 182 | len(list), |
| @@ -144,7 +185,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 144 | for commit in list: | 185 | for commit in list: |
| 145 | print ' %s' % commit | 186 | print ' %s' % commit |
| 146 | 187 | ||
| 147 | sys.stdout.write('to %s (y/n)? ' % remote.review) | 188 | sys.stdout.write('to %s (y/N)? ' % remote.review) |
| 148 | answer = sys.stdin.readline().strip() | 189 | answer = sys.stdin.readline().strip() |
| 149 | answer = answer in ('y', 'Y', 'yes', '1', 'true', 't') | 190 | answer = answer in ('y', 'Y', 'yes', '1', 'true', 't') |
| 150 | 191 | ||
| @@ -175,11 +216,12 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 175 | 216 | ||
| 176 | if b: | 217 | if b: |
| 177 | script.append('#') | 218 | script.append('#') |
| 178 | script.append('# branch %s (%2d commit%s, %s):' % ( | 219 | script.append('# branch %s (%2d commit%s, %s) to remote branch %s:' % ( |
| 179 | name, | 220 | name, |
| 180 | len(list), | 221 | len(list), |
| 181 | len(list) != 1 and 's' or '', | 222 | len(list) != 1 and 's' or '', |
| 182 | date)) | 223 | date, |
| 224 | project.revisionExpr)) | ||
| 183 | for commit in list: | 225 | for commit in list: |
| 184 | script.append('# %s' % commit) | 226 | script.append('# %s' % commit) |
| 185 | b[name] = branch | 227 | b[name] = branch |
| @@ -188,6 +230,11 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 188 | branches[project.name] = b | 230 | branches[project.name] = b |
| 189 | script.append('') | 231 | script.append('') |
| 190 | 232 | ||
| 233 | script = [ x.encode('utf-8') | ||
| 234 | if issubclass(type(x), unicode) | ||
| 235 | else x | ||
| 236 | for x in script ] | ||
| 237 | |||
| 191 | script = Editor.EditString("\n".join(script)).split("\n") | 238 | script = Editor.EditString("\n".join(script)).split("\n") |
| 192 | 239 | ||
| 193 | project_re = re.compile(r'^#?\s*project\s*([^\s]+)/:$') | 240 | project_re = re.compile(r'^#?\s*project\s*([^\s]+)/:$') |
| @@ -267,7 +314,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 267 | 314 | ||
| 268 | # if they want to auto upload, let's not ask because it could be automated | 315 | # if they want to auto upload, let's not ask because it could be automated |
| 269 | if answer is None: | 316 | if answer is None: |
| 270 | sys.stdout.write('Uncommitted changes in ' + branch.project.name + ' (did you forget to amend?). Continue uploading? (y/n) ') | 317 | sys.stdout.write('Uncommitted changes in ' + branch.project.name + ' (did you forget to amend?). Continue uploading? (y/N) ') |
| 271 | a = sys.stdin.readline().strip().lower() | 318 | a = sys.stdin.readline().strip().lower() |
| 272 | if a not in ('y', 'yes', 't', 'true', 'on'): | 319 | if a not in ('y', 'yes', 't', 'true', 'on'): |
| 273 | print >>sys.stderr, "skipping upload" | 320 | print >>sys.stderr, "skipping upload" |
| @@ -275,7 +322,12 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 275 | branch.error = 'User aborted' | 322 | branch.error = 'User aborted' |
| 276 | continue | 323 | continue |
| 277 | 324 | ||
| 278 | branch.UploadForReview(people, auto_topic=opt.auto_topic) | 325 | # Check if topic branches should be sent to the server during upload |
| 326 | if opt.auto_topic is not True: | ||
| 327 | key = 'review.%s.uploadtopic' % branch.project.remote.review | ||
| 328 | opt.auto_topic = branch.project.config.GetBoolean(key) | ||
| 329 | |||
| 330 | branch.UploadForReview(people, auto_topic=opt.auto_topic, draft=opt.draft) | ||
| 279 | branch.uploaded = True | 331 | branch.uploaded = True |
| 280 | except UploadError, e: | 332 | except UploadError, e: |
| 281 | branch.error = e | 333 | branch.error = e |
| @@ -312,6 +364,29 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 312 | pending = [] | 364 | pending = [] |
| 313 | reviewers = [] | 365 | reviewers = [] |
| 314 | cc = [] | 366 | cc = [] |
| 367 | branch = None | ||
| 368 | |||
| 369 | if opt.branch: | ||
| 370 | branch = opt.branch | ||
| 371 | |||
| 372 | for project in project_list: | ||
| 373 | if opt.current_branch: | ||
| 374 | cbr = project.CurrentBranch | ||
| 375 | avail = [project.GetUploadableBranch(cbr)] if cbr else None | ||
| 376 | else: | ||
| 377 | avail = project.GetUploadableBranches(branch) | ||
| 378 | if avail: | ||
| 379 | pending.append((project, avail)) | ||
| 380 | |||
| 381 | if pending and (not opt.bypass_hooks): | ||
| 382 | hook = RepoHook('pre-upload', self.manifest.repo_hooks_project, | ||
| 383 | self.manifest.topdir, abort_if_user_denies=True) | ||
| 384 | pending_proj_names = [project.name for (project, avail) in pending] | ||
| 385 | try: | ||
| 386 | hook.Run(opt.allow_all_hooks, project_list=pending_proj_names) | ||
| 387 | except HookError, e: | ||
| 388 | print >>sys.stderr, "ERROR: %s" % str(e) | ||
| 389 | return | ||
| 315 | 390 | ||
| 316 | if opt.reviewers: | 391 | if opt.reviewers: |
| 317 | reviewers = _SplitEmails(opt.reviewers) | 392 | reviewers = _SplitEmails(opt.reviewers) |
| @@ -319,11 +394,6 @@ Gerrit Code Review: http://code.google.com/p/gerrit/ | |||
| 319 | cc = _SplitEmails(opt.cc) | 394 | cc = _SplitEmails(opt.cc) |
| 320 | people = (reviewers,cc) | 395 | people = (reviewers,cc) |
| 321 | 396 | ||
| 322 | for project in project_list: | ||
| 323 | avail = project.GetUploadableBranches() | ||
| 324 | if avail: | ||
| 325 | pending.append((project, avail)) | ||
| 326 | |||
| 327 | if not pending: | 397 | if not pending: |
| 328 | print >>sys.stdout, "no branches ready for upload" | 398 | print >>sys.stdout, "no branches ready for upload" |
| 329 | elif len(pending) == 1 and len(pending[0][1]) == 1: | 399 | elif len(pending) == 1 and len(pending[0][1]) == 1: |
