From cf31fe9b4fb650b27e19f5d7ee7297e383660caf Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 21 Oct 2008 07:00:00 -0700 Subject: Initial Contribution --- gerrit_upload.py | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100755 gerrit_upload.py (limited to 'gerrit_upload.py') diff --git a/gerrit_upload.py b/gerrit_upload.py new file mode 100755 index 00000000..a49fb232 --- /dev/null +++ b/gerrit_upload.py @@ -0,0 +1,156 @@ +# +# 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) -- cgit v1.2.3-54-g00ecf