← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:charmrecipebuild-getFileUrls into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:charmrecipebuild-getFileUrls into launchpad:master.

Commit message:
Add and export CharmRecipeBuild.getFileUrls

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #2028406 in Launchpad itself: "Library does not provide a getFileUrls for charm_recipe_builds"
  https://bugs.launchpad.net/launchpad/+bug/2028406

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/447547

This is directly analogous to methods on other similar build types, such as `SnapBuild.getFileUrls`.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:charmrecipebuild-getFileUrls into launchpad:master.
diff --git a/lib/lp/charms/interfaces/charmrecipebuild.py b/lib/lp/charms/interfaces/charmrecipebuild.py
index b3bfd33..78cec6b 100644
--- a/lib/lp/charms/interfaces/charmrecipebuild.py
+++ b/lib/lp/charms/interfaces/charmrecipebuild.py
@@ -16,6 +16,7 @@ import http.client
 from lazr.enum import EnumeratedType, Item
 from lazr.restful.declarations import (
     error_status,
+    export_read_operation,
     export_write_operation,
     exported,
     exported_as_webservice_entry,
@@ -264,6 +265,13 @@ class ICharmRecipeBuildView(IPackageBuildView):
         :return: The corresponding `ILibraryFileAlias`.
         """
 
+    @export_read_operation()
+    @operation_for_version("devel")
+    def getFileUrls():
+        """URLs for all the files produced by this build.
+
+        :return: A collection of URLs for this build."""
+
 
 class ICharmRecipeBuildEdit(IBuildFarmJobEdit):
     """`ICharmRecipeBuild` methods that require launchpad.Edit."""
diff --git a/lib/lp/charms/model/charmrecipebuild.py b/lib/lp/charms/model/charmrecipebuild.py
index b5e4fe6..083c7ac 100644
--- a/lib/lp/charms/model/charmrecipebuild.py
+++ b/lib/lp/charms/model/charmrecipebuild.py
@@ -68,6 +68,7 @@ from lp.services.database.interfaces import IPrimaryStore, IStore
 from lp.services.database.stormbase import StormBase
 from lp.services.job.interfaces.job import JobStatus
 from lp.services.job.model.job import Job
+from lp.services.librarian.browser import ProxiedLibraryFileAlias
 from lp.services.librarian.model import LibraryFileAlias, LibraryFileContent
 from lp.services.propertycache import cachedproperty, get_property_cache
 from lp.services.webapp.snapshot import notify_modified
@@ -403,6 +404,13 @@ class CharmRecipeBuild(PackageBuildMixin, StormBase):
 
         raise NotFoundError(filename)
 
+    def getFileUrls(self):
+        """See `ICharmRecipeBuild`."""
+        return [
+            ProxiedLibraryFileAlias(lfa, self).http_url
+            for _, lfa, _ in self.getFiles()
+        ]
+
     def addFile(self, lfa):
         """See `ICharmRecipeBuild`."""
         charm_file = CharmFile(build=self, library_file=lfa)
diff --git a/lib/lp/charms/tests/test_charmrecipebuild.py b/lib/lp/charms/tests/test_charmrecipebuild.py
index e3816fe..c5903fa 100644
--- a/lib/lp/charms/tests/test_charmrecipebuild.py
+++ b/lib/lp/charms/tests/test_charmrecipebuild.py
@@ -45,6 +45,7 @@ from lp.services.config import config
 from lp.services.crypto.interfaces import IEncryptedContainer
 from lp.services.features.testing import FeatureFixture
 from lp.services.job.interfaces.job import JobStatus
+from lp.services.librarian.browser import ProxiedLibraryFileAlias
 from lp.services.propertycache import clear_property_cache
 from lp.services.webapp.interfaces import OAuthPermission
 from lp.services.webapp.publisher import canonical_url
@@ -998,3 +999,23 @@ class TestCharmRecipeBuildWebservice(TestCaseWithFactory):
         self.assertCanOpenRedirectedUrl(browser, build["build_log_url"])
         self.assertIsNotNone(build["upload_log_url"])
         self.assertCanOpenRedirectedUrl(browser, build["upload_log_url"])
+
+    def test_getFileUrls(self):
+        # API clients can fetch files attached to builds.
+        db_build = self.factory.makeCharmRecipeBuild(requester=self.person)
+        db_files = [
+            self.factory.makeCharmFile(build=db_build) for i in range(2)
+        ]
+        build_url = api_url(db_build)
+        file_urls = [
+            ProxiedLibraryFileAlias(file.library_file, db_build).http_url
+            for file in db_files
+        ]
+        logout()
+        response = self.webservice.named_get(build_url, "getFileUrls")
+        self.assertEqual(200, response.status)
+        self.assertContentEqual(file_urls, response.jsonBody())
+        browser = self.getNonRedirectingBrowser(user=self.person)
+        browser.raiseHttpErrors = False
+        for file_url in file_urls:
+            self.assertCanOpenRedirectedUrl(browser, file_url)