From 3e85bf5699936a453d303f248ae3ba7957c39ca9 Mon Sep 17 00:00:00 2001 From: danimtb Date: Mon, 29 Oct 2018 10:59:49 +0100 Subject: [PATCH 1/2] Rename Plugins as Hooks --- conans/client/client_cache.py | 22 +-- conans/client/cmd/build.py | 10 +- conans/client/cmd/download.py | 8 +- conans/client/cmd/export.py | 8 +- conans/client/cmd/export_pkg.py | 6 +- conans/client/cmd/test.py | 4 +- conans/client/cmd/uploader.py | 12 +- conans/client/command.py | 2 +- conans/client/conan_api.py | 49 ++--- conans/client/conf/__init__.py | 6 +- conans/client/hook_manager.py | 119 ++++++++++++ conans/client/installer.py | 26 +-- conans/client/manager.py | 8 +- conans/client/packager.py | 20 +- conans/client/plugin_manager.py | 120 ------------ conans/client/recorder/search_recorder.py | 3 +- conans/client/recorder/upload_recoder.py | 5 +- conans/client/remote_manager.py | 44 ++--- conans/client/source.py | 20 +- conans/test/command/info_test.py | 6 +- conans/test/functional/create_package_test.py | 2 +- ...n_manager_test.py => hook_manager_test.py} | 56 +++--- .../{plugin_test.py => hook_test.py} | 172 +++++++++--------- conans/test/utils/tools.py | 12 +- 24 files changed, 372 insertions(+), 368 deletions(-) create mode 100644 conans/client/hook_manager.py delete mode 100644 conans/client/plugin_manager.py rename conans/test/functional/{plugin_manager_test.py => hook_manager_test.py} (58%) rename conans/test/integration/{plugin_test.py => hook_test.py} (57%) diff --git a/conans/client/client_cache.py b/conans/client/client_cache.py index 65c9bb38c50..aebc9de728b 100644 --- a/conans/client/client_cache.py +++ b/conans/client/client_cache.py @@ -26,7 +26,7 @@ REGISTRY = "registry.txt" REGISTRY_JSON = "registry.json" PROFILES_FOLDER = "profiles" -PLUGINS_FOLDER = "plugins" +HOOKS_FOLDER = "hooks" # Client certificates CLIENT_CERT = "client.crt" @@ -156,11 +156,11 @@ def default_profile_path(self): self.conan_config.default_profile) @property - def plugins_path(self): + def hooks_path(self): """ - :return: Plugins folder in client cache + :return: Hooks folder in client cache """ - return join(self.conan_folder, PLUGINS_FOLDER) + return join(self.conan_folder, HOOKS_FOLDER) @property def default_profile(self): @@ -210,13 +210,13 @@ def settings(self): return self._settings @property - def plugins(self): - """Returns a list of plugins inside the plugins folder""" - plugins = [] - for plugin_name in os.listdir(self.plugins_path): - if os.path.isfile(plugin_name) and plugin_name.endswith(".py"): - plugins.append(plugin_name[:-3]) - return plugins + def hooks(self): + """Returns a list of hooks inside the hooks folder""" + hooks = [] + for hook_name in os.listdir(self.hooks_path): + if os.path.isfile(hook_name) and hook_name.endswith(".py"): + hooks.append(hook_name[:-3]) + return hooks def conan_packages(self, conan_reference): """ Returns a list of package_id from a local cache package folder """ diff --git a/conans/client/cmd/build.py b/conans/client/cmd/build.py index 2b5f59278a8..7755bcc4f2e 100644 --- a/conans/client/cmd/build.py +++ b/conans/client/cmd/build.py @@ -9,7 +9,7 @@ from conans.model.conan_file import get_env_context_manager -def build(graph_manager, plugin_manager, conanfile_path, output, +def build(graph_manager, hook_manager, conanfile_path, output, source_folder, build_folder, package_folder, install_folder, test=False, should_configure=True, should_build=True, should_install=True, should_test=True): @@ -50,14 +50,14 @@ def build(graph_manager, plugin_manager, conanfile_path, output, conan_file.source_folder = source_folder conan_file.package_folder = package_folder conan_file.install_folder = install_folder - plugin_manager.execute("pre_build", conanfile=conan_file, - conanfile_path=conanfile_path) + hook_manager.execute("pre_build", conanfile=conan_file, + conanfile_path=conanfile_path) with get_env_context_manager(conan_file): output.highlight("Running build()") with conanfile_exception_formatter(str(conan_file), "build"): conan_file.build() - plugin_manager.execute("post_build", conanfile=conan_file, - conanfile_path=conanfile_path) + hook_manager.execute("post_build", conanfile=conan_file, + conanfile_path=conanfile_path) if test: output.highlight("Running test()") with conanfile_exception_formatter(str(conan_file), "test"): diff --git a/conans/client/cmd/download.py b/conans/client/cmd/download.py index 0d6bad172de..26226beb42d 100644 --- a/conans/client/cmd/download.py +++ b/conans/client/cmd/download.py @@ -7,7 +7,7 @@ def download(reference, package_ids, remote_name, recipe, registry, remote_manager, - client_cache, out, recorder, loader, plugin_manager): + client_cache, out, recorder, loader, hook_manager): assert(isinstance(reference, ConanFileReference)) output = ScopedOutput(str(reference), out) @@ -16,7 +16,7 @@ def download(reference, package_ids, remote_name, recipe, registry, remote_manag if not package: # Search the reference first, and raise if it doesn't exist raise ConanException("'%s' not found in remote" % str(reference)) - plugin_manager.execute("pre_download", reference=reference, remote=remote) + hook_manager.execute("pre_download", reference=reference, remote=remote) # First of all download package recipe remote_manager.get_recipe(reference, remote) registry.refs.set(reference, remote.name) @@ -41,8 +41,8 @@ def download(reference, package_ids, remote_name, recipe, registry, remote_manag else: _download_binaries(reference, list(packages_props.keys()), client_cache, remote_manager, remote, output, recorder, loader) - plugin_manager.execute("post_download", conanfile_path=conan_file_path, reference=reference, - remote=remote) + hook_manager.execute("post_download", conanfile_path=conan_file_path, reference=reference, + remote=remote) def _download_binaries(reference, package_ids, client_cache, remote_manager, remote, output, diff --git a/conans/client/cmd/export.py b/conans/client/cmd/export.py index 96c7b523266..cb119c363f2 100644 --- a/conans/client/cmd/export.py +++ b/conans/client/cmd/export.py @@ -35,13 +35,13 @@ class AliasConanfile(ConanFile): def cmd_export(conanfile_path, conanfile, reference, keep_source, output, client_cache, - plugin_manager, registry): + hook_manager, registry): """ Export the recipe param conanfile_path: the original source directory of the user containing a conanfile.py """ - plugin_manager.execute("pre_export", conanfile=conanfile, conanfile_path=conanfile_path, - reference=reference) + hook_manager.execute("pre_export", conanfile=conanfile, conanfile_path=conanfile_path, + reference=reference) logger.debug("Exporting %s" % conanfile_path) output.highlight("Exporting package recipe") @@ -58,7 +58,7 @@ def cmd_export(conanfile_path, conanfile, reference, keep_source, output, client _export_conanfile(conanfile_path, conanfile.output, client_cache, conanfile, reference, keep_source) conanfile_cache_path = client_cache.conanfile(reference) - plugin_manager.execute("post_export", conanfile=conanfile, conanfile_path=conanfile_cache_path, + hook_manager.execute("post_export", conanfile=conanfile, conanfile_path=conanfile_cache_path, reference=reference) diff --git a/conans/client/cmd/export_pkg.py b/conans/client/cmd/export_pkg.py index 0fd7b6e3048..438357299b5 100644 --- a/conans/client/cmd/export_pkg.py +++ b/conans/client/cmd/export_pkg.py @@ -9,7 +9,7 @@ from conans.client.graph.graph_manager import load_deps_info -def export_pkg(client_cache, graph_manager, plugin_manager, recorder, output, +def export_pkg(client_cache, graph_manager, hook_manager, recorder, output, reference, source_folder, build_folder, package_folder, install_folder, profile, force): @@ -44,9 +44,9 @@ def export_pkg(client_cache, graph_manager, plugin_manager, recorder, output, package_output = ScopedOutput(str(reference), output) if package_folder: packager.export_pkg(conanfile, pkg_id, package_folder, dest_package_folder, package_output, - plugin_manager, conan_file_path, reference) + hook_manager, conan_file_path, reference) else: packager.create_package(conanfile, pkg_id, source_folder, build_folder, dest_package_folder, - install_folder, package_output, plugin_manager, conan_file_path, + install_folder, package_output, hook_manager, conan_file_path, reference, local=True) recorder.package_exported(pkg_reference) diff --git a/conans/client/cmd/test.py b/conans/client/cmd/test.py index e0614c05def..7814b4e6b9c 100644 --- a/conans/client/cmd/test.py +++ b/conans/client/cmd/test.py @@ -39,8 +39,8 @@ def install_build_and_test(self, conanfile_abs_path, reference, profile, manifest_verify=manifest_verify, manifest_interactive=manifest_interactive, keep_build=keep_build) - # FIXME: This is ugly access to graph_manager and plugin_manager. Will be cleaned in 2.0 - build(self._manager._graph_manager, self._manager._plugin_manager, conanfile_abs_path, + # FIXME: This is ugly access to graph_manager and hook_manager. Will be cleaned in 2.0 + build(self._manager._graph_manager, self._manager._hook_manager, conanfile_abs_path, self._user_io.out, base_folder, test_build_folder, package_folder=None, install_folder=test_build_folder, test=str(reference)) diff --git a/conans/client/cmd/uploader.py b/conans/client/cmd/uploader.py index 6a27978cea0..ecfaac36add 100644 --- a/conans/client/cmd/uploader.py +++ b/conans/client/cmd/uploader.py @@ -16,13 +16,13 @@ class CmdUpload(object): - def __init__(self, client_cache, user_io, remote_manager, registry, loader, plugin_manager): + def __init__(self, client_cache, user_io, remote_manager, registry, loader, hook_manager): self._client_cache = client_cache self._user_io = user_io self._remote_manager = remote_manager self._registry = registry self._loader = loader - self._plugin_manager = plugin_manager + self._hook_manager = hook_manager def upload(self, recorder, reference_or_pattern, package_id=None, all_packages=None, confirm=False, retry=0, retry_wait=0, integrity_check=False, policy=None, @@ -83,8 +83,8 @@ def _upload(self, conan_file, conan_ref, packages_ids, retry, retry_wait, conanfile_path = self._client_cache.conanfile(conan_ref) # FIXME: I think it makes no sense to specify a remote to "pre_upload" # FIXME: because the recipe can have one and the package a different one - self._plugin_manager.execute("pre_upload", conanfile_path=conanfile_path, - reference=conan_ref, remote=recipe_remote) + self._hook_manager.execute("pre_upload", conanfile_path=conanfile_path, + reference=conan_ref, remote=recipe_remote) if policy != UPLOAD_POLICY_FORCE: remote_manifest = self._check_recipe_date(conan_ref, recipe_remote) @@ -121,8 +121,8 @@ def _upload(self, conan_file, conan_ref, packages_ids, retry, retry_wait, # FIXME: I think it makes no sense to specify a remote to "post_upload" # FIXME: because the recipe can have one and the package a different one - self._plugin_manager.execute("post_upload", conanfile_path=conanfile_path, - reference=conan_ref, remote=recipe_remote) + self._hook_manager.execute("post_upload", conanfile_path=conanfile_path, + reference=conan_ref, remote=recipe_remote) def _upload_recipe(self, conan_reference, retry, retry_wait, policy, remote, remote_manifest): conan_file_path = self._client_cache.conanfile(conan_reference) diff --git a/conans/client/command.py b/conans/client/command.py index 884b4098fc2..83474423b72 100644 --- a/conans/client/command.py +++ b/conans/client/command.py @@ -431,7 +431,7 @@ def config(self, *args): try: key, value = args.item.split("=", 1) except ValueError: - if "plugins." in args.item: + if "hooks." in args.item: key, value = args.item.split("=", 1)[0], None else: raise ConanException("Please specify 'key=value'") diff --git a/conans/client/conan_api.py b/conans/client/conan_api.py index 1a4cfafd431..208373c2af7 100644 --- a/conans/client/conan_api.py +++ b/conans/client/conan_api.py @@ -7,7 +7,7 @@ import conans from conans import __version__ as client_version, tools from conans.client.cmd.create import create -from conans.client.plugin_manager import PluginManager +from conans.client.hook_manager import HookManager from conans.client.recorder.action_recorder import ActionRecorder from conans.client.client_cache import ClientCache from conans.client.conf import MIN_SERVER_COMPATIBLE_VERSION, ConanClientConfigParser @@ -150,7 +150,7 @@ class ConanAPIV1(object): @staticmethod def instance_remote_manager(requester, client_cache, user_io, _client_version, - min_server_compatible_version, plugin_manager): + min_server_compatible_version, hook_manager): # Verify client version against remotes version_checker_req = VersionCheckerRequester(requester, _client_version, @@ -166,7 +166,7 @@ def instance_remote_manager(requester, client_cache, user_io, _client_version, # Wraps RestApiClient to add authentication support (same interface) auth_manager = ConanApiAuthManager(rest_api_client, user_io, localdb) # Handle remote connections - remote_manager = RemoteManager(client_cache, auth_manager, user_io.out, plugin_manager) + remote_manager = RemoteManager(client_cache, auth_manager, user_io.out, hook_manager) return localdb, rest_api_client, remote_manager @staticmethod @@ -201,9 +201,9 @@ def factory(interactive=None): # Adjust CONAN_LOGGING_LEVEL with the env readed conans.util.log.logger = configure_logger() - # Create Plugin Manager - plugin_manager = PluginManager(client_cache.plugins_path, - get_env("CONAN_PLUGINS", list()), user_io.out) + # Create Hook Manager + hook_manager = HookManager(client_cache.hooks_path, get_env("CONAN_HOOKS", list()), + user_io.out) # Get the new command instance after migrations have been done requester = get_basic_requester(client_cache) @@ -212,7 +212,7 @@ def factory(interactive=None): client_cache, user_io, Version(client_version), Version(MIN_SERVER_COMPATIBLE_VERSION), - plugin_manager) + hook_manager) # Adjust global tool variables set_global_instances(out, requester) @@ -221,11 +221,11 @@ def factory(interactive=None): if interactive is None: interactive = not get_env("CONAN_NON_INTERACTIVE", False) conan = ConanAPIV1(client_cache, user_io, get_conan_runner(), remote_manager, - plugin_manager, interactive=interactive) + hook_manager, interactive=interactive) return conan, client_cache, user_io - def __init__(self, client_cache, user_io, runner, remote_manager, plugin_manager, + def __init__(self, client_cache, user_io, runner, remote_manager, hook_manager, interactive=True): assert isinstance(user_io, UserIO) assert isinstance(client_cache, ClientCache) @@ -243,14 +243,15 @@ def __init__(self, client_cache, user_io, runner, remote_manager, plugin_manager python_requires = ConanPythonRequire(self._proxy, resolver) self._loader = ConanFileLoader(self._runner, self._user_io.out, python_requires) self._graph_manager = GraphManager(self._user_io.out, self._client_cache, self._registry, - self._remote_manager, self._loader, self._proxy, resolver) - self._plugin_manager = plugin_manager + self._remote_manager, self._loader, self._proxy, + resolver) + self._hook_manager = hook_manager def _init_manager(self, action_recorder): """Every api call gets a new recorder and new manager""" return ConanManager(self._client_cache, self._user_io, self._remote_manager, action_recorder, self._registry, - self._graph_manager, self._plugin_manager) + self._graph_manager, self._hook_manager) @api_method def new(self, name, header=False, pure_c=False, test=False, exports_sources=False, bare=False, @@ -357,7 +358,7 @@ def create(self, conanfile_path, name=None, version=None, user=None, channel=Non # Forcing an export! if not not_export: cmd_export(conanfile_path, conanfile, reference, keep_source, self._user_io.out, - self._client_cache, self._plugin_manager, self._registry) + self._client_cache, self._hook_manager, self._registry) recorder.recipe_exported(reference) if build_modes is None: # Not specified, force build the tested library @@ -420,12 +421,13 @@ def export_pkg(self, conanfile_path, name, channel, source_folder=None, build_fo else: profile = read_conaninfo_profile(install_folder) - reference, conanfile = self._loader.load_export(conanfile_path, name, version, user, channel) + reference, conanfile = self._loader.load_export(conanfile_path, name, version, user, + channel) recorder.recipe_exported(reference) recorder.add_recipe_being_developed(reference) cmd_export(conanfile_path, conanfile, reference, False, self._user_io.out, - self._client_cache, self._plugin_manager, self._registry) - export_pkg(self._client_cache, self._graph_manager, self._plugin_manager, recorder, + self._client_cache, self._hook_manager, self._registry) + export_pkg(self._client_cache, self._graph_manager, self._hook_manager, recorder, self._user_io.out, reference, source_folder=source_folder, build_folder=build_folder, package_folder=package_folder, install_folder=install_folder, @@ -447,7 +449,7 @@ def download(self, reference, remote_name=None, package=None, recipe=False): recorder = ActionRecorder() download(conan_ref, package, remote_name, recipe, self._registry, self._remote_manager, self._client_cache, self._user_io.out, recorder, self._loader, - self._plugin_manager) + self._hook_manager) else: raise ConanException("Provide a valid full reference without wildcards.") @@ -629,7 +631,7 @@ def build(self, conanfile_path, source_folder=None, package_folder=None, build_f default_pkg_folder = os.path.join(build_folder, "package") package_folder = _make_abs_path(package_folder, cwd, default=default_pkg_folder) - build(self._graph_manager, self._plugin_manager, conanfile_path, self._user_io.out, + build(self._graph_manager, self._hook_manager, conanfile_path, self._user_io.out, source_folder, build_folder, package_folder, install_folder, should_configure=should_configure, should_build=should_build, should_install=should_install, should_test=should_test) @@ -652,7 +654,7 @@ def package(self, path, build_folder, package_folder, source_folder=None, instal conanfile = self._graph_manager.load_consumer_conanfile(conanfile_path, install_folder, output, deps_info_required=True) packager.create_package(conanfile, None, source_folder, build_folder, package_folder, - install_folder, output, self._plugin_manager, conanfile_path, None, + install_folder, output, self._hook_manager, conanfile_path, None, local=True, copy_info=True) @api_method @@ -675,7 +677,7 @@ def source(self, path, source_folder=None, info_folder=None, cwd=None): export_recipe(conanfile, conanfile_folder, source_folder, output) export_source(conanfile, conanfile_folder, source_folder, output) config_source_local(source_folder, conanfile, conanfile_folder, output, conanfile_path, - self._plugin_manager) + self._hook_manager) @api_method def imports(self, path, dest=None, info_folder=None, cwd=None): @@ -706,9 +708,10 @@ def imports_undo(self, manifest_path): @api_method def export(self, path, name, version, user, channel, keep_source=False, cwd=None): conanfile_path = _get_conanfile_path(path, cwd, py=True) - reference, conanfile = self._loader.load_export(conanfile_path, name, version, user, channel) + reference, conanfile = self._loader.load_export(conanfile_path, name, version, user, + channel) cmd_export(conanfile_path, conanfile, reference, keep_source, self._user_io.out, - self._client_cache, self._plugin_manager, self._registry) + self._client_cache, self._hook_manager, self._registry) @api_method def remove(self, pattern, query=None, packages=None, builds=None, src=False, force=False, @@ -809,7 +812,7 @@ def upload(self, pattern, package=None, remote_name=None, all_packages=False, co recorder = UploadRecorder() uploader = CmdUpload(self._client_cache, self._user_io, self._remote_manager, - self._registry, self._loader, self._plugin_manager) + self._registry, self._loader, self._hook_manager) try: uploader.upload(recorder, pattern, package, all_packages, confirm, retry, retry_wait, integrity_check, policy, remote_name, query=query) diff --git a/conans/client/conf/__init__.py b/conans/client/conf/__init__.py index dcdc1a808fa..7d4cd4825b6 100644 --- a/conans/client/conf/__init__.py +++ b/conans/client/conf/__init__.py @@ -140,7 +140,7 @@ # You can skip the proxy for the matching (fnmatch) urls (comma-separated) # no_proxy_match = *bintray.com*, https://myserver.* -[plugins] # environment CONAN_PLUGINS +[hooks] # environment CONAN_HOOKS attribute_checker # Default settings now declared in the default profile @@ -205,7 +205,7 @@ def env_vars(self): "CONAN_MAKE_PROGRAM": self._env_c("general.conan_make_program", "CONAN_MAKE_PROGRAM", None), "CONAN_TEMP_TEST_FOLDER": self._env_c("general.temp_test_folder", "CONAN_TEMP_TEST_FOLDER", "False"), "CONAN_SKIP_VS_PROJECTS_UPGRADE": self._env_c("general.skip_vs_projects_upgrade", "CONAN_SKIP_VS_PROJECTS_UPGRADE", "False"), - "CONAN_PLUGINS": self._env_c("plugins", "CONAN_PLUGINS", None) + "CONAN_HOOKS": self._env_c("hooks", "CONAN_HOOKS", None) } # Filter None values @@ -232,7 +232,7 @@ def get_item(self, item): raise ConanException("'%s' is not a section of conan.conf" % section_name) if len(tokens) == 1: result = [] - if section_name == "plugins": + if section_name == "hooks": for key, _ in section: result.append(key) return ",".join(result) diff --git a/conans/client/hook_manager.py b/conans/client/hook_manager.py new file mode 100644 index 00000000000..56b6745936b --- /dev/null +++ b/conans/client/hook_manager.py @@ -0,0 +1,119 @@ +import traceback +import os +import sys +import uuid +from collections import defaultdict + +from conans.client.output import ScopedOutput +from conans.errors import ConanException, NotFoundException +from conans.tools import chdir +from conans.util.files import save + + +attribute_checker_hook = """ +def pre_export(output, conanfile, conanfile_path, reference, **kwargs): + # Check basic meta-data + for field in ["url", "license", "description"]: + field_value = getattr(conanfile, field, None) + if not field_value: + output.warn("Conanfile doesn't have '%s'. It is recommended to add it as attribute" + % field) +""" + +valid_hook_methods = ["pre_export", "post_export", + "pre_source", "post_source", + "pre_build", "post_build", + "pre_package", "post_package", + "pre_upload", "post_upload", + "pre_upload_recipe", "post_upload_recipe", + "pre_upload_package", "post_upload_package", + "pre_download", "post_download", + "pre_download_recipe", "post_download_recipe", + "pre_download_package", "post_download_package"] + + +class HookManager(object): + + def __init__(self, hooks_folder, hook_names, output): + self._hooks_folder = hooks_folder + self._hook_names = hook_names + self.hooks = defaultdict(list) + self.output = output + + def create_default_hooks(self): + attribute_checker_path = os.path.join(self._hooks_folder, "attribute_checker.py") + save(attribute_checker_path, attribute_checker_hook) + + def execute(self, method_name, **kwargs): + if not os.path.exists(os.path.join(self._hooks_folder, "attribute_checker.py")): + self.create_default_hooks() + if not self.hooks: + self.load_hooks() + + assert method_name in valid_hook_methods + for name, method in self.hooks[method_name]: + try: + output = ScopedOutput("[HOOK - %s] %s()" % (name, method_name), self.output) + method(output, **kwargs) + except Exception as e: + raise ConanException("[HOOK - %s] %s(): %s\n%s" % (name, method_name, str(e), + traceback.format_exc())) + + def load_hooks(self): + for name in self._hook_names: + self.load_hook(name) + + def load_hook(self, hook_name): + filename = "%s.py" % hook_name + hook_path = os.path.join(self._hooks_folder, filename) + try: + hook = HookManager._load_module_from_file(hook_path) + for method in valid_hook_methods: + hook_method = getattr(hook, method, None) + if hook_method: + self.hooks[method].append((hook_name, hook_method)) + except NotFoundException: + self.output.warn("Hook '%s' not found in %s folder. Please remove hook " + "from conan.conf or include it inside the hooks folder." + % (filename, self._hooks_folder)) + except Exception as e: + raise ConanException("Error loading hook '%s': %s" % (hook_path, str(e))) + + @staticmethod + def _load_module_from_file(hook_path): + """ From a given path, obtain the in memory python import module + """ + if not os.path.exists(hook_path): + raise NotFoundException + filename = os.path.splitext(os.path.basename(hook_path))[0] + current_dir = os.path.dirname(hook_path) + + try: + sys.path.append(current_dir) + old_modules = list(sys.modules.keys()) + with chdir(current_dir): + sys.dont_write_bytecode = True + loaded = __import__(filename) + # Put all imported files under a new package name + module_id = uuid.uuid1() + added_modules = set(sys.modules).difference(old_modules) + for added in added_modules: + module = sys.modules[added] + if module: + try: + folder = os.path.dirname(module.__file__) + except AttributeError: # some module doesn't have __file__ + pass + else: + if folder.startswith(current_dir): + module = sys.modules.pop(added) + sys.modules["%s.%s" % (module_id, added)] = module + except Exception: + trace = traceback.format_exc().split('\n') + raise ConanException("Unable to load Hook in %s\n%s" % (hook_path, + '\n'.join(trace[3:]))) + finally: + sys.dont_write_bytecode = False + sys.path.pop() + + return loaded diff --git a/conans/client/installer.py b/conans/client/installer.py index bcbc0c1b053..1033cfbde02 100644 --- a/conans/client/installer.py +++ b/conans/client/installer.py @@ -50,14 +50,14 @@ def build_id(conan_file): class _ConanPackageBuilder(object): """Builds and packages a single conan_file binary package""" - def __init__(self, conan_file, package_reference, client_cache, output, plugin_manager): + def __init__(self, conan_file, package_reference, client_cache, output, hook_manager): self._client_cache = client_cache self._conan_file = conan_file self._out = output self._package_reference = package_reference self._conan_ref = self._package_reference.conan self._skip_build = False # If build_id() - self._plugin_manager = plugin_manager + self._hook_manager = hook_manager new_id = build_id(self._conan_file) self.build_reference = PackageReference(self._conan_ref, @@ -92,7 +92,7 @@ def prepare_build(self): local_sources_path = load(sources_pointer) if os.path.exists(sources_pointer) else None config_source(export_folder, export_source_folder, local_sources_path, self.source_folder, self._conan_file, self._out, conanfile_path, self._conan_ref, - self._plugin_manager, self._client_cache) + self._hook_manager, self._client_cache) self._out.info('Copying sources to build folder') if getattr(self._conan_file, 'no_copy_source', False): @@ -143,7 +143,7 @@ def package(self): conanfile_path = self._client_cache.conanfile(self._conan_ref) create_package(self._conan_file, pkg_id, source_folder, self.build_folder, - self.package_folder, install_folder, self._out, self._plugin_manager, + self.package_folder, install_folder, self._out, self._hook_manager, conanfile_path, self._conan_ref) if get_env("CONAN_READ_ONLY_CACHE", False): @@ -171,9 +171,9 @@ def _build_package(self): try: # This is necessary because it is different for user projects # than for packages - self._plugin_manager.execute("pre_build", conanfile=self._conan_file, - reference=self._conan_ref, - package_id=self._package_reference.package_id) + self._hook_manager.execute("pre_build", conanfile=self._conan_file, + reference=self._conan_ref, + package_id=self._package_reference.package_id) logger.debug("Call conanfile.build() with files in build folder: %s", os.listdir(self.build_folder)) self._out.highlight("Calling build()") @@ -182,9 +182,9 @@ def _build_package(self): self._out.success("Package '%s' built" % self._conan_file.info.package_id()) self._out.info("Build folder %s" % self.build_folder) - self._plugin_manager.execute("post_build", conanfile=self._conan_file, - reference=self._conan_ref, - package_id=self._package_reference.package_id) + self._hook_manager.execute("post_build", conanfile=self._conan_file, + reference=self._conan_ref, + package_id=self._package_reference.package_id) except Exception as exc: self._out.writeln("") self._out.error("Package '%s' build failed" % self._conan_file.info.package_id()) @@ -257,14 +257,14 @@ class ConanInstaller(object): locally in case they are not found in remotes """ def __init__(self, client_cache, output, remote_manager, registry, recorder, workspace, - plugin_manager): + hook_manager): self._client_cache = client_cache self._out = output self._remote_manager = remote_manager self._registry = registry self._recorder = recorder self._workspace = workspace - self._plugin_manager = plugin_manager + self._hook_manager = hook_manager def install(self, deps_graph, keep_build=False): # order by levels and separate the root node (conan_ref=None) from the rest @@ -380,7 +380,7 @@ def _build_package(self, node, package_ref, output, keep_build): conan_file, python_require.conan_ref) builder = _ConanPackageBuilder(conan_file, package_ref, self._client_cache, output, - self._plugin_manager) + self._hook_manager) if is_dirty(builder.build_folder): output.warn("Build folder is dirty, removing it: %s" % builder.build_folder) rmdir(builder.build_folder) diff --git a/conans/client/manager.py b/conans/client/manager.py index eada0f99ade..d3b67214b6e 100644 --- a/conans/client/manager.py +++ b/conans/client/manager.py @@ -19,7 +19,7 @@ class ConanManager(object): def __init__(self, client_cache, user_io, remote_manager, - recorder, registry, graph_manager, plugin_manager): + recorder, registry, graph_manager, hook_manager): assert isinstance(user_io, UserIO) assert isinstance(client_cache, ClientCache) self._client_cache = client_cache @@ -28,7 +28,7 @@ def __init__(self, client_cache, user_io, remote_manager, self._recorder = recorder self._registry = registry self._graph_manager = graph_manager - self._plugin_manager = plugin_manager + self._hook_manager = hook_manager def install_workspace(self, profile, workspace, remote_name, build_modes, update): references = [ConanFileReference(v, "root", "project", "develop") for v in workspace.root] @@ -42,7 +42,7 @@ def install_workspace(self, profile, workspace, remote_name, build_modes, update installer = ConanInstaller(self._client_cache, output, self._remote_manager, self._registry, recorder=self._recorder, workspace=workspace, - plugin_manager=self._plugin_manager) + hook_manager=self._hook_manager) installer.install(deps_graph, keep_build=False) workspace.generate() @@ -98,7 +98,7 @@ def install(self, reference, install_folder, profile, remote_name=None, build_mo installer = ConanInstaller(self._client_cache, output, self._remote_manager, self._registry, recorder=self._recorder, workspace=None, - plugin_manager=self._plugin_manager) + hook_manager=self._hook_manager) installer.install(deps_graph, keep_build) if manifest_folder: diff --git a/conans/client/packager.py b/conans/client/packager.py index 9b1914d7be7..61907eea137 100644 --- a/conans/client/packager.py +++ b/conans/client/packager.py @@ -12,14 +12,14 @@ from conans.client.file_copier import FileCopier -def export_pkg(conanfile, pkg_id, src_package_folder, package_folder, output, plugin_manager, +def export_pkg(conanfile, pkg_id, src_package_folder, package_folder, output, hook_manager, conanfile_path, reference): mkdir(package_folder) conanfile.package_folder = src_package_folder output.info("Exporting to cache existing package from user folder") output.info("Package folder %s" % package_folder) - plugin_manager.execute("pre_package", conanfile=conanfile, conanfile_path=conanfile_path, - reference=reference, package_id=pkg_id) + hook_manager.execute("pre_package", conanfile=conanfile, conanfile_path=conanfile_path, + reference=reference, package_id=pkg_id) copier = FileCopier(src_package_folder, package_folder) copier("*", symlinks=True) @@ -33,12 +33,12 @@ def export_pkg(conanfile, pkg_id, src_package_folder, package_folder, output, pl digest.save(package_folder) output.success("Package '%s' created" % pkg_id) conanfile.package_folder = package_folder - plugin_manager.execute("post_package", conanfile=conanfile, conanfile_path=conanfile_path, - reference=reference, package_id=pkg_id) + hook_manager.execute("post_package", conanfile=conanfile, conanfile_path=conanfile_path, + reference=reference, package_id=pkg_id) def create_package(conanfile, pkg_id, source_folder, build_folder, package_folder, install_folder, - output, plugin_manager, conanfile_path, reference, local=False, copy_info=False): + output, hook_manager, conanfile_path, reference, local=False, copy_info=False): """ copies built artifacts, libs, headers, data, etc. from build_folder to package folder """ @@ -54,8 +54,8 @@ def create_package(conanfile, pkg_id, source_folder, build_folder, package_folde conanfile.install_folder = install_folder conanfile.build_folder = build_folder - plugin_manager.execute("pre_package", conanfile=conanfile, conanfile_path=conanfile_path, - reference=reference, package_id=pkg_id) + hook_manager.execute("pre_package", conanfile=conanfile, conanfile_path=conanfile_path, + reference=reference, package_id=pkg_id) package_output = ScopedOutput("%s package()" % output.scope, output) output.highlight("Calling package()") @@ -95,8 +95,8 @@ def recipe_has(attribute): _create_aux_files(install_folder, package_folder, conanfile, copy_info) pkg_id = pkg_id or os.path.basename(package_folder) output.success("Package '%s' created" % pkg_id) - plugin_manager.execute("post_package", conanfile=conanfile, conanfile_path=conanfile_path, - reference=reference, package_id=pkg_id) + hook_manager.execute("post_package", conanfile=conanfile, conanfile_path=conanfile_path, + reference=reference, package_id=pkg_id) def _create_aux_files(install_folder, package_folder, conanfile, copy_info): diff --git a/conans/client/plugin_manager.py b/conans/client/plugin_manager.py deleted file mode 100644 index 5b0ac98ae6a..00000000000 --- a/conans/client/plugin_manager.py +++ /dev/null @@ -1,120 +0,0 @@ -import traceback -import os -import sys -import uuid -from collections import defaultdict - -from conans.client.output import ScopedOutput -from conans.errors import ConanException, NotFoundException -from conans.tools import chdir -from conans.util.files import save - - -attribute_checker_plugin = """ -def pre_export(output, conanfile, conanfile_path, reference, **kwargs): - # Check basic meta-data - for field in ["url", "license", "description"]: - field_value = getattr(conanfile, field, None) - if not field_value: - output.warn("Conanfile doesn't have '%s'. It is recommended to add it as attribute" - % field) -""" - -valid_plugin_methods = ["pre_export", "post_export", - "pre_source", "post_source", - "pre_build", "post_build", - "pre_package", "post_package", - "pre_upload", "post_upload", - "pre_upload_recipe", "post_upload_recipe", - "pre_upload_package", "post_upload_package", - "pre_download", "post_download", - "pre_download_recipe", "post_download_recipe", - "pre_download_package", "post_download_package" - ] - - -class PluginManager(object): - - def __init__(self, plugins_folder, plugin_names, output): - self._plugins_folder = plugins_folder - self._plugin_names = plugin_names - self.plugins = defaultdict(list) - self.output = output - - def create_default_plugins(self): - attribute_checker_path = os.path.join(self._plugins_folder, "attribute_checker.py") - save(attribute_checker_path, attribute_checker_plugin) - - def execute(self, method_name, **kwargs): - if not os.path.exists(os.path.join(self._plugins_folder, "attribute_checker.py")): - self.create_default_plugins() - if not self.plugins: - self.load_plugins() - - assert method_name in valid_plugin_methods - for name, method in self.plugins[method_name]: - try: - output = ScopedOutput("[PLUGIN - %s] %s()" % (name, method_name), self.output) - method(output, **kwargs) - except Exception as e: - raise ConanException("[PLUGIN - %s] %s(): %s\n%s" % (name, method_name, str(e), - traceback.format_exc())) - - def load_plugins(self): - for name in self._plugin_names: - self.load_plugin(name) - - def load_plugin(self, plugin_name): - filename = "%s.py" % plugin_name - plugin_path = os.path.join(self._plugins_folder, filename) - try: - plugin = PluginManager._load_module_from_file(plugin_path) - for method in valid_plugin_methods: - plugin_method = getattr(plugin, method, None) - if plugin_method: - self.plugins[method].append((plugin_name, plugin_method)) - except NotFoundException: - self.output.warn("Plugin '%s' not found in %s folder. Please remove plugin " - "from conan.conf or include it inside the plugins folder." - % (filename, self._plugins_folder)) - except Exception as e: - raise ConanException("Error loading plugin '%s': %s" % (plugin_path, str(e))) - - @staticmethod - def _load_module_from_file(plugin_path): - """ From a given path, obtain the in memory python import module - """ - if not os.path.exists(plugin_path): - raise NotFoundException - filename = os.path.splitext(os.path.basename(plugin_path))[0] - current_dir = os.path.dirname(plugin_path) - - try: - sys.path.append(current_dir) - old_modules = list(sys.modules.keys()) - with chdir(current_dir): - sys.dont_write_bytecode = True - loaded = __import__(filename) - # Put all imported files under a new package name - module_id = uuid.uuid1() - added_modules = set(sys.modules).difference(old_modules) - for added in added_modules: - module = sys.modules[added] - if module: - try: - folder = os.path.dirname(module.__file__) - except AttributeError: # some module doesn't have __file__ - pass - else: - if folder.startswith(current_dir): - module = sys.modules.pop(added) - sys.modules["%s.%s" % (module_id, added)] = module - except Exception: - trace = traceback.format_exc().split('\n') - raise ConanException("Unable to load Plugin in %s\n%s" % (plugin_path, - '\n'.join(trace[3:]))) - finally: - sys.dont_write_bytecode = False - sys.path.pop() - - return loaded diff --git a/conans/client/recorder/search_recorder.py b/conans/client/recorder/search_recorder.py index 6d8293eebde..b278c8ad1ae 100644 --- a/conans/client/recorder/search_recorder.py +++ b/conans/client/recorder/search_recorder.py @@ -31,7 +31,8 @@ def add_recipe(self, remote_name, reference, with_packages=True): self._info[remote_name] = OrderedDict() self._info[remote_name][reference] = {"recipe": recipe, "packages": []} - def add_package(self, remote_name, reference, package_id, options, settings, requires, outdated): + def add_package(self, remote_name, reference, package_id, options, settings, requires, + outdated): sp = _SearchPackage(package_id, options, settings, requires, outdated) self._info[remote_name][reference]["packages"].append(sp) diff --git a/conans/client/recorder/upload_recoder.py b/conans/client/recorder/upload_recoder.py index 8db8827ecbd..c011ad83920 100644 --- a/conans/client/recorder/upload_recoder.py +++ b/conans/client/recorder/upload_recoder.py @@ -38,10 +38,11 @@ def __init__(self): def add_recipe(self, reference, remote_name, remote_url): self._info[str(reference)] = {"recipe": _UploadElement(reference, remote_name, remote_url), - "packages": []} + "packages": []} def add_package(self, p_ref, remote_name, remote_url): - self._info[str(p_ref.conan)]["packages"].append(_UploadElement(p_ref, remote_name, remote_url)) + self._info[str(p_ref.conan)]["packages"].append(_UploadElement(p_ref, remote_name, + remote_url)) def get_info(self): info = {"error": self.error, "uploaded": []} diff --git a/conans/client/remote_manager.py b/conans/client/remote_manager.py index 0add6305082..a50e2f2a639 100644 --- a/conans/client/remote_manager.py +++ b/conans/client/remote_manager.py @@ -35,17 +35,17 @@ class RemoteManager(object): """ Will handle the remotes to get recipes, packages etc """ - def __init__(self, client_cache, auth_manager, output, plugin_manager): + def __init__(self, client_cache, auth_manager, output, hook_manager): self._client_cache = client_cache self._output = output self._auth_manager = auth_manager - self._plugin_manager = plugin_manager + self._hook_manager = hook_manager def upload_recipe(self, conan_reference, remote, retry, retry_wait, policy, remote_manifest): conanfile_path = self._client_cache.conanfile(conan_reference) - self._plugin_manager.execute("pre_upload_recipe", conanfile_path=conanfile_path, - reference=conan_reference, remote=remote) + self._hook_manager.execute("pre_upload_recipe", conanfile_path=conanfile_path, + reference=conan_reference, remote=remote) t1 = time.time() export_folder = self._client_cache.export(conan_reference) @@ -77,8 +77,8 @@ def upload_recipe(self, conan_reference, remote, retry, retry_wait, policy, remo else: msg = "Recipe is up to date, upload skipped" self._output.info(msg) - self._plugin_manager.execute("post_upload_recipe", conanfile_path=conanfile_path, - reference=conan_reference, remote=remote) + self._hook_manager.execute("post_upload_recipe", conanfile_path=conanfile_path, + reference=conan_reference, remote=remote) return new_ref def _package_integrity_check(self, package_reference, files, package_folder): @@ -111,10 +111,10 @@ def upload_package(self, package_reference, remote, retry, retry_wait, integrity_check=False, policy=None): """Will upload the package to the first remote""" conanfile_path = self._client_cache.conanfile(package_reference.conan) - self._plugin_manager.execute("pre_upload_package", conanfile_path=conanfile_path, - reference=package_reference.conan, - package_id=package_reference.package_id, - remote=remote) + self._hook_manager.execute("pre_upload_package", conanfile_path=conanfile_path, + reference=package_reference.conan, + package_id=package_reference.package_id, + remote=remote) t1 = time.time() # existing package, will use short paths if defined package_folder = self._client_cache.package(package_reference, short_paths=None) @@ -156,9 +156,9 @@ def upload_package(self, package_reference, remote, retry, retry_wait, self._output.rewrite_line("Package is up to date, upload skipped") self._output.writeln("") - self._plugin_manager.execute("post_upload_package", conanfile_path=conanfile_path, - reference=package_reference.conan, - package_id=package_reference.package_id, remote=remote) + self._hook_manager.execute("post_upload_package", conanfile_path=conanfile_path, + reference=package_reference.conan, + package_id=package_reference.package_id, remote=remote) return tmp def get_conan_manifest(self, conan_reference, remote): @@ -191,7 +191,7 @@ def get_recipe(self, conan_reference, remote): Will iterate the remotes to find the conans unless remote was specified returns (dict relative_filepath:abs_path , remote_name)""" - self._plugin_manager.execute("pre_download_recipe", reference=conan_reference, remote=remote) + self._hook_manager.execute("pre_download_recipe", reference=conan_reference, remote=remote) dest_folder = self._client_cache.export(conan_reference) rmdir(dest_folder) @@ -206,8 +206,8 @@ def get_recipe(self, conan_reference, remote): rm_conandir(self._client_cache.source(conan_reference)) touch_folder(dest_folder) conanfile_path = self._client_cache.conanfile(conan_reference) - self._plugin_manager.execute("post_download_recipe", conanfile_path=conanfile_path, - reference=conan_reference, remote=remote) + self._hook_manager.execute("post_download_recipe", conanfile_path=conanfile_path, + reference=conan_reference, remote=remote) return conan_reference def get_recipe_sources(self, conan_reference, export_folder, export_sources_folder, remote): @@ -234,9 +234,9 @@ def get_recipe_sources(self, conan_reference, export_folder, export_sources_fold def get_package(self, package_reference, dest_folder, remote, output, recorder): package_id = package_reference.package_id conanfile_path = self._client_cache.conanfile(package_reference.conan) - self._plugin_manager.execute("pre_download_package", conanfile_path=conanfile_path, - reference=package_reference.conan, package_id=package_id, - remote=remote) + self._hook_manager.execute("pre_download_package", conanfile_path=conanfile_path, + reference=package_reference.conan, package_id=package_id, + remote=remote) output.info("Retrieving package %s from remote '%s' " % (package_id, remote.name)) rm_conandir(dest_folder) # Remove first the destination folder t1 = time.time() @@ -263,9 +263,9 @@ def get_package(self, package_reference, dest_folder, remote, output, recorder): raise ConanException("%s\n\nCouldn't remove folder '%s', might be busy or open. Close any app " "using it, and retry" % (str(e), dest_folder)) raise - self._plugin_manager.execute("post_download_package", conanfile_path=conanfile_path, - reference=package_reference.conan, package_id=package_id, - remote=remote) + self._hook_manager.execute("post_download_package", conanfile_path=conanfile_path, + reference=package_reference.conan, package_id=package_id, + remote=remote) def search_recipes(self, remote, pattern=None, ignorecase=True): """ diff --git a/conans/client/source.py b/conans/client/source.py index ca27c022ad6..67d93bf5bfa 100644 --- a/conans/client/source.py +++ b/conans/client/source.py @@ -85,7 +85,7 @@ def get_scm_data(conanfile): def config_source(export_folder, export_source_folder, local_sources_path, src_folder, - conanfile, output, conanfile_path, reference, plugin_manager, + conanfile, output, conanfile_path, reference, hook_manager, client_cache): """ creates src folder and retrieve, calling source() from conanfile the necessary source code @@ -125,8 +125,8 @@ def remove_source(raise_error=True): with get_env_context_manager(conanfile): conanfile.build_folder = None conanfile.package_folder = None - plugin_manager.execute("pre_source", conanfile=conanfile, - conanfile_path=conanfile_path, reference=reference) + hook_manager.execute("pre_source", conanfile=conanfile, + conanfile_path=conanfile_path, reference=reference) output.info('Configuring sources in %s' % src_folder) scm_data = get_scm_data(conanfile) if scm_data: @@ -152,8 +152,8 @@ def remove_source(raise_error=True): pass conanfile.source() - plugin_manager.execute("post_source", conanfile=conanfile, - conanfile_path=conanfile_path, reference=reference) + hook_manager.execute("post_source", conanfile=conanfile, + conanfile_path=conanfile_path, reference=reference) clean_dirty(src_folder) # Everything went well, remove DIRTY flag except Exception as e: os.chdir(export_folder) @@ -167,7 +167,7 @@ def remove_source(raise_error=True): def config_source_local(dest_dir, conanfile, conanfile_folder, output, conanfile_path, - plugin_manager): + hook_manager): conanfile.source_folder = dest_dir conanfile.build_folder = None conanfile.package_folder = None @@ -175,8 +175,8 @@ def config_source_local(dest_dir, conanfile, conanfile_folder, output, conanfile try: with conanfile_exception_formatter(str(conanfile), "source"): with get_env_context_manager(conanfile): - plugin_manager.execute("pre_source", conanfile=conanfile, - conanfile_path=conanfile_path) + hook_manager.execute("pre_source", conanfile=conanfile, + conanfile_path=conanfile_path) output.info('Configuring sources in %s' % dest_dir) scm_data = get_scm_data(conanfile) if scm_data: @@ -186,8 +186,8 @@ def config_source_local(dest_dir, conanfile, conanfile_folder, output, conanfile _fetch_scm(scm_data, dest_dir, local_sources_path, output) conanfile.source() - plugin_manager.execute("post_source", conanfile=conanfile, - conanfile_path=conanfile_path) + hook_manager.execute("post_source", conanfile=conanfile, + conanfile_path=conanfile_path) except ConanExceptionInUserConanfileMethod: raise except Exception as e: diff --git a/conans/test/command/info_test.py b/conans/test/command/info_test.py index ea024fa4628..ac2d1ce7a3a 100644 --- a/conans/test/command/info_test.py +++ b/conans/test/command/info_test.py @@ -38,9 +38,9 @@ def _create(self, number, version, deps=None, deps_dev=None, export=True): self.client.run("export . lasote/stable") expected_output = textwrap.dedent( """\ - [PLUGIN - attribute_checker] pre_export(): WARN: Conanfile doesn't have 'url'. It is recommended to add it as attribute - [PLUGIN - attribute_checker] pre_export(): WARN: Conanfile doesn't have 'license'. It is recommended to add it as attribute - [PLUGIN - attribute_checker] pre_export(): WARN: Conanfile doesn't have 'description'. It is recommended to add it as attribute + [HOOK - attribute_checker] pre_export(): WARN: Conanfile doesn't have 'url'. It is recommended to add it as attribute + [HOOK - attribute_checker] pre_export(): WARN: Conanfile doesn't have 'license'. It is recommended to add it as attribute + [HOOK - attribute_checker] pre_export(): WARN: Conanfile doesn't have 'description'. It is recommended to add it as attribute """) self.assertIn(expected_output, self.client.user_io.out) diff --git a/conans/test/functional/create_package_test.py b/conans/test/functional/create_package_test.py index 425890c6f5b..b741c47d99c 100644 --- a/conans/test/functional/create_package_test.py +++ b/conans/test/functional/create_package_test.py @@ -84,7 +84,7 @@ def complete_test(self): conanfile = loader.load_conanfile(conanfile_path, None, ProcessedProfile()) create_package(conanfile, None, build_folder, build_folder, package_folder, install_folder, - output, client.plugin_manager, conanfile_path, conan_ref, copy_info=True) + output, client.hook_manager, conanfile_path, conan_ref, copy_info=True) # test build folder self.assertTrue(os.path.exists(build_folder)) diff --git a/conans/test/functional/plugin_manager_test.py b/conans/test/functional/hook_manager_test.py similarity index 58% rename from conans/test/functional/plugin_manager_test.py rename to conans/test/functional/hook_manager_test.py index 53efeac7748..d506664f7a6 100644 --- a/conans/test/functional/plugin_manager_test.py +++ b/conans/test/functional/hook_manager_test.py @@ -2,13 +2,13 @@ import unittest from conans import load -from conans.client.plugin_manager import PluginManager +from conans.client.hook_manager import HookManager from conans.errors import ConanException from conans.test.utils.test_files import temp_folder from conans.test.utils.tools import TestBufferConanOutput from conans.util.files import save -my_plugin = """ +my_hook = """ def pre_export(output, **kwargs): output.info("pre_export()") @@ -59,55 +59,55 @@ def post_download_package(output, **kwargs): """ -class PluginManagerTest(unittest.TestCase): +class HookManagerTest(unittest.TestCase): def _init(self): temp_dir = temp_folder() - plugin_path = os.path.join(temp_dir, "my_plugin.py") - save(os.path.join(temp_dir, "my_plugin.py"), my_plugin) + hook_path = os.path.join(temp_dir, "my_hook.py") + save(os.path.join(temp_dir, "my_hook.py"), my_hook) output = TestBufferConanOutput() - plugin_manager = PluginManager(temp_dir, ["my_plugin"], output) - return plugin_manager, output, plugin_path + hook_manager = HookManager(temp_dir, ["my_hook"], output) + return hook_manager, output, hook_path def load_test(self): - plugin_manager, output, _ = self._init() - self.assertEqual({}, plugin_manager.plugins) - self.assertEqual(["my_plugin"], plugin_manager._plugin_names) - plugin_manager.load_plugins() - self.assertEqual(16, len(plugin_manager.plugins)) # Checks number of methods loaded + hook_manager, output, _ = self._init() + self.assertEqual({}, hook_manager.hooks) + self.assertEqual(["my_hook"], hook_manager._hook_names) + hook_manager.load_hooks() + self.assertEqual(16, len(hook_manager.hooks)) # Checks number of methods loaded def check_output_test(self): - plugin_manager, output, _ = self._init() - plugin_manager.load_plugins() - methods = plugin_manager.plugins.keys() + hook_manager, output, _ = self._init() + hook_manager.load_hooks() + methods = hook_manager.hooks.keys() for method in methods: - plugin_manager.execute(method) - self.assertIn("[PLUGIN - my_plugin] %s(): %s()" % (method, method), output) + hook_manager.execute(method) + self.assertIn("[HOOK - my_hook] %s(): %s()" % (method, method), output) def no_error_with_no_method_test(self): - plugin_manager, output, plugin_path = self._init() - other_plugin = """ + hook_manager, output, hook_path = self._init() + other_hook = """ def my_custom_function(): pass """ - save(plugin_path, other_plugin) - self.assertEqual(other_plugin, load(plugin_path)) - plugin_manager.execute("pre_source") + save(hook_path, other_hook) + self.assertEqual(other_hook, load(hook_path)) + hook_manager.execute("pre_source") self.assertEqual("", output) def exception_in_method_test(self): - plugin_manager, output, plugin_path = self._init() - my_plugin = """ + hook_manager, output, hook_path = self._init() + my_hook = """ from conans.errors import ConanException def pre_build(output, **kwargs): raise Exception("My custom exception") """ - save(plugin_path, my_plugin) + save(hook_path, my_hook) with self.assertRaisesRegexp(ConanException, "My custom exception"): - plugin_manager.execute("pre_build") + hook_manager.execute("pre_build") # Check traceback output try: - plugin_manager.execute("pre_build") + hook_manager.execute("pre_build") except ConanException as e: - self.assertIn("[PLUGIN - my_plugin] pre_build(): My custom exception", str(e)) + self.assertIn("[HOOK - my_hook] pre_build(): My custom exception", str(e)) diff --git a/conans/test/integration/plugin_test.py b/conans/test/integration/hook_test.py similarity index 57% rename from conans/test/integration/plugin_test.py rename to conans/test/integration/hook_test.py index 86eb1638784..e076a33a7e5 100644 --- a/conans/test/integration/plugin_test.py +++ b/conans/test/integration/hook_test.py @@ -12,7 +12,7 @@ class AConan(ConanFile): version = "0.1" """ -complete_plugin = """ +complete_hook = """ from conans.model.ref import ConanFileReference @@ -131,7 +131,7 @@ def post_download_package(output, conanfile_path, reference, package_id, remote, output.info("remote.name=%s" % remote.name) """ -HEADER = "[PLUGIN - complete_plugin] {method_name}():" +HEADER = "[HOOK - complete_hook] {method_name}():" REFERENCE_LOCAL = "basic/0.1@PROJECT" REFERENCE_CACHE = "basic/0.1@danimtb/testing" PACKAGE_ID = "5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9" @@ -141,7 +141,7 @@ def my_printer(output): output.info("my_printer(): CUSTOM MODULE") """ -my_plugin = """ +my_hook = """ from custom_module.custom import my_printer def pre_export(output, conanfile_path, reference, **kwargs): @@ -149,29 +149,29 @@ def pre_export(output, conanfile_path, reference, **kwargs): """ -class PluginTest(unittest.TestCase): +class HookTest(unittest.TestCase): - def default_plugin_test(self): + def default_hook_test(self): client = TestClient() - self.assertTrue(client.client_cache.plugins_path.endswith("plugins")) + self.assertTrue(client.client_cache.hooks_path.endswith("hooks")) client.save({"conanfile.py": conanfile_basic}) client.run("export . danimtb/testing") - self.assertIn("[PLUGIN - attribute_checker] pre_export(): WARN: Conanfile doesn't have 'url'", + self.assertIn("[HOOK - attribute_checker] pre_export(): WARN: Conanfile doesn't have 'url'", client.out) - self.assertIn("[PLUGIN - attribute_checker] pre_export(): WARN: Conanfile doesn't have " + self.assertIn("[HOOK - attribute_checker] pre_export(): WARN: Conanfile doesn't have " "'description'", client.out) - self.assertIn("[PLUGIN - attribute_checker] pre_export(): WARN: Conanfile doesn't have " + self.assertIn("[HOOK - attribute_checker] pre_export(): WARN: Conanfile doesn't have " "'license'", client.out) - def complete_plugin_test(self): + def complete_hook_test(self): server = TestServer([], users={"danimtb": "pass"}) client = TestClient(servers={"default": server}, users={"default": [("danimtb", "pass")]}) - plugin_path = os.path.join(client.client_cache.plugins_path, "complete_plugin.py") - client.save({plugin_path: complete_plugin, "conanfile.py": conanfile_basic}) + hook_path = os.path.join(client.client_cache.hooks_path, "complete_hook.py") + client.save({hook_path: complete_hook, "conanfile.py": conanfile_basic}) conanfile_path = os.path.join(client.current_folder, "conanfile.py") conanfile_cache_path = client.client_cache.conanfile( ConanFileReference("basic", "0.1", "danimtb", "testing")) - client.run("config set plugins.complete_plugin") + client.run("config set hooks.complete_hook") client.run("source .") self._check_source(conanfile_path, client.out) @@ -227,111 +227,111 @@ def complete_plugin_test(self): def _check_source(self, conanfile_path, out, in_cache=False): reference = REFERENCE_CACHE if in_cache else REFERENCE_LOCAL - self.assertIn("[PLUGIN - complete_plugin] pre_source(): conanfile_path=%s" % conanfile_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_source(): conanfile_path=%s" % conanfile_path, out) + self.assertIn("[HOOK - complete_hook] pre_source(): conanfile_path=%s" % conanfile_path, out) + self.assertIn("[HOOK - complete_hook] post_source(): conanfile_path=%s" % conanfile_path, out) if in_cache: - self.assertIn("[PLUGIN - complete_plugin] pre_source(): reference=%s" % reference, out) - self.assertIn("[PLUGIN - complete_plugin] post_source(): reference=%s" % reference, out) + self.assertIn("[HOOK - complete_hook] pre_source(): reference=%s" % reference, out) + self.assertIn("[HOOK - complete_hook] post_source(): reference=%s" % reference, out) def _check_build(self, conanfile_path, out, in_cache=False): reference = REFERENCE_CACHE if in_cache else REFERENCE_LOCAL if in_cache: - self.assertIn("[PLUGIN - complete_plugin] pre_build(): reference=%s" % reference, out) - self.assertIn("[PLUGIN - complete_plugin] pre_build(): package_id=%s" % PACKAGE_ID, out) - self.assertIn("[PLUGIN - complete_plugin] post_build(): reference=%s" % reference, out) - self.assertIn("[PLUGIN - complete_plugin] post_build(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] pre_build(): reference=%s" % reference, out) + self.assertIn("[HOOK - complete_hook] pre_build(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] post_build(): reference=%s" % reference, out) + self.assertIn("[HOOK - complete_hook] post_build(): package_id=%s" % PACKAGE_ID, out) else: - self.assertIn("[PLUGIN - complete_plugin] pre_build(): conanfile_path=%s" % conanfile_path, + self.assertIn("[HOOK - complete_hook] pre_build(): conanfile_path=%s" % conanfile_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_build(): conanfile_path=%s" % conanfile_path, + self.assertIn("[HOOK - complete_hook] post_build(): conanfile_path=%s" % conanfile_path, out) def _check_package(self, conanfile_path, out, in_cache=False): reference = REFERENCE_CACHE if in_cache else REFERENCE_LOCAL - self.assertIn("[PLUGIN - complete_plugin] pre_package(): conanfile_path=%s" % conanfile_path, + self.assertIn("[HOOK - complete_hook] pre_package(): conanfile_path=%s" % conanfile_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_package(): conanfile_path=%s" % conanfile_path, + self.assertIn("[HOOK - complete_hook] post_package(): conanfile_path=%s" % conanfile_path, out) if in_cache: - self.assertIn("[PLUGIN - complete_plugin] pre_package(): reference=%s" % reference, out) - self.assertIn("[PLUGIN - complete_plugin] pre_package(): package_id=%s" % PACKAGE_ID, out) - self.assertIn("[PLUGIN - complete_plugin] post_package(): reference=%s" % reference, out) - self.assertIn("[PLUGIN - complete_plugin] post_package(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] pre_package(): reference=%s" % reference, out) + self.assertIn("[HOOK - complete_hook] pre_package(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] post_package(): reference=%s" % reference, out) + self.assertIn("[HOOK - complete_hook] post_package(): package_id=%s" % PACKAGE_ID, out) def _check_export(self, conanfile_path, conanfile_cache_path, out): - self.assertIn("[PLUGIN - complete_plugin] pre_export(): conanfile_path=%s" % conanfile_path, out) - self.assertIn("[PLUGIN - complete_plugin] pre_export(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] post_export(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_export(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] pre_export(): conanfile_path=%s" % conanfile_path, out) + self.assertIn("[HOOK - complete_hook] pre_export(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] post_export(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] post_export(): reference=%s" % REFERENCE_CACHE, out) def _check_export_pkg(self, conanfile_cache_path, out): - self.assertIn("[PLUGIN - complete_plugin] pre_package(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] pre_package(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] pre_package(): package_id=%s" % PACKAGE_ID, out) - self.assertIn("[PLUGIN - complete_plugin] post_package(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_package(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] post_package(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] pre_package(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] pre_package(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] pre_package(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] post_package(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] post_package(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] post_package(): package_id=%s" % PACKAGE_ID, out) def _check_upload(self, conanfile_cache_path, out): - self.assertIn("[PLUGIN - complete_plugin] pre_upload(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] pre_upload(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] pre_upload(): remote.name=default", out) - self.assertIn("[PLUGIN - complete_plugin] post_upload(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_upload(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] post_upload(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] pre_upload(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] pre_upload(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] pre_upload(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] post_upload(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] post_upload(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] post_upload(): remote.name=default", out) def _check_upload_recipe(self, conanfile_cache_path, out): - self.assertIn("[PLUGIN - complete_plugin] pre_upload_recipe(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] pre_upload_recipe(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] pre_upload_recipe(): remote.name=default", out) - self.assertIn("[PLUGIN - complete_plugin] post_upload_recipe(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_upload_recipe(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] post_upload_recipe(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] pre_upload_recipe(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] pre_upload_recipe(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] pre_upload_recipe(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] post_upload_recipe(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] post_upload_recipe(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] post_upload_recipe(): remote.name=default", out) def _check_upload_package(self, conanfile_cache_path, out): - self.assertIn("[PLUGIN - complete_plugin] pre_upload_package(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] pre_upload_package(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] pre_upload_package(): package_id=%s" % PACKAGE_ID, out) - self.assertIn("[PLUGIN - complete_plugin] pre_upload_package(): remote.name=default", out) - self.assertIn("[PLUGIN - complete_plugin] post_upload_package(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_upload_package(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] post_upload_package(): package_id=%s" % PACKAGE_ID, out) - self.assertIn("[PLUGIN - complete_plugin] post_upload_package(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] pre_upload_package(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] pre_upload_package(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] pre_upload_package(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] pre_upload_package(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] post_upload_package(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] post_upload_package(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] post_upload_package(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] post_upload_package(): remote.name=default", out) def _check_download(self, conanfile_cache_path, out): - self.assertIn("[PLUGIN - complete_plugin] pre_download(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] pre_download(): remote.name=default", out) - self.assertIn("[PLUGIN - complete_plugin] post_download(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_download(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] post_download(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] pre_download(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] pre_download(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] post_download(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] post_download(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] post_download(): remote.name=default", out) def _check_download_recipe(self, conanfile_cache_path, out): - self.assertIn("[PLUGIN - complete_plugin] pre_download_recipe(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] pre_download_recipe(): remote.name=default", out) - self.assertIn("[PLUGIN - complete_plugin] post_download_recipe(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_download_recipe(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] post_download_recipe(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] pre_download_recipe(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] pre_download_recipe(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] post_download_recipe(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] post_download_recipe(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] post_download_recipe(): remote.name=default", out) def _check_download_package(self, conanfile_cache_path, out): - self.assertIn("[PLUGIN - complete_plugin] pre_download_package(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] pre_download_package(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] pre_download_package(): package_id=%s" % PACKAGE_ID, out) - self.assertIn("[PLUGIN - complete_plugin] pre_download_package(): remote.name=default", out) - self.assertIn("[PLUGIN - complete_plugin] post_download_package(): conanfile_path=%s" % conanfile_cache_path, out) - self.assertIn("[PLUGIN - complete_plugin] post_download_package(): reference=%s" % REFERENCE_CACHE, out) - self.assertIn("[PLUGIN - complete_plugin] post_download_package(): package_id=%s" % PACKAGE_ID, out) - self.assertIn("[PLUGIN - complete_plugin] post_download_package(): remote.name=default", out) - - def import_plugin_test(self): + self.assertIn("[HOOK - complete_hook] pre_download_package(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] pre_download_package(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] pre_download_package(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] pre_download_package(): remote.name=default", out) + self.assertIn("[HOOK - complete_hook] post_download_package(): conanfile_path=%s" % conanfile_cache_path, out) + self.assertIn("[HOOK - complete_hook] post_download_package(): reference=%s" % REFERENCE_CACHE, out) + self.assertIn("[HOOK - complete_hook] post_download_package(): package_id=%s" % PACKAGE_ID, out) + self.assertIn("[HOOK - complete_hook] post_download_package(): remote.name=default", out) + + def import_hook_test(self): client = TestClient() - plugin_path = os.path.join(client.client_cache.plugins_path, "my_plugin.py") - init_path = os.path.join(client.client_cache.plugins_path, "custom_module", "__init__.py") - custom_path = os.path.join(client.client_cache.plugins_path, "custom_module", "custom.py") - client.save({plugin_path: complete_plugin, + hook_path = os.path.join(client.client_cache.hooks_path, "my_hook.py") + init_path = os.path.join(client.client_cache.hooks_path, "custom_module", "__init__.py") + custom_path = os.path.join(client.client_cache.hooks_path, "custom_module", "custom.py") + client.save({hook_path: complete_hook, init_path: "", custom_path: custom_module, - plugin_path: my_plugin, + hook_path: my_hook, "conanfile.py": conanfile_basic}) - client.run("config set plugins.my_plugin") + client.run("config set hooks.my_hook") client.run("export . danimtb/testing") - self.assertIn("[PLUGIN - my_plugin] pre_export(): my_printer(): CUSTOM MODULE", client.out) + self.assertIn("[HOOK - my_hook] pre_export(): my_printer(): CUSTOM MODULE", client.out) diff --git a/conans/test/utils/tools.py b/conans/test/utils/tools.py index 0360250c955..51247a6eda6 100644 --- a/conans/test/utils/tools.py +++ b/conans/test/utils/tools.py @@ -29,7 +29,7 @@ from conans.client.conan_command_output import CommandOutputer from conans.client.conf import MIN_SERVER_COMPATIBLE_VERSION from conans.client.output import ConanOutput -from conans.client.plugin_manager import PluginManager +from conans.client.hook_manager import HookManager from conans.client.remote_registry import RemoteRegistry, dump_registry from conans.client.rest.conan_requester import ConanRequester from conans.client.rest.uploader_downloader import IterableToFileAdapter @@ -532,15 +532,15 @@ def _init_collaborators(self, user_io=None): self.requester = ConanRequester(requester, self.client_cache, get_request_timeout()) - self.plugin_manager = PluginManager(self.client_cache.plugins_path, - get_env("CONAN_PLUGINS", list()), - self.user_io.out) + self.hook_manager = HookManager(self.client_cache.hooks_path, + get_env("CONAN_HOOKS", list()), + self.user_io.out) self.localdb, self.rest_api_client, self.remote_manager = Conan.instance_remote_manager( self.requester, self.client_cache, self.user_io, self.client_version, self.min_server_compatible_version, - self.plugin_manager) + self.hook_manager) set_global_instances(output, self.requester) def init_dynamic_vars(self, user_io=None): @@ -561,7 +561,7 @@ def run(self, command_line, user_io=None, ignore_error=False): # Settings preprocessor interactive = not get_env("CONAN_NON_INTERACTIVE", False) conan = Conan(self.client_cache, self.user_io, self.runner, self.remote_manager, - self.plugin_manager, interactive=interactive) + self.hook_manager, interactive=interactive) outputer = CommandOutputer(self.user_io, self.client_cache) command = Command(conan, self.client_cache, self.user_io, outputer) args = shlex.split(command_line) From 19ad8e9a49da08e18b8db29883177cbac44209c8 Mon Sep 17 00:00:00 2001 From: danimtb Date: Mon, 29 Oct 2018 11:57:58 +0100 Subject: [PATCH 2/2] Migration from plugins to hooks --- conans/client/migrations.py | 10 +++ conans/test/test_migration_default_profile.py | 71 --------------- conans/test/test_migrations.py | 88 +++++++++++++++++++ 3 files changed, 98 insertions(+), 71 deletions(-) delete mode 100644 conans/test/test_migration_default_profile.py create mode 100644 conans/test/test_migrations.py diff --git a/conans/client/migrations.py b/conans/client/migrations.py index b47db7f2db7..6ed71d86b2d 100644 --- a/conans/client/migrations.py +++ b/conans/client/migrations.py @@ -2,6 +2,7 @@ import shutil from conans.client.client_cache import CONAN_CONF, PROFILES_FOLDER +from conans.client.tools import replace_in_file from conans.migrations import Migrator from conans.paths import EXPORT_SOURCES_DIR_OLD from conans.util.files import load, save, list_folder_subdirs @@ -109,6 +110,7 @@ def _make_migrations(self, old_version): cppstd: [None, 98, gnu98, 11, gnu11, 14, gnu14, 17, gnu17, 20, gnu20] """ self._update_settings_yml(old_settings) + migrate_plugins_to_hooks(self.client_cache) if old_version < Version("1.0"): _migrate_lock_files(self.client_cache, self.out) @@ -186,3 +188,11 @@ def migrate_c_src_export_source(client_cache, out): except Exception: out.warn("Migration: Can't remove the '%s' directory, " "remove it manually" % package_folder) + + +def migrate_plugins_to_hooks(client_cache): + plugins_path = os.path.join(client_cache.conan_folder, "plugins") + if os.path.exists(plugins_path): + os.rename(plugins_path, client_cache.hooks_path) + conf_path = client_cache.conan_conf_path + replace_in_file(conf_path, "[plugins]", "[hooks]", strict=False) diff --git a/conans/test/test_migration_default_profile.py b/conans/test/test_migration_default_profile.py deleted file mode 100644 index 7aa1891a132..00000000000 --- a/conans/test/test_migration_default_profile.py +++ /dev/null @@ -1,71 +0,0 @@ -import unittest -import os - -from conans.client.migrations import migrate_to_default_profile -from conans.test.utils.test_files import temp_folder -from conans.util.files import save, load - - -class TestMigrationToDefaultProfile(unittest.TestCase): - - def test_something(self): - tmp = temp_folder() - old_conf = """ -[general] -the old general - -[settings_defaults] -some settings - -[other_section] - -with other values - -""" - conf_path = os.path.join(tmp, "conan.conf") - default_profile_path = os.path.join(tmp, "conan_default") - save(conf_path, old_conf) - - migrate_to_default_profile(conf_path, default_profile_path) - - new_content = load(conf_path) - self.assertEquals(new_content, """ -[general] -the old general - -[other_section] - -with other values - -""") - - default_profile = load(default_profile_path) - self.assertEquals(default_profile, """[settings] -some settings""") - - old_conf = """ -[general] -the old general - -[settings_defaults] -some settings - -""" - conf_path = os.path.join(tmp, "conan.conf") - default_profile_path = os.path.join(tmp, "conan_default") - save(conf_path, old_conf) - - migrate_to_default_profile(conf_path, default_profile_path) - default_profile = load(default_profile_path) - self.assertEquals(default_profile, """[settings] -some settings""") - - new_content = load(conf_path) - self.assertEquals(new_content, """ -[general] -the old general - -""") - -if __name__ == '__main__': - unittest.main() diff --git a/conans/test/test_migrations.py b/conans/test/test_migrations.py new file mode 100644 index 00000000000..22ae13d683c --- /dev/null +++ b/conans/test/test_migrations.py @@ -0,0 +1,88 @@ +import unittest +import os + +from conans.client.migrations import migrate_to_default_profile, migrate_plugins_to_hooks +from conans.test.utils.test_files import temp_folder +from conans.test.utils.tools import TestClient +from conans.tools import save +from conans.util.files import load + + +class TestMigrations(unittest.TestCase): + + def migration_to_default_profile_test(self): + tmp = temp_folder() + old_conf = """ +[general] +the old general + +[settings_defaults] +some settings + +[other_section] + +with other values + +""" + conf_path = os.path.join(tmp, "conan.conf") + default_profile_path = os.path.join(tmp, "conan_default") + save(conf_path, old_conf) + + migrate_to_default_profile(conf_path, default_profile_path) + + new_content = load(conf_path) + self.assertEquals(new_content, """ +[general] +the old general + +[other_section] + +with other values + +""") + + default_profile = load(default_profile_path) + self.assertEquals(default_profile, """[settings] +some settings""") + + old_conf = """ +[general] +the old general + +[settings_defaults] +some settings + +""" + conf_path = os.path.join(tmp, "conan.conf") + default_profile_path = os.path.join(tmp, "conan_default") + save(conf_path, old_conf) + + migrate_to_default_profile(conf_path, default_profile_path) + default_profile = load(default_profile_path) + self.assertEquals(default_profile, """[settings] +some settings""") + + new_content = load(conf_path) + self.assertEquals(new_content, """ +[general] +the old general + +""") + + def migration_from_plugins_to_hooks_test(self): + old_user_home = temp_folder() + old_conan_folder = os.path.join(old_user_home, ".conan") + old_conf_path = os.path.join(old_conan_folder, "conan.conf") + old_attribute_checker_plugin = os.path.join(old_conan_folder, "plugins", + "attribute_checker.py") + save(old_conf_path, "\n[plugins] # CONAN_PLUGINS\nattribute_checker") + save(old_attribute_checker_plugin, "") + self.assertTrue(os.path.exists(old_attribute_checker_plugin)) + client_cache = TestClient(base_folder=old_user_home).client_cache + self.assertEqual(old_conan_folder, client_cache.conan_folder) + migrate_plugins_to_hooks(client_cache) + self.assertFalse(os.path.exists(old_attribute_checker_plugin)) + self.assertTrue(os.path.join(old_conan_folder, "hooks")) + conf_content = load(old_conf_path) + self.assertNotIn("[plugins]", conf_content) + self.assertIn("[hooks]", conf_content)