← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~wgrant/launchpad/bug-860920 into lp:launchpad

 

William Grant has proposed merging lp:~wgrant/launchpad/bug-860920 into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #860920 in Launchpad itself: "reassigning bugs between packages in a single distribution clears the milestone"
  https://bugs.launchpad.net/launchpad/+bug/860920

For more details, see:
https://code.launchpad.net/~wgrant/launchpad/bug-860920/+merge/77271

This branch fixes bug #860920, preserving bug task milestones when transitioning between targets within a pillar (eg. changing the package name of a distribution task).

I added a new IBugTarget['pillar'], added it to the various implementations, and altered the milestone unsetting code to match the pillars instead of the targets themselves.
-- 
https://code.launchpad.net/~wgrant/launchpad/bug-860920/+merge/77271
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/bug-860920 into lp:launchpad.
=== modified file 'lib/lp/bugs/browser/bugtask.py'
--- lib/lp/bugs/browser/bugtask.py	2011-09-26 06:30:07 +0000
+++ lib/lp/bugs/browser/bugtask.py	2011-09-28 03:43:50 +0000
@@ -1570,7 +1570,8 @@
         milestone_ignored = False
         missing = object()
         new_target = new_values.pop("target", missing)
-        if new_target is not missing and bugtask.target != new_target:
+        if (new_target is not missing and
+            bugtask.target.pillar != new_target.pillar):
             # We clear the milestone value if one was already set. We ignore
             # the milestone value if it was currently None, and the user tried
             # to set a milestone value while also changing the product. This

=== modified file 'lib/lp/bugs/interfaces/bugtarget.py'
--- lib/lp/bugs/interfaces/bugtarget.py	2011-07-29 05:33:02 +0000
+++ lib/lp/bugs/interfaces/bugtarget.py	2011-09-28 03:43:50 +0000
@@ -296,6 +296,8 @@
     bugtargetdisplayname = Attribute("A display name for this bug target")
     bugtargetname = Attribute("The target as shown in mail notifications.")
 
+    pillar = Attribute("The pillar containing this target.")
+
     bug_reporting_guidelines = exported(
         Text(
             title=(

=== modified file 'lib/lp/bugs/model/bugtask.py'
--- lib/lp/bugs/model/bugtask.py	2011-09-26 02:06:25 +0000
+++ lib/lp/bugs/model/bugtask.py	2011-09-28 03:43:50 +0000
@@ -563,14 +563,7 @@
     @property
     def pillar(self):
         """See `IBugTask`."""
-        if self.product is not None:
-            return self.product
-        elif self.productseries is not None:
-            return self.productseries.product
-        elif self.distribution is not None:
-            return self.distribution
-        else:
-            return self.distroseries.distribution
+        return self.target.pillar
 
     @property
     def other_affected_pillars(self):
@@ -1120,10 +1113,8 @@
             # are product tasks).
             distros = set()
             for potential_target in (target, self.target):
-                if IDistribution.providedBy(potential_target):
-                    distros.add(potential_target)
-                elif IDistributionSourcePackage.providedBy(potential_target):
-                    distros.add(potential_target.distribution)
+                if IDistribution.providedBy(potential_target.pillar):
+                    distros.add(potential_target.pillar)
                 else:
                     distros.add(None)
             if len(distros) > 1:
@@ -1159,7 +1150,7 @@
         target_before_change = self.target
 
         if (self.milestone is not None and
-            self.milestone.target != target):
+            self.milestone.target != target.pillar):
             # If the milestone for this bugtask is set, we
             # have to make sure that it's a milestone of the
             # current target, or reset it to None

=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
--- lib/lp/bugs/model/tests/test_bugtask.py	2011-09-12 20:27:32 +0000
+++ lib/lp/bugs/model/tests/test_bugtask.py	2011-09-28 03:43:50 +0000
@@ -1913,6 +1913,18 @@
                 task.transitionToTarget, self.factory.makeSourcePackage())
         self.assertEqual(milestone, task.milestone)
 
+    def test_milestone_preserved_within_a_pillar(self):
+        # Milestones are pillar-global, so transitions between packages
+        # don't unset them.
+        sp = self.factory.makeSourcePackage(publish=True)
+        dsp = sp.distribution_sourcepackage
+        task = self.factory.makeBugTask(target=dsp.distribution)
+        with person_logged_in(task.owner):
+            task.milestone = milestone = self.factory.makeMilestone(
+                distribution=dsp.distribution)
+            task.transitionToTarget(dsp)
+        self.assertEqual(milestone, task.milestone)
+
     def test_targetnamecache_updated(self):
         new_product = self.factory.makeProduct()
         task = self.factory.makeBugTask()

=== modified file 'lib/lp/bugs/tests/test_bugtarget2.py'
--- lib/lp/bugs/tests/test_bugtarget2.py	2011-07-29 06:53:06 +0000
+++ lib/lp/bugs/tests/test_bugtarget2.py	2011-09-28 03:43:50 +0000
@@ -41,6 +41,9 @@
         super(TestDistribution, self).setUp()
         self.bugtarget = self.factory.makeDistribution()
 
+    def test_pillar(self):
+        self.assertEqual(self.bugtarget, self.bugtarget.pillar)
+
 
 class TestDistroSeries(BugTargetBugFilingDuplicateSearchAlwaysOn,
                        TestCaseWithFactory):
@@ -57,6 +60,9 @@
         self.assertEqual(
             self.bugtarget.distribution, self.bugtarget.bugtarget_parent)
 
+    def test_pillar(self):
+        self.assertEqual(self.bugtarget.distribution, self.bugtarget.pillar)
+
 
 class TestProjectGroup(BugTargetBugFilingDuplicateSearchAlwaysOn,
                        TestCaseWithFactory):
@@ -96,6 +102,9 @@
         self.bugtarget = self.factory.makeProduct(
             bug_supervisor=self.bug_supervisor)
 
+    def test_pillar(self):
+        self.assertEqual(self.bugtarget, self.bugtarget.pillar)
+
 
 class TestDistributionSourcePackage(BugTargetBugFilingDuplicateSearchSettable,
                                     TestCaseWithFactory):
@@ -111,6 +120,9 @@
         self.bugtarget = self.factory.makeDistributionSourcePackage(
             distribution=distribution)
 
+    def test_pillar(self):
+        self.assertEqual(self.bugtarget.distribution, self.bugtarget.pillar)
+
 
 class BugTargetBugFilingDuplicateSearchInherited:
     """A base class for tests of bug targets where the dupe search policy
@@ -148,6 +160,9 @@
         self.assertEqual(
             self.bugtarget.product, self.bugtarget.bugtarget_parent)
 
+    def test_pillar(self):
+        self.assertEqual(self.bugtarget.product, self.bugtarget.pillar)
+
 
 class TestSourcePackage(BugTargetBugFilingDuplicateSearchInherited,
                        TestCaseWithFactory):
@@ -170,3 +185,7 @@
         self.assertEqual(
             self.bugtarget.distribution_sourcepackage,
             self.bugtarget.bugtarget_parent)
+
+    def test_pillar(self):
+        self.assertEqual(
+            self.bugtarget.distroseries.distribution, self.bugtarget.pillar)

=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml	2011-09-20 16:59:39 +0000
+++ lib/lp/registry/configure.zcml	2011-09-28 03:43:50 +0000
@@ -459,6 +459,7 @@
     <class
         class="lp.registry.model.distributionsourcepackage.DistributionSourcePackage">
         <allow interface="lp.bugs.interfaces.bugsummary.IBugSummaryDimension"/>
+        <allow interface="lp.bugs.interfaces.bugtarget.IBugTarget"/>
         <allow
             interface="lp.bugs.interfaces.bugtarget.IHasBugHeat"/>
         <allow
@@ -470,15 +471,8 @@
                 __getitem__
                 __ne__
                 _getOfficialTagClause
-                all_bugtasks
                 bug_count
-                bug_reported_acknowledgement
-                bug_reporting_guidelines
-                bugtargetdisplayname
-                bugtargetname
                 bugtasks
-                closed_bugtasks
-                critical_bugtasks
                 current_publishing_records
                 currentrelease
                 delete
@@ -486,7 +480,6 @@
                 displayname
                 distribution
                 distro
-                enable_bugfiling_duplicate_search
                 findRelatedArchivePublications
                 findRelatedArchives
                 getMergeProposals
@@ -495,27 +488,17 @@
                 getUsedBugTagsWithOpenCounts
                 getVersion
                 get_distroseries_packages
-                has_bugtasks
-                high_bugtasks
-                inprogress_bugtasks
                 latest_overall_publication
                 name
-                new_bugtasks
                 official_bug_tags
-                open_bugtasks
                 publishing_history
                 releases
-                searchTasks
                 sourcepackagename
                 subscribers
                 summary
                 title
                 total_bug_heat
-                unassigned_bugtasks
                 upstream_product"/>
-        <require
-            permission="launchpad.AnyPerson"
-            attributes="createBug"/>
 
         <!-- IStructuralSubscriptionTarget -->
 

=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py	2011-08-29 00:13:22 +0000
+++ lib/lp/registry/model/distribution.py	2011-09-28 03:43:50 +0000
@@ -279,6 +279,11 @@
             alsoProvides(self, IDerivativeDistribution)
 
     @property
+    def pillar(self):
+        """See `IBugTarget`."""
+        return self
+
+    @property
     def pillar_category(self):
         """See `IPillar`."""
         return "Distribution"

=== modified file 'lib/lp/registry/model/distributionsourcepackage.py'
--- lib/lp/registry/model/distributionsourcepackage.py	2011-09-20 16:59:39 +0000
+++ lib/lp/registry/model/distributionsourcepackage.py	2011-09-28 03:43:50 +0000
@@ -472,6 +472,11 @@
         """See `IDistributionSourcePackage`."""
         return not self.__eq__(other)
 
+    @property
+    def pillar(self):
+        """See `IBugTarget`."""
+        return self.distribution
+
     def getBugSummaryContextWhereClause(self):
         """See `BugTargetBase`."""
         # Circular fail.

=== modified file 'lib/lp/registry/model/distroseries.py'
--- lib/lp/registry/model/distroseries.py	2011-09-10 00:16:56 +0000
+++ lib/lp/registry/model/distroseries.py	2011-09-28 03:43:50 +0000
@@ -265,6 +265,11 @@
         intermediateTable='SectionSelection')
 
     @property
+    def pillar(self):
+        """See `IBugTarget`."""
+        return self.distribution
+
+    @property
     def named_version(self):
         return '%s (%s)' % (self.displayname, self.version)
 

=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py	2011-09-13 05:23:16 +0000
+++ lib/lp/registry/model/product.py	2011-09-28 03:43:50 +0000
@@ -386,6 +386,11 @@
     date_next_suggest_packaging = UtcDateTimeCol(default=None)
 
     @property
+    def pillar(self):
+        """See `IBugTarget`."""
+        return self
+
+    @property
     def pillar_category(self):
         """See `IPillar`."""
         return "Project"

=== modified file 'lib/lp/registry/model/productseries.py'
--- lib/lp/registry/model/productseries.py	2011-07-29 06:53:06 +0000
+++ lib/lp/registry/model/productseries.py	2011-09-28 03:43:50 +0000
@@ -170,6 +170,11 @@
                             orderBy=['-id'])
 
     @property
+    def pillar(self):
+        """See `IBugTarget`."""
+        return self.product
+
+    @property
     def answers_usage(self):
         """See `IServiceUsage.`"""
         return self.product.answers_usage

=== modified file 'lib/lp/registry/model/sourcepackage.py'
--- lib/lp/registry/model/sourcepackage.py	2011-09-19 22:43:14 +0000
+++ lib/lp/registry/model/sourcepackage.py	2011-09-28 03:43:50 +0000
@@ -542,6 +542,11 @@
             "future. For now, you probably meant to file the bug on the "
             "distro-wide (i.e. not series-specific) source package.")
 
+    @property
+    def pillar(self):
+        """See `IBugTarget`."""
+        return self.distroseries.distribution
+
     def getBugSummaryContextWhereClause(self):
         """See BugTargetBase."""
         # Circular fail.