launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #03834
[Merge] lp:~rvb/launchpad/init-multiple-parents-bug-777120 into lp:launchpad/db-devel
Raphaël Victor Badin has proposed merging lp:~rvb/launchpad/init-multiple-parents-bug-777120 into lp:launchpad/db-devel.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #777120 in Launchpad itself: "DistroSeriesDerivationVocabularyFactory needs revisiting in light of multiple-parent work"
https://bugs.launchpad.net/launchpad/+bug/777120
For more details, see:
https://code.launchpad.net/~rvb/launchpad/init-multiple-parents-bug-777120/+merge/63341
This branch fixes the vocabulary of possible parents for a derived series (DistroSeriesDerivationVocabulary) so that it uses DistroSeriesParent -instead of previous_series). It also fixes the +initseries page to disable the rebuild option if an initialized series (i.e. a series with published sources) already exists in the distribution.
= Tests =
(New tests)
./bin/test -cvv test_distroseries test_rebuilding_allowed
./bin/test -cvv test_distroseries test_rebuilding_not_allowed
./bin/test -cvv test_distroseries_vocabularies test_distribution_with_derived_series_from_multiple_parents
(Modified tests)
./bin/test -cvv test_distroseries_vocabularies
./bin/test -cvv -t distribution.txt
= QA =
- Test initializing a series from a distribution with an existing initialised series: it should not be possible to rebuild the packages
- Test initializing a series from a distribution without any existing initialised series: it should be possible to rebuild the packages.
--
https://code.launchpad.net/~rvb/launchpad/init-multiple-parents-bug-777120/+merge/63341
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~rvb/launchpad/init-multiple-parents-bug-777120 into lp:launchpad/db-devel.
=== modified file 'lib/lp/registry/browser/distroseries.py'
--- lib/lp/registry/browser/distroseries.py 2011-06-03 00:13:41 +0000
+++ lib/lp/registry/browser/distroseries.py 2011-06-03 09:34:37 +0000
@@ -647,6 +647,12 @@
return getFeatureFlag("soyuz.derived_series_ui.enabled") is not None
@property
+ def rebuilding_allowed(self):
+ # If the distro has got any initialised series already,
+ # no rebuilding is allowed.
+ return not self.context.distribution.has_published_sources
+
+ @property
def next_url(self):
return canonical_url(self.context)
=== modified file 'lib/lp/registry/browser/tests/test_distroseries.py'
--- lib/lp/registry/browser/tests/test_distroseries.py 2011-06-02 18:36:43 +0000
+++ lib/lp/registry/browser/tests/test_distroseries.py 2011-06-03 09:34:37 +0000
@@ -455,6 +455,26 @@
u"javascript-disabled",
message.get("class").split())
+ def test_rebuilding_allowed(self):
+ # If the distro has no initialised series, rebuilding is allowed.
+ distroseries = self.factory.makeDistroSeries()
+ self.factory.makeDistroSeries(
+ distribution=distroseries.distribution)
+ view = create_initialized_view(distroseries, "+initseries")
+
+ self.assertTrue(view.rebuilding_allowed)
+
+ def test_rebuilding_not_allowed(self):
+ # If the distro has an initialised series, no rebuilding is allowed.
+ distroseries = self.factory.makeDistroSeries()
+ another_distroseries = self.factory.makeDistroSeries(
+ distribution=distroseries.distribution)
+ self.factory.makeSourcePackagePublishingHistory(
+ distroseries=another_distroseries)
+ view = create_initialized_view(distroseries, "+initseries")
+
+ self.assertFalse(view.rebuilding_allowed)
+
class DistroSeriesDifferenceMixin:
"""A helper class for testing differences pages"""
=== modified file 'lib/lp/registry/doc/distribution.txt'
--- lib/lp/registry/doc/distribution.txt 2011-05-27 19:53:20 +0000
+++ lib/lp/registry/doc/distribution.txt 2011-06-03 09:34:37 +0000
@@ -142,6 +142,15 @@
>>> gentoo.has_published_binaries
False
+You can use the has_published_sources property to find out if the
+distribution has any published sources.
+
+ >>> ubuntu.has_published_sources
+ True
+
+ >>> gentoo.has_published_sources
+ False
+
Distribution Sorting
--------------------
=== modified file 'lib/lp/registry/interfaces/distribution.py'
--- lib/lp/registry/interfaces/distribution.py 2011-05-29 21:18:09 +0000
+++ lib/lp/registry/interfaces/distribution.py 2011-06-03 09:34:37 +0000
@@ -340,6 +340,11 @@
"on disk."),
readonly=True, required=False)
+ has_published_sources = Bool(
+ title=_("Has Published Sources"),
+ description=_("True if this distribution has sources published."),
+ readonly=True, required=False)
+
def getArchiveIDList(archive=None):
"""Return a list of archive IDs suitable for sqlvalues() or quote().
=== modified file 'lib/lp/registry/javascript/distroseries.js'
--- lib/lp/registry/javascript/distroseries.js 2011-06-01 10:31:05 +0000
+++ lib/lp/registry/javascript/distroseries.js 2011-06-03 09:34:37 +0000
@@ -1369,6 +1369,15 @@
"Copy Source and Binaries"])
.set("choice", "Copy Source and Binaries")
.render(form_table_body);
+ // Disable rebuilding if LP.cache['rebuilding_allowed'] is false.
+ if (!LP.cache['rebuilding_allowed']) {
+ package_copy_options.fieldNode
+ .one('input[value="Copy Source and Rebuild"]')
+ .set('disabled', 'disabled');
+ package_copy_options.set("description", (
+ "Note that you cannot rebuild sources because the " +
+ "distribution already has an initialised series."));
+ }
var form_actions =
new DeriveDistroSeriesActionsWidget({
context: LP.cache.context,
=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py 2011-05-27 21:12:25 +0000
+++ lib/lp/registry/model/distribution.py 2011-06-03 09:34:37 +0000
@@ -29,7 +29,10 @@
Or,
SQL,
)
-from storm.store import Store
+from storm.store import (
+ EmptyResultSet,
+ Store,
+ )
from zope.component import getUtility
from zope.interface import (
alsoProvides,
@@ -1879,6 +1882,14 @@
return weight_function
+ @property
+ def has_published_sources(self):
+ archives_sources = EmptyResultSet()
+ for archive in self.all_distro_archives:
+ archives_sources = archives_sources.union(
+ archive.getPublishedSources())
+ return not archives_sources.is_empty()
+
class DistributionSet:
"""This class is to deal with Distribution related stuff"""
=== modified file 'lib/lp/registry/templates/distroseries-initialize.pt'
--- lib/lp/registry/templates/distroseries-initialize.pt 2011-05-30 15:17:11 +0000
+++ lib/lp/registry/templates/distroseries-initialize.pt 2011-06-03 09:34:37 +0000
@@ -26,6 +26,9 @@
please use the <code>initDerivedDistroSeries</code> API call via the
web service.
</p>
+ <script
+ tal:content="string:LP.cache['rebuilding_allowed'] = ('${view/rebuilding_allowed}' === 'True');">
+ </script>
<div class="unseen" id="initseries-form-container">
<metal:form use-macro="context/@@launchpad_form/form" />
</div>
=== modified file 'lib/lp/registry/tests/test_distroseries_vocabularies.py'
--- lib/lp/registry/tests/test_distroseries_vocabularies.py 2011-05-31 15:08:34 +0000
+++ lib/lp/registry/tests/test_distroseries_vocabularies.py 2011-06-03 09:34:37 +0000
@@ -13,9 +13,7 @@
from pytz import utc
from testtools.matchers import Equals
from zope.component import getUtility
-from zope.schema.interfaces import (
- IVocabularyFactory,
- )
+from zope.schema.interfaces import IVocabularyFactory
from zope.security.proxy import removeSecurityProxy
from canonical.database.sqlbase import flush_database_caches
@@ -70,16 +68,38 @@
# the vocabulary factory returns a vocabulary for all distroseries of
# the distribution from which the derived series have been derived.
parent_distroseries = self.factory.makeDistroSeries()
- # Create a sibling to the parent.
self.factory.makeDistroSeries(
distribution=parent_distroseries.distribution)
- distroseries = self.factory.makeDistroSeries(
- previous_series=parent_distroseries)
+ distroseries = self.factory.makeDistroSeries()
+ self.factory.makeDistroSeriesParent(
+ derived_series=distroseries, parent_series=parent_distroseries)
vocabulary = DistroSeriesDerivationVocabulary(distroseries)
expected_distroseries = set(parent_distroseries.distribution.series)
observed_distroseries = set(term.value for term in vocabulary)
self.assertEqual(expected_distroseries, observed_distroseries)
+ def test_distribution_with_derived_series_from_multiple_parents(self):
+ # Given a distribution with series, one or more of which are derived
+ # from multiple parents, the vocabulary factory returns a vocabulary
+ # for all distroseries of the distribution*s* from which the derived
+ # series have been derived.
+ parent_distroseries = self.factory.makeDistroSeries()
+ another_parent_distroseries = self.factory.makeDistroSeries()
+ self.factory.makeDistroSeries(
+ distribution=parent_distroseries.distribution)
+ distroseries = self.factory.makeDistroSeries()
+ self.factory.makeDistroSeriesParent(
+ derived_series=distroseries, parent_series=parent_distroseries)
+ self.factory.makeDistroSeriesParent(
+ derived_series=distroseries,
+ parent_series=another_parent_distroseries)
+ vocabulary = DistroSeriesDerivationVocabulary(distroseries)
+ expected_distroseries = set(
+ parent_distroseries.distribution.series).union(
+ set(another_parent_distroseries.distribution.series))
+ observed_distroseries = set(term.value for term in vocabulary)
+ self.assertEqual(expected_distroseries, observed_distroseries)
+
def test_distribution_with_derived_series_of_self(self):
# Given a distribution with series derived from other of its series
# (which shouldn't happen), the vocabulary factory returns a
@@ -87,8 +107,9 @@
# given distribution.
parent_distroseries = self.factory.makeDistroSeries()
distroseries = self.factory.makeDistroSeries(
- distribution=parent_distroseries.distribution,
- previous_series=parent_distroseries)
+ distribution=parent_distroseries.distribution)
+ self.factory.makeDistroSeriesParent(
+ derived_series=distroseries, parent_series=parent_distroseries)
vocabulary = DistroSeriesDerivationVocabulary(distroseries)
expected_distroseries = (
set(self.all_distroseries).difference(
@@ -168,8 +189,9 @@
distribution = self.factory.makeDistribution()
parent_distroseries = self.factory.makeDistroSeries()
distroseries = self.factory.makeDistroSeries(
- previous_series=parent_distroseries,
distribution=distribution)
+ self.factory.makeDistroSeriesParent(
+ derived_series=distroseries, parent_series=parent_distroseries)
flush_database_caches()
# Reload distroseries and distribution; these will reasonably already
# be loaded before using the vocabulary.
=== modified file 'lib/lp/registry/vocabularies.py'
--- lib/lp/registry/vocabularies.py 2011-05-31 15:08:34 +0000
+++ lib/lp/registry/vocabularies.py 2011-06-03 09:34:37 +0000
@@ -79,9 +79,7 @@
from storm.info import ClassAlias
from zope.component import getUtility
from zope.interface import implements
-from zope.schema.interfaces import (
- IVocabularyTokenized,
- )
+from zope.schema.interfaces import IVocabularyTokenized
from zope.schema.vocabulary import (
SimpleTerm,
SimpleVocabulary,
@@ -164,11 +162,15 @@
from lp.registry.interfaces.sourcepackage import ISourcePackage
from lp.registry.model.distribution import Distribution
from lp.registry.model.distroseries import DistroSeries
+from lp.registry.model.distroseriesparent import DistroSeriesParent
from lp.registry.model.featuredproject import FeaturedProject
from lp.registry.model.karma import KarmaCategory
from lp.registry.model.mailinglist import MailingList
from lp.registry.model.milestone import Milestone
-from lp.registry.model.person import Person, IrcID
+from lp.registry.model.person import (
+ IrcID,
+ Person,
+ )
from lp.registry.model.pillar import PillarName
from lp.registry.model.product import Product
from lp.registry.model.productrelease import ProductRelease
@@ -1603,7 +1605,8 @@
parent.distributionID, And(
parent.distributionID != self.distribution.id,
child.distributionID == self.distribution.id,
- child.previous_seriesID == parent.id))
+ child.id == DistroSeriesParent.derived_series_id,
+ parent.id == DistroSeriesParent.parent_series_id))
where.append(
DistroSeries.distributionID.is_in(parent_distributions))
terms = self.find_terms(where)