launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #18239
[Merge] lp:~blr/launchpad/init-with-clone into lp:launchpad
Bayard 'kit' Randel has proposed merging lp:~blr/launchpad/init-with-clone into lp:launchpad.
Requested reviews:
Bayard 'kit' Randel (blr)
For more details, see:
https://code.launchpad.net/~blr/launchpad/init-with-clone/+merge/254702
On creating a repository, clone from target default repository if exists.
--
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.
=== modified file 'lib/lp/code/githosting.py'
--- lib/lp/code/githosting.py 2015-03-20 11:52:54 +0000
+++ lib/lp/code/githosting.py 2015-03-31 21:26:41 +0000
@@ -37,15 +37,19 @@
# over, but is there some more robust way to do this?
return 5.0
- def create(self, path):
+ def create(self, path, clone_from=None):
try:
# XXX cjwatson 2015-03-01: Once we're on requests >= 2.4.2, we
# should just use post(json=) and drop the explicit Content-Type
# header.
+ if clone_from:
+ request = {"repo_path": path, "clone_from": clone_from}
+ else:
+ request = {"repo_path": path}
response = self._makeSession().post(
urlutils.join(self.endpoint, "repo"),
headers={"Content-Type": "application/json"},
- data=json.dumps({"repo_path": path, "bare_repo": True}),
+ data=json.dumps(request),
timeout=self.timeout)
except Exception as e:
raise GitRepositoryCreationFault(
=== modified file 'lib/lp/code/xmlrpc/git.py'
--- lib/lp/code/xmlrpc/git.py 2015-03-31 16:29:51 +0000
+++ lib/lp/code/xmlrpc/git.py 2015-03-31 21:26:41 +0000
@@ -24,6 +24,7 @@
GitRepositoryCreationForbidden,
GitRepositoryCreationFault,
GitRepositoryExists,
+ GitTargetError,
InvalidNamespace,
)
from lp.code.githosting import GitHostingClient
@@ -146,7 +147,7 @@
getUtility(IErrorReportingUtility).raising(sys.exc_info(), request)
raise faults.OopsOccurred("creating a Git repository", request.oopsid)
- def _createRepository(self, requester, path):
+ def _createRepository(self, requester, path, clone_from=None):
try:
namespace, repository_name, default_func = (
self._getGitNamespaceExtras(path, requester))
@@ -196,9 +197,20 @@
Store.of(repository).flush()
assert repository.id is not None
+ # If repository has target_default, clone from default.
+ target_path = None
+ try:
+ repository_set = getUtility(IGitRepositorySet)
+ target_default = repository_set.getDefaultRepository(
+ repository.target)
+ if target_default and target_default.visibleByUser(requester):
+ target_path = target_default.getInternalPath()
+ except GitTargetError:
+ pass # Ignore Personal repositories.
+
hosting_path = repository.getInternalPath()
try:
- self.hosting_client.create(hosting_path)
+ self.hosting_client.create(hosting_path, clone_from=target_path)
except GitRepositoryCreationFault as e:
# The hosting service failed. Log an OOPS for investigation.
self._reportError(path, e, hosting_path=hosting_path)
=== modified file 'lib/lp/code/xmlrpc/tests/test_git.py'
--- lib/lp/code/xmlrpc/tests/test_git.py 2015-03-31 04:29:24 +0000
+++ lib/lp/code/xmlrpc/tests/test_git.py 2015-03-31 21:26:41 +0000
@@ -43,14 +43,14 @@
def __init__(self):
self.calls = []
- def create(self, path):
- self.calls.append(("create", path))
+ def create(self, path, clone_from=None):
+ self.calls.append(("create", path, clone_from))
class BrokenGitHostingClient:
"""A GitHostingClient lookalike that pretends the remote end is down."""
- def create(self, path):
+ def create(self, path, clone_from=None):
raise GitRepositoryCreationFault("nothing here")
@@ -109,6 +109,7 @@
self.useFixture(FeatureFixture({GIT_FEATURE_FLAG: u"on"}))
self.git_api = GitAPI(None, None)
self.git_api.hosting_client = FakeGitHostingClient()
+ self.repository_set = getUtility(IGitRepositorySet)
def assertPathTranslationError(self, requester, path, permission="read",
can_authenticate=False):
@@ -212,10 +213,18 @@
"trailing": ""},
translation)
self.assertEqual(
- [("create", repository.getInternalPath())],
- self.git_api.hosting_client.calls)
+ ("create", repository.getInternalPath()),
+ self.git_api.hosting_client.calls[0][0:2])
return repository
+ def assertCreatesFromClone(self, requester, path, can_authenticate=False):
+ repository = self.assertCreates(requester, path, can_authenticate)
+ target_default = removeSecurityProxy(
+ self.repository_set.getDefaultRepository(repository.target))
+ self.assertIsNotNone(target_default)
+ self.assertEqual(target_default.getInternalPath(),
+ self.git_api.hosting_client.calls[0][2])
+
def test_translatePath_private_repository(self):
requester = self.factory.makePerson()
repository = removeSecurityProxy(
@@ -418,6 +427,18 @@
self.assertCreates(
requester, u"/~%s/%s/+git/random" % (requester.name, project.name))
+ def test_translatePath_create_project_with_default_target(self):
+ # translatePath creates a project repository cloned from the
+ # target default if it exists.
+ target = self.factory.makeProduct()
+ repository = self.factory.makeGitRepository(
+ owner=target.owner, target=target)
+ with person_logged_in(target.owner):
+ self.repository_set.setDefaultRepository(target, repository)
+ self.assertCreatesFromClone(
+ target.owner, u"/~%s/%s/+git/random" % (target.owner.name,
+ target.name))
+
def test_translatePath_create_package(self):
# translatePath creates a package repository that doesn't exist, if
# it can.
Follow ups