From 2896a79120fe1de65472736f756c47b558b44db1 Mon Sep 17 00:00:00 2001 From: Joe Onorato Date: Mon, 17 Nov 2008 16:56:36 -0500 Subject: [PATCH] Add --review and --cc flags to repo upload, so you can assign reviewers when you upload changes. --- codereview/__init__.py | 2 +- codereview/upload_bundle_pb2.py | 42 ++++++++++++++++++++++++++---- gerrit_upload.py | 9 +++++++ project.py | 8 +++--- subcmds/upload.py | 45 +++++++++++++++++++++++++-------- 5 files changed, 87 insertions(+), 19 deletions(-) diff --git a/codereview/__init__.py b/codereview/__init__.py index 82216880..58835553 100644 --- a/codereview/__init__.py +++ b/codereview/__init__.py @@ -1 +1 @@ -__version__ = 'v1.0-99-g9cd3ea2f' +__version__ = 'v1.0-112-gbcd4db5a' diff --git a/codereview/upload_bundle_pb2.py b/codereview/upload_bundle_pb2.py index 7cf2f86e..ff91ee1f 100644 --- a/codereview/upload_bundle_pb2.py +++ b/codereview/upload_bundle_pb2.py @@ -35,23 +35,27 @@ _UPLOADBUNDLERESPONSE_CODETYPE = descriptor.EnumDescriptor( options=None, type=None), descriptor.EnumValueDescriptor( - name='UNKNOWN_PROJECT', index=5, number=2, + name='UNKNOWN_EMAIL', index=5, number=11, options=None, type=None), descriptor.EnumValueDescriptor( - name='UNKNOWN_BRANCH', index=6, number=3, + name='UNKNOWN_PROJECT', index=6, number=2, options=None, type=None), descriptor.EnumValueDescriptor( - name='UNKNOWN_BUNDLE', index=7, number=5, + name='UNKNOWN_BRANCH', index=7, number=3, options=None, type=None), descriptor.EnumValueDescriptor( - name='NOT_BUNDLE_OWNER', index=8, number=6, + name='UNKNOWN_BUNDLE', index=8, number=5, options=None, type=None), descriptor.EnumValueDescriptor( - name='BUNDLE_CLOSED', index=9, number=8, + name='NOT_BUNDLE_OWNER', index=9, number=6, + options=None, + type=None), + descriptor.EnumValueDescriptor( + name='BUNDLE_CLOSED', index=10, number=8, options=None, type=None), ], @@ -136,6 +140,20 @@ _UPLOADBUNDLEREQUEST = descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), + descriptor.FieldDescriptor( + name='reviewers', full_name='codereview.UploadBundleRequest.reviewers', index=6, + number=3, type=9, cpp_type=9, label=3, + default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + descriptor.FieldDescriptor( + name='cc', full_name='codereview.UploadBundleRequest.cc', index=7, + number=4, type=9, cpp_type=9, label=3, + default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), ], extensions=[ ], @@ -165,6 +183,20 @@ _UPLOADBUNDLERESPONSE = descriptor.Descriptor( message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), + descriptor.FieldDescriptor( + name='invalid_reviewers', full_name='codereview.UploadBundleResponse.invalid_reviewers', index=2, + number=12, type=9, cpp_type=9, label=3, + default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + descriptor.FieldDescriptor( + name='invalid_cc', full_name='codereview.UploadBundleResponse.invalid_cc', index=3, + number=13, type=9, cpp_type=9, label=3, + default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), ], extensions=[ ], diff --git a/gerrit_upload.py b/gerrit_upload.py index d3d4ff3e..17112aac 100755 --- a/gerrit_upload.py +++ b/gerrit_upload.py @@ -75,6 +75,7 @@ def UploadBundle(project, dest_branch, src_branch, bases, + people, replace_changes = None, save_cookies=True): @@ -112,6 +113,10 @@ def UploadBundle(project, req = UploadBundleRequest() req.dest_project = str(dest_project) req.dest_branch = str(dest_branch) + for e in people[0]: + req.reviewers.append(e) + for e in people[1]: + req.cc.append(e) for c in revlist: req.contained_object.append(c) if replace_changes: @@ -158,6 +163,10 @@ def UploadBundle(project, reason = 'invalid change id' elif rsp.status_code == UploadBundleResponse.CHANGE_CLOSED: reason = 'one or more changes are closed' + elif rsp.status_code == UploadBundleResponse.UNKNOWN_EMAIL: + emails = [x for x in rsp.invalid_reviewers] + [ + x for x in rsp.invalid_cc] + reason = 'invalid email addresses: %s' % ", ".join(emails) else: reason = 'unknown error ' + str(rsp.status_code) raise UploadError(reason) diff --git a/project.py b/project.py index 39550335..fe3ce34a 100644 --- a/project.py +++ b/project.py @@ -142,9 +142,10 @@ class ReviewableBranch(object): R_HEADS + self.name, '--') - def UploadForReview(self): + def UploadForReview(self, people): self.project.UploadForReview(self.name, - self.replace_changes) + self.replace_changes, + people) @property def tip_url(self): @@ -456,7 +457,7 @@ class Project(object): return rb return None - def UploadForReview(self, branch=None, replace_changes=None): + def UploadForReview(self, branch=None, replace_changes=None, people=([],[])): """Uploads the named branch for code review. """ if branch is None: @@ -495,6 +496,7 @@ class Project(object): dest_branch = dest_branch, src_branch = R_HEADS + branch.name, bases = base_list, + people = people, replace_changes = replace_changes) except proto_client.ClientLoginError: raise UploadError('Login failure') diff --git a/subcmds/upload.py b/subcmds/upload.py index 11f035d7..49d00187 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py @@ -25,11 +25,17 @@ def _die(fmt, *args): print >>sys.stderr, 'error: %s' % msg sys.exit(1) +def _SplitEmails(values): + result = [] + for str in values: + result.extend([s.strip() for s in str.split(',')]) + return result + class Upload(InteractiveCommand): common = True helpSummary = "Upload changes for code review" helpUsage=""" -%prog {[]... | --replace } +%prog [--re --cc] {[]... | --replace } """ helpDescription = """ The '%prog' command is used to send changes to the Gerrit code @@ -44,14 +50,25 @@ at the command line. Projects can be specified either by name, or by a relative or absolute path to the project's local directory. If no projects are specified, '%prog' will search for uploadable changes in all projects listed in the manifest. + +If the --reviewers or --cc options are passed, those emails are +added to the respective list of users, and emails are sent to any +new users. Users passed to --reviewers must be already registered +with the code review system, or the upload will fail. """ def _Options(self, p): p.add_option('--replace', dest='replace', action='store_true', help='Upload replacement patchesets from this branch') + p.add_option('--re', '--reviewers', + type='string', action='append', dest='reviewers', + help='Request reviews from these people.') + p.add_option('--cc', + type='string', action='append', dest='cc', + help='Also send email to these email addresses.') - def _SingleBranch(self, branch): + def _SingleBranch(self, branch, people): project = branch.project name = branch.name date = branch.date @@ -69,11 +86,11 @@ changes in all projects listed in the manifest. sys.stdout.write('(y/n)? ') answer = sys.stdin.readline().strip() if answer in ('y', 'Y', 'yes', '1', 'true', 't'): - self._UploadAndReport([branch]) + self._UploadAndReport([branch], people) else: _die("upload aborted by user") - def _MultipleBranches(self, pending): + def _MultipleBranches(self, pending, people): projects = {} branches = {} @@ -132,7 +149,7 @@ changes in all projects listed in the manifest. todo.append(branch) if not todo: _die("nothing uncommented for upload") - self._UploadAndReport(todo) + self._UploadAndReport(todo, people) def _ReplaceBranch(self, project): branch = project.CurrentBranch @@ -176,13 +193,13 @@ changes in all projects listed in the manifest. sys.exit(1) branch.replace_changes = to_replace - self._UploadAndReport([branch]) + self._UploadAndReport([branch], people) - def _UploadAndReport(self, todo): + def _UploadAndReport(self, todo, people): have_errors = False for branch in todo: try: - branch.UploadForReview() + branch.UploadForReview(people) branch.uploaded = True except UploadError, e: branch.error = e @@ -216,6 +233,14 @@ changes in all projects listed in the manifest. def Execute(self, opt, args): project_list = self.GetProjects(args) pending = [] + reviewers = [] + cc = [] + + if opt.reviewers: + reviewers = _SplitEmails(opt.reviewers) + if opt.cc: + cc = _SplitEmails(opt.cc) + people = (reviewers,cc) if opt.replace: if len(project_list) != 1: @@ -233,6 +258,6 @@ changes in all projects listed in the manifest. if not pending: print >>sys.stdout, "no branches ready for upload" elif len(pending) == 1 and len(pending[0][1]) == 1: - self._SingleBranch(pending[0][1][0]) + self._SingleBranch(pending[0][1][0], people) else: - self._MultipleBranches(pending) + self._MultipleBranches(pending, people)