launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #21127
[Merge] lp:~cjwatson/launchpad/codeimport-git-configure-code into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/codeimport-git-configure-code into lp:launchpad with lp:~cjwatson/launchpad/codeimport-git-refactor-name-validation as a prerequisite.
Commit message:
Extend Product:+configure-code to be able to create Git-to-Git code imports.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/codeimport-git-configure-code/+merge/308577
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/codeimport-git-configure-code into lp:launchpad.
=== modified file 'lib/lp/code/javascript/productseries-setbranch.js'
--- lib/lp/code/javascript/productseries-setbranch.js 2015-06-25 07:39:40 +0000
+++ lib/lp/code/javascript/productseries-setbranch.js 2016-10-15 14:08:56 +0000
@@ -97,10 +97,9 @@
}
}
// Linked
- module.set_enabled('field.branch_location', type === 'link-lp-bzr');
- module.set_enabled('field.branch_name', type !== 'link-lp-bzr');
- module.set_enabled('field.branch_owner', type !== 'link-lp-bzr');
- // New, empty branch.
+ module.set_enabled('field.branch_location', type === 'link-lp');
+ module.set_enabled('field.branch_name', type !== 'link-lp');
+ module.set_enabled('field.branch_owner', type !== 'link-lp');
// Import
var is_external = (type === 'import-external');
module.set_enabled('field.repo_url', is_external);
@@ -113,6 +112,27 @@
}
};
+ module.onclick_git_repository_type = function(e) {
+ /* Which Git repository type radio button was selected? */
+ var types = document.getElementsByName('field.git_repository_type');
+ var type = 'None';
+ var i;
+ for (i = 0; i < types.length; i++) {
+ if (types[i].checked) {
+ type = types[i].value;
+ break;
+ }
+ }
+ // Linked
+ module.set_enabled(
+ 'field.git_repository_location', type === 'link-lp');
+ module.set_enabled('field.git_repository_name', type !== 'link-lp');
+ module.set_enabled('field.git_repository_owner', type !== 'link-lp');
+ // Import
+ var is_external = (type === 'import-external');
+ module.set_enabled('field.git_repository_url', is_external);
+ };
+
module.setup = function() {
Y.all('input[name="field.rcs_type"]').on(
'click', module.onclick_rcs_type);
@@ -120,6 +140,8 @@
'click', module.onclick_branch_type);
Y.all('input[name="field.default_vcs"]').on(
'click', module.onclick_default_vcs);
+ Y.all('input[name="field.git_repository_type"]').on(
+ 'click', module.onclick_git_repository_type);
// Set the initial state.
module.onclick_rcs_type();
@@ -128,6 +150,7 @@
if (document.getElementById('default_vcs')) {
module.setup_expanders();
module.onclick_default_vcs();
+ module.onclick_git_repository_type();
}
};
=== modified file 'lib/lp/code/javascript/tests/test_productseries-setbranch.html'
--- lib/lp/code/javascript/tests/test_productseries-setbranch.html 2012-10-26 09:54:28 +0000
+++ lib/lp/code/javascript/tests/test_productseries-setbranch.html 2016-10-15 14:08:56 +0000
@@ -61,7 +61,7 @@
<label>
<input class="radioType" checked="checked"
id="field.branch_type.0"
- name="field.branch_type" type="radio" value="link-lp-bzr" />
+ name="field.branch_type" type="radio" value="link-lp" />
Link to a Bazaar branch already in Launchpad
</label>
<table>
=== modified file 'lib/lp/code/templates/configure-code.pt'
--- lib/lp/code/templates/configure-code.pt 2016-04-28 02:09:21 +0000
+++ lib/lp/code/templates/configure-code.pt 2016-10-15 14:08:56 +0000
@@ -51,10 +51,10 @@
<div metal:use-macro="context/@@+configure-code-macros/no-keys"></div>
</div>
+ <h3>Link or import an existing branch</h3>
<table id="form_bzr" class="form">
<tr>
<td>
- <h3>Link or import an existing branch</h3>
<label tal:replace="structure view/branch_type_link">
Link to a Bazaar branch already on Launchpad
</label>
@@ -133,20 +133,47 @@
<span class="sprite gitbranch">Git settings</span>
</a>
<div id="git-expander-content">
- <div id="form_git" class="form">
- <div class="push-instructions">
- <div metal:use-macro="context/@@+configure-code-macros/push-instructions-git"></div>
- <div metal:use-macro="context/@@+configure-code-macros/no-keys"></div>
- </div>
-
- <h3>Link an existing repository</h3>
- <p>Link to an existing Git repository already on Launchpad</p>
- <table>
- <tal:widget define="widget nocall:view/widgets/git_repository_location">
- <metal:block use-macro="context/@@launchpad_form/widget_row" />
- </tal:widget>
- </table>
+ <div class="push-instructions">
+ <div metal:use-macro="context/@@+configure-code-macros/push-instructions-git"></div>
+ <div metal:use-macro="context/@@+configure-code-macros/no-keys"></div>
</div>
+
+ <h3>Link or import an existing repository</h3>
+ <table id="form_git" class="form">
+ <tr>
+ <td>
+ <label tal:replace="structure view/git_repository_type_link">
+ Link to a Git repository already on Launchpad
+ </label>
+ <table class="subordinate">
+ <tal:widget define="widget nocall:view/widgets/git_repository_location">
+ <metal:block use-macro="context/@@launchpad_form/widget_row" />
+ </tal:widget>
+ </table>
+ </td>
+ </tr>
+
+ <tr id="git_mirror"
+ tal:condition="request/features/code.import.git_target">
+ <td>
+ <label tal:replace="structure view/git_repository_type_import">
+ Import a repository hosted somewhere else
+ </label>
+ <table class="subordinate">
+ <tal:widget define="widget nocall:view/widgets/git_repository_name">
+ <metal:block use-macro="context/@@launchpad_form/widget_row" />
+ </tal:widget>
+ <tal:widget define="widget nocall:view/widgets/git_repository_owner">
+ <metal:block use-macro="context/@@launchpad_form/widget_row" />
+ </tal:widget>
+
+ <tal:widget define="widget nocall:view/widgets/git_repository_url">
+ <metal:block use-macro="context/@@launchpad_form/widget_row" />
+ </tal:widget>
+ </table>
+ </td>
+ </tr>
+ </table>
</div>
</div>
</tal:block>
=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py 2016-10-15 14:08:56 +0000
+++ lib/lp/registry/browser/product.py 2016-10-15 14:08:56 +0000
@@ -151,14 +151,20 @@
RevisionControlSystems,
TargetRevisionControlSystems,
)
-from lp.code.errors import BranchExists
+from lp.code.errors import (
+ BranchExists,
+ GitRepositoryExists,
+ )
from lp.code.interfaces.branch import IBranch
from lp.code.interfaces.branchjob import IRosettaUploadJobSource
from lp.code.interfaces.codeimport import (
ICodeImport,
ICodeImportSet,
)
-from lp.code.interfaces.gitrepository import IGitRepositorySet
+from lp.code.interfaces.gitrepository import (
+ IGitRepository,
+ IGitRepositorySet,
+ )
from lp.registry.browser import (
add_subscribe_link,
BaseRdfView,
@@ -1658,18 +1664,26 @@
return BatchNavigator(decorated_result, self.request)
-LINK_LP_BZR = 'link-lp-bzr'
+LINK_LP = 'link-lp'
IMPORT_EXTERNAL = 'import-external'
BRANCH_TYPE_VOCABULARY = SimpleVocabulary((
- SimpleTerm(LINK_LP_BZR, LINK_LP_BZR,
+ SimpleTerm(LINK_LP, LINK_LP,
_("Link to a Bazaar branch already on Launchpad")),
SimpleTerm(IMPORT_EXTERNAL, IMPORT_EXTERNAL,
_("Import a branch hosted somewhere else")),
))
+GIT_REPOSITORY_TYPE_VOCABULARY = SimpleVocabulary((
+ SimpleTerm(LINK_LP, LINK_LP,
+ _("Link to a Git repository already on Launchpad")),
+ SimpleTerm(IMPORT_EXTERNAL, IMPORT_EXTERNAL,
+ _("Import a repository hosted somewhere else")),
+ ))
+
+
class SetBranchForm(Interface):
"""The fields presented on the form for setting a branch."""
@@ -1706,23 +1720,37 @@
IBranch['owner'], __name__='branch_owner', title=_('Branch owner'),
description=_(''), required=True)
-
-def create_git_fields():
- return form.Fields(
- Choice(__name__='default_vcs',
- title=_("Project VCS"),
- required=True, vocabulary=VCSType,
- description=_("The version control system for "
- "this project.")),
- Choice(__name__='git_repository_location',
- title=_('Git repository'),
- required=False,
- vocabulary='GitRepositoryRestrictedOnProduct',
- description=_(
- "The Git repository for this project in Launchpad, "
- "if one exists, in the form: "
- "~user/project-name/+git/repo-name"))
- )
+ default_vcs = Choice(
+ title=_("Project VCS"), required=True, vocabulary=VCSType,
+ description=_("The version control system for this project."))
+
+ git_repository_location = Choice(
+ title=_('Git repository'), required=False,
+ vocabulary='GitRepositoryRestrictedOnProduct',
+ description=_(
+ "The Git repository for this project in Launchpad, "
+ "if one exists, in the form: "
+ "~user/project-name/+git/repo-name"))
+
+ git_repository_type = Choice(
+ title=_('Import type'), required=True,
+ vocabulary=GIT_REPOSITORY_TYPE_VOCABULARY,
+ description=_('The type of import'))
+
+ git_repository_name = copy_field(
+ IGitRepository['name'], __name__='git_repository_name',
+ title=_('Repository name'), description=_(''), required=True)
+
+ git_repository_owner = copy_field(
+ IGitRepository['owner'], __name__='git_repository_owner',
+ title=_('Repository owner'), description=_(''), required=True)
+
+ git_repository_url = URIField(
+ title=_('Repository URL'), required=True,
+ description=_('The URL of the Git repository.'),
+ allowed_schemes=["git", "http", "https"],
+ allow_userinfo=True, allow_port=True, allow_query=False,
+ allow_fragment=False, trailing_slash=False)
class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView,
@@ -1740,6 +1768,7 @@
custom_widget('rcs_type', LaunchpadRadioWidget)
custom_widget('branch_type', LaunchpadRadioWidget)
custom_widget('default_vcs', LaunchpadRadioWidget)
+ custom_widget('git_repository_type', LaunchpadRadioWidget)
errors_in_action = False
is_series = False
@@ -1754,8 +1783,9 @@
return dict(
rcs_type=RevisionControlSystems.BZR,
default_vcs=(self.context.pillar.inferred_vcs or VCSType.BZR),
- branch_type=LINK_LP_BZR,
+ branch_type=LINK_LP,
branch_location=self.series.branch,
+ git_repository_type=LINK_LP,
git_repository_location=repository_set.getDefaultRepository(
self.context.pillar))
@@ -1781,8 +1811,11 @@
def setUpFields(self):
"""See `LaunchpadFormView`."""
super(ProductSetBranchView, self).setUpFields()
- if not self.is_series:
- self.form_fields = (self.form_fields + create_git_fields())
+ if self.is_series:
+ self.form_fields = self.form_fields.omit(
+ 'default_vcs', 'git_repository_location',
+ 'git_repository_type', 'git_repository_name',
+ 'git_repository_owner', 'git_repository_url')
def setUpWidgets(self):
"""See `LaunchpadFormView`."""
@@ -1803,11 +1836,9 @@
widget = self.widgets['branch_type']
current_value = widget._getFormValue()
vocab = widget.vocabulary
-
- (self.branch_type_link,
- self.branch_type_import) = [
+ self.branch_type_link, self.branch_type_import = [
render_radio_widget_part(widget, value, current_value)
- for value in (LINK_LP_BZR, IMPORT_EXTERNAL)]
+ for value in (LINK_LP, IMPORT_EXTERNAL)]
if not self.is_series:
widget = self.widgets['default_vcs']
@@ -1818,14 +1849,21 @@
self.default_vcs_bzr = render_radio_widget_part(
widget, vocab.BZR, current_value, 'Bazaar')
+ widget = self.widgets['git_repository_type']
+ current_value = widget._getFormValue()
+ vocab = widget.vocabulary
+ self.git_repository_type_link, self.git_repository_type_import = [
+ render_radio_widget_part(widget, value, current_value)
+ for value in (LINK_LP, IMPORT_EXTERNAL)]
+
def _validateLinkLpBzr(self, data):
- """Validate data for link-lp-bzr case."""
+ """Validate data for link-lp bzr case."""
if 'branch_location' not in data:
self.setFieldError(
'branch_location', 'The branch location must be set.')
def _validateLinkLpGit(self, data):
- """Validate data for link-lp-git case."""
+ """Validate data for link-lp git case."""
if data.get('git_repository_location'):
repo = data.get('git_repository_location')
if not repo:
@@ -1833,8 +1871,8 @@
'git_repository_location',
'The repository does not exist.')
- def _validateImportExternal(self, data):
- """Validate data for import external case."""
+ def _validateImportExternalBzr(self, data):
+ """Validate data for import-external bzr case."""
rcs_type = data.get('rcs_type')
repo_url = data.get('repo_url')
@@ -1864,15 +1902,41 @@
elif rcs_type == RevisionControlSystems.CVS:
if 'cvs_module' not in data:
self.setFieldError('cvs_module', 'The CVS module must be set.')
- self._validateBranch(data)
- def _validateBranch(self, data):
- """Validate that branch name and owner are set."""
if 'branch_name' not in data:
self.setFieldError('branch_name', 'The branch name must be set.')
if 'branch_owner' not in data:
self.setFieldError('branch_owner', 'The branch owner must be set.')
+ def _validateImportExternalGit(self, data):
+ """Validate data for import-external git case."""
+ git_repository_url = data.get('git_repository_url')
+
+ # Private teams are forbidden from owning code imports.
+ git_repository_owner = data.get('git_repository_owner')
+ if git_repository_owner is not None and git_repository_owner.private:
+ self.setFieldError(
+ 'git_repository_owner',
+ 'Private teams are forbidden from owning external imports.')
+
+ if git_repository_url is None:
+ self.setFieldError(
+ 'git_repository_url',
+ 'You must set the external repository URL.')
+ else:
+ reason = validate_import_url(
+ git_repository_url, RevisionControlSystems.GIT,
+ TargetRevisionControlSystems.GIT)
+ if reason:
+ self.setFieldError('git_repository_url', reason)
+
+ if 'git_repository_name' not in data:
+ self.setFieldError(
+ 'git_repository_name', 'The repository name must be set.')
+ if 'git_repository_owner' not in data:
+ self.setFieldError(
+ 'git_repository_owner', 'The repository owner must be set.')
+
def _setRequired(self, names, value):
"""Mark the widget field as optional."""
for name in names:
@@ -1897,11 +1961,25 @@
def validate_widgets(self, data, names=None):
"""See `LaunchpadFormView`."""
- names = ['branch_type', 'rcs_type', 'default_vcs']
+ names = [
+ 'branch_type', 'rcs_type', 'default_vcs', 'git_repository_type']
super(ProductSetBranchView, self).validate_widgets(data, names)
+
+ if not self.is_series:
+ git_repository_type = data.get('git_repository_type')
+ if git_repository_type == LINK_LP:
+ # Mark other widgets as non-required.
+ self._setRequired(['git_repository_url', 'git_repository_name',
+ 'git_repository_owner'], False)
+ elif git_repository_type == IMPORT_EXTERNAL:
+ # The repository location is not required for validation.
+ self._setRequired(['git_repository_location'], False)
+ else:
+ raise AssertionError(
+ "Unknown Git repository type %s" % git_repository_type)
+
branch_type = data.get('branch_type')
-
- if branch_type == LINK_LP_BZR:
+ if branch_type == LINK_LP:
# Mark other widgets as non-required.
self._setRequired(['rcs_type', 'repo_url', 'cvs_module',
'branch_name', 'branch_owner'], False)
@@ -1918,6 +1996,7 @@
self._setRequired(['cvs_module'], True)
else:
raise AssertionError("Unknown branch type %s" % branch_type)
+
# Perform full validation now.
super(ProductSetBranchView, self).validate_widgets(data)
@@ -1927,13 +2006,22 @@
# continue as we'd likely just override the errors reported there.
if len(self.errors) > 0:
return
+
+ if not self.is_series:
+ git_repository_type = data.get('git_repository_type')
+ if git_repository_type == LINK_LP:
+ self._validateLinkLpGit(data)
+ elif git_repository_type == IMPORT_EXTERNAL:
+ self._validateImportExternalGit(data)
+ else:
+ raise AssertionError(
+ "Unknown Git repository type %s" % git_repository_type)
+
branch_type = data.get('branch_type')
- if not self.is_series:
- self._validateLinkLpGit(data)
- if branch_type == IMPORT_EXTERNAL:
- self._validateImportExternal(data)
- elif branch_type == LINK_LP_BZR:
+ if branch_type == LINK_LP:
self._validateLinkLpBzr(data)
+ elif branch_type == IMPORT_EXTERNAL:
+ self._validateImportExternalBzr(data)
else:
raise AssertionError("Unknown branch type %s" % branch_type)
@@ -1959,54 +2047,80 @@
if default_vcs:
self.context.vcs = default_vcs
- repo = data.get('git_repository_location')
- getUtility(IGitRepositorySet).setDefaultRepository(
- self.context, repo)
- if branch_type == LINK_LP_BZR:
+ git_repository_type = data.get('git_repository_type')
+
+ if git_repository_type == LINK_LP:
+ repo = data.get('git_repository_location')
+ repository_set = getUtility(IGitRepositorySet)
+ if repository_set.getDefaultRepository(self.context) != repo:
+ repository_set.setDefaultRepository(self.context, repo)
+ self.add_update_notification()
+ elif git_repository_type == IMPORT_EXTERNAL:
+ name = data.get('git_repository_name')
+ owner = data.get('git_repository_owner')
+ url = data.get('git_repository_url')
+ try:
+ code_import = getUtility(ICodeImportSet).new(
+ owner=owner,
+ registrant=self.user,
+ context=self.context,
+ branch_name=name,
+ rcs_type=RevisionControlSystems.GIT,
+ target_rcs_type=TargetRevisionControlSystems.GIT,
+ url=url)
+ except GitRepositoryExists as e:
+ self._setBranchExists(
+ e.existing_repository, 'git_repository_name')
+ self.abort_update()
+ return
+ getUtility(IGitRepositorySet).setDefaultRepository(
+ self.context, code_import.git_repository)
+ self.request.response.addInfoNotification(
+ 'Code import created and repository set as default.')
+ else:
+ raise UnexpectedFormData(git_repository_type)
+
+ if branch_type == LINK_LP:
branch_location = data.get('branch_location')
if branch_location != self.series.branch:
self.series.branch = branch_location
# Request an initial upload of translation files.
getUtility(IRosettaUploadJobSource).create(
self.series.branch, NULL_REVISION)
- else:
- self.series.branch = branch_location
- self.add_update_notification()
- else:
+ self.add_update_notification()
+ elif branch_type == IMPORT_EXTERNAL:
branch_name = data.get('branch_name')
branch_owner = data.get('branch_owner')
-
- if branch_type == IMPORT_EXTERNAL:
- rcs_type = data.get('rcs_type')
- if rcs_type == RevisionControlSystems.CVS:
- cvs_root = data.get('repo_url')
- cvs_module = data.get('cvs_module')
- url = None
- else:
- cvs_root = None
- cvs_module = None
- url = data.get('repo_url')
- rcs_item = RevisionControlSystems.items[rcs_type.name]
- try:
- code_import = getUtility(ICodeImportSet).new(
- owner=branch_owner,
- registrant=self.user,
- context=self.context,
- branch_name=branch_name,
- rcs_type=rcs_item,
- target_rcs_type=TargetRevisionControlSystems.BZR,
- url=url,
- cvs_root=cvs_root,
- cvs_module=cvs_module)
- except BranchExists as e:
- self._setBranchExists(e.existing_branch, 'branch_name')
- self.abort_update()
- return
- self.series.branch = code_import.branch
- self.request.response.addInfoNotification(
- 'Code import created and branch linked to the series.')
+ rcs_type = data.get('rcs_type')
+ if rcs_type == RevisionControlSystems.CVS:
+ cvs_root = data.get('repo_url')
+ cvs_module = data.get('cvs_module')
+ url = None
else:
- raise UnexpectedFormData(branch_type)
+ cvs_root = None
+ cvs_module = None
+ url = data.get('repo_url')
+ rcs_item = RevisionControlSystems.items[rcs_type.name]
+ try:
+ code_import = getUtility(ICodeImportSet).new(
+ owner=branch_owner,
+ registrant=self.user,
+ context=self.context,
+ branch_name=branch_name,
+ rcs_type=rcs_item,
+ target_rcs_type=TargetRevisionControlSystems.BZR,
+ url=url,
+ cvs_root=cvs_root,
+ cvs_module=cvs_module)
+ except BranchExists as e:
+ self._setBranchExists(e.existing_branch, 'branch_name')
+ self.abort_update()
+ return
+ self.series.branch = code_import.branch
+ self.request.response.addInfoNotification(
+ 'Code import created and branch linked to the series.')
+ else:
+ raise UnexpectedFormData(branch_type)
class ProductRdfView(BaseRdfView):
=== modified file 'lib/lp/registry/browser/tests/productseries-setbranch-view.txt'
--- lib/lp/registry/browser/tests/productseries-setbranch-view.txt 2016-10-15 14:08:56 +0000
+++ lib/lp/registry/browser/tests/productseries-setbranch-view.txt 2016-10-15 14:08:56 +0000
@@ -39,7 +39,7 @@
must be provided.
>>> form = {
- ... 'field.branch_type': 'link-lp-bzr',
+ ... 'field.branch_type': 'link-lp',
... 'field.actions.update': 'Update',
... }
>>> view = create_initialized_view(
@@ -52,7 +52,7 @@
validation error.
>>> form = {
- ... 'field.branch_type': 'link-lp-bzr',
+ ... 'field.branch_type': 'link-lp',
... 'field.branch_location': 'foo',
... 'field.actions.update': 'Update',
... }
@@ -69,7 +69,7 @@
>>> branch = factory.makeBranch(
... name='impala-branch', owner=driver, product=product)
>>> form = {
- ... 'field.branch_type': 'link-lp-bzr',
+ ... 'field.branch_type': 'link-lp',
... 'field.branch_location': branch.unique_name,
... 'field.actions.update': 'Update',
... }
=== modified file 'lib/lp/registry/browser/tests/test_product.py'
--- lib/lp/registry/browser/tests/test_product.py 2016-09-19 11:47:33 +0000
+++ lib/lp/registry/browser/tests/test_product.py 2016-10-15 14:08:56 +0000
@@ -30,7 +30,10 @@
InformationType,
ServiceUsage,
)
+from lp.code.enums import RevisionControlSystems
+from lp.code.interfaces.codeimport import CODE_IMPORT_GIT_TARGET_FEATURE_FLAG
from lp.code.interfaces.gitrepository import IGitRepositorySet
+from lp.code.tests.helpers import GitHostingFixture
from lp.registry.browser.product import (
ProjectAddStepOne,
ProjectAddStepTwo,
@@ -47,6 +50,7 @@
from lp.registry.model.product import Product
from lp.services.config import config
from lp.services.database.interfaces import IStore
+from lp.services.features.testing import FeatureFixture
from lp.services.webapp.publisher import canonical_url
from lp.services.webapp.vhosts import allvhosts
from lp.testing import (
@@ -914,7 +918,7 @@
# control defaults to empty.
project = self.factory.makeProduct()
browser = self.getBrowser(project, '+configure-code')
- self.assertEqual('', browser.getControl('Git repository').value)
+ self.assertEqual('', browser.getControl('Git repository:').value)
def test_initial_git_repository(self):
# If a project has a default Git repository, its "Git repository"
@@ -926,14 +930,16 @@
unique_name = repo.unique_name
browser = self.getBrowser(project, '+configure-code')
self.assertEqual(
- unique_name, browser.getControl('Git repository').value)
+ unique_name, browser.getControl('Git repository:').value)
def test_link_existing_git_repository(self):
repo = removeSecurityProxy(self.factory.makeGitRepository(
target=self.factory.makeProduct()))
browser = self.getBrowser(repo.project, '+configure-code')
browser.getControl('Git', index=0).click()
- browser.getControl('Git repository').value = repo.shortened_path
+ self.assertTrue(browser.getControl(
+ 'Link to a Git repository already on Launchpad').selected)
+ browser.getControl('Git repository:').value = repo.shortened_path
browser.getControl('Update').click()
tag = Tag(
@@ -941,6 +947,62 @@
text='Project settings updated.')
self.assertThat(browser.contents, HTMLContains(tag))
+ def test_import_git_repository_requires_feature_flag(self):
+ project = self.factory.makeProduct()
+ browser = self.getBrowser(project, '+configure-code')
+ self.assertRaises(
+ LookupError, browser.getControl,
+ 'Import a repository hosted somewhere else')
+
+ def test_import_git_repository(self):
+ self.useFixture(
+ FeatureFixture({CODE_IMPORT_GIT_TARGET_FEATURE_FLAG: u'on'}))
+ self.useFixture(GitHostingFixture())
+ owner = self.factory.makePerson()
+ project = self.factory.makeProduct(owner=owner)
+ browser = self.getBrowser(project, '+configure-code')
+ browser.getControl('Git', index=0).click()
+ browser.getControl('Import a repository hosted somewhere else').click()
+ browser.getControl('Repository name').value = 'imported'
+ browser.getControl('Repository URL').value = (
+ 'https://git.example.org/imported')
+ browser.getControl('Update').click()
+
+ tag = Tag(
+ 'success-div', 'div', attrs={'class': 'informational message'},
+ text='Code import created and repository set as default.')
+ self.assertThat(browser.contents, HTMLContains(tag))
+ login_person(owner)
+ repo = getUtility(IGitRepositorySet).getDefaultRepository(project)
+ self.assertIsNotNone(repo.code_import)
+ self.assertEqual(RevisionControlSystems.GIT, repo.code_import.rcs_type)
+ self.assertEqual(
+ 'https://git.example.org/imported', repo.code_import.url)
+
+ def test_import_git_repository_bad_scheme(self):
+ self.useFixture(
+ FeatureFixture({CODE_IMPORT_GIT_TARGET_FEATURE_FLAG: u'on'}))
+ owner = self.factory.makePerson()
+ project = self.factory.makeProduct(owner=owner)
+ browser = self.getBrowser(project, '+configure-code')
+ browser.getControl('Git', index=0).click()
+ browser.getControl('Import a repository hosted somewhere else').click()
+ browser.getControl('Repository name').value = 'imported'
+ browser.getControl('Repository URL').value = (
+ 'svn://svn.example.org/imported')
+ browser.getControl('Update').click()
+
+ tag = Tag(
+ 'error', 'div', attrs={'class': 'message'},
+ text=(
+ 'The URI scheme "svn" is not allowed. '
+ 'Only URIs with the following schemes may be used: '
+ 'git, http, https'))
+ self.assertThat(browser.contents, HTMLContains(tag))
+ login_person(owner)
+ self.assertIsNone(
+ getUtility(IGitRepositorySet).getDefaultRepository(project))
+
def test_editsshkeys_link_if_no_keys_registered(self):
project = self.factory.makeProduct()
browser = self.getBrowser(project, '+configure-code')
Follow ups