Merge lp:~jtv/launchpad/get_derived_distros into lp:launchpad

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Jeroen T. Vermeulen
Approved revision: no longer in the source branch.
Merged at revision: 13495
Proposed branch: lp:~jtv/launchpad/get_derived_distros
Merge into: lp:launchpad
Diff against target: 230 lines (+68/-47)
5 files modified
lib/lp/registry/interfaces/distribution.py (+8/-1)
lib/lp/registry/model/distribution.py (+11/-1)
lib/lp/registry/tests/test_distribution.py (+47/-1)
lib/lp/soyuz/scripts/processaccepted.py (+1/-16)
lib/lp/soyuz/tests/test_processaccepted.py (+1/-28)
To merge this branch: bzr merge lp:~jtv/launchpad/get_derived_distros
Reviewer Review Type Date Requested Status
j.c.sackett (community) Approve
Review via email: mp+68675@code.launchpad.net

Commit message

Move finding of derived distros into IDistributionSet.

Description of the change

= Summary =

I recently added an option to process-accepted: "process all derived distributions (not counting Ubuntu, even if it is technically derived from Ubuntu)."

Now I'm adding a similar option to publish-distro, so the ability to find all derived distributions should be in a reusable place.

== Proposed fix ==

IDistributionSet.getDerivedDistributions().

== Pre-implementation notes ==

The notion "derived distributions" is a bit vague in this case. It doesn't matter for the foreseeable future; we're currently thinking "Ubuntu-derived distros" but we're not planning to set up any other derived distros (except perhaps Ubuntu as a derivative of Debian).

It's important that Ubuntu not be included in the list of "derived distributions" because it's large and needs to be processed separately. That's the whole point.

== Implementation details ==

I was unable to find any unit tests for DistributionSet, so I added one.

== Tests ==

{{{
./bin/test -vvc lp.registry.tests.test_distribution -t DistributionSet
./bin/test -vvc lp.soyuz.tests.test_processaccepted
}}}

== Demo and Q/A ==

There isn't much to demo or Q/A, really; existing code has moved a bit. Just so long as "process-accepted --derived" still runs.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/soyuz/scripts/processaccepted.py
  lib/lp/soyuz/tests/test_processaccepted.py
  lib/lp/registry/interfaces/distribution.py
  lib/lp/registry/tests/test_distribution.py
  lib/lp/registry/model/distribution.py

To post a comment you must log in.
Revision history for this message
j.c.sackett (jcsackett) wrote :

Looks like a sensible move of the code.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/registry/interfaces/distribution.py'
--- lib/lp/registry/interfaces/distribution.py 2011-07-13 18:18:42 +0000
+++ lib/lp/registry/interfaces/distribution.py 2011-07-21 12:46:33 +0000
@@ -1,4 +1,4 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the1# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4# pylint: disable-msg=E0211,E02134# pylint: disable-msg=E0211,E0213
@@ -750,6 +750,13 @@
750 :return: A dict as per `IDistribution.getCurrentSourceReleases`750 :return: A dict as per `IDistribution.getCurrentSourceReleases`
751 """751 """
752752
753 def getDerivedDistributions():
754 """Find derived distributions.
755
756 :return: An iterable of all derived distributions (not including
757 Ubuntu, even if it is technically derived from Debian).
758 """
759
753760
754class NoSuchDistribution(NameLookupFailed):761class NoSuchDistribution(NameLookupFailed):
755 """Raised when we try to find a distribution that doesn't exist."""762 """Raised when we try to find a distribution that doesn't exist."""
756763
=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py 2011-07-14 14:08:04 +0000
+++ lib/lp/registry/model/distribution.py 2011-07-21 12:46:33 +0000
@@ -1,4 +1,4 @@
1# Copyright 2009-2010 Canonical Ltd. This software is licensed under the1# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4# pylint: disable-msg=E0611,W02124# pylint: disable-msg=E0611,W0212
@@ -157,6 +157,7 @@
157 DistributionSourcePackage,157 DistributionSourcePackage,
158 )158 )
159from lp.registry.model.distroseries import DistroSeries159from lp.registry.model.distroseries import DistroSeries
160from lp.registry.model.distroseriesparent import DistroSeriesParent
160from lp.registry.model.hasdrivers import HasDriversMixin161from lp.registry.model.hasdrivers import HasDriversMixin
161from lp.registry.model.karma import KarmaContextMixin162from lp.registry.model.karma import KarmaContextMixin
162from lp.registry.model.milestone import (163from lp.registry.model.milestone import (
@@ -1993,3 +1994,12 @@
1993 result[sourcepackage] = DistributionSourcePackageRelease(1994 result[sourcepackage] = DistributionSourcePackageRelease(
1994 distro, sp_release)1995 distro, sp_release)
1995 return result1996 return result
1997
1998 def getDerivedDistributions(self):
1999 """See `IDistributionSet`."""
2000 ubuntu_id = getUtility(ILaunchpadCelebrities).ubuntu.id
2001 return IStore(DistroSeries).find(
2002 Distribution,
2003 Distribution.id == DistroSeries.distributionID,
2004 DistroSeries.id == DistroSeriesParent.derived_series_id,
2005 DistroSeries.distributionID != ubuntu_id).config(distinct=True)
19962006
=== modified file 'lib/lp/registry/tests/test_distribution.py'
--- lib/lp/registry/tests/test_distribution.py 2011-06-17 19:47:36 +0000
+++ lib/lp/registry/tests/test_distribution.py 2011-07-21 12:46:33 +0000
@@ -20,10 +20,15 @@
20from canonical.testing.layers import (20from canonical.testing.layers import (
21 DatabaseFunctionalLayer,21 DatabaseFunctionalLayer,
22 LaunchpadFunctionalLayer,22 LaunchpadFunctionalLayer,
23 ZopelessDatabaseLayer,
23 )24 )
24from lp.app.errors import NotFoundError25from lp.app.errors import NotFoundError
26from lp.app.interfaces.launchpad import ILaunchpadCelebrities
25from lp.registry.errors import NoSuchDistroSeries27from lp.registry.errors import NoSuchDistroSeries
26from lp.registry.interfaces.distribution import IDistribution28from lp.registry.interfaces.distribution import (
29 IDistribution,
30 IDistributionSet,
31 )
27from lp.registry.interfaces.person import IPersonSet32from lp.registry.interfaces.person import IPersonSet
28from lp.registry.interfaces.series import SeriesStatus33from lp.registry.interfaces.series import SeriesStatus
29from lp.registry.tests.test_distroseries import (34from lp.registry.tests.test_distroseries import (
@@ -37,6 +42,7 @@
37 login_person,42 login_person,
38 TestCaseWithFactory,43 TestCaseWithFactory,
39 )44 )
45from lp.testing.matchers import Provides
40from lp.testing.views import create_initialized_view46from lp.testing.views import create_initialized_view
4147
4248
@@ -421,3 +427,43 @@
421 self.assertNotEqual(distribution.owner, distribution.registrant)427 self.assertNotEqual(distribution.owner, distribution.registrant)
422 self.assertEqual(distribution.owner, self.owner)428 self.assertEqual(distribution.owner, self.owner)
423 self.assertEqual(distribution.registrant, self.registrant)429 self.assertEqual(distribution.registrant, self.registrant)
430
431
432class DistributionSet(TestCaseWithFactory):
433 """Test case for `IDistributionSet`."""
434
435 layer = ZopelessDatabaseLayer
436
437 def test_implements_interface(self):
438 self.assertThat(
439 getUtility(IDistributionSet), Provides(IDistributionSet))
440
441 def test_getDerivedDistributions_finds_derived_distro(self):
442 dsp = self.factory.makeDistroSeriesParent()
443 derived_distro = dsp.derived_series.distribution
444 distroset = getUtility(IDistributionSet)
445 self.assertIn(derived_distro, distroset.getDerivedDistributions())
446
447 def test_getDerivedDistributions_ignores_nonderived_distros(self):
448 distroset = getUtility(IDistributionSet)
449 nonderived_distro = self.factory.makeDistribution()
450 self.assertNotIn(
451 nonderived_distro, distroset.getDerivedDistributions())
452
453 def test_getDerivedDistributions_ignores_ubuntu_even_if_derived(self):
454 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
455 self.factory.makeDistroSeriesParent(
456 derived_series=ubuntu.currentseries)
457 distroset = getUtility(IDistributionSet)
458 self.assertNotIn(ubuntu, distroset.getDerivedDistributions())
459
460 def test_getDerivedDistribution_finds_each_distro_just_once(self):
461 # Derived distros are not duplicated in the output of
462 # getDerivedDistributions, even if they have multiple parents and
463 # multiple derived series.
464 dsp = self.factory.makeDistroSeriesParent()
465 distro = dsp.derived_series.distribution
466 other_series = self.factory.makeDistroSeries(distribution=distro)
467 self.factory.makeDistroSeriesParent(derived_series=other_series)
468 distroset = getUtility(IDistributionSet)
469 self.assertEqual(1, len(list(distroset.getDerivedDistributions())))
424470
=== modified file 'lib/lp/soyuz/scripts/processaccepted.py'
--- lib/lp/soyuz/scripts/processaccepted.py 2011-07-14 16:51:59 +0000
+++ lib/lp/soyuz/scripts/processaccepted.py 2011-07-21 12:46:33 +0000
@@ -19,7 +19,6 @@
19from zope.component import getUtility19from zope.component import getUtility
20from zope.security.proxy import removeSecurityProxy20from zope.security.proxy import removeSecurityProxy
2121
22from canonical.launchpad.interfaces.lpstorm import IStore
23from canonical.launchpad.webapp.errorlog import (22from canonical.launchpad.webapp.errorlog import (
24 ErrorReportingUtility,23 ErrorReportingUtility,
25 ScriptRequest,24 ScriptRequest,
@@ -31,7 +30,6 @@
31from lp.bugs.interfaces.bugtask import BugTaskStatus30from lp.bugs.interfaces.bugtask import BugTaskStatus
32from lp.registry.interfaces.distribution import IDistributionSet31from lp.registry.interfaces.distribution import IDistributionSet
33from lp.registry.interfaces.pocket import PackagePublishingPocket32from lp.registry.interfaces.pocket import PackagePublishingPocket
34from lp.registry.model.distroseriesparent import DistroSeriesParent
35from lp.services.scripts.base import (33from lp.services.scripts.base import (
36 LaunchpadCronScript,34 LaunchpadCronScript,
37 LaunchpadScriptFailure,35 LaunchpadScriptFailure,
@@ -287,19 +285,6 @@
287 else:285 else:
288 self.txn.commit()286 self.txn.commit()
289287
290 def findDerivedDistros(self):
291 """Find Ubuntu-derived distributions."""
292 # Avoid circular imports.
293 from lp.registry.model.distribution import Distribution
294 from lp.registry.model.distroseries import DistroSeries
295
296 ubuntu_id = getUtility(ILaunchpadCelebrities).ubuntu.id
297 return IStore(DistroSeries).find(
298 Distribution,
299 Distribution.id == DistroSeries.distributionID,
300 DistroSeries.id == DistroSeriesParent.derived_series_id,
301 DistroSeries.distributionID != ubuntu_id).config(distinct=True)
302
303 def findNamedDistro(self, distro_name):288 def findNamedDistro(self, distro_name):
304 """Find the `Distribution` called `distro_name`."""289 """Find the `Distribution` called `distro_name`."""
305 self.logger.debug("Finding distribution %s.", distro_name)290 self.logger.debug("Finding distribution %s.", distro_name)
@@ -312,7 +297,7 @@
312 def findTargetDistros(self):297 def findTargetDistros(self):
313 """Find the distribution(s) to process, based on arguments."""298 """Find the distribution(s) to process, based on arguments."""
314 if self.options.derived:299 if self.options.derived:
315 return self.findDerivedDistros()300 return getUtility(IDistributionSet).getDerivedDistributions()
316 else:301 else:
317 return [self.findNamedDistro(self.args[0])]302 return [self.findNamedDistro(self.args[0])]
318303
319304
=== modified file 'lib/lp/soyuz/tests/test_processaccepted.py'
--- lib/lp/soyuz/tests/test_processaccepted.py 2011-07-14 16:54:41 +0000
+++ lib/lp/soyuz/tests/test_processaccepted.py 2011-07-21 12:46:33 +0000
@@ -4,7 +4,6 @@
4"""Test process-accepted.py"""4"""Test process-accepted.py"""
55
6from cStringIO import StringIO6from cStringIO import StringIO
7from zope.component import getUtility
87
9from canonical.launchpad.interfaces.lpstorm import IStore8from canonical.launchpad.interfaces.lpstorm import IStore
10from debian.deb822 import Changes9from debian.deb822 import Changes
@@ -14,7 +13,6 @@
14from canonical.config import config13from canonical.config import config
15from canonical.launchpad.webapp.errorlog import ErrorReportingUtility14from canonical.launchpad.webapp.errorlog import ErrorReportingUtility
16from canonical.testing.layers import LaunchpadZopelessLayer15from canonical.testing.layers import LaunchpadZopelessLayer
17from lp.app.interfaces.launchpad import ILaunchpadCelebrities
18from lp.registry.interfaces.series import SeriesStatus16from lp.registry.interfaces.series import SeriesStatus
19from lp.services.log.logger import BufferLogger17from lp.services.log.logger import BufferLogger
20from lp.services.scripts.base import LaunchpadScriptFailure18from lp.services.scripts.base import LaunchpadScriptFailure
@@ -223,32 +221,7 @@
223 dsp = self.factory.makeDistroSeriesParent()221 dsp = self.factory.makeDistroSeriesParent()
224 script = ProcessAccepted(test_args=['--derived'])222 script = ProcessAccepted(test_args=['--derived'])
225 self.assertIn(223 self.assertIn(
226 dsp.derived_series.distribution, script.findDerivedDistros())224 dsp.derived_series.distribution, script.findTargetDistros())
227
228 def test_findDerivedDistros_for_derived_ignores_non_derived_distros(self):
229 distro = self.factory.makeDistribution()
230 script = ProcessAccepted(test_args=['--derived'])
231 self.assertNotIn(distro, script.findDerivedDistros())
232
233 def test_findDerivedDistros_ignores_ubuntu_even_if_derived(self):
234 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
235 self.factory.makeDistroSeriesParent(
236 derived_series=ubuntu.currentseries)
237 script = ProcessAccepted(test_args=['--derived'])
238 self.assertNotIn(ubuntu, script.findDerivedDistros())
239
240 def test_findDerivedDistros_finds_each_distro_just_once(self):
241 # Derived distros are not duplicated in the output of
242 # findDerivedDistros, even if they have multiple parents and
243 # multiple derived series.
244 dsp = self.factory.makeDistroSeriesParent()
245 distro = dsp.derived_series.distribution
246 other_series = self.factory.makeDistroSeries(distribution=distro)
247 self.factory.makeDistroSeriesParent(derived_series=other_series)
248 script = ProcessAccepted(test_args=['--derived'])
249 derived_distros = list(script.findDerivedDistros())
250 self.assertEqual(
251 1, derived_distros.count(dsp.derived_series.distribution))
252225
253226
254class TestBugsFromChangesFile(TestCaseWithFactory):227class TestBugsFromChangesFile(TestCaseWithFactory):