mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
157 lines
4.7 KiB
Python
157 lines
4.7 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 getpass
|
||
|
import os
|
||
|
import subprocess
|
||
|
import sys
|
||
|
from tempfile import mkstemp
|
||
|
|
||
|
from codereview.proto_client import HttpRpc, Proxy
|
||
|
from codereview.review_pb2 import ReviewService_Stub
|
||
|
from codereview.upload_bundle_pb2 import *
|
||
|
from git_command import GitCommand
|
||
|
from error import UploadError
|
||
|
|
||
|
try:
|
||
|
import readline
|
||
|
except ImportError:
|
||
|
pass
|
||
|
|
||
|
MAX_SEGMENT_SIZE = 1020 * 1024
|
||
|
|
||
|
def _GetRpcServer(email, server, save_cookies):
|
||
|
"""Returns an RpcServer.
|
||
|
|
||
|
Returns:
|
||
|
A new RpcServer, on which RPC calls can be made.
|
||
|
"""
|
||
|
|
||
|
def GetUserCredentials():
|
||
|
"""Prompts the user for a username and password."""
|
||
|
e = email
|
||
|
if e is None:
|
||
|
e = raw_input("Email: ").strip()
|
||
|
password = getpass.getpass("Password for %s: " % e)
|
||
|
return (e, password)
|
||
|
|
||
|
# If this is the dev_appserver, use fake authentication.
|
||
|
lc_server = server.lower()
|
||
|
if lc_server == "localhost" or lc_server.startswith("localhost:"):
|
||
|
if email is None:
|
||
|
email = "test@example.com"
|
||
|
server = HttpRpc(
|
||
|
server,
|
||
|
lambda: (email, "password"),
|
||
|
extra_headers={"Cookie":
|
||
|
'dev_appserver_login="%s:False"' % email})
|
||
|
# Don't try to talk to ClientLogin.
|
||
|
server.authenticated = True
|
||
|
return server
|
||
|
|
||
|
if save_cookies:
|
||
|
cookie_file = ".gerrit_cookies"
|
||
|
else:
|
||
|
cookie_file = None
|
||
|
|
||
|
return HttpRpc(server, GetUserCredentials,
|
||
|
cookie_file=cookie_file)
|
||
|
|
||
|
def UploadBundle(project,
|
||
|
server,
|
||
|
email,
|
||
|
dest_project,
|
||
|
dest_branch,
|
||
|
src_branch,
|
||
|
bases,
|
||
|
save_cookies=True):
|
||
|
|
||
|
srv = _GetRpcServer(email, server, save_cookies)
|
||
|
review = Proxy(ReviewService_Stub(srv))
|
||
|
tmp_fd, tmp_bundle = mkstemp(".bundle", ".gpq")
|
||
|
os.close(tmp_fd)
|
||
|
|
||
|
srcid = project.bare_git.rev_parse(src_branch)
|
||
|
revlist = project._revlist(src_branch, *bases)
|
||
|
|
||
|
if srcid not in revlist:
|
||
|
# This can happen if src_branch is an annotated tag
|
||
|
#
|
||
|
revlist.append(srcid)
|
||
|
revlist_size = len(revlist) * 42
|
||
|
|
||
|
try:
|
||
|
cmd = ['bundle', 'create', tmp_bundle, src_branch]
|
||
|
cmd.extend(bases)
|
||
|
if GitCommand(project, cmd).Wait() != 0:
|
||
|
raise UploadError('cannot create bundle')
|
||
|
fd = open(tmp_bundle, "rb")
|
||
|
|
||
|
bundle_id = None
|
||
|
segment_id = 0
|
||
|
next_data = fd.read(MAX_SEGMENT_SIZE - revlist_size)
|
||
|
|
||
|
while True:
|
||
|
this_data = next_data
|
||
|
next_data = fd.read(MAX_SEGMENT_SIZE)
|
||
|
segment_id += 1
|
||
|
|
||
|
if bundle_id is None:
|
||
|
req = UploadBundleRequest()
|
||
|
req.dest_project = str(dest_project)
|
||
|
req.dest_branch = str(dest_branch)
|
||
|
for c in revlist:
|
||
|
req.contained_object.append(c)
|
||
|
else:
|
||
|
req = UploadBundleContinue()
|
||
|
req.bundle_id = bundle_id
|
||
|
req.segment_id = segment_id
|
||
|
|
||
|
req.bundle_data = this_data
|
||
|
if len(next_data) > 0:
|
||
|
req.partial_upload = True
|
||
|
else:
|
||
|
req.partial_upload = False
|
||
|
|
||
|
if bundle_id is None:
|
||
|
rsp = review.UploadBundle(req)
|
||
|
else:
|
||
|
rsp = review.ContinueBundle(req)
|
||
|
|
||
|
if rsp.status_code == UploadBundleResponse.CONTINUE:
|
||
|
bundle_id = rsp.bundle_id
|
||
|
elif rsp.status_code == UploadBundleResponse.RECEIVED:
|
||
|
bundle_id = rsp.bundle_id
|
||
|
return bundle_id
|
||
|
else:
|
||
|
if rsp.status_code == UploadBundleResponse.UNKNOWN_PROJECT:
|
||
|
reason = 'unknown project "%s"' % dest_project
|
||
|
elif rsp.status_code == UploadBundleResponse.UNKNOWN_BRANCH:
|
||
|
reason = 'unknown branch "%s"' % dest_branch
|
||
|
elif rsp.status_code == UploadBundleResponse.UNKNOWN_BUNDLE:
|
||
|
reason = 'unknown bundle'
|
||
|
elif rsp.status_code == UploadBundleResponse.NOT_BUNDLE_OWNER:
|
||
|
reason = 'not bundle owner'
|
||
|
elif rsp.status_code == UploadBundleResponse.BUNDLE_CLOSED:
|
||
|
reason = 'bundle closed'
|
||
|
elif rsp.status_code == UploadBundleResponse.UNAUTHORIZED_USER:
|
||
|
reason = ('Unauthorized user. Visit http://%s/hello to sign up.'
|
||
|
% server)
|
||
|
else:
|
||
|
reason = 'unknown error ' + str(rsp.status_code)
|
||
|
raise UploadError(reason)
|
||
|
finally:
|
||
|
os.unlink(tmp_bundle)
|