← Back to team overview

launchpad-reviewers team mailing list archive

[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