← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~cjwatson/launchpad/packageset-is-source-included into lp:launchpad

 

Colin Watson has proposed merging lp:~cjwatson/launchpad/packageset-is-source-included into lp:launchpad.

Commit message:
Add IPackageset.isSourceIncluded.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1842658 in Launchpad itself: "Support central filtering of which packages build for some architectures"
  https://bugs.launchpad.net/launchpad/+bug/1842658

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/packageset-is-source-included/+merge/372259

This makes it more efficient to query whether a single packageset includes a single source package name, which will shortly be useful for evaluating distro arch series filters.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/packageset-is-source-included into lp:launchpad.
=== modified file 'lib/lp/soyuz/interfaces/packageset.py'
--- lib/lp/soyuz/interfaces/packageset.py	2014-07-04 12:42:08 +0000
+++ lib/lp/soyuz/interfaces/packageset.py	2019-09-04 13:51:53 +0000
@@ -182,6 +182,16 @@
             names.
         """
 
+    def isSourceIncluded(sourcepackagename, direct_inclusion=False):
+        """Is this source package name included in this package set?
+
+        :param sourcepackagename: an `ISourcePackageName`.
+        :param direct_inclusion: if this flag is set to True only sources
+            directly included by this package set will be considered.
+        :return: True if the source is included in this package set,
+            otherwise False.
+        """
+
     @operation_parameters(
         other_package_set=Reference(
             Interface,

=== modified file 'lib/lp/soyuz/model/packageset.py'
--- lib/lp/soyuz/model/packageset.py	2018-12-10 13:54:34 +0000
+++ lib/lp/soyuz/model/packageset.py	2019-09-04 13:51:53 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 __metaclass__ = type
@@ -142,8 +142,7 @@
         ''' % ','.join(str(packageset.id) for packageset in packagesets)
         store.execute(rdsq, (self.id,), noresult=True)
 
-    def sourcesIncluded(self, direct_inclusion=False):
-        """See `IPackageset`."""
+    def _sourcesIncludedClause(self, direct_inclusion=False):
         if direct_inclusion == False:
             source_name_query = '''
                 SELECT pss.sourcepackagename
@@ -155,10 +154,14 @@
                 SELECT pss.sourcepackagename FROM packagesetsources pss
                 WHERE pss.packageset = ?
             '''
+        return SourcePackageName.id.is_in(SQL(source_name_query, (self.id,)))
+
+    def sourcesIncluded(self, direct_inclusion=False):
+        """See `IPackageset`."""
         store = IStore(Packageset)
-        source_names = SQL(source_name_query, (self.id,))
         result_set = store.find(
-            SourcePackageName, SourcePackageName.id.is_in(source_names))
+            SourcePackageName,
+            self._sourcesIncludedClause(direct_inclusion=direct_inclusion))
         return _order_result_set(result_set)
 
     def getSourcesIncluded(self, direct_inclusion=False):
@@ -166,6 +169,15 @@
         result_set = self.sourcesIncluded(direct_inclusion)
         return list(result_set.values(SourcePackageName.name))
 
+    def isSourceIncluded(self, sourcepackagename, direct_inclusion=False):
+        """See `IPackageset`."""
+        store = IStore(Packageset)
+        result_set = store.find(
+            SourcePackageName,
+            SourcePackageName.id == sourcepackagename.id,
+            self._sourcesIncludedClause(direct_inclusion=direct_inclusion))
+        return not result_set.is_empty()
+
     def setsIncludedBy(self, direct_inclusion=False):
         """See `IPackageset`."""
         if direct_inclusion == False:

=== modified file 'lib/lp/soyuz/tests/test_packageset.py'
--- lib/lp/soyuz/tests/test_packageset.py	2018-02-09 14:56:43 +0000
+++ lib/lp/soyuz/tests/test_packageset.py	2019-09-04 13:51:53 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd.  This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
 """Test Packageset features."""
@@ -453,6 +453,30 @@
             sorted(packageset1.sourcesIncluded()),
             sorted(packages1 + packages2))
 
+    def test_is_source_included(self):
+        # Test if a source package name is included in a set
+        packageset, packages = self.buildSet()
+        for spn in packages:
+            self.assertTrue(packageset.isSourceIncluded(spn))
+        self.assertFalse(
+            packageset.isSourceIncluded(self.factory.makeSourcePackageName()))
+
+    def test_is_source_included_indirect(self):
+        # isSourceIncluded traverses the set tree, by default
+        packageset1, packages1 = self.buildSet()
+        packageset2, packages2 = self.buildSet()
+        packageset1.add((packageset2,))
+        for spn in packages1 + packages2:
+            self.assertTrue(packageset1.isSourceIncluded(spn))
+
+        # direct_inclusion disables traversal
+        for spn in packages1:
+            self.assertTrue(
+                packageset1.isSourceIncluded(spn, direct_inclusion=True))
+        for spn in packages2:
+            self.assertFalse(
+                packageset1.isSourceIncluded(spn, direct_inclusion=True))
+
     def test_add_already_included_sources(self):
         # Adding source packages to a package set repeatedly has no effect
         packageset, packages = self.buildSet()


Follow ups