launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #28514
[Merge] ~cjwatson/launchpad:artifactory-pypi into launchpad:master
Colin Watson has proposed merging ~cjwatson/launchpad:artifactory-pypi into launchpad:master with ~cjwatson/launchpad:diskpool-add-source-version as a prerequisite.
Commit message:
Handle path changes to publish Python packages via Artifactory
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/423563
Unlike .debs, Python packages (sdists and wheels) are published in <name>/<version>/ subdirectories.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:artifactory-pypi into launchpad:master.
diff --git a/lib/lp/archivepublisher/artifactory.py b/lib/lp/archivepublisher/artifactory.py
index 53b43a6..5ce6460 100644
--- a/lib/lp/archivepublisher/artifactory.py
+++ b/lib/lp/archivepublisher/artifactory.py
@@ -41,6 +41,21 @@ from lp.soyuz.interfaces.publishing import (
)
+def _path_for(archive: IArchive, rootpath: ArtifactoryPath, source_name: str,
+ source_version: str, filename: Optional[str] = None) -> Path:
+ repository_format = archive.repository_format
+ if repository_format == ArchiveRepositoryFormat.DEBIAN:
+ path = rootpath / poolify(source_name)
+ elif repository_format == ArchiveRepositoryFormat.PYTHON:
+ path = rootpath / source_name / source_version
+ else:
+ raise AssertionError(
+ "Unsupported repository format: %r" % repository_format)
+ if filename:
+ path = path / filename
+ return path
+
+
class ArtifactoryPoolEntry:
def __init__(self, archive: IArchive, rootpath: ArtifactoryPath,
@@ -63,7 +78,9 @@ class ArtifactoryPoolEntry:
# the pool structure, and doing so would introduce significant
# complications in terms of having to keep track of components just
# in order to update an artifact's properties.
- return self.rootpath / poolify(self.source_name) / self.filename
+ return _path_for(
+ self.archive, self.rootpath, self.source_name, self.source_version,
+ self.filename)
def makeReleaseID(self, pub_file: IPackageReleaseFile) -> str:
"""
@@ -156,8 +173,7 @@ class ArtifactoryPoolEntry:
else:
properties["launchpad.channel"] = sorted({
"%s:%s" % (
- pub.distroseries.getSuite(pub.pocket),
- pub.channel_string)
+ pub.distroseries.getSuite(pub.pocket), pub.channel)
for pub in publications})
return properties
@@ -285,10 +301,8 @@ class ArtifactoryPool:
# the pool structure, and doing so would introduce significant
# complications in terms of having to keep track of components just
# in order to update an artifact's properties.
- path = self.rootpath / poolify(source_name)
- if file:
- path = path / file
- return path
+ return _path_for(
+ self.archive, self.rootpath, source_name, source_version, file)
def addFile(self, component: str, source_name: str, source_version: str,
filename: str, pub_file: IPackageReleaseFile):
diff --git a/lib/lp/archivepublisher/config.py b/lib/lp/archivepublisher/config.py
index 55603dc..06ae2a7 100644
--- a/lib/lp/archivepublisher/config.py
+++ b/lib/lp/archivepublisher/config.py
@@ -20,6 +20,7 @@ from lp.soyuz.enums import (
archive_suffixes,
ArchivePublishingMethod,
ArchivePurpose,
+ ArchiveRepositoryFormat,
)
@@ -111,8 +112,12 @@ def getPubConfig(archive):
pubconf.signingroot = None
pubconf.signingautokey = False
- pubconf.poolroot = os.path.join(pubconf.archiveroot, 'pool')
- pubconf.distsroot = os.path.join(pubconf.archiveroot, 'dists')
+ if archive.repository_format == ArchiveRepositoryFormat.DEBIAN:
+ pubconf.poolroot = os.path.join(pubconf.archiveroot, 'pool')
+ pubconf.distsroot = os.path.join(pubconf.archiveroot, 'dists')
+ else:
+ pubconf.poolroot = pubconf.archiveroot
+ pubconf.distsroot = None
# META_DATA custom uploads are stored in a separate directory
# outside the archive root so Ubuntu Software Center can get some
diff --git a/lib/lp/archivepublisher/tests/test_artifactory.py b/lib/lp/archivepublisher/tests/test_artifactory.py
index f611ac9..6954a2c 100644
--- a/lib/lp/archivepublisher/tests/test_artifactory.py
+++ b/lib/lp/archivepublisher/tests/test_artifactory.py
@@ -5,6 +5,7 @@
from pathlib import PurePath
+from artifactory import ArtifactoryPath
import transaction
from zope.component import getUtility
@@ -18,12 +19,16 @@ from lp.archivepublisher.tests.test_pool import (
PoolTestingFile,
)
from lp.registry.interfaces.pocket import PackagePublishingPocket
-from lp.registry.interfaces.sourcepackage import SourcePackageFileType
+from lp.registry.interfaces.sourcepackage import (
+ SourcePackageFileType,
+ SourcePackageType,
+ )
from lp.services.log.logger import BufferLogger
from lp.soyuz.enums import (
ArchivePurpose,
ArchiveRepositoryFormat,
BinaryPackageFileType,
+ BinaryPackageFormat,
)
from lp.soyuz.interfaces.publishing import (
IPublishingSet,
@@ -77,16 +82,53 @@ class TestArtifactoryPool(TestCase):
self.repository_name = "repository"
self.artifactory = self.useFixture(
FakeArtifactoryFixture(self.base_url, self.repository_name))
- root_url = "%s/%s/pool" % (self.base_url, self.repository_name)
- self.pool = ArtifactoryPool(FakeArchive(), root_url, BufferLogger())
+
+ def makePool(self, repository_format=ArchiveRepositoryFormat.DEBIAN):
+ # Matches behaviour of lp.archivepublisher.config.getPubConfig.
+ root_url = "%s/%s" % (self.base_url, self.repository_name)
+ if repository_format == ArchiveRepositoryFormat.DEBIAN:
+ root_url += "/pool"
+ return ArtifactoryPool(
+ FakeArchive(repository_format), root_url, BufferLogger())
+
+ def test_pathFor_debian_without_file(self):
+ pool = self.makePool()
+ self.assertEqual(
+ ArtifactoryPath(
+ "https://foo.example.com/artifactory/repository/pool/f/foo"),
+ pool.pathFor(None, "foo", "1.0"))
+
+ def test_pathFor_debian_with_file(self):
+ pool = self.makePool()
+ self.assertEqual(
+ ArtifactoryPath(
+ "https://foo.example.com/artifactory/repository/pool/f/foo/"
+ "foo-1.0.deb"),
+ pool.pathFor(None, "foo", "1.0", "foo-1.0.deb"))
+
+ def test_pathFor_python_without_file(self):
+ pool = self.makePool(ArchiveRepositoryFormat.PYTHON)
+ self.assertEqual(
+ ArtifactoryPath(
+ "https://foo.example.com/artifactory/repository/foo/1.0"),
+ pool.pathFor(None, "foo", "1.0"))
+
+ def test_pathFor_python_with_file(self):
+ pool = self.makePool(ArchiveRepositoryFormat.PYTHON)
+ self.assertEqual(
+ ArtifactoryPath(
+ "https://foo.example.com/artifactory/repository/foo/1.0/"
+ "foo-1.0.whl"),
+ pool.pathFor(None, "foo", "1.0", "foo-1.0.whl"))
def test_addFile(self):
+ pool = self.makePool()
foo = ArtifactoryPoolTestingFile(
- self.pool, "foo", "1.0", "foo-1.0.deb",
+ pool, "foo", "1.0", "foo-1.0.deb",
release_type=FakeReleaseType.BINARY, release_id=1)
self.assertFalse(foo.checkIsFile())
result = foo.addToPool()
- self.assertEqual(self.pool.results.FILE_ADDED, result)
+ self.assertEqual(pool.results.FILE_ADDED, result)
self.assertTrue(foo.checkIsFile())
self.assertEqual(
{
@@ -97,18 +139,20 @@ class TestArtifactoryPool(TestCase):
foo.getProperties())
def test_addFile_exists_identical(self):
+ pool = self.makePool()
foo = ArtifactoryPoolTestingFile(
- self.pool, "foo", "1.0", "foo-1.0.deb",
+ pool, "foo", "1.0", "foo-1.0.deb",
release_type=FakeReleaseType.BINARY, release_id=1)
foo.addToPool()
self.assertTrue(foo.checkIsFile())
result = foo.addToPool()
- self.assertEqual(self.pool.results.NONE, result)
+ self.assertEqual(pool.results.NONE, result)
self.assertTrue(foo.checkIsFile())
def test_addFile_exists_overwrite(self):
+ pool = self.makePool()
foo = ArtifactoryPoolTestingFile(
- self.pool, "foo", "1.0", "foo-1.0.deb",
+ pool, "foo", "1.0", "foo-1.0.deb",
release_type=FakeReleaseType.BINARY, release_id=1)
foo.addToPool()
self.assertTrue(foo.checkIsFile())
@@ -116,8 +160,8 @@ class TestArtifactoryPool(TestCase):
self.assertRaises(PoolFileOverwriteError, foo.addToPool)
def test_removeFile(self):
- foo = ArtifactoryPoolTestingFile(
- self.pool, "foo", "1.0", "foo-1.0.deb")
+ pool = self.makePool()
+ foo = ArtifactoryPoolTestingFile(pool, "foo", "1.0", "foo-1.0.deb")
foo.addToPool()
self.assertTrue(foo.checkIsFile())
size = foo.removeFromPool()
@@ -125,6 +169,7 @@ class TestArtifactoryPool(TestCase):
self.assertEqual(3, size)
def test_getArtifactPatterns_debian(self):
+ pool = self.makePool()
self.assertEqual(
[
"*.ddeb",
@@ -134,12 +179,13 @@ class TestArtifactoryPool(TestCase):
"*.tar.*",
"*.udeb",
],
- self.pool.getArtifactPatterns(ArchiveRepositoryFormat.DEBIAN))
+ pool.getArtifactPatterns(ArchiveRepositoryFormat.DEBIAN))
def test_getArtifactPatterns_python(self):
+ pool = self.makePool()
self.assertEqual(
["*.whl"],
- self.pool.getArtifactPatterns(ArchiveRepositoryFormat.PYTHON))
+ pool.getArtifactPatterns(ArchiveRepositoryFormat.PYTHON))
def test_getAllArtifacts(self):
# getAllArtifacts mostly relies on constructing a correct AQL query,
@@ -147,14 +193,15 @@ class TestArtifactoryPool(TestCase):
# instance, although `FakeArtifactoryFixture` tries to do something
# with it. This test mainly ensures that we transform the response
# correctly.
+ pool = self.makePool()
ArtifactoryPoolTestingFile(
- self.pool, "foo", "1.0", "foo-1.0.deb",
+ pool, "foo", "1.0", "foo-1.0.deb",
release_type=FakeReleaseType.BINARY, release_id=1).addToPool()
ArtifactoryPoolTestingFile(
- self.pool, "foo", "1.1", "foo-1.1.deb",
+ pool, "foo", "1.1", "foo-1.1.deb",
release_type=FakeReleaseType.BINARY, release_id=2).addToPool()
ArtifactoryPoolTestingFile(
- self.pool, "bar", "1.0", "bar-1.0.whl",
+ pool, "bar", "1.0", "bar-1.0.whl",
release_type=FakeReleaseType.BINARY, release_id=3).addToPool()
self.assertEqual(
{
@@ -169,7 +216,7 @@ class TestArtifactoryPool(TestCase):
"launchpad.source-version": ["1.1"],
},
},
- self.pool.getAllArtifacts(
+ pool.getAllArtifacts(
self.repository_name, ArchiveRepositoryFormat.DEBIAN))
self.assertEqual(
{
@@ -179,7 +226,7 @@ class TestArtifactoryPool(TestCase):
"launchpad.source-version": ["1.0"],
},
},
- self.pool.getAllArtifacts(
+ pool.getAllArtifacts(
self.repository_name, ArchiveRepositoryFormat.PYTHON))
@@ -193,17 +240,24 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
self.repository_name = "repository"
self.artifactory = self.useFixture(
FakeArtifactoryFixture(self.base_url, self.repository_name))
- root_url = "%s/%s/pool" % (self.base_url, self.repository_name)
- self.archive = self.factory.makeArchive(purpose=ArchivePurpose.PPA)
- self.pool = ArtifactoryPool(self.archive, root_url, BufferLogger())
+
+ def makePool(self, repository_format=ArchiveRepositoryFormat.DEBIAN):
+ # Matches behaviour of lp.archivepublisher.config.getPubConfig.
+ root_url = "%s/%s" % (self.base_url, self.repository_name)
+ if repository_format == ArchiveRepositoryFormat.DEBIAN:
+ root_url += "/pool"
+ archive = self.factory.makeArchive(
+ purpose=ArchivePurpose.PPA, repository_format=repository_format)
+ return ArtifactoryPool(archive, root_url, BufferLogger())
def test_updateProperties_debian_source(self):
+ pool = self.makePool()
dses = [
self.factory.makeDistroSeries(
- distribution=self.archive.distribution)
+ distribution=pool.archive.distribution)
for _ in range(2)]
spph = self.factory.makeSourcePackagePublishingHistory(
- archive=self.archive, distroseries=dses[0],
+ archive=pool.archive, distroseries=dses[0],
pocket=PackagePublishingPocket.RELEASE, component="main",
sourcepackagename="foo", version="1.0")
spr = spph.sourcepackagerelease
@@ -214,11 +268,11 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
filetype=SourcePackageFileType.DSC)
spphs = [spph]
spphs.append(spph.copyTo(
- dses[1], PackagePublishingPocket.RELEASE, self.archive))
+ dses[1], PackagePublishingPocket.RELEASE, pool.archive))
transaction.commit()
- self.pool.addFile(
+ pool.addFile(
None, spr.name, spr.version, sprf.libraryfile.filename, sprf)
- path = self.pool.rootpath / "f" / "foo" / "foo_1.0.dsc"
+ path = pool.rootpath / "f" / "foo" / "foo_1.0.dsc"
self.assertTrue(path.exists())
self.assertFalse(path.is_symlink())
self.assertEqual(
@@ -228,7 +282,7 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
"launchpad.source-version": ["1.0"],
},
path.properties)
- self.pool.updateProperties(
+ pool.updateProperties(
spr.name, spr.version, sprf.libraryfile.filename, spphs)
self.assertEqual(
{
@@ -241,9 +295,10 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
path.properties)
def test_updateProperties_debian_binary_multiple_series(self):
+ pool = self.makePool()
dses = [
self.factory.makeDistroSeries(
- distribution=self.archive.distribution)
+ distribution=pool.archive.distribution)
for _ in range(2)]
processor = self.factory.makeProcessor()
dases = [
@@ -251,9 +306,9 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
distroseries=ds, architecturetag=processor.name)
for ds in dses]
spr = self.factory.makeSourcePackageRelease(
- archive=self.archive, sourcepackagename="foo", version="1.0")
+ archive=pool.archive, sourcepackagename="foo", version="1.0")
bpph = self.factory.makeBinaryPackagePublishingHistory(
- archive=self.archive, distroarchseries=dases[0],
+ archive=pool.archive, distroarchseries=dases[0],
pocket=PackagePublishingPocket.RELEASE, component="main",
source_package_release=spr, binarypackagename="foo",
architecturespecific=True)
@@ -265,14 +320,13 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
filetype=BinaryPackageFileType.DEB)
bpphs = [bpph]
bpphs.append(bpph.copyTo(
- dses[1], PackagePublishingPocket.RELEASE, self.archive)[0])
+ dses[1], PackagePublishingPocket.RELEASE, pool.archive)[0])
transaction.commit()
- self.pool.addFile(
+ pool.addFile(
None, bpr.sourcepackagename, bpr.sourcepackageversion,
bpf.libraryfile.filename, bpf)
path = (
- self.pool.rootpath / "f" / "foo" /
- ("foo_1.0_%s.deb" % processor.name))
+ pool.rootpath / "f" / "foo" / ("foo_1.0_%s.deb" % processor.name))
self.assertTrue(path.exists())
self.assertFalse(path.is_symlink())
self.assertEqual(
@@ -282,7 +336,7 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
"launchpad.source-version": ["1.0"],
},
path.properties)
- self.pool.updateProperties(
+ pool.updateProperties(
bpr.sourcepackagename, bpr.sourcepackageversion,
bpf.libraryfile.filename, bpphs)
self.assertEqual(
@@ -297,15 +351,16 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
path.properties)
def test_updateProperties_debian_binary_multiple_architectures(self):
+ pool = self.makePool()
ds = self.factory.makeDistroSeries(
- distribution=self.archive.distribution)
+ distribution=pool.archive.distribution)
dases = [
self.factory.makeDistroArchSeries(distroseries=ds)
for _ in range(2)]
spr = self.factory.makeSourcePackageRelease(
- archive=self.archive, sourcepackagename="foo", version="1.0")
+ archive=pool.archive, sourcepackagename="foo", version="1.0")
bpb = self.factory.makeBinaryPackageBuild(
- archive=self.archive, source_package_release=spr,
+ archive=pool.archive, source_package_release=spr,
distroarchseries=dases[0], pocket=PackagePublishingPocket.RELEASE)
bpr = self.factory.makeBinaryPackageRelease(
binarypackagename="foo", build=bpb, component="main",
@@ -316,13 +371,13 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
filename="foo_1.0_all.deb"),
filetype=BinaryPackageFileType.DEB)
bpphs = getUtility(IPublishingSet).publishBinaries(
- self.archive, ds, PackagePublishingPocket.RELEASE,
+ pool.archive, ds, PackagePublishingPocket.RELEASE,
{bpr: (bpr.component, bpr.section, bpr.priority, None)})
transaction.commit()
- self.pool.addFile(
+ pool.addFile(
None, bpr.sourcepackagename, bpr.sourcepackageversion,
bpf.libraryfile.filename, bpf)
- path = self.pool.rootpath / "f" / "foo" / "foo_1.0_all.deb"
+ path = pool.rootpath / "f" / "foo" / "foo_1.0_all.deb"
self.assertTrue(path.exists())
self.assertFalse(path.is_symlink())
self.assertEqual(
@@ -332,7 +387,7 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
"launchpad.source-version": ["1.0"],
},
path.properties)
- self.pool.updateProperties(
+ pool.updateProperties(
bpr.sourcepackagename, bpr.sourcepackageversion,
bpf.libraryfile.filename, bpphs)
self.assertEqual(
@@ -347,16 +402,120 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
},
path.properties)
+ def test_updateProperties_python_sdist(self):
+ pool = self.makePool(ArchiveRepositoryFormat.PYTHON)
+ dses = [
+ self.factory.makeDistroSeries(
+ distribution=pool.archive.distribution)
+ for _ in range(2)]
+ spph = self.factory.makeSourcePackagePublishingHistory(
+ archive=pool.archive, distroseries=dses[0],
+ pocket=PackagePublishingPocket.RELEASE, component="main",
+ sourcepackagename="foo", version="1.0", channel="edge",
+ format=SourcePackageType.SDIST)
+ spr = spph.sourcepackagerelease
+ sprf = self.factory.makeSourcePackageReleaseFile(
+ sourcepackagerelease=spr,
+ library_file=self.factory.makeLibraryFileAlias(
+ filename="foo-1.0.tar.gz"),
+ filetype=SourcePackageFileType.SDIST)
+ spphs = [spph]
+ spphs.append(spph.copyTo(
+ dses[1], PackagePublishingPocket.RELEASE, pool.archive))
+ transaction.commit()
+ pool.addFile(
+ None, spr.name, spr.version, sprf.libraryfile.filename, sprf)
+ path = pool.rootpath / "foo" / "1.0" / "foo-1.0.tar.gz"
+ self.assertTrue(path.exists())
+ self.assertFalse(path.is_symlink())
+ self.assertEqual(
+ {
+ "launchpad.release-id": ["source:%d" % spr.id],
+ "launchpad.source-name": ["foo"],
+ "launchpad.source-version": ["1.0"],
+ },
+ path.properties)
+ pool.updateProperties(
+ spr.name, spr.version, sprf.libraryfile.filename, spphs)
+ self.assertEqual(
+ {
+ "launchpad.release-id": ["source:%d" % spr.id],
+ "launchpad.source-name": ["foo"],
+ "launchpad.source-version": ["1.0"],
+ "launchpad.channel": list(
+ sorted("%s:edge" % ds.name for ds in dses)),
+ },
+ path.properties)
+
+ def test_updateProperties_python_wheel(self):
+ pool = self.makePool(ArchiveRepositoryFormat.PYTHON)
+ dses = [
+ self.factory.makeDistroSeries(
+ distribution=pool.archive.distribution)
+ for _ in range(2)]
+ processor = self.factory.makeProcessor()
+ dases = [
+ self.factory.makeDistroArchSeries(
+ distroseries=ds, architecturetag=processor.name)
+ for ds in dses]
+ spr = self.factory.makeSourcePackageRelease(
+ archive=pool.archive, sourcepackagename="foo", version="1.0",
+ format=SourcePackageType.SDIST)
+ bpph = self.factory.makeBinaryPackagePublishingHistory(
+ archive=pool.archive, distroarchseries=dases[0],
+ pocket=PackagePublishingPocket.RELEASE, component="main",
+ source_package_release=spr, binarypackagename="foo",
+ binpackageformat=BinaryPackageFormat.WHL,
+ architecturespecific=False, channel="edge")
+ bpr = bpph.binarypackagerelease
+ bpf = self.factory.makeBinaryPackageFile(
+ binarypackagerelease=bpr,
+ library_file=self.factory.makeLibraryFileAlias(
+ filename="foo-1.0-py3-none-any.whl"),
+ filetype=BinaryPackageFileType.WHL)
+ bpphs = [bpph]
+ bpphs.append(
+ getUtility(IPublishingSet).copyBinaries(
+ pool.archive, dses[1], PackagePublishingPocket.RELEASE, [bpph],
+ channel="edge")[0])
+ transaction.commit()
+ pool.addFile(
+ None, bpr.sourcepackagename, bpr.sourcepackageversion,
+ bpf.libraryfile.filename, bpf)
+ path = pool.rootpath / "foo" / "1.0" / "foo-1.0-py3-none-any.whl"
+ self.assertTrue(path.exists())
+ self.assertFalse(path.is_symlink())
+ self.assertEqual(
+ {
+ "launchpad.release-id": ["binary:%d" % bpr.id],
+ "launchpad.source-name": ["foo"],
+ "launchpad.source-version": ["1.0"],
+ },
+ path.properties)
+ pool.updateProperties(
+ bpr.sourcepackagename, bpr.sourcepackageversion,
+ bpf.libraryfile.filename, bpphs)
+ self.assertEqual(
+ {
+ "launchpad.release-id": ["binary:%d" % bpr.id],
+ "launchpad.source-name": ["foo"],
+ "launchpad.source-version": ["1.0"],
+ "launchpad.channel": list(
+ sorted("%s:edge" % ds.name for ds in dses)),
+ },
+ path.properties)
+
def test_updateProperties_preserves_externally_set_properties(self):
# Artifactory sets some properties by itself as part of scanning
# packages. We leave those untouched.
+ pool = self.makePool()
ds = self.factory.makeDistroSeries(
- distribution=self.archive.distribution)
+ distribution=pool.archive.distribution)
das = self.factory.makeDistroArchSeries(distroseries=ds)
spr = self.factory.makeSourcePackageRelease(
- archive=self.archive, sourcepackagename="foo", version="1.0")
+ archive=pool.archive, sourcepackagename="foo", version="1.0")
bpb = self.factory.makeBinaryPackageBuild(
- archive=self.archive, source_package_release=spr,
+ archive=pool.archive, source_package_release=spr,
distroarchseries=das, pocket=PackagePublishingPocket.RELEASE)
bpr = self.factory.makeBinaryPackageRelease(
binarypackagename="foo", build=bpb, component="main",
@@ -367,13 +526,13 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
filename="foo_1.0_all.deb"),
filetype=BinaryPackageFileType.DEB)
bpphs = getUtility(IPublishingSet).publishBinaries(
- self.archive, ds, PackagePublishingPocket.RELEASE,
+ pool.archive, ds, PackagePublishingPocket.RELEASE,
{bpr: (bpr.component, bpr.section, bpr.priority, None)})
transaction.commit()
- self.pool.addFile(
+ pool.addFile(
None, bpr.sourcepackagename, bpr.sourcepackageversion,
bpf.libraryfile.filename, bpf)
- path = self.pool.rootpath / "f" / "foo" / "foo_1.0_all.deb"
+ path = pool.rootpath / "f" / "foo" / "foo_1.0_all.deb"
path.set_properties({"deb.version": ["1.0"]}, recursive=False)
self.assertEqual(
{
@@ -383,7 +542,7 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
"deb.version": ["1.0"],
},
path.properties)
- self.pool.updateProperties(
+ pool.updateProperties(
bpr.sourcepackagename, bpr.sourcepackageversion,
bpf.libraryfile.filename, bpphs)
self.assertEqual(
diff --git a/lib/lp/archivepublisher/tests/test_config.py b/lib/lp/archivepublisher/tests/test_config.py
index 915b4e7..75b1431 100644
--- a/lib/lp/archivepublisher/tests/test_config.py
+++ b/lib/lp/archivepublisher/tests/test_config.py
@@ -16,7 +16,11 @@ from lp.archivepublisher.config import getPubConfig
from lp.registry.interfaces.distribution import IDistributionSet
from lp.services.config import config
from lp.services.log.logger import BufferLogger
-from lp.soyuz.enums import ArchivePurpose
+from lp.soyuz.enums import (
+ ArchivePublishingMethod,
+ ArchivePurpose,
+ ArchiveRepositoryFormat,
+ )
from lp.soyuz.interfaces.archive import IArchiveSet
from lp.testing import TestCaseWithFactory
from lp.testing.layers import ZopelessDatabaseLayer
@@ -235,3 +239,35 @@ class TestGetPubConfigPPACompatUefi(TestCaseWithFactory):
signingroot = "/var/tmp/ppa-signing-keys.test/uefi/%s/%s" % (
self.ppa.owner.name, self.ppa.name)
self.assertEqual(signingroot, self.ppa_config.signingroot)
+
+
+class TestGetPubConfigPPARepositoryFormatPython(TestCaseWithFactory):
+
+ layer = ZopelessDatabaseLayer
+
+ def setUp(self):
+ super().setUp()
+ self.base_url = "https://foo.example.com/artifactory"
+ self.pushConfig("artifactory", base_url=self.base_url)
+ self.ppa = self.factory.makeArchive(
+ purpose=ArchivePurpose.PPA,
+ publishing_method=ArchivePublishingMethod.ARTIFACTORY,
+ repository_format=ArchiveRepositoryFormat.PYTHON)
+ self.ppa_config = getPubConfig(self.ppa)
+
+ def test_config(self):
+ # Python-format archives published via Artifactory use paths under
+ # the Artifactory base URL, and have various features disabled that
+ # only make sense for locally-published Debian-format archives.
+ self.assertIsNone(self.ppa_config.distroroot)
+ archiveroot = "%s/%s" % (self.base_url, self.ppa.name)
+ self.assertEqual(archiveroot, self.ppa_config.archiveroot)
+ self.assertEqual(archiveroot, self.ppa_config.poolroot)
+ self.assertIsNone(self.ppa_config.distsroot)
+ self.assertIsNone(self.ppa_config.overrideroot)
+ self.assertIsNone(self.ppa_config.cacheroot)
+ self.assertIsNone(self.ppa_config.miscroot)
+ self.assertEqual(
+ "/var/tmp/archive/%s-temp" % self.ppa.distribution.name,
+ self.ppa_config.temproot)
+ self.assertIsNone(self.ppa_config.metaroot)
diff --git a/lib/lp/registry/interfaces/sourcepackage.py b/lib/lp/registry/interfaces/sourcepackage.py
index eddd622..21d02ca 100644
--- a/lib/lp/registry/interfaces/sourcepackage.py
+++ b/lib/lp/registry/interfaces/sourcepackage.py
@@ -418,6 +418,12 @@ class SourcePackageFileType(DBEnumeratedType):
This file is a detached signature for an Ubuntu component "orig"
file.""")
+ SDIST = DBItem(11, """
+ Python Source Distribution
+
+ This file is a Python source distribution ("sdist").
+ """)
+
class SourcePackageType(DBEnumeratedType):
"""Source Package Format
@@ -447,6 +453,12 @@ class SourcePackageType(DBEnumeratedType):
This is the source package format used by Gentoo.
""")
+ SDIST = DBItem(4, """
+ The Python Format
+
+ This is the source package format used by Python packages.
+ """)
+
class SourcePackageUrgency(DBEnumeratedType):
"""Source Package Urgency