launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #04140
[Merge] lp:~jtv/launchpad/dsd-packageset-filter into lp:launchpad
Jeroen T. Vermeulen has proposed merging lp:~jtv/launchpad/dsd-packageset-filter into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~jtv/launchpad/dsd-packageset-filter/+merge/66757
= Summary =
Plans are underway to add various filtering options to the +localpackagediffs page. One of those would be on packagesets. It would be helpful for the model code to start supporting these filters.
== Proposed fix ==
Here I implement a filter on package sets. Having it in the code will make it easier to add the UI knobs, experiment with performance etc.
== Pre-implementation notes ==
Based on discussion with Julian at the Thunderdome. He actually wants more filters, but those will need more work because they're likely to be more complex and more performance-sensitive.
The prospective feature would ideally allow for a multi-packageset filter. I was told I could start off with a single-packageset filter, but with the query structure I chose there was really no difference.
== Implementation details ==
I match on packagesets using an "IN" subquery. That seems more appropriate than flattening into a join, since doing so would likely multiply the number of output rows for the database to consider by large numbers. A subquery is of course also simpler because it does not affect sorting or uniqueness clauses.
An easy change would be to add a "UNIQUE" to the subquery, but I wouldn't expect that to pay except with significant packageset overlap.
== Tests ==
{{{
./bin/test -vvc lp.registry.tests.test_distroseriesdifference
}}}
== Demo and Q/A ==
The code isn't hooked up anywhere yet. We'll have to experiment in "make harness" on dogfood.
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/registry/tests/test_distroseriesdifference.py
lib/lp/soyuz/model/packagesetsources.py
lib/lp/registry/interfaces/distroseriesdifference.py
lib/lp/registry/model/distroseriesdifference.py
--
https://code.launchpad.net/~jtv/launchpad/dsd-packageset-filter/+merge/66757
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jtv/launchpad/dsd-packageset-filter into lp:launchpad.
=== modified file 'lib/lp/registry/interfaces/distroseriesdifference.py'
--- lib/lp/registry/interfaces/distroseriesdifference.py 2011-06-14 13:47:51 +0000
+++ lib/lp/registry/interfaces/distroseriesdifference.py 2011-07-04 08:47:29 +0000
@@ -297,7 +297,8 @@
source_package_name_filter=None,
status=None,
child_version_higher=False,
- parent_series=None):
+ parent_series=None,
+ packagesets=None):
"""Return differences for the derived distro series sorted by
package name.
@@ -319,6 +320,7 @@
:param parent_series: The parent series to consider. Consider all
parent series if this parameter is None.
:type distro_series: `IDistroSeries`.
+ :param packagesets: Optional iterable of `Packageset` to filter by.
:return: A result set of `IDistroSeriesDifference`.
"""
=== modified file 'lib/lp/registry/model/distroseriesdifference.py'
--- lib/lp/registry/model/distroseriesdifference.py 2011-06-23 10:52:32 +0000
+++ lib/lp/registry/model/distroseriesdifference.py 2011-07-04 08:47:29 +0000
@@ -25,6 +25,7 @@
And,
Column,
Desc,
+ Select,
Table,
)
from storm.locals import (
@@ -65,7 +66,6 @@
)
from lp.registry.interfaces.distroseriesparent import IDistroSeriesParentSet
from lp.registry.interfaces.person import IPersonSet
-from lp.registry.model.distroseries import DistroSeries
from lp.registry.model.distroseriesdifferencecomment import (
DistroSeriesDifferenceComment,
)
@@ -203,7 +203,7 @@
return DecoratedResultSet(comments, itemgetter(0))
-def packagesets(dsds, in_parent):
+def get_packagesets(dsds, in_parent):
"""Return the packagesets for the given dsds inside the parent or
the derived `DistroSeries`.
@@ -336,7 +336,8 @@
source_package_name_filter=None,
status=None,
child_version_higher=False,
- parent_series=None):
+ parent_series=None,
+ packagesets=None):
"""See `IDistroSeriesDifferenceSource`."""
if difference_type is None:
difference_type = DistroSeriesDifferenceType.DIFFERENT_VERSIONS
@@ -368,6 +369,14 @@
DistroSeriesDifference.source_version >
DistroSeriesDifference.parent_source_version])
+ if packagesets is not None:
+ set_ids = [packageset.id for packageset in packagesets]
+ conditions.extend([
+ DistroSeriesDifference.source_package_name_id.is_in(
+ Select(
+ PackagesetSources.sourcepackagename_id,
+ PackagesetSources.packageset_id.is_in(set_ids)))])
+
differences = IStore(DistroSeriesDifference).find(
DistroSeriesDifference,
And(*conditions)).order_by(SourcePackageName.name)
@@ -410,8 +419,8 @@
("sourcepackagereleaseID",))
# Get packagesets and parent_packagesets for each DSD.
- dsd_packagesets = packagesets(dsds, in_parent=False)
- dsd_parent_packagesets = packagesets(dsds, in_parent=True)
+ dsd_packagesets = get_packagesets(dsds, in_parent=False)
+ dsd_parent_packagesets = get_packagesets(dsds, in_parent=True)
# Cache latest messages contents (MessageChunk).
messages = bulk.load_related(
=== modified file 'lib/lp/registry/tests/test_distroseriesdifference.py'
--- lib/lp/registry/tests/test_distroseriesdifference.py 2011-06-10 23:02:22 +0000
+++ lib/lp/registry/tests/test_distroseriesdifference.py 2011-07-04 08:47:29 +0000
@@ -36,9 +36,9 @@
most_recent_publications,
)
from lp.services.propertycache import get_property_cache
-from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
from lp.soyuz.enums import PackageDiffStatus
from lp.soyuz.interfaces.publishing import PackagePublishingStatus
+from lp.soyuz.model.packagesetsources import PackagesetSources
from lp.testing import (
celebrity_logged_in,
person_logged_in,
@@ -217,7 +217,8 @@
source_package_name_str="foonew",
versions=dict(parent='1.0', derived='1.0'),
status=DistroSeriesDifferenceStatus.RESOLVED)
- new_parent_pub = self.factory.makeSourcePackagePublishingHistory(
+ # Publish package in the parent series.
+ self.factory.makeSourcePackagePublishingHistory(
sourcepackagename=ds_diff.source_package_name,
distroseries=ds_diff.parent_series,
status=PackagePublishingStatus.PENDING,
@@ -1063,6 +1064,39 @@
self.assertContentEqual(diffs['normal'], results)
self.assertContentEqual(diffs2['normal'], results2)
+ def test_getForDistroSeries_matches_packageset(self):
+ dsd = self.factory.makeDistroSeriesDifference()
+ packageset = self.factory.makePackageset(
+ distroseries=dsd.derived_series)
+ Store.of(dsd).add(PackagesetSources(
+ packageset=packageset, sourcepackagename=dsd.source_package_name))
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ self.assertContentEqual(
+ [dsd], dsd_source.getForDistroSeries(
+ dsd.derived_series, packagesets=(packageset, )))
+
+ def test_getForDistroSeries_matches_any_packageset_in_filter(self):
+ dsd = self.factory.makeDistroSeriesDifference()
+ packagesets = [
+ self.factory.makePackageset(distroseries=dsd.derived_series)
+ for counter in xrange(2)]
+ Store.of(dsd).add(PackagesetSources(
+ packageset=packagesets[0],
+ sourcepackagename=dsd.source_package_name))
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ self.assertContentEqual(
+ [dsd], dsd_source.getForDistroSeries(
+ dsd.derived_series, packagesets=packagesets))
+
+ def test_getForDistroSeries_filters_by_packageset(self):
+ dsd = self.factory.makeDistroSeriesDifference()
+ packageset = self.factory.makePackageset(
+ distroseries=dsd.derived_series)
+ dsd_source = getUtility(IDistroSeriesDifferenceSource)
+ self.assertContentEqual(
+ [], dsd_source.getForDistroSeries(
+ dsd.derived_series, packagesets=(packageset, )))
+
def test_getByDistroSeriesNameAndParentSeries(self):
# An individual difference is obtained using the name.
ds_diff = self.factory.makeDistroSeriesDifference(
=== modified file 'lib/lp/soyuz/model/packagesetsources.py'
--- lib/lp/soyuz/model/packagesetsources.py 2011-06-22 13:08:05 +0000
+++ lib/lp/soyuz/model/packagesetsources.py 2011-07-04 08:47:29 +0000
@@ -39,3 +39,7 @@
sourcepackagename_id = Int(name='sourcepackagename')
sourcepackagename = Reference(
sourcepackagename_id, 'SourcePackageName.id')
+
+ def __init__(self, packageset, sourcepackagename):
+ self.packageset = packageset
+ self.sourcepackagename = sourcepackagename