diff --git a/conda_forge_tick/make_migrators.py b/conda_forge_tick/make_migrators.py index 6d3667cab..ba8c176fb 100644 --- a/conda_forge_tick/make_migrators.py +++ b/conda_forge_tick/make_migrators.py @@ -64,6 +64,7 @@ PyPIOrgMigrator, Replacement, RUCRTCleanup, + CDTMigrator, StaticLibMigrator, StdlibMigrator, UpdateCMakeArgsMigrator, diff --git a/conda_forge_tick/migrators/__init__.py b/conda_forge_tick/migrators/__init__.py index d4ffa5aa1..ff0193d98 100644 --- a/conda_forge_tick/migrators/__init__.py +++ b/conda_forge_tick/migrators/__init__.py @@ -39,6 +39,7 @@ from .pip_wheel_dep import PipWheelMigrator from .pypi_org import PyPIOrgMigrator from .r_ucrt import RUCRTCleanup +from .cdt import CDTMigrator from .recipe_v1 import CombineV1ConditionsMigrator from .replacement import Replacement, MiniReplacement from .use_pip import PipMigrator diff --git a/conda_forge_tick/migrators/cdt.py b/conda_forge_tick/migrators/cdt.py new file mode 100644 index 000000000..905319031 --- /dev/null +++ b/conda_forge_tick/migrators/cdt.py @@ -0,0 +1,128 @@ +import re +import typing +from typing import Any +import textwrap + +from conda_forge_tick.contexts import ClonedFeedstockContext, FeedstockContext +from conda_forge_tick.migrators.core import Migrator +from conda_forge_tick.os_utils import pushd + +cdt_mapping = { + 'libx11-devel': 'xorg-libx11', + 'libxext-devel': 'xorg-libxext', + 'libxrender-devel': 'xorg-libxrender', + 'libdrm-devel': 'libdrm', + 'libxcomposite-devel': 'xorg-libxcomposite', + 'libxcursor-devel': 'xorg-libxcursor', + 'libxdamage': 'xorg-libxdamage', + 'libxfixes': 'xorg-libxfixes', + 'libxscrnsaver-devel': 'xorg-libxscrnsaver', + 'libxtst-devel': 'xorg-libxtst', + 'libxxf86vm': 'xorg-libxxf86vm', + 'libselinux-devel': 'libselinux-devel', + 'xorg-x11-proto-devel': 'xorgproto', + 'libxrender': 'xorg-libxrender', + 'libxext': 'xorg-libxext', + 'libsm-devel': 'xorg-libsm', + 'mesa-libgbm': 'libgl-devel', + 'mesa-libgl-devel': 'libgl-devel', + 'mesa-dri-drivers': 'libgl-devel', + 'mesa-libegl-devel': 'libgl-devel', + 'libselinux': 'libselinux', + 'libglvnd-opengl': 'libglvnd-opengl', + 'libxcb': 'libxcb', + 'libxau': 'xorg-libxau', + 'systemd-devel': 'systemd-devel', + 'libudev': 'libudev', + 'libudev-devel': 'libudev-devel', + 'numactl-devel': 'numactl-devel', + 'pciutils-devel': 'pciutils-devel', + 'libxi-devel': 'xorg-libxi', + 'libxrandr-devel': 'xorg-librandr', + 'libuuid': 'libuuid', + 'alsa-lib-devel': 'alsa-lib-devel', + 'gtk2-devel': 'gtk2-devel' +} + +def _replace_cdts(yaml): + + def replacer(match): + package = match.group(1).strip() + return cdt_mapping.get(package, package) + + pattern = re.compile(r"\{\{\s*cdt\('([^']+)'\)\s*\}\}") + replaced_yaml = pattern.sub(replacer, yaml) + return replaced_yaml + +class CDTMigrator(Migrator): + """Description""" + + name = "CDT Migrator" + rerender = True + migrator_version = 1 + + def filter_not_in_migration(self, attrs, not_bad_str_start=""): + if super().filter_not_in_migration(attrs, not_bad_str_start): + return True + + # we need to check if there is any cdt package as dependency + requirements = attrs.get("requirements", {}) + + rq = ( + requirements.get("build", set()) + | requirements.get("host", set()) + | requirements.get("run", set()) + | requirements.get("test", set()) + ) + needed = False + + for k in ctd_mapping.keys(): + if k in requirements: + needed = True + break + + return (not needed) + #return len(rq & self.packages) == 0 + + def migrate(self, recipe_dir: str, attrs: "AttrsTypedDict", **kwargs: Any) -> None: + with pushd(recipe_dir): + with open("meta.yaml") as fp: + yaml = fp.read() + + yaml = _replace_cdts(yaml) + + # Rewrite the recipe file + with open("meta.yaml", "w") as fp: + fp.write(yaml) + + # TODO: remove duplicate libgl entries + + + def pr_body( + self, feedstock_ctx: ClonedFeedstockContext, add_label_text: bool = True + ) -> str: + body = super().pr_body(feedstock_ctx) + body = body.format( + textwrap.dedent( + """\ + +""", + ) + ) + return body + + def commit_message(self, feedstock_ctx) -> str: + return "Migrate CDT dependencies to regular feedstocks" + + def pr_title(self, feedstock_ctx) -> str: + return "Migrate CDT dependencies to regular feedstocks" + + def remote_branch(self, feedstock_ctx) -> str: + return f"{self.name}-migration-{self.migrator_version}" + + def migrator_uid(self, attrs): + if self.name is None: + raise ValueError("name is None") + n = super().migrator_uid(attrs) + n["name"] = self.name + return n \ No newline at end of file diff --git a/tests/test_cdt.py b/tests/test_cdt.py new file mode 100644 index 000000000..901da07d5 --- /dev/null +++ b/tests/test_cdt.py @@ -0,0 +1,255 @@ +import networkx as nx + +from test_migrators import run_test_migration + +from conda_forge_tick.migrators import CDTMigrator, Version + +TOTAL_GRAPH = nx.DiGraph() +TOTAL_GRAPH.graph["outputs_lut"] = {} +cdt_migrator = CDTMigrator(total_graph = TOTAL_GRAPH) + +freecad_recipe = """\ +{% set name = "freecad" %} +{% set version = "1.0.0" %} +{% set build_number = 4 %} +{% set build_number = build_number + 500 %} # [FEATURE_DEBUG] + +package: + name: {{ name }} + version: {{ version }} + +source: + url: https://github.com/FreeCAD/FreeCAD/releases/download/{{ version }}/freecad_source.tar.gz + sha256: b5af251615eeab3905b2aa5fbd432cf90c57b86f9ba2a50ca23c9cc1703f81d9 + patches: + - patches/osx_arm64_cross_compiling.patch # [osx and arm64] + - patches/py313.patch + +build: + number: {{ build_number }} + script_env: + - USE_QT6=1 + +requirements: + build: + - python # [build_platform != target_platform] + - cross-python_{{ target_platform }} # [build_platform != target_platform] + - pybind11 # [build_platform != target_platform] + - {{ compiler("cxx") }} + - {{ stdlib("c") }} + - libgl-devel # [linux] + - xorg-libselinux # [linux] + - xorg-libxdamage # [linux] + - xorg-libxfixes # [linux] + - xorg-libxxf86vm # [linux] + - xorg-libxcb # [linux] + - xorg-libxext # [linux] + - xorg-x11-server-xvfb # [linux] + - xorg-libxau # [linux] + - xorg-libxi # [linux] + - cmake + - swig + - ninja + - sed # [unix] + - qt6-main # [build_platform != target_platform] + - noqt5 # [build_platform != target_platform] + - doxygen + host: + - coin3d + - eigen + - freetype + - hdf5 + - libboost-devel + - libspnav # [linux] + - matplotlib-base + - noqt5 + - occt + - pcl + - pivy + - ply + - pybind11 + - pyside6 + - python + - qt6-main + - six + - smesh + - tbb-devel # [win] + - vtk + - xerces-c + - xorg-xproto # [linux] + - yaml-cpp + - zlib + run: + - graphviz + - gmsh + - libspnav # [linux] + - numpy + - python + - pyside6 + - pivy + - pyyaml + - ply + - six + +test: + commands: + - freecadcmd -t 0 # [unix and build_platform == target_platform] + +about: + home: https://www.freecad.org/ + license: LGPL-2.1-or-later + license_family: LGPL + license_file: LICENSE + summary: 'FreeCAD is a parametric 3D modeler made primarily to design real-life objects of any size. ' + description: | + FreeCAD is a general purpose feature-based, parametric 3D modeler for + CAD, MCAD, CAx, CAE and PLM, aimed directly at mechanical engineering + and product design but also fits a wider range of uses in engineering, + such as architecture or other engineering specialties. It is 100% Open + Source (LGPL2+ license) and extremely modular, allowing for very + advanced extension and customization. + FreeCAD is based on OpenCASCADE, a powerful geometry kernel, features an + Open Inventor-compliant 3D scene representation model provided by the + Coin 3D library, and a broad Python API. The interface is built with Qt. + FreeCAD runs exactly the same way on Windows, Mac OSX, BSD and Linux + platforms. + doc_url: https://wiki.freecad.org/Main_Page + dev_url: https://github.com/FreeCAD/FreeCAD + +extra: + recipe-maintainers: + - adrianinsaval + - looooo +""" # noqa + +freecad_recipe_correct = """\ +{% set name = "freecad" %} +{% set version = "1.0.0" %} +{% set build_number = 4 %} +{% set build_number = build_number + 500 %} # [FEATURE_DEBUG] + +package: + name: {{ name }} + version: {{ version }} + +source: + url: https://github.com/FreeCAD/FreeCAD/releases/download/{{ version }}/freecad_source.tar.gz + sha256: b5af251615eeab3905b2aa5fbd432cf90c57b86f9ba2a50ca23c9cc1703f81d9 + patches: + - patches/osx_arm64_cross_compiling.patch # [osx and arm64] + - patches/py313.patch + +build: + number: {{ build_number }} + script_env: + - USE_QT6=1 + +requirements: + build: + - python # [build_platform != target_platform] + - cross-python_{{ target_platform }} # [build_platform != target_platform] + - pybind11 # [build_platform != target_platform] + - {{ compiler("cxx") }} + - {{ stdlib("c") }} + - {{ cdt('mesa-libgl-devel') }} # [linux] + - {{ cdt('mesa-dri-drivers') }} # [linux] + - {{ cdt('mesa-libegl-devel') }} # [linux] + - {{ cdt('libselinux') }} # [linux] + - {{ cdt('libxdamage') }} # [linux] + - {{ cdt('libxfixes') }} # [linux] + - {{ cdt('libxxf86vm') }} # [linux] + - {{ cdt('libxcb') }} # [linux] + - {{ cdt('libxext') }} # [linux] + - {{ cdt('xorg-x11-server-xvfb') }} # [linux] + - {{ cdt('libxau') }} # [linux] + - {{ cdt('libxi-devel') }} # [linux] + - cmake + - swig + - ninja + - sed # [unix] + - qt6-main # [build_platform != target_platform] + - noqt5 # [build_platform != target_platform] + - doxygen + host: + - coin3d + - eigen + - freetype + - hdf5 + - libboost-devel + - libspnav # [linux] + - matplotlib-base + - noqt5 + - occt + - pcl + - pivy + - ply + - pybind11 + - pyside6 + - python + - qt6-main + - six + - smesh + - tbb-devel # [win] + - vtk + - xerces-c + - xorg-xproto # [linux] + - yaml-cpp + - zlib + run: + - graphviz + - gmsh + - libspnav # [linux] + - numpy + - python + - pyside6 + - pivy + - pyyaml + - ply + - six + +test: + commands: + - freecadcmd -t 0 # [unix and build_platform == target_platform] + +about: + home: https://www.freecad.org/ + license: LGPL-2.1-or-later + license_family: LGPL + license_file: LICENSE + summary: 'FreeCAD is a parametric 3D modeler made primarily to design real-life objects of any size. ' + description: | + FreeCAD is a general purpose feature-based, parametric 3D modeler for + CAD, MCAD, CAx, CAE and PLM, aimed directly at mechanical engineering + and product design but also fits a wider range of uses in engineering, + such as architecture or other engineering specialties. It is 100% Open + Source (LGPL2+ license) and extremely modular, allowing for very + advanced extension and customization. + FreeCAD is based on OpenCASCADE, a powerful geometry kernel, features an + Open Inventor-compliant 3D scene representation model provided by the + Coin 3D library, and a broad Python API. The interface is built with Qt. + FreeCAD runs exactly the same way on Windows, Mac OSX, BSD and Linux + platforms. + doc_url: https://wiki.freecad.org/Main_Page + dev_url: https://github.com/FreeCAD/FreeCAD + +extra: + recipe-maintainers: + - adrianinsaval + - looooo +""" # noqa + + +def test_cdt(tmp_path): + run_test_migration( + m=cdt_migrator, + inp=freecad_recipe, + output=freecad_recipe_correct, + prb="Dependencies have been updated if changed", + kwargs={"new_version": "1.0.0"}, + mr_out={ + "migrator_name": Version.name, + "migrator_version": Version.migrator_version, + "version": "1.0.0", + }, + tmp_path=tmp_path, + )