launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #01247
[Merge] lp:~julian-edwards/launchpad/build-api-bug-498079 into lp:launchpad/devel
Julian Edwards has proposed merging lp:~julian-edwards/launchpad/build-api-bug-498079 into lp:launchpad/devel.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
#498079 API missing "changes_file_url" for builds, and "debdiff" for source
https://bugs.launchpad.net/bugs/498079
= Summary =
Expose some API properties for the security guys
== Proposed fix ==
Add IBinaryPackageBuild.changesfile_url property and
SourcePackagePublishingHistory.packageDiffUrl() custom method.
== Implementation details ==
The security team is still screen scraping a couple of things to get the stuff
they need for their USNs. These two API changes will allow them to stop doing
that and use the API for everything.
== Tests ==
bin/test -cvvt xx-source-package-publishing.txt -t binarypackagebuild.txt -t
xx-builds.txt
--
https://code.launchpad.net/~julian-edwards/launchpad/build-api-bug-498079/+merge/36730
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~julian-edwards/launchpad/build-api-bug-498079 into lp:launchpad/devel.
=== modified file 'lib/lp/soyuz/doc/binarypackagebuild.txt'
--- lib/lp/soyuz/doc/binarypackagebuild.txt 2010-08-30 15:00:23 +0000
+++ lib/lp/soyuz/doc/binarypackagebuild.txt 2010-09-27 14:53:17 +0000
@@ -90,6 +90,9 @@
>>> print firefox_build.upload_changesfile.filename
firefox_0.9_i386.changes
+ >>> print firefox_build.changesfile_url
+ http://launchpad.dev/ubuntutest/+source/mozilla-firefox/0.9/+build/.../+files/firefox_0.9_i386.changes
+
The 'firefox_build' is already finished and requesting the estimated build
start time makes no sense. Hence an exception is raised.
=== modified file 'lib/lp/soyuz/interfaces/binarypackagebuild.py'
--- lib/lp/soyuz/interfaces/binarypackagebuild.py 2010-08-30 19:06:34 +0000
+++ lib/lp/soyuz/interfaces/binarypackagebuild.py 2010-09-27 14:53:17 +0000
@@ -35,6 +35,7 @@
Bool,
Int,
Text,
+ TextLine,
)
from canonical.launchpad import _
@@ -118,6 +119,12 @@
"was originally uploaded with the results of this build. It's "
"'None' if it is build imported by Gina.")
+ changesfile_url = exported(
+ TextLine(
+ title=_("Changes File URL"), required=False,
+ description=_("The URL for the changes file for this build. "
+ "Will be None if the build was imported by Gina.")))
+
package_upload = Attribute(
"The `PackageUpload` record corresponding to the original upload "
"of the binaries resulted from this build. It's 'None' if it is "
=== modified file 'lib/lp/soyuz/interfaces/publishing.py'
--- lib/lp/soyuz/interfaces/publishing.py 2010-08-24 15:29:01 +0000
+++ lib/lp/soyuz/interfaces/publishing.py 2010-09-27 14:53:17 +0000
@@ -596,6 +596,17 @@
:return: A collection of URLs for this source.
"""
+ @export_read_operation()
+ @operation_parameters(
+ to_version=TextLine(title=_("To Version"), required=True))
+ def packageDiffUrl(to_version):
+ """URL of the debdiff file between this and the supplied version.
+
+ :param to_version: The version of the source package for which you
+ want to get the diff to.
+ :return: A URL to the librarian file containing the diff.
+ """
+
class ISourcePackagePublishingHistory(ISourcePackagePublishingHistoryPublic,
IPublishingEdit):
=== modified file 'lib/lp/soyuz/model/binarypackagebuild.py'
--- lib/lp/soyuz/model/binarypackagebuild.py 2010-09-16 12:27:46 +0000
+++ lib/lp/soyuz/model/binarypackagebuild.py 2010-09-27 14:53:17 +0000
@@ -193,6 +193,14 @@
return package_upload.changesfile
@property
+ def changesfile_url(self):
+ """See `IBinaryPackageBuild`."""
+ changesfile = self.upload_changesfile
+ if changesfile is None:
+ return None
+ return ProxiedLibraryFileAlias(changesfile, self).http_url
+
+ @property
def package_upload(self):
"""See `IBuild`."""
store = Store.of(self)
=== modified file 'lib/lp/soyuz/model/publishing.py'
--- lib/lp/soyuz/model/publishing.py 2010-08-30 15:00:23 +0000
+++ lib/lp/soyuz/model/publishing.py 2010-09-27 14:53:17 +0000
@@ -45,6 +45,9 @@
SQLBase,
sqlvalues,
)
+from canonical.launchpad.browser.librarian import (
+ ProxiedLibraryFileAlias,
+ )
from canonical.launchpad.components.decoratedresultset import (
DecoratedResultSet,
)
@@ -819,8 +822,6 @@
def _proxied_urls(self, files, parent):
"""Run the files passed through `ProxiedLibraryFileAlias`."""
- from canonical.launchpad.browser.librarian import (
- ProxiedLibraryFileAlias)
return [
ProxiedLibraryFileAlias(file, parent).http_url for file in files]
@@ -840,6 +841,17 @@
[binary for _source, binary, _content in binaries], self.archive)
return binary_urls
+ def packageDiffUrl(self, to_version):
+ """See `ISourcePackagePublishingHistory`."""
+ # There will be only very few diffs for each package so
+ # iterating is fine here, since the package_diffs property is a
+ # multiple join and returns all the diffs quite quickly.
+ for diff in self.sourcepackagerelease.package_diffs:
+ if diff.to_source.version == to_version:
+ return ProxiedLibraryFileAlias(
+ diff.diff_content, self.archive).http_url
+ return None
+
class BinaryPackagePublishingHistory(SQLBase, ArchivePublisherBase):
"""A binary package publishing record."""
=== modified file 'lib/lp/soyuz/stories/webservice/xx-builds.txt'
--- lib/lp/soyuz/stories/webservice/xx-builds.txt 2010-08-30 02:07:38 +0000
+++ lib/lp/soyuz/stories/webservice/xx-builds.txt 2010-09-27 14:53:17 +0000
@@ -44,6 +44,7 @@
archive_link: u'http://.../beta/~cprov/+archive/ppa'
can_be_rescored: False
can_be_retried: True
+ changesfile_url: None
current_source_publication_link: u'http://.../beta/~cprov/+archive/ppa/+sourcepub/27'
date_created: u'2007-07-08T00:00:00+00:00'
date_finished: u'2007-07-08T00:00:01+00:00'
@@ -70,6 +71,7 @@
buildstate: u'Failed to build'
can_be_rescored: False
can_be_retried: True
+ changesfile_url: None
current_source_publication_link: u'http://.../~cprov/+archive/ppa/+sourcepub/27'
date_first_dispatched: None
datebuilt: u'2007-07-08T00:00:01+00:00'
=== modified file 'lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt'
--- lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2010-08-24 15:29:01 +0000
+++ lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2010-09-27 14:53:17 +0000
@@ -356,6 +356,13 @@
Source ID 27: FAILEDTOBUILD ([u'i386'])
Source ID 28: FULLYBUILT_PENDING ([u'i386'])
+
+Associated Files In The Librarian
+=================================
+
+sourceFileUrls() is a custom method to return the URLs of the source files
+for this package:
+
>>> pubs = webservice.named_get(
... cprov_archive['self_link'], 'getPublishedSources').jsonBody()
>>> for pub_link in sorted(
@@ -368,6 +375,8 @@
[]
[u'http://launchpad.dev/~cprov/+archive/ppa/+files/testwebservice_666.dsc']
+binaryFileUrls() is similar:
+
>>> for pub_link in sorted(
... entry['self_link'] for entry in pubs['entries']):
... binary_urls = webservice.named_get(
@@ -378,3 +387,53 @@
[]
[]
+The debdiff to a particular version can also be retrieved using the
+packageDiffUrl() method. It takes one parameter, 'to_version' which
+specifies the version of the package you want a diff against. If there
+is no diff available for that version, None is returned, otherwise a
+librarian URL is returned.
+
+We need to create a fake package diff to show this:
+
+ >>> login("admin@xxxxxxxxxxxxx")
+ >>> to_pub = test_publisher.getPubSource(
+ ... sourcename='difftest', version='1.0', archive=cprov.archive)
+ >>> from_pub = test_publisher.getPubSource(
+ ... sourcename='difftest', version='1.1', archive=cprov.archive)
+ >>> new_diff = factory.makePackageDiff(
+ ... from_source=from_pub.sourcepackagerelease,
+ ... to_source=to_pub.sourcepackagerelease,
+ ... diff_content="test diff")
+ >>> import transaction
+ >>> transaction.commit()
+ >>> logout()
+
+Using the web service, grab the new publishing record:
+
+ >>> pubs = webservice.named_get(
+ ... cprov_archive['self_link'], 'getPublishedSources',
+ ... source_name="difftest", version="1.0",
+ ... exact_match=True).jsonBody()
+ >>> source_pub = pubs['entries'][0]
+
+And then obtain the URL to the diff:
+
+ >>> diff_url = webservice.named_get(
+ ... source_pub['self_link'], 'packageDiffUrl',
+ ... to_version='1.0').jsonBody()
+
+The URL is a standard proxied URL in case the file is private:
+
+ >>> print diff_url
+ http://launchpad.dev/~cprov/+archive/ppa/+files/...
+
+It will match the fake content we added earlier:
+
+ >>> login("admin@xxxxxxxxxxxxx")
+ >>> from canonical.launchpad.browser.librarian import (
+ ... ProxiedLibraryFileAlias)
+ >>> diff_url == ProxiedLibraryFileAlias(
+ ... new_diff.diff_content, cprov.archive).http_url
+ True
+
+ >>> logout()
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-09-23 12:34:57 +0000
+++ lib/lp/testing/factory.py 2010-09-27 14:53:17 +0000
@@ -222,6 +222,7 @@
ArchivePurpose,
BinaryPackageFileType,
BinaryPackageFormat,
+ PackageDiffStatus,
PackagePublishingPriority,
PackagePublishingStatus,
PackageUploadStatus,
@@ -243,6 +244,9 @@
BinaryPackageFile,
SourcePackageReleaseFile,
)
+from lp.soyuz.model.packagediff import (
+ PackageDiff,
+ )
from lp.soyuz.model.processor import ProcessorFamilySet
from lp.testing import (
ANONYMOUS,
@@ -3091,6 +3095,29 @@
return getUtility(ITemporaryStorageManager).fetch(new_uuid)
+ def makePackageDiff(self, from_source=None, to_source=None,
+ requester=None, status=None, date_fulfilled=None,
+ diff_content=None):
+ """Create a new `PackageDiff`."""
+ if from_source is None:
+ from_source = self.makeSourcePackageRelease()
+ if to_source is None:
+ to_source = self.makeSourcePackageRelease()
+ if requester is None:
+ requester = self.makePerson()
+ if status is None:
+ status = PackageDiffStatus.COMPLETED
+ if date_fulfilled is None:
+ date_fulfilled = UTC_NOW
+ if diff_content is None:
+ diff_content = self.getUniqueString("packagediff")
+ lfa = self.makeLibraryFileAlias(content=diff_content)
+ return ProxyFactory(
+ PackageDiff(
+ requester=requester, from_source=from_source,
+ to_source=to_source, date_fulfilled=date_fulfilled,
+ status=status, diff_content=lfa))
+
# Some factory methods return simple Python types. We don't add
# security wrappers for them, as well as for objects created by