← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~alvarocs/launchpad:fix-charm-build-metadataurl into launchpad:master

 

Alvaro Crespo Serrano has proposed merging ~alvarocs/launchpad:fix-charm-build-metadataurl into launchpad:master.

Commit message:
Expose CharmRecipeBuild.build_metadata_url

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~alvarocs/launchpad/+git/launchpad/+merge/490628
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~alvarocs/launchpad:fix-charm-build-metadataurl into launchpad:master.
diff --git a/lib/lp/charms/model/charmrecipebuild.py b/lib/lp/charms/model/charmrecipebuild.py
index 3e6e95b..7bea233 100644
--- a/lib/lp/charms/model/charmrecipebuild.py
+++ b/lib/lp/charms/model/charmrecipebuild.py
@@ -31,6 +31,7 @@ from zope.component import getUtility
 from zope.interface import implementer
 
 from lp.app.errors import NotFoundError
+from lp.buildmaster.builderproxy import BUILD_METADATA_FILENAME_FORMAT
 from lp.buildmaster.enums import (
     BuildFarmJobType,
     BuildQueueStatus,
@@ -60,7 +61,7 @@ from lp.registry.model.distribution import Distribution
 from lp.registry.model.distroseries import DistroSeries
 from lp.registry.model.person import Person
 from lp.services.config import config
-from lp.services.database.bulk import load_related
+from lp.services.database.bulk import load_referencing, load_related
 from lp.services.database.constants import DEFAULT
 from lp.services.database.decoratedresultset import DecoratedResultSet
 from lp.services.database.enumcol import DBEnum
@@ -75,6 +76,27 @@ from lp.services.webapp.snapshot import notify_modified
 from lp.soyuz.model.distroarchseries import DistroArchSeries
 
 
+@implementer(ICharmFile)
+class CharmFile(StormBase):
+    """See `ICharmFile`."""
+
+    __storm_table__ = "CharmFile"
+
+    id = Int(name="id", primary=True)
+
+    build_id = Int(name="build", allow_none=False)
+    build = Reference(build_id, "CharmRecipeBuild.id")
+
+    library_file_id = Int(name="library_file", allow_none=False)
+    library_file = Reference(library_file_id, "LibraryFileAlias.id")
+
+    def __init__(self, build, library_file):
+        """Construct a `CharmFile`."""
+        super().__init__()
+        self.build = build
+        self.library_file = library_file
+
+
 @implementer(ICharmRecipeBuild)
 class CharmRecipeBuild(PackageBuildMixin, StormBase):
     """See `ICharmRecipeBuild`."""
@@ -415,6 +437,25 @@ class CharmRecipeBuild(PackageBuildMixin, StormBase):
             for _, lfa, _ in self.getFiles()
         ]
 
+    def lfaUrl(self, lfa):
+        """Return the URL for a LibraryFileAlias in this context."""
+        if lfa is None:
+            return None
+        return ProxiedLibraryFileAlias(lfa, self).http_url
+
+    @property
+    def metadata_filename(self):
+        return BUILD_METADATA_FILENAME_FORMAT.format(
+            build_id=self.build_cookie
+        )
+
+    @cachedproperty
+    def build_metadata_url(self):
+        try:
+            return self.lfaUrl(self.getFileByName(self.metadata_filename))
+        except NotFoundError:
+            return None
+
     def addFile(self, lfa):
         """See `ICharmRecipeBuild`."""
         charm_file = CharmFile(build=self, library_file=lfa)
@@ -575,6 +616,24 @@ class CharmRecipeBuildSet(SpecificBuildFarmJobSourceMixin):
             )
         load_related(Job, crbjs, ["job_id"])
 
+        # Prefetch all charms metadata files
+        charm_files = load_referencing(CharmFile, builds, ["build_id"])
+        lfas = load_related(LibraryFileAlias, charm_files, ["libraryfile_id"])
+
+        metadata_files = {}
+        for charm_file in charm_files:
+            if (
+                charm_file.libraryfile.filename
+                == charm_file.charmbuild.metadata_filename
+            ):
+                metadata_files[charm_file.build_id] = charm_file.libraryfile
+
+        for build in builds:
+            cache = get_property_cache(build)
+            cache.build_metadata_url = build.lfaUrl(
+                metadata_files.get(build.id)
+            )
+
     def getByBuildFarmJobs(self, build_farm_jobs):
         """See `ISpecificBuildFarmJobSource`."""
         if len(build_farm_jobs) == 0:
@@ -586,24 +645,3 @@ class CharmRecipeBuildSet(SpecificBuildFarmJobSourceMixin):
             ),
         )
         return DecoratedResultSet(rows, pre_iter_hook=self.preloadBuildsData)
-
-
-@implementer(ICharmFile)
-class CharmFile(StormBase):
-    """See `ICharmFile`."""
-
-    __storm_table__ = "CharmFile"
-
-    id = Int(name="id", primary=True)
-
-    build_id = Int(name="build", allow_none=False)
-    build = Reference(build_id, "CharmRecipeBuild.id")
-
-    library_file_id = Int(name="library_file", allow_none=False)
-    library_file = Reference(library_file_id, "LibraryFileAlias.id")
-
-    def __init__(self, build, library_file):
-        """Construct a `CharmFile`."""
-        super().__init__()
-        self.build = build
-        self.library_file = library_file

Follow ups