| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #
- # Copyright (C) 2008 The Android Open Source Project
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import re
- import sys
- from command import InteractiveCommand
- from editor import Editor
- from error import UploadError
- def _die(fmt, *args):
- msg = fmt % args
- print >>sys.stderr, 'error: %s' % msg
- sys.exit(1)
- class Upload(InteractiveCommand):
- common = True
- helpSummary = "Upload changes for code review"
- helpUsage="""
- %prog [<project>]...
- """
- helpDescription = """
- The '%prog' command is used to send changes to the Gerrit code
- review system. It searches for changes in local projects that do
- not yet exist in the corresponding remote repository. If multiple
- changes are found, '%prog' opens an editor to allow the
- user to choose which change to upload. After a successful upload,
- repo prints the URL for the change in the Gerrit code review system.
- '%prog' searches for uploadable changes in all projects listed
- 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.
- """
- def _SingleBranch(self, branch):
- project = branch.project
- name = branch.name
- date = branch.date
- list = branch.commits
- print 'Upload project %s/:' % project.relpath
- print ' branch %s (%2d commit%s, %s):' % (
- name,
- len(list),
- len(list) != 1 and 's' or '',
- date)
- for commit in list:
- print ' %s' % commit
- sys.stdout.write('(y/n)? ')
- answer = sys.stdin.readline().strip()
- if answer in ('y', 'Y', 'yes', '1', 'true', 't'):
- self._UploadAndReport([branch])
- else:
- _die("upload aborted by user")
- def _MultipleBranches(self, pending):
- projects = {}
- branches = {}
- script = []
- script.append('# Uncomment the branches to upload:')
- for project, avail in pending:
- script.append('#')
- script.append('# project %s/:' % project.relpath)
- b = {}
- for branch in avail:
- name = branch.name
- date = branch.date
- list = branch.commits
- if b:
- script.append('#')
- script.append('# branch %s (%2d commit%s, %s):' % (
- name,
- len(list),
- len(list) != 1 and 's' or '',
- date))
- for commit in list:
- script.append('# %s' % commit)
- b[name] = branch
- projects[project.relpath] = project
- branches[project.name] = b
- script.append('')
- script = Editor.EditString("\n".join(script)).split("\n")
- project_re = re.compile(r'^#?\s*project\s*([^\s]+)/:$')
- branch_re = re.compile(r'^\s*branch\s*([^\s(]+)\s*\(.*')
- project = None
- todo = []
- for line in script:
- m = project_re.match(line)
- if m:
- name = m.group(1)
- project = projects.get(name)
- if not project:
- _die('project %s not available for upload', name)
- continue
- m = branch_re.match(line)
- if m:
- name = m.group(1)
- if not project:
- _die('project for branch %s not in script', name)
- branch = branches[project.name].get(name)
- if not branch:
- _die('branch %s not in %s', name, project.relpath)
- todo.append(branch)
- if not todo:
- _die("nothing uncommented for upload")
- self._UploadAndReport(todo)
- def _UploadAndReport(self, todo):
- have_errors = False
- for branch in todo:
- try:
- branch.UploadForReview()
- branch.uploaded = True
- except UploadError, e:
- branch.error = e
- branch.uploaded = False
- have_errors = True
- print >>sys.stderr, ''
- print >>sys.stderr, '--------------------------------------------'
- if have_errors:
- for branch in todo:
- if not branch.uploaded:
- print >>sys.stderr, '[FAILED] %-15s %-15s (%s)' % (
- branch.project.relpath + '/', \
- branch.name, \
- branch.error)
- print >>sys.stderr, ''
- for branch in todo:
- if branch.uploaded:
- print >>sys.stderr, '[OK ] %-15s %s' % (
- branch.project.relpath + '/',
- branch.name)
- print >>sys.stderr, '%s' % branch.tip_url
- print >>sys.stderr, '(as %s)' % branch.owner_email
- print >>sys.stderr, ''
- if have_errors:
- sys.exit(1)
- def Execute(self, opt, args):
- project_list = self.GetProjects(args)
- pending = []
- for project in project_list:
- avail = project.GetUploadableBranches()
- if avail:
- pending.append((project, avail))
- 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])
- else:
- self._MultipleBranches(pending)
|