From 8cd5f1692f99c102c0f8935233b1f475ee6d6f9f Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Wed, 21 Sep 2022 19:21:31 +0200 Subject: [PATCH] Add support global.conf (#608) --- README.md | 2 ++ cpt/config.py | 24 ++++++++++++++ cpt/packager.py | 7 +++- cpt/run_in_docker.py | 4 ++- cpt/runner.py | 14 ++++++-- cpt/test/test_client/global_conf_test.py | 29 +++++++++++++++++ cpt/test/unit/global_conf_test.py | 41 ++++++++++++++++++++++++ cpt/test/unit/utils.py | 7 ++-- 8 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 cpt/test/test_client/global_conf_test.py create mode 100644 cpt/test/unit/global_conf_test.py diff --git a/README.md b/README.md index 9a32de0b..c491a3ed 100644 --- a/README.md +++ b/README.md @@ -1205,6 +1205,7 @@ Check [Conan Build policies](https://docs.conan.io/en/latest/mastering/policies. - **force_selinux**: Force docker to relabel file objects on the shared volumes - **skip_recipe_export**: If True, the package recipe will only be exported on the first build. Default [False] - **update_dependencies**: Update all dependencies before building e.g conan create -u +- **global_conf**: A list with values to be added to `global.conf` file Upload related parameters: @@ -1372,6 +1373,7 @@ Check [Conan Build policies](https://docs.conan.io/en/latest/mastering/policies. - **CONAN_SKIP_RECIPE_EXPORT**: If defined, the package recipe will only be exported on the first build. - **CPT_UPDATE_DEPENDENCIES**: Update all dependencies before building e.g conan create -u - **CONAN_PURE_C**: Set `pure_c` by environment variable, default `True` +- **CONAN_GLOBAL_CONF**: Add `global.conf` file with listed values e.g '*:tools.cmake.cmaketoolchain:generator=Ninja,tools.system.package_manager:mode=install' # Full example diff --git a/cpt/config.py b/cpt/config.py index 4be1ec52..e19d664f 100644 --- a/cpt/config.py +++ b/cpt/config.py @@ -1,3 +1,7 @@ +import os.path +from conans import tools +from conans.model.conf import ConfDefinition + class ConfigManager(object): @@ -11,3 +15,23 @@ def install(self, url, args=None): message += " with args \"%s\"" % args self.printer.print_message(message) self._conan_api.config_install(url, verify_ssl=True, args=args) + + +class GlobalConf(object): + def __init__(self, conan_api, printer): + self._conan_api = conan_api + self.printer = printer + + def populate(self, values): + global_conf = self._conan_api.app.cache.new_config_path + if isinstance(values, str): + values = values.split(",") + config = ConfDefinition() + if os.path.exists(global_conf): + content = tools.load(global_conf) + config.loads(content) + for value in values: + key = value[:value.find('=')] + k_value = value[value.find('=') + 1:] + config.update(key, k_value) + tools.save(global_conf, config.dumps()) diff --git a/cpt/packager.py b/cpt/packager.py index d3ef608b..bc79c2e2 100644 --- a/cpt/packager.py +++ b/cpt/packager.py @@ -147,7 +147,8 @@ def __init__(self, username=None, channel=None, runner=None, force_selinux=None, skip_recipe_export=False, update_dependencies=None, - lockfile=None): + lockfile=None, + global_conf=None): conan_version = get_client_version() @@ -338,6 +339,8 @@ def __init__(self, username=None, channel=None, runner=None, self.builds_in_current_page = [] + self.global_conf = global_conf or os.getenv("CONAN_GLOBAL_CONF") + self.test_folder = test_folder or os.getenv("CPT_TEST_FOLDER") self.config_url = config_url or os.getenv("CONAN_CONFIG_URL") @@ -705,6 +708,7 @@ def run_builds(self, curpage=None, total_pages=None, base_profile_name=None, skip_recipe_export=skip_recipe_export, update_dependencies=self.update_dependencies, profile_build_abs_path=profile_build_abs_path, + global_conf=self.global_conf, ) r.run() self._packages_summary.append({"configuration": build, "package" : r.results}) @@ -747,6 +751,7 @@ def run_builds(self, curpage=None, total_pages=None, base_profile_name=None, update_dependencies=self.update_dependencies, profile_build_text=profile_build_text, base_profile_build_text=base_profile_build_text, + global_conf=self.global_conf, cwd=self.cwd) r.run(pull_image=not pulled_docker_images[docker_image], diff --git a/cpt/run_in_docker.py b/cpt/run_in_docker.py index 2bbfa3e1..a569d83a 100644 --- a/cpt/run_in_docker.py +++ b/cpt/run_in_docker.py @@ -37,6 +37,7 @@ def run(): build_policy = unscape_env(os.getenv("CPT_BUILD_POLICY")) require_overrides = unscape_env(os.getenv("CPT_REQUIRE_OVERRIDES")) test_folder = unscape_env(os.getenv("CPT_TEST_FOLDER")) + global_conf = unscape_env(os.getenv("CPT_GLOBAL_CONF")) reference = ConanFileReference.loads(os.getenv("CONAN_REFERENCE")) profile_text = unscape_env(os.getenv("CPT_PROFILE")) @@ -68,7 +69,8 @@ def run(): skip_recipe_export=skip_recipe_export, update_dependencies=update_dependencies, lockfile=lockfile, - profile_build_abs_path=abs_profile_build_path) + profile_build_abs_path=abs_profile_build_path, + global_conf=global_conf) runner.run() diff --git a/cpt/runner.py b/cpt/runner.py index 163e23ed..eefb4873 100644 --- a/cpt/runner.py +++ b/cpt/runner.py @@ -10,7 +10,7 @@ from conans.model.ref import ConanFileReference from cpt import __version__ as package_tools_version, get_client_version -from cpt.config import ConfigManager +from cpt.config import ConfigManager, GlobalConf from cpt.printer import Printer from cpt.profiles import load_profile, patch_default_base_profile from conans.client.conan_api import ProfileData @@ -23,7 +23,7 @@ def __init__(self, profile_abs_path, reference, conan_api, uploader, cwd=None, printer=None, upload=False, upload_only_recipe=None, test_folder=None, config_url=None, config_args=None, upload_dependencies=None, conanfile=None, skip_recipe_export=False, - update_dependencies=False, lockfile=None, profile_build_abs_path=None): + update_dependencies=False, lockfile=None, profile_build_abs_path=None, global_conf=None): self.printer = printer or Printer() self._cwd = cwd or os.getcwd() @@ -54,6 +54,7 @@ def __init__(self, profile_abs_path, reference, conan_api, uploader, self._update_dependencies = update_dependencies self._results = None self._profile_build_abs_path = profile_build_abs_path + self._global_conf = global_conf patch_default_base_profile(conan_api, profile_abs_path) client_version = get_client_version() @@ -86,6 +87,10 @@ def run(self): if self._config_url: ConfigManager(self._conan_api, self.printer).install(url=self._config_url, args=self._config_args) + if self._global_conf: + global_conf = GlobalConf(self._conan_api, self.printer) + global_conf.populate(self._global_conf) + context = tools.no_op() compiler = self.settings.get("compiler", None) if not self._exclude_vcvars_precommand: @@ -213,7 +218,8 @@ def __init__(self, profile_text, base_profile_text, base_profile_name, reference lockfile=None, profile_build_text=None, base_profile_build_text=None, - cwd=None): + cwd=None, + global_conf=None): self.printer = printer or Printer() self._upload = upload @@ -253,6 +259,7 @@ def __init__(self, profile_text, base_profile_text, base_profile_name, reference self._profile_build_text = profile_build_text self._base_profile_build_text = base_profile_build_text self._cwd = cwd or os.getcwd() + self._global_conf = global_conf def _pip_update_conan_command(self): commands = [] @@ -375,6 +382,7 @@ def get_env_vars(self): ret["CPT_BASE_PROFILE"] = escape_env(self._base_profile_text) ret["CPT_BASE_PROFILE_NAME"] = escape_env(self._base_profile_name) ret["CPT_PROFILE_BUILD"] = escape_env(self._profile_build_text) + ret["CPT_GLOBAL_CONF"] = escape_env(self._global_conf) ret["CONAN_USERNAME"] = escape_env(self._reference.user or ret.get("CONAN_USERNAME")) ret["CONAN_TEMP_TEST_FOLDER"] = "1" # test package folder to a temp one diff --git a/cpt/test/test_client/global_conf_test.py b/cpt/test/test_client/global_conf_test.py new file mode 100644 index 00000000..7b4c13ad --- /dev/null +++ b/cpt/test/test_client/global_conf_test.py @@ -0,0 +1,29 @@ +import unittest +import textwrap + +from conans.client.tools import environment_append, load +from cpt.test.utils.tools import TestClient + +from cpt.test.test_client.tools import get_patched_multipackager + + +class GlobalConfTest(unittest.TestCase): + + conanfile = textwrap.dedent(""" + from conans import ConanFile + class Pkg(ConanFile): + pass + """) + + def test_environment_variable(self): + tc = TestClient(users={"default": [("user", "password")]}) + tc.save({"conanfile.py": self.conanfile}) + global_conf = ["tools.system.package_manager:mode=install", "tools.system.package_manager:sudo=True"] + + with environment_append({"CONAN_GLOBAL_CONF": ",".join(global_conf)}): + mulitpackager = get_patched_multipackager(tc, exclude_vcvars_precommand=True) + mulitpackager.add_common_builds(reference="lib/1.0@user/stable", shared_option_name=False) + mulitpackager.run() + assert textwrap.dedent("""tools.system.package_manager:mode=install + tools.system.package_manager:sudo=True + """.replace(" ", "")) == load(tc.cache.new_config_path) diff --git a/cpt/test/unit/global_conf_test.py b/cpt/test/unit/global_conf_test.py new file mode 100644 index 00000000..0ccf7228 --- /dev/null +++ b/cpt/test/unit/global_conf_test.py @@ -0,0 +1,41 @@ +import unittest +import textwrap +from cpt.config import GlobalConf +from cpt.printer import Printer +from cpt.test.unit.packager_test import MockConanAPI +from conans import tools + + +class GlobalConfUnitTest(unittest.TestCase): + + def setUp(self): + self.conan_api = MockConanAPI() + self.configuration = ["tools.system.package_manager:mode=install", "tools.system.package_manager:sudo=True"] + + def test_new_global_conf(self): + manager = GlobalConf(self.conan_api, Printer()) + manager.populate(self.configuration) + content = tools.load(self.conan_api._cache.new_config_path) + assert content == textwrap.dedent("""tools.system.package_manager:mode=install + tools.system.package_manager:sudo=True + """.replace(" ", "")) + + def test_append_global_conf(self): + manager = GlobalConf(self.conan_api, Printer()) + manager.populate(self.configuration) + append_conf = ["tools.system.package_manager:tool=yum"] + manager.populate(append_conf) + content = tools.load(self.conan_api._cache.new_config_path) + assert content == textwrap.dedent("""tools.system.package_manager:mode=install + tools.system.package_manager:sudo=True + tools.system.package_manager:tool=yum + """.replace(" ", "")) + + def test_string_global_conf(self): + configuration = "tools.system.package_manager:mode=install,tools.system.package_manager:sudo=True" + manager = GlobalConf(self.conan_api, Printer()) + manager.populate(configuration) + content = tools.load(self.conan_api._cache.new_config_path) + assert content == textwrap.dedent("""tools.system.package_manager:mode=install + tools.system.package_manager:sudo=True + """.replace(" ", "")) diff --git a/cpt/test/unit/utils.py b/cpt/test/unit/utils.py index 2de41313..2de72091 100644 --- a/cpt/test/unit/utils.py +++ b/cpt/test/unit/utils.py @@ -29,8 +29,11 @@ class MockConanCache(object): def __init__(self, *args, **kwargs): _base_dir = temp_folder() - self.default_profile_path = os.path.join(_base_dir, "default") - self.profiles_path = _base_dir + self.default_profile_path = os.path.join(_base_dir, "profiles", "default") + self.profiles_path = os.path.join(_base_dir, "profiles") + self.new_config_path = os.path.join(_base_dir, "global.conf") + if not os.path.exists(self.profiles_path): + os.mkdir(self.profiles_path) Action = namedtuple("Action", "name args kwargs")