launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #22849
[Merge] lp:~twom/launchpad/git-active-review-on-more-git-repo into lp:launchpad
Tom Wardill has proposed merging lp:~twom/launchpad/git-active-review-on-more-git-repo into lp:launchpad.
Commit message:
Add available review targets and proposals to the git repository overview page
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~twom/launchpad/git-active-review-on-more-git-repo/+merge/353884
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~twom/launchpad/git-active-review-on-more-git-repo into lp:launchpad.
=== modified file 'lib/lp/_schema_circular_imports.py'
--- lib/lp/_schema_circular_imports.py 2018-05-01 16:08:03 +0000
+++ lib/lp/_schema_circular_imports.py 2018-08-28 15:42:29 +0000
@@ -521,6 +521,8 @@
IGitRepository, '_api_landing_candidates', IBranchMergeProposal)
patch_collection_property(
IGitRepository, 'dependent_landings', IBranchMergeProposal)
+patch_collection_return_type(
+ IGitRepository, 'getMergeProposals', IBranchMergeProposal)
# ILiveFSFile
patch_reference_property(ILiveFSFile, 'livefsbuild', ILiveFSBuild)
=== modified file 'lib/lp/code/browser/configure.zcml'
--- lib/lp/code/browser/configure.zcml 2018-08-20 23:33:01 +0000
+++ lib/lp/code/browser/configure.zcml 2018-08-28 15:42:29 +0000
@@ -819,6 +819,9 @@
name="++repository-recipes"
template="../templates/gitrepository-recipes.pt"/>
<browser:page
+ name="++ref-pending-merges"
+ template="../templates/gitrepository-pending-merges.pt"/>
+ <browser:page
name="++repository-import-details"
template="../templates/import-details.pt"/>
</browser:pages>
@@ -902,6 +905,13 @@
permission="launchpad.AnyAllowedPerson"
name="+try-again"
template="../templates/inline-form-only-buttons.pt"/>
+ <browser:page
+ for="lp.code.interfaces.gitrepository.IGitRepository"
+ class="lp.code.browser.branchmergeproposallisting.BranchActiveReviewsView"
+ permission="zope.Public"
+ name="+activereviews"
+ template="../templates/active-reviews.pt"/>
+
<adapter
provides="lp.services.webapp.interfaces.IBreadcrumb"
for="lp.code.interfaces.gitrepository.IGitRepository"
=== modified file 'lib/lp/code/browser/gitrepository.py'
--- lib/lp/code/browser/gitrepository.py 2018-08-24 16:52:27 +0000
+++ lib/lp/code/browser/gitrepository.py 2018-08-28 15:42:29 +0000
@@ -57,6 +57,9 @@
from lp.app.vocabularies import InformationTypeVocabulary
from lp.app.widgets.itemswidgets import LaunchpadRadioWidgetWithDescription
from lp.code.browser.branch import CodeEditOwnerMixin
+from lp.code.browser.branchmergeproposal import (
+ latest_proposals_for_each_branch,
+ )
from lp.code.browser.codeimport import CodeImportTargetMixin
from lp.code.browser.sourcepackagerecipelisting import HasRecipesMenuMixin
from lp.code.browser.widgets.gitrepositorytarget import (
@@ -369,6 +372,44 @@
"""Is this an imported repository?"""
return self.context.repository_type == GitRepositoryType.IMPORTED
+ @property
+ def show_merge_links(self):
+ return True
+
+ @cachedproperty
+ def landing_candidates(self):
+ candidates = self.context.getPrecachedLandingCandidates(self.user)
+ return [proposal for proposal in candidates
+ if check_permission("launchpad.View", proposal)]
+
+ def _getBranchCountText(self, count):
+ """Help to show user friendly text."""
+ if count == 0:
+ return 'No branches'
+ elif count == 1:
+ return '1 branch'
+ else:
+ return '%s branches' % coun
+
+ @cachedproperty
+ def landing_candidate_count_text(self):
+ return self._getBranchCountText(len(self.landing_candidates))
+
+ @cachedproperty
+ def dependent_landings(self):
+ return [proposal for proposal in self.context.dependent_landings
+ if check_permission("launchpad.View", proposal)]
+
+ @cachedproperty
+ def dependent_landing_count_text(self):
+ return self._getBranchCountText(len(self.dependent_landings))
+
+ @property
+ def landing_targets(self):
+ """Return a filtered list of landing targets."""
+ targets = self.context.getPrecachedLandingTargets(self.user)
+ return latest_proposals_for_each_branch(targets)
+
class GitRepositoryEditFormView(LaunchpadEditFormView):
"""Base class for forms that edit a Git repository."""
=== modified file 'lib/lp/code/browser/tests/test_gitrepository.py'
--- lib/lp/code/browser/tests/test_gitrepository.py 2018-08-24 16:52:27 +0000
+++ lib/lp/code/browser/tests/test_gitrepository.py 2018-08-28 15:42:29 +0000
@@ -24,10 +24,10 @@
from lp.app.enums import InformationType
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
from lp.app.interfaces.services import IService
-from lp.code.enums import GitRepositoryType
+from lp.code.enums import BranchMergeProposalStatus, GitRepositoryType
from lp.code.interfaces.revision import IRevisionSet
from lp.code.tests.helpers import GitHostingFixture
-from lp.registry.enums import BranchSharingPolicy
+from lp.registry.enums import BranchSharingPolicy, VCSType
from lp.registry.interfaces.accesspolicy import IAccessPolicySource
from lp.registry.interfaces.person import PersonVisibility
from lp.services.beautifulsoup import BeautifulSoup
@@ -246,6 +246,39 @@
browser = self.getUserBrowser(url, user=user)
self.assertIn(project_name, browser.contents)
+ def test_view_with_active_reviews(self):
+ repository = self.factory.makeGitRepository()
+ git_refs = self.factory.makeGitRefs(
+ repository,
+ paths=["refs/heads/master", "refs/heads/1.0", "refs/tags/1.1"])
+ self.factory.makeBranchMergeProposalForGit(
+ target_ref=git_refs[0],
+ set_state=BranchMergeProposalStatus.NEEDS_REVIEW)
+ with person_logged_in(repository.owner):
+ browser = self.getViewBrowser(repository)
+ self.assertIsNotNone(
+ find_tag_by_id(browser.contents, 'landing-candidates'))
+
+ def test_view_with_landing_targets(self):
+ product = self.factory.makeProduct(name="foo", vcs=VCSType.GIT)
+ target_repository = self.factory.makeGitRepository(target=product)
+ source_repository = self.factory.makeGitRepository(target=product)
+ target_git_refs = self.factory.makeGitRefs(
+ target_repository,
+ paths=["refs/heads/master", "refs/heads/1.0", "refs/tags/1.1"])
+ source_git_refs = self.factory.makeGitRefs(
+ source_repository,
+ paths=["refs/heads/master"])
+ self.factory.makeBranchMergeProposalForGit(
+ target_ref=target_git_refs[0],
+ source_ref=source_git_refs[0],
+ set_state=BranchMergeProposalStatus.NEEDS_REVIEW)
+ with person_logged_in(target_repository.owner):
+ browser = self.getViewBrowser(
+ source_repository, user=source_repository.owner)
+ self.assertIsNotNone(
+ find_tag_by_id(browser.contents, 'landing-targets'))
+
class TestGitRepositoryViewPrivateArtifacts(BrowserTestCase):
"""Tests that Git repositories with private team artifacts can be viewed.
=== modified file 'lib/lp/code/interfaces/gitrepository.py'
--- lib/lp/code/interfaces/gitrepository.py 2017-11-06 09:32:45 +0000
+++ lib/lp/code/interfaces/gitrepository.py 2018-08-28 15:42:29 +0000
@@ -58,6 +58,7 @@
from lp.app.enums import InformationType
from lp.app.validators import LaunchpadValidationError
from lp.code.enums import (
+ BranchMergeProposalStatus,
BranchSubscriptionDiffSize,
BranchSubscriptionNotificationLevel,
CodeReviewNotificationLevel,
@@ -531,6 +532,21 @@
Source and prerequisite repositories are preloaded.
"""
+ @operation_parameters(
+ status=List(
+ title=_("A list of merge proposal statuses to filter by."),
+ value_type=Choice(vocabulary=BranchMergeProposalStatus)),
+ merged_revision_ids=List(TextLine(
+ title=_('The target revision ID of the merge.'))))
+ @call_with(visible_by_user=REQUEST_USER)
+ # Really IBranchMergeProposal, patched in _schema_circular_imports.py.
+ @operation_returns_collection_of(Interface)
+ @export_read_operation()
+ @operation_for_version("devel")
+ def getMergeProposals(status=None, visible_by_user=None,
+ merged_revision_ids=None, eager_load=False):
+ """Return matching BranchMergeProposals."""
+
def getMergeProposalByID(id):
"""Return this repository's merge proposal with this id, or None."""
=== modified file 'lib/lp/code/model/gitrepository.py'
--- lib/lp/code/model/gitrepository.py 2018-07-24 11:57:33 +0000
+++ lib/lp/code/model/gitrepository.py 2018-08-28 15:42:29 +0000
@@ -942,6 +942,21 @@
Not(BranchMergeProposal.queue_status.is_in(
BRANCH_MERGE_PROPOSAL_FINAL_STATES)))
+ def getMergeProposals(self, status=None, visible_by_user=None,
+ merged_revision_ids=None, eager_load=False):
+ """See `IGitRef`."""
+ if not status:
+ status = (
+ BranchMergeProposalStatus.CODE_APPROVED,
+ BranchMergeProposalStatus.NEEDS_REVIEW,
+ BranchMergeProposalStatus.WORK_IN_PROGRESS)
+
+ collection = getUtility(IAllGitRepositories).visibleByUser(
+ visible_by_user)
+ return collection.getMergeProposals(
+ status, target_repository=self,
+ merged_revision_ids=merged_revision_ids, eager_load=eager_load)
+
def getMergeProposalByID(self, id):
"""See `IGitRepository`."""
return self.landing_targets.find(BranchMergeProposal.id == id).one()
=== modified file 'lib/lp/code/templates/gitrepository-index.pt'
--- lib/lp/code/templates/gitrepository-index.pt 2018-01-26 12:01:02 +0000
+++ lib/lp/code/templates/gitrepository-index.pt 2018-08-28 15:42:29 +0000
@@ -44,6 +44,13 @@
</div>
</div>
+ <div class="yui-g first">
+ <div id="repository-relations" class="portlet">
+ <tal:ref-pending-merges
+ replace="structure context/@@++ref-pending-merges" />
+ </div>
+ </div>
+
<div class="yui-g">
<div id="repository-relations" class="portlet">
<tal:repository-recipes
=== added file 'lib/lp/code/templates/gitrepository-pending-merges.pt'
--- lib/lp/code/templates/gitrepository-pending-merges.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/code/templates/gitrepository-pending-merges.pt 2018-08-28 15:42:29 +0000
@@ -0,0 +1,35 @@
+<div
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ xmlns:metal="http://xml.zope.org/namespaces/metal"
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+ tal:define="
+ context_menu view/context/menu:context;
+ features request/features"
+ tal:condition="view/show_merge_links">
+
+ <h3>Branch merges</h3>
+ <div id="merge-links"
+ class="actions">
+ <div id="merge-summary">
+
+ <div id="landing-candidates"
+ tal:condition="view/landing_candidates">
+ <img src="/@@/merge-proposal-icon" />
+ <a href="+activereviews" tal:content="structure view/landing_candidate_count_text">
+ 1 branch
+ </a>
+ proposed for merging into this repository.
+
+ </div>
+
+ <div id="landing-targets" tal:condition="view/landing_targets">
+ <tal:landing-candidates repeat="mergeproposal view/landing_targets">
+ <tal:merge-fragment
+ tal:replace="structure mergeproposal/@@+summary-fragment"/>
+ </tal:landing-candidates>
+ </div>
+
+ </div>
+ </div>
+
+</div>
Follow ups