Skip to main content
Glama
conan_common.py5.57 kB
# Copyright (c) Meta Platforms, Inc. and affiliates. # # This source code is licensed under both the MIT license found in the # LICENSE-MIT file in the root directory of this source tree and the Apache # License, Version 2.0 found in the LICENSE-APACHE file in the root directory # of this source tree. import os import shutil import subprocess def _none(s): if not s or s == "_": return None else: return s def parse_reference(ref): """Parse a Conan package reference. These take the shape `name/version@channel/name#revision`. Omitted values or `_` are read as `None`. """ name = None version = None user = None channel = None revision = None if "#" in ref: ref, revision = ref.split("#", 1) if "@" in ref: ref, user_channel = ref.split("@", 1) if "/" in user_channel: user, channel = user_channel.split("/", 1) else: user = user_channel if "/" in ref: name, version = ref.split("/", 1) else: name = ref return _none(name), _none(version), _none(user), _none(channel), _none(revision) CONAN_DIR = ".conan" GENERATORS_DIR = "generators" STORE_DIR = "data" PACKAGE_DIR = "package" def conan_dir(user_home): """Conan folder under the Conen user home.""" return os.path.join(user_home, CONAN_DIR) def generators_dir(user_home): """Custom generators folder under the Conen user home.""" return os.path.join(conan_dir(user_home), "generators") def store_dir(user_home): """Store folder under the Conen user home.""" return os.path.join(conan_dir(user_home), "data") def reference_subtree(name, version, user, channel): """Package base directory subtree under the Conan store folder.""" return os.path.join(name or "_", version or "_", user or "_", channel or "_") def package_subtree(package_id): """Package directory subtree under the package base directory.""" return os.path.join(PACKAGE_DIR, package_id) def reference_dir(user_home, name, version, user, channel): """Package base directory under the Conan store folder.""" return os.path.join( store_dir(user_home), reference_subtree(name, version, user, channel) ) def package_dir(user_home, name, version, user, channel, package_id): """Package directory under the Conan store folder.""" return os.path.join( reference_dir(user_home, name, version, user, channel), package_subtree(package_id), ) def _copytree(src, dst): """Recursively copy the source directory tree to the destination. Copies symbolic links and ignores dangling symbolic links. """ shutil.copytree(src, dst, symlinks=True, ignore_dangling_symlinks=True) def install_user_home(user_home, base_user_home): """Copy the given base user-home to the current user-home.""" src = base_user_home dst = user_home _copytree(src, dst) def install_generator(user_home, generator_file): """Copy the given custom generator into the generators path. Note, this will overwrite any pre-existing generators. """ src = generator_file dstdir = generators_dir(user_home) dst = os.path.join(dstdir, "conanfile.py") os.makedirs(dstdir, exist_ok=True) shutil.copyfile(src, dst) def install_reference(user_home, reference, path): """Copy the cache directory of a given package reference into the store.""" name, version, user, channel, _ = parse_reference(reference) src = path dst = reference_dir(user_home, name, version, user, channel) _copytree(src, dst) def extract_reference(user_home, reference, output): """Copy the cache directory of the given package reference out of the store.""" name, version, user, channel, _ = parse_reference(reference) src = reference_dir(user_home, name, version, user, channel) dst = output _copytree(src, dst) def extract_package(user_home, reference, package_id, output): """Copy the package directory of the given package out of the store.""" name, version, user, channel, _ = parse_reference(reference) src = package_dir(user_home, name, version, user, channel, package_id) dst = output _copytree(src, dst) def conan_env(user_home=None, trace_log=None): """Generate environment variables needed to invoke Conan.""" env = dict(os.environ) if user_home is not None: # Set the Conan base directory. env["CONAN_USER_HOME"] = os.path.abspath(user_home) if trace_log is not None: # Enable Conan debug trace. env["CONAN_TRACE_FILE"] = os.path.abspath(trace_log) # TODO[AH] Enable Conan revisions for reproducibility # Enable Conan revisions for reproducibility # env["CONAN_REVISIONS_ENABLED"] = "1" # Prevent over-allocation. # TODO[AH] Support parallelized package builds and set an appropriate action # weight using the `weight` parameter to `ctx.actions.run`. # Note that not all Conan packages respect the `CONAN_CPU_COUNT` setting. env["CONAN_CPU_COUNT"] = "1" # Prevent interactive prompts. env["CONAN_NON_INTERACTIVE"] = "1" # Print every `self.run` invocation. # TODO[AH] Remove this debug output. env["CONAN_PRINT_RUN_COMMANDS"] = "1" # Disable the short paths feature on Windows. # TODO[AH] Enable if needed with a hermetic short path. env["CONAN_USER_HOME_SHORT"] = "None" return env def run_conan(conan, *args, env=None): return subprocess.check_call([conan] + list(args), env=env or {})

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server