mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
181 lines
5.3 KiB
Python
181 lines
5.3 KiB
Python
|
#
|
||
|
# 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, ''
|
||
|
|
||
|
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)
|