diff options
| -rw-r--r-- | git_config.py | 42 | ||||
| -rw-r--r-- | project.py | 73 |
2 files changed, 91 insertions, 24 deletions
diff --git a/git_config.py b/git_config.py index 9ddb2edc..ed5a44a4 100644 --- a/git_config.py +++ b/git_config.py | |||
| @@ -16,7 +16,8 @@ | |||
| 16 | import os | 16 | import os |
| 17 | import re | 17 | import re |
| 18 | import sys | 18 | import sys |
| 19 | from error import GitError | 19 | from urllib2 import urlopen, HTTPError |
| 20 | from error import GitError, UploadError | ||
| 20 | from git_command import GitCommand | 21 | from git_command import GitCommand |
| 21 | 22 | ||
| 22 | R_HEADS = 'refs/heads/' | 23 | R_HEADS = 'refs/heads/' |
| @@ -261,6 +262,45 @@ class Remote(object): | |||
| 261 | self.projectname = self._Get('projectname') | 262 | self.projectname = self._Get('projectname') |
| 262 | self.fetch = map(lambda x: RefSpec.FromString(x), | 263 | self.fetch = map(lambda x: RefSpec.FromString(x), |
| 263 | self._Get('fetch', all=True)) | 264 | self._Get('fetch', all=True)) |
| 265 | self._review_protocol = None | ||
| 266 | |||
| 267 | @property | ||
| 268 | def ReviewProtocol(self): | ||
| 269 | if self._review_protocol is None: | ||
| 270 | if self.review is None: | ||
| 271 | return None | ||
| 272 | |||
| 273 | u = self.review | ||
| 274 | if not u.startswith('http:') and not u.startswith('https:'): | ||
| 275 | u = 'http://%s' % u | ||
| 276 | if not u.endswith('/'): | ||
| 277 | u += '/' | ||
| 278 | u += 'ssh_info' | ||
| 279 | |||
| 280 | try: | ||
| 281 | info = urlopen(u).read() | ||
| 282 | if info == 'NOT_AVAILABLE': | ||
| 283 | raise UploadError('Upload over ssh unavailable') | ||
| 284 | |||
| 285 | self._review_protocol = 'ssh' | ||
| 286 | self._review_host = info.split(" ")[0] | ||
| 287 | self._review_port = info.split(" ")[1] | ||
| 288 | |||
| 289 | except HTTPError, e: | ||
| 290 | if e.code == 404: | ||
| 291 | self._review_protocol = 'http-post' | ||
| 292 | else: | ||
| 293 | raise UploadError('Cannot guess Gerrit version') | ||
| 294 | return self._review_protocol | ||
| 295 | |||
| 296 | def SshReviewUrl(self, userEmail): | ||
| 297 | if self.ReviewProtocol != 'ssh': | ||
| 298 | return None | ||
| 299 | return 'ssh://%s@%s:%s/%s' % ( | ||
| 300 | userEmail.split("@")[0], | ||
| 301 | self._review_host, | ||
| 302 | self._review_port, | ||
| 303 | self.projectname) | ||
| 264 | 304 | ||
| 265 | def ToLocal(self, rev): | 305 | def ToLocal(self, rev): |
| 266 | """Convert a remote revision string to something we have locally. | 306 | """Convert a remote revision string to something we have locally. |
| @@ -46,6 +46,8 @@ def _info(fmt, *args): | |||
| 46 | def not_rev(r): | 46 | def not_rev(r): |
| 47 | return '^' + r | 47 | return '^' + r |
| 48 | 48 | ||
| 49 | def sq(r): | ||
| 50 | return "'" + r.replace("'", "'\''") + "'" | ||
| 49 | 51 | ||
| 50 | hook_list = None | 52 | hook_list = None |
| 51 | def repo_hooks(): | 53 | def repo_hooks(): |
| @@ -475,33 +477,58 @@ class Project(object): | |||
| 475 | if not dest_branch.startswith(R_HEADS): | 477 | if not dest_branch.startswith(R_HEADS): |
| 476 | dest_branch = R_HEADS + dest_branch | 478 | dest_branch = R_HEADS + dest_branch |
| 477 | 479 | ||
| 478 | base_list = [] | ||
| 479 | for name, id in self._allrefs.iteritems(): | ||
| 480 | if branch.remote.WritesTo(name): | ||
| 481 | base_list.append(not_rev(name)) | ||
| 482 | if not base_list: | ||
| 483 | raise GitError('no base refs, cannot upload %s' % branch.name) | ||
| 484 | |||
| 485 | if not branch.remote.projectname: | 480 | if not branch.remote.projectname: |
| 486 | branch.remote.projectname = self.name | 481 | branch.remote.projectname = self.name |
| 487 | branch.remote.Save() | 482 | branch.remote.Save() |
| 488 | 483 | ||
| 489 | print >>sys.stderr, '' | 484 | if branch.remote.ReviewProtocol == 'http-post': |
| 490 | _info("Uploading %s to %s:", branch.name, self.name) | 485 | base_list = [] |
| 491 | try: | 486 | for name, id in self._allrefs.iteritems(): |
| 492 | UploadBundle(project = self, | 487 | if branch.remote.WritesTo(name): |
| 493 | server = branch.remote.review, | 488 | base_list.append(not_rev(name)) |
| 494 | email = self.UserEmail, | 489 | if not base_list: |
| 495 | dest_project = branch.remote.projectname, | 490 | raise GitError('no base refs, cannot upload %s' % branch.name) |
| 496 | dest_branch = dest_branch, | 491 | |
| 497 | src_branch = R_HEADS + branch.name, | 492 | print >>sys.stderr, '' |
| 498 | bases = base_list, | 493 | _info("Uploading %s to %s:", branch.name, self.name) |
| 499 | people = people, | 494 | try: |
| 500 | replace_changes = replace_changes) | 495 | UploadBundle(project = self, |
| 501 | except proto_client.ClientLoginError: | 496 | server = branch.remote.review, |
| 502 | raise UploadError('Login failure') | 497 | email = self.UserEmail, |
| 503 | except urllib2.HTTPError, e: | 498 | dest_project = branch.remote.projectname, |
| 504 | raise UploadError('HTTP error %d' % e.code) | 499 | dest_branch = dest_branch, |
| 500 | src_branch = R_HEADS + branch.name, | ||
| 501 | bases = base_list, | ||
| 502 | people = people, | ||
| 503 | replace_changes = replace_changes) | ||
| 504 | except proto_client.ClientLoginError: | ||
| 505 | raise UploadError('Login failure') | ||
| 506 | except urllib2.HTTPError, e: | ||
| 507 | raise UploadError('HTTP error %d' % e.code) | ||
| 508 | |||
| 509 | elif branch.remote.ReviewProtocol == 'ssh': | ||
| 510 | if dest_branch.startswith(R_HEADS): | ||
| 511 | dest_branch = dest_branch[len(R_HEADS):] | ||
| 512 | |||
| 513 | rp = ['gerrit receive-pack'] | ||
| 514 | for e in people[0]: | ||
| 515 | rp.append('--reviewer=%s' % sq(e)) | ||
| 516 | for e in people[1]: | ||
| 517 | rp.append('--cc=%s' % sq(e)) | ||
| 518 | |||
| 519 | cmd = ['push'] | ||
| 520 | cmd.append('--receive-pack=%s' % " ".join(rp)) | ||
| 521 | cmd.append(branch.remote.SshReviewUrl(self.UserEmail)) | ||
| 522 | cmd.append('%s:refs/for/%s' % (R_HEADS + branch.name, dest_branch)) | ||
| 523 | if replace_changes: | ||
| 524 | for change_id,commit_id in replace_changes.iteritems(): | ||
| 525 | cmd.append('%s:refs/changes/%s/new' % (commit_id, change_id)) | ||
| 526 | if GitCommand(self, cmd, bare = True).Wait() != 0: | ||
| 527 | raise UploadError('Upload failed') | ||
| 528 | |||
| 529 | else: | ||
| 530 | raise UploadError('Unsupported protocol %s' \ | ||
| 531 | % branch.remote.review) | ||
| 505 | 532 | ||
| 506 | msg = "posted to %s for %s" % (branch.remote.review, dest_branch) | 533 | msg = "posted to %s for %s" % (branch.remote.review, dest_branch) |
| 507 | self.bare_git.UpdateRef(R_PUB + branch.name, | 534 | self.bare_git.UpdateRef(R_PUB + branch.name, |
