| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- #
- # 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 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,
- replace_changes = None,
- 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)
- if replace_changes:
- for change_id,commit_id in replace_changes.iteritems():
- r = req.replace.add()
- r.change_id = change_id
- r.object_id = commit_id
- 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)
- elif rsp.status_code == UploadBundleResponse.UNKNOWN_CHANGE:
- reason = 'invalid change id'
- elif rsp.status_code == UploadBundleResponse.CHANGE_CLOSED:
- reason = 'one or more changes are closed'
- else:
- reason = 'unknown error ' + str(rsp.status_code)
- raise UploadError(reason)
- finally:
- os.unlink(tmp_bundle)
|