← Back to team overview

launchpad-reviewers team mailing list archive

Re: [Merge] lp:~cjwatson/launchpad/git-target-inline-default-repo into lp:launchpad

 

Review: Approve code



Diff comments:

> === modified file 'lib/lp/code/browser/branchlisting.py'
> --- lib/lp/code/browser/branchlisting.py	2015-04-22 12:03:05 +0000
> +++ lib/lp/code/browser/branchlisting.py	2015-05-01 13:26:23 +0000
> @@ -1,4 +1,4 @@
> -# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
> +# Copyright 2009-2015 Canonical Ltd.  This software is licensed under the
>  # GNU Affero General Public License version 3 (see the file LICENSE).
>  
>  """Base class view for branch listings."""
> @@ -69,6 +69,7 @@
>  from lp.bugs.interfaces.bugbranch import IBugBranchSet
>  from lp.code.browser.branch import BranchMirrorMixin
>  from lp.code.browser.branchmergeproposallisting import ActiveReviewsView
> +from lp.code.browser.gitrepository import GitRefBatchNavigator
>  from lp.code.browser.summary import BranchCountSummaryView
>  from lp.code.enums import (
>      BranchLifecycleStatus,
> @@ -85,6 +86,7 @@
>  from lp.code.interfaces.branchcollection import IAllBranches
>  from lp.code.interfaces.branchnamespace import IBranchNamespacePolicy
>  from lp.code.interfaces.branchtarget import IBranchTarget
> +from lp.code.interfaces.gitrepository import IGitRepositorySet
>  from lp.code.interfaces.revision import IRevisionSet
>  from lp.code.interfaces.revisioncache import IRevisionCache
>  from lp.code.interfaces.seriessourcepackagebranch import (
> @@ -525,6 +527,7 @@
>      field_names = ['lifecycle', 'sort_by']
>      development_focus_branch = None
>      show_set_development_focus = False
> +    default_git_repository = None
>      custom_widget('lifecycle', LaunchpadDropdownWidget)
>      custom_widget('sort_by', LaunchpadDropdownWidget)
>      # Showing the series links is only really useful on product listing
> @@ -1096,6 +1099,26 @@
>          else:
>              return None
>  
> +    @cachedproperty
> +    def default_git_repository(self):
> +        repository = getUtility(IGitRepositorySet).getDefaultRepository(
> +            self.context)
> +        if repository is None:
> +            return None
> +        elif check_permission('launchpad.View', repository):
> +            return repository
> +        else:
> +            return None
> +
> +    def default_git_repository_branches(self):
> +        """All branches in the default Git repository, sorted for display."""
> +        return GitRefBatchNavigator(self, self.default_git_repository)
> +
> +    @property
> +    def has_default_git_repository(self):
> +        """Is there a default Git repository?"""
> +        return self.default_git_repository is not None
> +
>      @property
>      def no_branch_message(self):
>          if (self.selected_lifecycle_status is not None
> 
> === modified file 'lib/lp/code/browser/gitrepository.py'
> --- lib/lp/code/browser/gitrepository.py	2015-04-21 09:31:58 +0000
> +++ lib/lp/code/browser/gitrepository.py	2015-05-01 13:26:23 +0000
> @@ -6,6 +6,7 @@
>  __metaclass__ = type
>  
>  __all__ = [
> +    'GitRefBatchNavigator',
>      'GitRepositoryBreadcrumb',
>      'GitRepositoryContextMenu',
>      'GitRepositoryNavigation',
> @@ -13,7 +14,7 @@
>      'GitRepositoryView',
>      ]
>  
> -from bzrlib import urlutils
> +from storm.expr import Desc
>  from zope.interface import implements
>  
>  from lp.app.browser.informationtype import InformationTypePortletMixin
> @@ -115,13 +116,19 @@
>      implements(IGitRefBatchNavigator)
>  
>      def __init__(self, view, context):
> +        self.context = context
>          super(GitRefBatchNavigator, self).__init__(
> -            context.branches, view.request,
> +            self._branches, view.request,
>              size=config.launchpad.branchlisting_batch_size)
>          self.view = view
>          self.column_count = 3
>  
>      @property
> +    def _branches(self):
> +        from lp.code.model.gitref import GitRef
> +        return self.context.branches.order_by(Desc(GitRef.committer_date))
> +
> +    @property
>      def table_class(self):
>          # XXX: MichaelHudson 2007-10-18 bug=153894: This means there are two
>          # ways of sorting a one-page branch listing, which is confusing and
> @@ -151,22 +158,6 @@
>                  self.request, "launchpad.LimitedView", authorised_people)
>  
>      @property
> -    def anon_url(self):
> -        if self.context.visibleByUser(None):
> -            return urlutils.join(
> -                config.codehosting.git_anon_root, self.context.shortened_path)
> -        else:
> -            return None
> -
> -    @property
> -    def ssh_url(self):
> -        if self.user is not None:
> -            return urlutils.join(
> -                config.codehosting.git_ssh_root, self.context.shortened_path)
> -        else:
> -            return None
> -
> -    @property
>      def user_can_push(self):
>          """Whether the user can push to this branch."""
>          return check_permission("launchpad.Edit", self.context)
> 
> === modified file 'lib/lp/code/browser/tests/test_gitrepository.py'
> --- lib/lp/code/browser/tests/test_gitrepository.py	2015-03-24 15:15:23 +0000
> +++ lib/lp/code/browser/tests/test_gitrepository.py	2015-05-01 13:26:23 +0000
> @@ -8,7 +8,6 @@
>  from datetime import datetime
>  
>  from BeautifulSoup import BeautifulSoup
> -from bzrlib import urlutils
>  from fixtures import FakeLogger
>  import pytz
>  from testtools.matchers import Equals
> @@ -21,7 +20,6 @@
>  from lp.code.interfaces.gitrepository import GIT_FEATURE_FLAG
>  from lp.code.interfaces.revision import IRevisionSet
>  from lp.registry.interfaces.person import PersonVisibility
> -from lp.services.config import config
>  from lp.services.features.testing import FeatureFixture
>  from lp.services.webapp.publisher import canonical_url
>  from lp.testing import (
> @@ -70,49 +68,6 @@
>          super(TestGitRepositoryView, self).setUp()
>          self.useFixture(FeatureFixture({GIT_FEATURE_FLAG: u"on"}))
>  
> -    def test_anon_url_for_public(self):
> -        # Public repositories have an anonymous URL, visible to anyone.
> -        repository = self.factory.makeGitRepository()
> -        view = create_initialized_view(repository, "+index")
> -        expected_url = urlutils.join(
> -            config.codehosting.git_anon_root, repository.shortened_path)
> -        self.assertEqual(expected_url, view.anon_url)
> -
> -    def test_anon_url_not_for_private(self):
> -        # Private repositories do not have an anonymous URL.
> -        owner = self.factory.makePerson()
> -        repository = self.factory.makeGitRepository(
> -            owner=owner, information_type=InformationType.USERDATA)
> -        with person_logged_in(owner):
> -            view = create_initialized_view(repository, "+index")
> -            self.assertIsNone(view.anon_url)
> -
> -    def test_ssh_url_for_public_logged_in(self):
> -        # Public repositories have an SSH URL, visible if logged in.
> -        repository = self.factory.makeGitRepository()
> -        with person_logged_in(repository.owner):
> -            view = create_initialized_view(repository, "+index")
> -            expected_url = urlutils.join(
> -                config.codehosting.git_ssh_root, repository.shortened_path)
> -            self.assertEqual(expected_url, view.ssh_url)
> -
> -    def test_ssh_url_for_public_not_anonymous(self):
> -        # Public repositories do not have an SSH URL if not logged in.
> -        repository = self.factory.makeGitRepository()
> -        view = create_initialized_view(repository, "+index")
> -        self.assertIsNone(view.ssh_url)
> -
> -    def test_ssh_url_for_private(self):
> -        # Private repositories have an SSH URL.
> -        owner = self.factory.makePerson()
> -        repository = self.factory.makeGitRepository(
> -            owner=owner, information_type=InformationType.USERDATA)
> -        with person_logged_in(owner):
> -            view = create_initialized_view(repository, "+index")
> -            expected_url = urlutils.join(
> -                config.codehosting.git_ssh_root, repository.shortened_path)
> -            self.assertEqual(expected_url, view.ssh_url)
> -
>      def test_user_can_push(self):
>          # A user can push if they have edit permissions.
>          repository = self.factory.makeGitRepository()
> 
> === modified file 'lib/lp/code/browser/tests/test_product.py'
> --- lib/lp/code/browser/tests/test_product.py	2014-02-25 06:42:01 +0000
> +++ lib/lp/code/browser/tests/test_product.py	2015-05-01 13:26:23 +0000
> @@ -1,4 +1,4 @@
> -# Copyright 2009-2012 Canonical Ltd.  This software is licensed under the
> +# Copyright 2009-2015 Canonical Ltd.  This software is licensed under the
>  # GNU Affero General Public License version 3 (see the file LICENSE).
>  
>  """Tests for the product view classes and templates."""
> @@ -19,8 +19,13 @@
>      ServiceUsage,
>      )
>  from lp.code.enums import BranchType
> +from lp.code.interfaces.gitrepository import (
> +    GIT_FEATURE_FLAG,
> +    IGitRepositorySet,
> +    )
>  from lp.code.interfaces.revision import IRevisionSet
>  from lp.registry.enums import BranchSharingPolicy
> +from lp.services.features.testing import FeatureFixture
>  from lp.services.webapp import canonical_url
>  from lp.testing import (
>      ANONYMOUS,
> @@ -207,6 +212,39 @@
>          expected = 'There are no branches for %s' % product.displayname
>          self.assertIn(expected, html)
>  
> +    def test_no_default_git_repository(self):
> +        # If there is no default Git repository, Product:+branches does not
> +        # try to render one.
> +        product = self.factory.makeProduct()
> +        view = create_initialized_view(
> +            product, '+branches', rootsite='code', principal=product.owner)
> +        self.assertIsNone(view.default_git_repository)
> +        self.assertFalse(view.has_default_git_repository)
> +        content = view()
> +        self.assertNotIn('git clone', content)
> +
> +    def test_default_git_repository(self):
> +        # If there is a default Git repository, Product:+branches shows a
> +        # summary of its branches.
> +        self.useFixture(FeatureFixture({GIT_FEATURE_FLAG: u"on"}))
> +        product = self.factory.makeProduct()
> +        repository = self.factory.makeGitRepository(target=product)
> +        self.factory.makeGitRefs(
> +            repository=repository,
> +            paths=[u"refs/heads/master", u"refs/heads/another-branch"])
> +        with person_logged_in(product.owner):
> +            getUtility(IGitRepositorySet).setDefaultRepository(
> +                product, repository)
> +        view = create_initialized_view(
> +            product, '+branches', rootsite='code', principal=product.owner)
> +        self.assertEqual(repository, view.default_git_repository)
> +        self.assertTrue(view.has_default_git_repository)
> +        content = view()
> +        self.assertIn('git clone', content)
> +        # XXX cjwatson 2015-04-30: These tests are not very precise.
> +        self.assertIn('master', content)
> +        self.assertIn('another-branch', content)
> +
>  
>  class TestProductCodeIndexServiceUsages(ProductTestBase, BrowserTestCase):
>      """Tests for the product code page, especially the usage messasges."""
> 
> === modified file 'lib/lp/code/interfaces/gitrepository.py'
> --- lib/lp/code/interfaces/gitrepository.py	2015-04-28 16:39:15 +0000
> +++ lib/lp/code/interfaces/gitrepository.py	2015-05-01 13:26:23 +0000
> @@ -217,6 +217,12 @@
>          "The identity of this repository: a VCS-independent synonym for "
>          "git_identity.")
>  
> +    anon_url = Attribute(
> +        "An anonymous (git://) URL for this repository, or None in the case "
> +        "of private repositories.")
> +
> +    ssh_url = Attribute("A git+ssh:// URL for this repository.")
> +
>      refs = exported(CollectionField(
>          title=_("The references present in this repository."),
>          readonly=True,
> 
> === modified file 'lib/lp/code/model/gitrepository.py'
> --- lib/lp/code/model/gitrepository.py	2015-04-28 16:39:15 +0000
> +++ lib/lp/code/model/gitrepository.py	2015-05-01 13:26:23 +0000
> @@ -322,6 +322,21 @@
>              config.codehosting.git_browse_root, self.unique_name)
>  
>      @property
> +    def anon_url(self):
> +        """See `IGitRepository`."""
> +        if self.visibleByUser(None):
> +            return urlutils.join(
> +                config.codehosting.git_anon_root, self.shortened_path)
> +        else:
> +            return None
> +
> +    @property
> +    def ssh_url(self):
> +        """See `IGitRepository`."""
> +        return urlutils.join(
> +            config.codehosting.git_ssh_root, self.shortened_path)
> +
> +    @property
>      def private(self):
>          return self.information_type in PRIVATE_INFORMATION_TYPES
>  
> 
> === modified file 'lib/lp/code/model/tests/test_gitrepository.py'
> --- lib/lp/code/model/tests/test_gitrepository.py	2015-04-28 16:39:15 +0000
> +++ lib/lp/code/model/tests/test_gitrepository.py	2015-05-01 13:26:23 +0000
> @@ -11,6 +11,7 @@
>  import hashlib
>  import json
>  
> +from bzrlib import urlutils
>  from lazr.lifecycle.event import ObjectModifiedEvent
>  from lazr.lifecycle.snapshot import Snapshot
>  import transaction
> @@ -72,6 +73,7 @@
>      )
>  from lp.registry.interfaces.personproduct import IPersonProductFactory
>  from lp.registry.tests.test_accesspolicy import get_policies_for_artifact
> +from lp.services.config import config
>  from lp.services.database.constants import UTC_NOW
>  from lp.services.features.testing import FeatureFixture
>  from lp.services.mail import stub
> @@ -353,21 +355,53 @@
>      # actually notices any interesting kind of repository modifications.
>  
>  
> -class TestCodebrowse(TestCaseWithFactory):
> -    """Tests for Git repository codebrowse support."""
> +class TestGitRepositoryURLs(TestCaseWithFactory):
> +    """Tests for Git repository URLs."""
>  
>      layer = DatabaseFunctionalLayer
>  
>      def setUp(self):
> -        super(TestCodebrowse, self).setUp()
> +        super(TestGitRepositoryURLs, self).setUp()
>          self.useFixture(FeatureFixture({GIT_FEATURE_FLAG: u"on"}))
>  
> -    def test_simple(self):
> +    def test_codebrowse_url(self):
>          # The basic codebrowse URL for a repository is an 'https' URL.
>          repository = self.factory.makeGitRepository()
> -        self.assertEqual(
> -            "https://git.launchpad.dev/"; + repository.unique_name,
> -            repository.getCodebrowseUrl())
> +        expected_url = urlutils.join(
> +            config.codehosting.git_browse_root, repository.unique_name)
> +        self.assertEqual(expected_url, repository.getCodebrowseUrl())
> +
> +    def test_anon_url_for_public(self):
> +        # Public repositories have an anonymous URL, visible to anyone.
> +        repository = self.factory.makeGitRepository()
> +        expected_url = urlutils.join(
> +            config.codehosting.git_anon_root, repository.shortened_path)
> +        self.assertEqual(expected_url, repository.anon_url)
> +
> +    def test_anon_url_not_for_private(self):
> +        # Private repositories do not have an anonymous URL.
> +        owner = self.factory.makePerson()
> +        repository = self.factory.makeGitRepository(
> +            owner=owner, information_type=InformationType.USERDATA)
> +        with person_logged_in(owner):
> +            self.assertIsNone(repository.anon_url)
> +
> +    def test_ssh_url_for_public(self):
> +        # Public repositories have an SSH URL.
> +        repository = self.factory.makeGitRepository()
> +        expected_url = urlutils.join(
> +            config.codehosting.git_ssh_root, repository.shortened_path)
> +        self.assertEqual(expected_url, repository.ssh_url)
> +
> +    def test_ssh_url_for_private(self):
> +        # Private repositories have an SSH URL.
> +        owner = self.factory.makePerson()
> +        repository = self.factory.makeGitRepository(
> +            owner=owner, information_type=InformationType.USERDATA)
> +        with person_logged_in(owner):
> +            expected_url = urlutils.join(
> +                config.codehosting.git_ssh_root, repository.shortened_path)
> +            self.assertEqual(expected_url, repository.ssh_url)
>  
>  
>  class TestGitRepositoryNamespace(TestCaseWithFactory):
> 
> === modified file 'lib/lp/code/templates/gitref-listing.pt'
> --- lib/lp/code/templates/gitref-listing.pt	2015-04-29 15:06:39 +0000
> +++ lib/lp/code/templates/gitref-listing.pt	2015-05-01 13:26:23 +0000
> @@ -24,7 +24,7 @@
>      </div>
>    </tal:needs-batch>
>  
> -  <table tal:attributes="class context/table_class" id="branchtable">
> +  <table tal:attributes="class context/table_class" id="gitreftable">
>      <thead>
>        <tr>
>          <th>Name</th>
> 
> === modified file 'lib/lp/code/templates/gitrepository-management.pt'
> --- lib/lp/code/templates/gitrepository-management.pt	2015-03-04 16:49:42 +0000
> +++ lib/lp/code/templates/gitrepository-management.pt	2015-05-01 13:26:23 +0000
> @@ -7,15 +7,15 @@
>    <dl id="clone-url">
>      <dt>Get this repository:</dt>
>      <dd>
> -      <tal:anonymous condition="view/anon_url">
> +      <tal:anonymous condition="context/anon_url">
>          <tt class="command">
> -          git clone <span class="anon-url" tal:content="view/anon_url" />
> +          git clone <span class="anon-url" tal:content="context/anon_url" />
>          </tt>
>          <br />
>        </tal:anonymous>
> -      <tal:ssh condition="view/ssh_url">
> +      <tal:ssh condition="view/user">
>          <tt class="command">
> -          git clone <span class="ssh-url" tal:content="view/ssh_url" />
> +          git clone <span class="ssh-url" tal:content="context/ssh_url" />
>          </tt>
>        </tal:ssh>
>      </dd>
> 
> === modified file 'lib/lp/code/templates/product-branch-summary.pt'
> --- lib/lp/code/templates/product-branch-summary.pt	2012-10-08 02:02:19 +0000
> +++ lib/lp/code/templates/product-branch-summary.pt	2015-05-01 13:26:23 +0000
> @@ -56,7 +56,8 @@
>      </p>
>    </div>
>  
> -  <tal:no-branches condition="not: view/branch_count">
> +  <tal:no-branches
> +      condition="python: not view.branch_count and not view.has_default_git_repository">
>      There are no branches for <tal:project-name replace="context/displayname"/>
>      in Launchpad.
>      <tal:can-configure condition="view/can_configure_branches">
> @@ -78,6 +79,23 @@
>      </tal:can-configure>
>    </tal:no-branches>
>  
> +  <div tal:condition="view/has_default_git_repository"
> +       style="margin: 1em 0"
> +       tal:define="repository view/default_git_repository">
> +    You can
> +    <a tal:attributes="href repository/getCodebrowseUrl">browse the
> +      source code</a>
> +    for the default Git repository or get a copy of the repository using
> +    the command:<br/>
> +    <tt class="command">git clone
> +    <tal:logged-in condition="view/user">
> +      <tal:git-ssh-url replace="repository/ssh_url"/>
> +    </tal:logged-in>
> +    <tal:not-logged-in condition="not: view/user">
> +      <tal:git-anon-url replace="repository/anon_url"/>
> +    </tal:not-logged-in></tt>
> +  </div>
> +
>    <tal:has-branches condition="view/branch_count">
>      <div tal:condition="view/has_development_focus_branch"
>           style="margin: 1em 0"
> @@ -99,7 +117,7 @@
>    <tal:has-user condition="view/user">
>      <p id="push-instructions"
>        tal:condition="not: context/codehosting_usage/enumvalue:UNKNOWN">
> -      You can push the branch directly to Launchpad with the command:<br />
> +      You can push a Bazaar branch directly to Launchpad with the command:<br />
>        <tt class="command">
>          bzr push lp:~<tal:user replace="view/user/name"/>/<tal:project replace="context/name"/>/<tal:series replace="context/name"/>
>        </tt>
> 
> === modified file 'lib/lp/code/templates/product-branches.pt'
> --- lib/lp/code/templates/product-branches.pt	2012-10-08 02:02:19 +0000
> +++ lib/lp/code/templates/product-branches.pt	2015-05-01 13:26:23 +0000
> @@ -60,9 +60,22 @@
>        condition="not: view/context/codehosting_usage/enumvalue:UNKNOWN"
>        replace="structure context/@@+portlet-product-codestatistics" />
>  
> +    <tal:has-default-git-repository condition="view/has_default_git_repository">
> +      <div id="default-repository-branches" class="portlet"
> +           tal:define="repository view/default_git_repository;
> +                       branches view/default_git_repository_branches">
> +        <h2>Git branches</h2>
> +        <tal:default-repository-branches
> +          replace="structure branches/@@+ref-listing" />
> +      </div>
> +    </tal:has-default-git-repository>
> +
>      <tal:has-branches condition="view/branch_count"
>                        define="branches view/branches">
> -      <tal:branchlisting content="structure branches/@@+branch-listing" />
> +      <div class="portlet">
> +        <h2>Bazaar branches</h2>
> +        <tal:branchlisting content="structure branches/@@+branch-listing" />
> +      </div>
>      </tal:has-branches>
>  
>    </tal:main>
> 
> === modified file 'lib/lp/registry/doc/product.txt'
> --- lib/lp/registry/doc/product.txt	2015-01-29 18:43:52 +0000
> +++ lib/lp/registry/doc/product.txt	2015-05-01 13:26:23 +0000
> @@ -521,6 +521,31 @@
>      landscape
>  
>  
> +Products with Git repositories
> +------------------------------
> +
> +Products are considered to officially support Launchpad as a location for
> +their code if they have a default Git repository.
> +
> +    >>> from lp.code.interfaces.gitrepository import (
> +    ...     GIT_FEATURE_FLAG,
> +    ...     IGitRepositorySet,
> +    ...     )
> +    >>> from lp.services.features.testing import FeatureFixture
> +    >>> firefox.development_focus.branch = None
> +    >>> print firefox.official_codehosting
> +    False
> +    >>> print firefox.codehosting_usage.name
> +    UNKNOWN
> +    >>> with FeatureFixture({GIT_FEATURE_FLAG: 'on'}):
> +    ...     getUtility(IGitRepositorySet).setDefaultRepository(
> +    ...         firefox, factory.makeGitRepository(target=firefox))
> +    >>> print firefox.official_codehosting
> +    True
> +    >>> print firefox.codehosting_usage.name
> +    LAUNCHPAD
> +
> +
>  Primary translatable
>  --------------------
>  
> 
> === modified file 'lib/lp/registry/model/product.py'
> --- lib/lp/registry/model/product.py	2015-03-17 10:45:07 +0000
> +++ lib/lp/registry/model/product.py	2015-05-01 13:26:23 +0000
> @@ -116,6 +116,7 @@
>      )
>  from lp.code.enums import BranchType
>  from lp.code.interfaces.branch import DEFAULT_BRANCH_STATUS_IN_LISTING
> +from lp.code.interfaces.gitrepository import IGitRepositorySet
>  from lp.code.model.branch import Branch
>  from lp.code.model.branchnamespace import BRANCH_POLICY_ALLOWED_TYPES
>  from lp.code.model.hasbranches import (
> @@ -581,7 +582,10 @@
>  
>      @property
>      def official_codehosting(self):
> -        return self.development_focus.branch is not None
> +        repository = getUtility(IGitRepositorySet).getDefaultRepository(self)
> +        return (
> +            self.development_focus.branch is not None or
> +            repository is not None)
>  
>      @property
>      def official_anything(self):
> @@ -613,9 +617,11 @@
>  
>      @property
>      def codehosting_usage(self):
> -        if self.development_focus.branch is None:
> +        repository = getUtility(IGitRepositorySet).getDefaultRepository(self)
> +        if self.development_focus.branch is None and repository is None:
>              return ServiceUsage.UNKNOWN
> -        elif self.development_focus.branch.branch_type == BranchType.HOSTED:
> +        elif (repository is not None or
> +              self.development_focus.branch.branch_type == BranchType.HOSTED):
>              return ServiceUsage.LAUNCHPAD
>          elif self.development_focus.branch.branch_type in (
>              BranchType.MIRRORED,

This'll do for now, but we should probably make it explicit to allow mirrors to not lie about officialness.

> 
> === modified file 'lib/lp/registry/templates/productseries-setbranch.pt'
> --- lib/lp/registry/templates/productseries-setbranch.pt	2012-10-09 01:07:52 +0000
> +++ lib/lp/registry/templates/productseries-setbranch.pt	2015-05-01 13:26:23 +0000
> @@ -19,7 +19,7 @@
>  <div metal:fill-slot="main">
>  
>    <p id="push-instructions">
> -    You can push the branch directly to Launchpad with the command:<br />
> +    You can push a Bazaar branch directly to Launchpad with the command:<br />
>      <tt class="command">
>        bzr push lp:~<tal:user replace="view/user/name"/>/<tal:project replace="context/product/name"/>/<tal:series replace="context/name"/>
>      </tt>
> 
> === modified file 'lib/lp/registry/tests/test_service_usage.py'
> --- lib/lp/registry/tests/test_service_usage.py	2012-01-01 02:58:52 +0000
> +++ lib/lp/registry/tests/test_service_usage.py	2015-05-01 13:26:23 +0000
> @@ -1,10 +1,17 @@
> -# Copyright 2010 Canonical Ltd.  This software is licensed under the
> +# Copyright 2010-2015 Canonical Ltd.  This software is licensed under the
>  # GNU Affero General Public License version 3 (see the file LICENSE).
>  
>  __metaclass__ = type
>  
> +from zope.component import getUtility
> +
>  from lp.app.enums import ServiceUsage
>  from lp.code.enums import BranchType
> +from lp.code.interfaces.gitrepository import (
> +    GIT_FEATURE_FLAG,
> +    IGitRepositorySet,
> +    )
> +from lp.services.features.testing import FeatureFixture
>  from lp.testing import (
>      login_person,
>      TestCaseWithFactory,
> @@ -192,7 +199,7 @@
>              self.target.codehosting_usage)
>  
>      def test_codehosting_hosted_branch(self):
> -        # A branch on Launchpad is HOSTED.
> +        # A branch on Launchpad has LAUNCHPAD usage.
>          login_person(self.target.owner)
>          self.target.development_focus.branch = self.factory.makeProductBranch(
>              product=self.target,
> @@ -201,6 +208,17 @@
>              ServiceUsage.LAUNCHPAD,
>              self.target.codehosting_usage)
>  
> +    def test_codehosting_default_git_repository(self):
> +        # A default Git repository on Launchpad has LAUNCHPAD usage.
> +        self.useFixture(FeatureFixture({GIT_FEATURE_FLAG: u"on"}))
> +        login_person(self.target.owner)
> +        repository = self.factory.makeGitRepository(target=self.target)
> +        getUtility(IGitRepositorySet).setDefaultRepository(
> +            self.target, repository)
> +        self.assertEqual(
> +            ServiceUsage.LAUNCHPAD,
> +            self.target.codehosting_usage)
> +
>  
>  class TestProductSeriesUsageEnums(
>      TestCaseWithFactory,
> 


-- 
https://code.launchpad.net/~cjwatson/launchpad/git-target-inline-default-repo/+merge/258033
Your team Launchpad code reviewers is subscribed to branch lp:launchpad.


References