launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #02818
[Merge] lp:~wgrant/launchpad/generalise-add-missing-builds into lp:launchpad
William Grant has proposed merging lp:~wgrant/launchpad/generalise-add-missing-builds into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
#726900 ppa-add-missing-builds.py should work for more than just PPAs
https://bugs.launchpad.net/bugs/726900
#726904 ppa-add-missing-builds.py should parse P-a-s
https://bugs.launchpad.net/bugs/726904
For more details, see:
https://code.launchpad.net/~wgrant/launchpad/generalise-add-missing-builds/+merge/51873
This branch renames ppa-add-missing-builds.py to add-missing-builds.py, and makes it work for the primary archive too.
Rather than duplicating the archive selection logic, I turned AddMissingBuilds into a SoyuzScript. This allowed deletion of much of its code, as I reused the suite selection too.
The other change is the introduction of Packages-arch-specific support. This should be reasonably clear. determineArchitecturesToBuild knows not to respect P-a-s for PPA builds, so it is fine to give it to createMissingBuilds unconditionally.
I added a test to verify that it works for primary archives with P-a-s. The script's parsing of P-a-s from the right place is difficult to check in the test suite, but I've confirmed that it works.
--
https://code.launchpad.net/~wgrant/launchpad/generalise-add-missing-builds/+merge/51873
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/generalise-add-missing-builds into lp:launchpad.
=== renamed file 'lib/lp/soyuz/scripts/ppa_add_missing_builds.py' => 'lib/lp/soyuz/scripts/add_missing_builds.py'
--- lib/lp/soyuz/scripts/ppa_add_missing_builds.py 2011-01-12 15:25:24 +0000
+++ lib/lp/soyuz/scripts/add_missing_builds.py 2011-03-02 10:22:43 +0000
@@ -4,23 +4,29 @@
import sys
-from zope.component import getUtility
-
+from canonical.config import config
from lp.app.errors import NotFoundError
-from lp.services.scripts.base import LaunchpadScript
+from lp.services.scripts.base import LaunchpadScriptFailure
+from lp.soyuz.pas import BuildDaemonPackagesArchSpecific
+from lp.soyuz.scripts.ftpmasterbase import (
+ SoyuzScript,
+ SoyuzScriptError,
+ )
from lp.soyuz.enums import PackagePublishingStatus
-class PPAMissingBuilds(LaunchpadScript):
+class AddMissingBuilds(SoyuzScript):
"""Helper class to create builds in PPAs for requested architectures."""
- def add_missing_ppa_builds(self, ppa, required_arches, distroseries):
- """For a PPA, create builds as necessary.
+ def add_missing_builds(self, archive, required_arches, pas_verify,
+ distroseries, pocket):
+ """Create builds in an archive as necessary.
- :param ppa: The PPA
- :param required_arches: A list of `DistroArchSeries`
+ :param archive: The `Archive`.
+ :param required_arches: A list of `DistroArchSeries`.
:param distroseries: The context `DistroSeries` in which to create
builds.
+ :param pocket: The context `PackagePublishingPocket`.
"""
# Listify the architectures to avoid hitting this MultipleJoin
# multiple times.
@@ -50,8 +56,9 @@
self.logger.error("Requested architectures not available")
return
- sources = ppa.getPublishedSources(
+ sources = archive.getPublishedSources(
distroseries=distroseries,
+ pocket=pocket,
status=PackagePublishingStatus.PUBLISHED)
if not bool(sources):
self.logger.info("No sources published, nothing to do.")
@@ -63,68 +70,46 @@
for pubrec in sources:
self.logger.info("Considering %s" % pubrec.displayname)
builds = pubrec.createMissingBuilds(
- architectures_available=doable_arch_set, logger=self.logger)
+ architectures_available=doable_arch_set,
+ pas_verify=pas_verify, logger=self.logger)
if len(builds) > 0:
self.logger.info("Created %s build(s)" % len(builds))
def add_my_options(self):
"""Command line options for this script."""
+ self.add_archive_options()
+ self.add_distro_options()
self.parser.add_option(
"-a", action="append", dest='arch_tags', default=[])
- self.parser.add_option("-s", action="store", dest='distroseries_name')
- self.parser.add_option(
- "-d", action="store", dest='distribution_name', default="ubuntu")
- self.parser.add_option(
- "--owner", action="store", dest='ppa_owner_name')
- self.parser.add_option(
- "--ppa", action="store", dest='ppa_name', default="ppa")
def main(self):
"""Entry point for `LaunchpadScript`s."""
+ try:
+ self.setupLocation()
+ except SoyuzScriptError, err:
+ raise LaunchpadScriptFailure(err)
+
if not self.options.arch_tags:
self.parser.error("Specify at least one architecture.")
- if not self.options.distroseries_name:
- self.parser.error("Specify a distroseries.")
-
- if not self.options.ppa_owner_name:
- self.parser.error("Specify a PPA owner name.")
-
- # Avoid circular imports by importing here.
- from lp.registry.interfaces.distribution import IDistributionSet
- distro = getUtility(IDistributionSet).getByName(
- self.options.distribution_name)
- if distro is None:
- self.parser.error("%s not found" % self.options.distribution_name)
-
- try:
- distroseries = distro.getSeries(self.options.distroseries_name)
- except NotFoundError:
- self.parser.error("%s not found" % self.options.distroseries_name)
-
arches = []
for arch_tag in self.options.arch_tags:
try:
- das = distroseries.getDistroArchSeries(arch_tag)
+ das = self.location.distroseries.getDistroArchSeries(arch_tag)
arches.append(das)
except NotFoundError:
self.parser.error(
"%s not a valid architecture for %s" % (
- arch_tag, self.options.distroseries_name))
-
- from lp.registry.interfaces.person import IPersonSet
- owner = getUtility(IPersonSet).getByName(self.options.ppa_owner_name)
- if owner is None:
- self.parser.error("%s not found" % self.options.ppa_owner_name)
-
- try:
- ppa = owner.getPPAByName(self.options.ppa_name)
- except NotFoundError:
- self.parser.error("%s not found" % self.options.ppa_name)
+ arch_tag, self.location.distroseries.name))
+
+ pas_verify = BuildDaemonPackagesArchSpecific(
+ config.builddmaster.root, self.location.distroseries)
# I'm tired of parsing options. Let's do it.
try:
- self.add_missing_ppa_builds(ppa, arches, distroseries)
+ self.add_missing_builds(
+ self.location.archive, arches, pas_verify,
+ self.location.distroseries, self.location.pocket)
self.txn.commit()
self.logger.info("Finished adding builds.")
except Exception, err:
@@ -133,4 +118,3 @@
self.logger.info("Errors, aborted transaction.")
sys.exit(1)
-
=== renamed file 'lib/lp/soyuz/scripts/tests/test_ppa_add_missing_builds.py' => 'lib/lp/soyuz/scripts/tests/test_add_missing_builds.py'
--- lib/lp/soyuz/scripts/tests/test_ppa_add_missing_builds.py 2010-12-20 03:21:03 +0000
+++ lib/lp/soyuz/scripts/tests/test_add_missing_builds.py 2011-03-02 10:22:43 +0000
@@ -1,11 +1,13 @@
# Copyright 2010 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
-"""Test the ppa-add-missing-builds.py script. """
+"""Test the add-missing-builds.py script. """
import os
import subprocess
import sys
+import shutil
+import tempfile
from canonical.config import config
from canonical.database.sqlbase import (
@@ -13,18 +15,20 @@
flush_database_updates,
)
from canonical.testing.layers import LaunchpadZopelessLayer
+from lp.registry.interfaces.pocket import PackagePublishingPocket
from lp.services.log.logger import BufferLogger
from lp.soyuz.enums import (
ArchivePurpose,
PackagePublishingStatus,
)
-from lp.soyuz.scripts.ppa_add_missing_builds import PPAMissingBuilds
+from lp.soyuz.pas import BuildDaemonPackagesArchSpecific
+from lp.soyuz.scripts.add_missing_builds import AddMissingBuilds
from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
from lp.testing import TestCaseWithFactory
-class TestPPAAddMissingBuilds(TestCaseWithFactory):
- """Test the ppa-add-missing-builds.py script. """
+class TestAddMissingBuilds(TestCaseWithFactory):
+ """Test the add-missing-builds.py script. """
layer = LaunchpadZopelessLayer
dbuser = config.builddmaster.dbuser
@@ -40,7 +44,8 @@
self.stp.breezy_autotest_hppa.supports_virtualized = True
# Create an arch-any and an arch-all source in a PPA.
- self.ppa = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
+ self.ppa = self.factory.makeArchive(
+ purpose=ArchivePurpose.PPA, distribution=self.stp.ubuntutest)
self.all = self.stp.getPubSource(
sourcename="all", architecturehintlist="all", archive=self.ppa,
status=PackagePublishingStatus.PUBLISHED)
@@ -60,7 +65,7 @@
if test_args is None:
test_args = []
script = os.path.join(
- config.root, "scripts", "ppa-add-missing-builds.py")
+ config.root, "scripts", "add-missing-builds.py")
args = [sys.executable, script]
args.extend(test_args)
process = subprocess.Popen(
@@ -70,10 +75,21 @@
def getScript(self):
"""Return an instance of the script object."""
- script = PPAMissingBuilds("test", test_args=[])
+ script = AddMissingBuilds("test", test_args=[])
script.logger = BufferLogger()
return script
+ def makePasVerifier(self, content, series):
+ """Create a BuildDaemonPackagesArchSpecific."""
+ temp_dir = tempfile.mkdtemp()
+ filename = os.path.join(temp_dir, "Packages-arch-specific")
+ file = open(filename, "w")
+ file.write(content)
+ file.close()
+ verifier = BuildDaemonPackagesArchSpecific(temp_dir, series)
+ shutil.rmtree(temp_dir)
+ return verifier
+
def getBuilds(self):
"""Helper to return build records."""
any_build_i386 = self.any.sourcepackagerelease.getBuildByArch(
@@ -121,8 +137,8 @@
"-s", "breezy-autotest",
"-a", "i386",
"-a", "hppa",
- "--owner", "%s" % self.ppa.owner.name,
- "--ppa", self.ppa.name,
+ "--ppa", "%s" % self.ppa.owner.name,
+ "--ppa-name", self.ppa.name,
]
code, stdout, stderr = self.runScript(args)
self.assertEqual(
@@ -153,6 +169,31 @@
self.any.requestDeletion(self.ppa.owner)
script = self.getScript()
- script.add_missing_ppa_builds(
- self.ppa, self.required_arches, self.stp.breezy_autotest)
+ script.add_missing_builds(
+ self.ppa, self.required_arches, None, self.stp.breezy_autotest,
+ PackagePublishingPocket.RELEASE)
self.assertNoBuilds()
+
+ def testPrimaryArchiveWithPas(self):
+ """Test that the script functions correctly on a primary archive.
+
+ Also verifies that it respects Packages-arch-specific in this case.
+ """
+ archive = self.stp.ubuntutest.main_archive
+ any = self.stp.getPubSource(
+ sourcename="any", architecturehintlist="any",
+ status=PackagePublishingStatus.PUBLISHED)
+ pas_any = self.stp.getPubSource(
+ sourcename="pas-any", architecturehintlist="any",
+ status=PackagePublishingStatus.PUBLISHED)
+
+ verifier = self.makePasVerifier(
+ "%pas-any: hppa", self.stp.breezy_autotest)
+ script = self.getScript()
+ script.add_missing_builds(
+ archive, self.required_arches, verifier,
+ self.stp.breezy_autotest, PackagePublishingPocket.RELEASE)
+
+ # any gets i386 and hppa builds, but pas-any is restricted to hppa.
+ self.assertEquals(len(any.getBuilds()), 2)
+ self.assertEquals(len(pas_any.getBuilds()), 1)
=== renamed file 'scripts/ppa-add-missing-builds.py' => 'scripts/add-missing-builds.py'
--- scripts/ppa-add-missing-builds.py 2011-01-13 17:39:55 +0000
+++ scripts/add-missing-builds.py 2011-03-02 10:22:43 +0000
@@ -7,10 +7,10 @@
import _pythonpath
-from lp.soyuz.scripts.ppa_add_missing_builds import PPAMissingBuilds
+from lp.soyuz.scripts.add_missing_builds import AddMissingBuilds
from canonical.config import config
if __name__ == "__main__":
- script = PPAMissingBuilds(
- "ppa-add-missing-builds", dbuser=config.uploader.dbuser)
+ script = AddMissingBuilds(
+ "add-missing-builds", dbuser=config.uploader.dbuser)
script.lock_and_run()