Skip to content

Commit

Permalink
initial metadata proposal (#13330)
Browse files Browse the repository at this point in the history
* initial metadata proposal

* fix

* remove conf

* hooks tests

* removed test
  • Loading branch information
memsharded authored Mar 14, 2023
1 parent f01fc3b commit cca46e0
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 0 deletions.
2 changes: 2 additions & 0 deletions conan/api/subapi/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def source(self, path, name=None, version=None, user=None, channel=None):
folder = conanfile.recipe_folder
conanfile.folders.set_base_source(folder)
conanfile.folders.set_base_export_sources(folder)
conanfile.folders.set_base_recipe_metadata(os.path.join(folder, "metadata"))
conanfile.folders.set_base_build(None)
conanfile.folders.set_base_package(None)

Expand All @@ -92,6 +93,7 @@ def build(self, conanfile):
"""
app = ConanApp(self._conan_api.cache_folder)
conanfile.folders.set_base_package(conanfile.folders.base_build)
conanfile.folders.set_base_pkg_metadata(os.path.join(conanfile.build_folder, "metadata"))
run_build_method(conanfile, app.hook_manager)

@staticmethod
Expand Down
6 changes: 6 additions & 0 deletions conan/internal/cache/conan_reference_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ def export(self):
def export_sources(self):
return os.path.join(self.base_folder, EXPORT_SRC_FOLDER)

def metadata(self):
return os.path.join(self.download_export(), "metadata")

def download_export(self):
return os.path.join(self.base_folder, DOWNLOAD_EXPORT_FOLDER)

Expand Down Expand Up @@ -112,6 +115,9 @@ def package(self):
def download_package(self):
return os.path.join(self.base_folder, DOWNLOAD_EXPORT_FOLDER)

def metadata(self):
return os.path.join(self.download_package(), "metadata")

def package_manifests(self):
package_folder = self.package()
readed_manifest = FileTreeManifest.load(package_folder)
Expand Down
1 change: 1 addition & 0 deletions conans/client/cmd/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def cmd_export(app, conanfile_path, name, version, user, channel, graph_lock=Non
# TODO: cache2.0 move this creation to other place
mkdir(export_folder)
mkdir(export_src_folder)
conanfile.folders.set_base_recipe_metadata(recipe_layout.metadata())
export_recipe(conanfile, export_folder)
export_source(conanfile, export_src_folder)
shutil.copy2(conanfile_path, recipe_layout.conanfile())
Expand Down
2 changes: 2 additions & 0 deletions conans/client/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ def build_package(self, node, package_layout):
conanfile.folders.set_base_package(base_package)
# In local cache, generators folder always in build_folder
conanfile.folders.set_base_generators(base_build)
conanfile.folders.set_base_pkg_metadata(package_layout.metadata())

if not skip_build:
# In local cache, install folder always is build_folder
Expand Down Expand Up @@ -187,6 +188,7 @@ def _install_source(self, node, remotes):

conanfile.folders.set_base_source(source_folder)
conanfile.folders.set_base_export_sources(source_folder)
conanfile.folders.set_base_recipe_metadata(recipe_layout.metadata())
config_source(export_source_folder, conanfile, self._hook_manager)

@staticmethod
Expand Down
8 changes: 8 additions & 0 deletions conans/model/conan_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,14 @@ def build_folder(self):
"""
return self.folders.build_folder

@property
def recipe_metadata_folder(self):
return self.folders.recipe_metadata_folder

@property
def pkg_metadata_folder(self):
return self.folders.pkg_metadata_folder

@property
def build_path(self) -> Path:
assert self.build_folder is not None, "`build_folder` is `None`"
Expand Down
19 changes: 19 additions & 0 deletions conans/model/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def __init__(self):
self._base_export = None
self._base_export_sources = None

self._base_recipe_metadata = None
self._base_pkg_metadata = None

self.source = ""
self.build = ""
self.package = ""
Expand Down Expand Up @@ -78,6 +81,8 @@ def set_base_folders(self, conanfile_folder, output_folder):
self._base_build = output_folder or base_folder
self._base_generators = output_folder or base_folder
self._base_export_sources = output_folder or base_folder
self._base_recipe_metadata = base_folder
self._base_pkg_metadata = output_folder or base_folder

@property
def source_folder(self):
Expand All @@ -103,6 +108,20 @@ def build_folder(self):
return self._base_build
return os.path.join(self._base_build, self.build)

@property
def recipe_metadata_folder(self):
return self._base_recipe_metadata

def set_base_recipe_metadata(self, folder):
self._base_recipe_metadata = folder

@property
def pkg_metadata_folder(self):
return self._base_pkg_metadata

def set_base_pkg_metadata(self, folder):
self._base_pkg_metadata = folder

@property
def base_build(self):
return self._base_build
Expand Down
Empty file.
140 changes: 140 additions & 0 deletions conans/test/integration/metadata/test_metadata_logs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import os
import textwrap

import pytest

from conans.model.recipe_ref import RecipeReference
from conans.test.utils.tools import TestClient
from conans.util.files import load, save


class TestRecipeMetadataLogs:

conanfile = textwrap.dedent("""
import os
from conan import ConanFile
from conan.tools.files import save, copy
class Pkg(ConanFile):
name = "pkg"
version = "0.1"
def export(self):
copy(self, "*.log", src=self.recipe_folder,
dst=os.path.join(self.recipe_metadata_folder, "logs"))
def layout(self):
self.folders.build = "mybuild"
self.folders.generators = "mybuild/generators"
def source(self):
save(self, os.path.join(self.recipe_metadata_folder, "logs", "src.log"), "srclog!!")
def build(self):
save(self, "mylogs.txt", "some logs!!!")
copy(self, "mylogs.txt", src=self.build_folder,
dst=os.path.join(self.pkg_metadata_folder, "logs"))
""")

def test_metadata_logs(self):
c = TestClient(default_server_user=True)
c.save({"conanfile.py": self.conanfile,
"file.log": "log contents!"})
c.run("create .")
# Test local cache looks good
ref = RecipeReference.loads("pkg/0.1")
ref_layout = c.get_latest_ref_layout(ref)
assert os.listdir(ref_layout.metadata()) == ["logs"]
assert os.listdir(os.path.join(ref_layout.metadata(), "logs")) == ["file.log", "src.log"]
assert load(os.path.join(ref_layout.metadata(), "logs", "file.log")) == "log contents!"
assert load(os.path.join(ref_layout.metadata(), "logs", "src.log")) == "srclog!!"

pref = c.get_latest_package_reference(ref)
pref_layout = c.get_latest_pkg_layout(pref)
assert os.listdir(pref_layout.metadata()) == ["logs"]
assert os.listdir(os.path.join(pref_layout.metadata(), "logs")) == ["mylogs.txt"]
assert load(os.path.join(pref_layout.metadata(), "logs", "mylogs.txt")) == "some logs!!!"

def test_metadata_logs_local(self):
c = TestClient(default_server_user=True)
c.save({"conanfile.py": self.conanfile,
"file.log": "log contents!"})
c.run("source .")
assert c.load("metadata/logs/src.log") == "srclog!!"
c.run("build .")
assert c.load("mybuild/metadata/logs/mylogs.txt") == "some logs!!!"


class TestHooksMetadataLogs:

@pytest.fixture()
def _client(self):
c = TestClient(default_server_user=True)
my_hook = textwrap.dedent("""\
import os
from conan.tools.files import copy
def post_export(conanfile):
conanfile.output.info("post_export")
copy(conanfile, "*.log", src=conanfile.recipe_folder,
dst=os.path.join(conanfile.recipe_metadata_folder, "logs"))
def post_source(conanfile):
conanfile.output.info("post_source")
copy(conanfile, "*", src=os.path.join(conanfile.source_folder, "logs"),
dst=os.path.join(conanfile.recipe_metadata_folder, "logs"))
def post_build(conanfile):
conanfile.output.info("post_build")
copy(conanfile, "*", src=os.path.join(conanfile.build_folder, "logs"),
dst=os.path.join(conanfile.pkg_metadata_folder, "logs"))
""")
hook_path = os.path.join(c.cache.hooks_path, "my_hook", "hook_my_hook.py")
save(hook_path, my_hook)
conanfile = textwrap.dedent("""
import os
from conan import ConanFile
from conan.tools.files import save, copy
class Pkg(ConanFile):
name = "pkg"
version = "0.1"
no_copy_source = True
def layout(self):
self.folders.build = "mybuild"
self.folders.generators = "mybuild/generators"
def source(self):
save(self, "logs/src.log", "srclog!!")
def build(self):
save(self, "logs/mylogs.txt", "some logs!!!")
""")
c.save({"conanfile.py": conanfile,
"file.log": "log contents!"})
return c

def test_metadata_logs_hook(self, _client):
c = _client
c.run("create .")
# Test local cache looks good
ref = RecipeReference.loads("pkg/0.1")
ref_layout = c.get_latest_ref_layout(ref)
assert os.listdir(ref_layout.metadata()) == ["logs"]
assert os.listdir(os.path.join(ref_layout.metadata(), "logs")) == ["file.log", "src.log"]
assert load(os.path.join(ref_layout.metadata(), "logs", "file.log")) == "log contents!"
assert load(os.path.join(ref_layout.metadata(), "logs", "src.log")) == "srclog!!"

pref = c.get_latest_package_reference(ref)
pref_layout = c.get_latest_pkg_layout(pref)
assert os.listdir(pref_layout.metadata()) == ["logs"]
assert os.listdir(os.path.join(pref_layout.metadata(), "logs")) == ["mylogs.txt"]
assert load(os.path.join(pref_layout.metadata(), "logs", "mylogs.txt")) == "some logs!!!"

def test_metadata_logs_local(self, _client):
c = _client
c.run("source .")
assert c.load("metadata/logs/src.log") == "srclog!!"
c.run("build .")
assert c.load("mybuild/metadata/logs/mylogs.txt") == "some logs!!!"

0 comments on commit cca46e0

Please sign in to comment.