From 6e665578c4cc33949f6ce9a1a891dd7e34446d34 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 30 Dec 2024 07:58:44 +0100 Subject: [PATCH] Feature/workspace api (#17501) * working in workspace_api * fixed loader + run() error --- conan/api/subapi/workspace.py | 2 +- conan/internal/workspace.py | 15 +++++++--- test/integration/workspace/test_workspace.py | 29 ++++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/conan/api/subapi/workspace.py b/conan/api/subapi/workspace.py index 18c33d40c1b..3c51b7b70a1 100644 --- a/conan/api/subapi/workspace.py +++ b/conan/api/subapi/workspace.py @@ -16,7 +16,7 @@ class WorkspaceAPI: def __init__(self, conan_api): self._conan_api = conan_api - self._workspace = Workspace() + self._workspace = Workspace(conan_api) def home_folder(self): return self._workspace.home_folder() diff --git a/conan/internal/workspace.py b/conan/internal/workspace.py index 74cc1ffbb17..5f95ff83625 100644 --- a/conan/internal/workspace.py +++ b/conan/internal/workspace.py @@ -4,6 +4,8 @@ import yaml from conan.api.output import ConanOutput +from conan.internal.cache.home_paths import HomePaths +from conan.internal.conan_app import CmdWrapper, ConanFileHelpers from conans.client.loader import load_python_file from conan.errors import ConanException from conans.model.recipe_ref import RecipeReference @@ -20,13 +22,17 @@ def _find_ws_folder(): class _UserWorkspaceAPI: - def __init__(self, folder): + def __init__(self, folder, conan_api): self.folder = folder + self._conan_api = conan_api def load(self, conanfile_path): conanfile_path = os.path.join(self.folder, conanfile_path) from conans.client.loader import ConanFileLoader - loader = ConanFileLoader(pyreq_loader=None, conanfile_helpers=None) + cmd_wrap = CmdWrapper(HomePaths(self._conan_api.home_folder).wrapper_path) + helpers = ConanFileHelpers(None, cmd_wrap, self._conan_api.config.global_conf, + cache=None, home_folder=self._conan_api.home_folder) + loader = ConanFileLoader(pyreq_loader=None, conanfile_helpers=helpers) conanfile = loader.load_named(conanfile_path, name=None, version=None, user=None, channel=None, remotes=None, graph_lock=None) return conanfile @@ -35,7 +41,8 @@ def load(self, conanfile_path): class Workspace: TEST_ENABLED = False - def __init__(self): + def __init__(self, conan_api): + self._conan_api = conan_api self._folder = _find_ws_folder() if self._folder: ConanOutput().warning(f"Workspace found: {self._folder}") @@ -58,7 +65,7 @@ def __init__(self): py_file = os.path.join(self._folder, "conanws.py") if os.path.exists(py_file): self._py, _ = load_python_file(py_file) - setattr(self._py, "workspace_api", _UserWorkspaceAPI(self._folder)) + setattr(self._py, "workspace_api", _UserWorkspaceAPI(self._folder, conan_api)) setattr(self._py, "conanws_data", self._yml) @property diff --git a/test/integration/workspace/test_workspace.py b/test/integration/workspace/test_workspace.py index fc78c08473c..2dbb50917ba 100644 --- a/test/integration/workspace/test_workspace.py +++ b/test/integration/workspace/test_workspace.py @@ -192,6 +192,35 @@ def editables(*args, **kwargs): # Doesn't fail assert "other/14.5 - Editable" in c.out + def test_api_dynamic_version_run(self): + # https://github.com/conan-io/conan/issues/17306 + c = TestClient(light=True) + conanfile = textwrap.dedent(""" + from io import StringIO + from conan import ConanFile + class Lib(ConanFile): + name= "pkg" + def set_version(self): + my_buf = StringIO() + self.run('echo 2.1', stdout=my_buf) + self.version = my_buf.getvalue().strip() + """) + + workspace = textwrap.dedent("""\ + import os + name = "myws" + + def editables(*args, **kwargs): + conanfile = workspace_api.load("dep1/conanfile.py") + return {f"{conanfile.name}/{conanfile.version}": {"path": "dep1/conanfile.py"}} + """) + + c.save({"conanws.py": workspace, + "dep1/conanfile.py": conanfile}) + c.run("workspace info --format=json") + info = json.loads(c.stdout) + assert info["editables"] == {"pkg/2.1": {"path": "dep1/conanfile.py"}} + def test_error_uppercase(self): c = TestClient(light=True) c.save({"conanws.py": "name='myws'",