|
|
|
|
from pathlib import Path
|
|
|
|
|
from typing import Dict
|
|
|
|
|
|
|
|
|
|
from jinja2 import Template
|
|
|
|
|
from conan import ConanFile
|
|
|
|
|
from conan.tools.scm import Version
|
|
|
|
|
from conan.tools.files import save
|
|
|
|
|
from conan.tools.env.virtualrunenv import VirtualRunEnv
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PyCharmRunEnv:
|
|
|
|
|
def __init__(self, conanfile: ConanFile):
|
|
|
|
|
self.conanfile: ConanFile = conanfile
|
|
|
|
|
self.settings = self.conanfile.settings
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def _base_dir(self):
|
|
|
|
|
venv_name = f"{self.conanfile.name}_venv"
|
|
|
|
|
return Path("$PROJECT_DIR$", "build", "generators", venv_name)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def _py_interp(self):
|
|
|
|
|
if self.settings.os == "Windows":
|
|
|
|
|
py_interp = Path(
|
|
|
|
|
*[f'"{p}"' if " " in p else p for p in self._base_dir.joinpath("Scripts", "python.exe").parts])
|
|
|
|
|
return py_interp
|
|
|
|
|
return self._base_dir.joinpath("bin", "python")
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def _site_packages(self):
|
|
|
|
|
if self.settings.os == "Windows":
|
|
|
|
|
return self._base_dir.joinpath("Lib", "site-packages")
|
|
|
|
|
py_version = Version(self.conanfile.dependencies["cpython"].ref.version)
|
|
|
|
|
return self._base_dir.joinpath("lib", f"python{py_version.major}.{py_version.minor}", "site-packages")
|
|
|
|
|
|
|
|
|
|
def generate(self) -> None:
|
|
|
|
|
if self.conanfile.conan_data is None or "pycharm_targets" not in self.conanfile.conan_data:
|
|
|
|
|
# There are no _pycharm_targets in the conanfile for the package using this generator.
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Collect environment variables for use in the template
|
|
|
|
|
env = VirtualRunEnv(self.conanfile).environment()
|
|
|
|
|
env.prepend_path("PYTHONPATH", str(self._site_packages))
|
|
|
|
|
|
|
|
|
|
if hasattr(self.conanfile, f"_{self.conanfile.name}_run_env"):
|
|
|
|
|
project_run_env = getattr(self.conanfile, f"_{self.conanfile.name}_run_env")
|
|
|
|
|
if project_run_env:
|
|
|
|
|
env.compose_env(project_run_env) # TODO: Add logic for dependencies
|
|
|
|
|
|
|
|
|
|
# Create Pycharm run configuration from template for each target
|
|
|
|
|
run_folder = Path(self.conanfile.source_folder, ".run")
|
|
|
|
|
self.conanfile.output.info(f"Generating pycharm run targets in '{run_folder}'")
|
|
|
|
|
for target in self.conanfile.conan_data["pycharm_targets"]:
|
|
|
|
|
target["env_vars"] = env.vars(self.conanfile, scope="run")
|
|
|
|
|
target["sdk_path"] = str(self._py_interp)
|
|
|
|
|
if "parameters" not in target:
|
|
|
|
|
target["parameters"] = ""
|
|
|
|
|
|
|
|
|
|
with open(Path(self.conanfile.source_folder, target["jinja_path"]), "r") as f:
|
|
|
|
|
template = Template(f.read())
|
|
|
|
|
run_configuration = template.render(target)
|
|
|
|
|
save(self.conanfile, Path(run_folder, f"{target['name']}.run.xml"), run_configuration)
|