diff --git a/installers-conda/build_conda_pkgs.py b/installers-conda/build_conda_pkgs.py index cb0f62511ff..ffead8038f8 100644 --- a/installers-conda/build_conda_pkgs.py +++ b/installers-conda/build_conda_pkgs.py @@ -7,7 +7,6 @@ # Standard library imports import os import re -import sys from argparse import ArgumentParser, RawTextHelpFormatter from configparser import ConfigParser from datetime import timedelta @@ -19,7 +18,7 @@ # Third-party imports from git import Repo, rmtree -from ruamel.yaml import YAML +import ruamel.yaml as ry from setuptools_scm import get_version fmt = Formatter('%(asctime)s [%(levelname)s] [%(name)s] -> %(message)s') @@ -43,6 +42,9 @@ BUILD.mkdir(exist_ok=True) SPYPATCHFILE = BUILD / "installers-conda.patch" +yaml = ry.YAML(typ='jinja2') +yaml.indent(mapping=2, sequence=4, offset=2) + class BuildCondaPkg: """Base class for building a conda package for conda-based installer""" @@ -142,21 +144,26 @@ def patch_recipe(self): self.logger.info("Patching 'meta.yaml'...") file = self._fdstk_path / "recipe" / "meta.yaml" - meta = file.read_text() + meta_str = file.read_text() # Replace jinja variable values for k, v in self.data.items(): - meta = re.sub(f".*set {k} =.*", f'{{% set {k} = "{v}" %}}', meta) + meta_str = re.sub( + f".*set {k} =.*", f'{{% set {k} = "{v}" %}}', + meta_str + ) + + meta = yaml.load(meta_str) - # Replace source, but keep patches - meta = re.sub(r'^(source:\n)( (url|sha256):.*\n)*', - rf'\g<1> path: {self._bld_src.as_posix()}\n', - meta, flags=re.MULTILINE) + # Replace source url & sha256 with source path + meta["source"].pop("url", None) + meta["source"].pop("sha256", None) + meta["source"].insert(0, 'path', self._bld_src.as_posix()) meta = self._patch_meta(meta) file.rename(file.parent / ("_" + file.name)) # keep copy of original - file.write_text(meta) + yaml.dump(meta, file) self.logger.info(f"Patched 'meta.yaml' contents:\n{file.read_text()}") @@ -214,31 +221,34 @@ def _patch_source(self): file.write_text(file_text) def _patch_meta(self, meta): - # Get current Spyder requirements - yaml = YAML() - current_requirements = ['python'] - current_requirements += yaml.load( - REQ_MAIN.read_text())['dependencies'] - if os.name == 'nt': - win_requirements = yaml.load( - REQ_WINDOWS.read_text())['dependencies'] - current_requirements += win_requirements - current_requirements.append('ptyprocess >=0.5') - elif sys.platform == 'darwin': - mac_requirements = yaml.load( - REQ_MAC.read_text())['dependencies'] - if 'python.app' in mac_requirements: - mac_requirements.remove('python.app') - current_requirements += mac_requirements - else: - linux_requirements = yaml.load( - REQ_LINUX.read_text())['dependencies'] - current_requirements += linux_requirements - - # Replace run requirements - cr_string = '\n - '.join(current_requirements) - meta = re.sub(r'^(requirements:\n(.*\n)+ run:\n)( .*\n)+', - rf'\g<1> - {cr_string}\n', meta, flags=re.MULTILINE) + run_reqs = meta['requirements']['run'] + run_reqs.clear() + run_reqs.append('python') + + # Add current Spyder requirements + reqs = yaml.load(REQ_MAIN.read_text()) + run_reqs.extend(reqs['dependencies']) + + # Add current platform specific requirements + def append_dep_with_comment(dependency, comment): + _comment = ry.tokens.CommentToken( + f' # {comment}\n', ry.error.CommentMark(0), None + ) + key = len(run_reqs) + run_reqs.append(dependency) + run_reqs.ca.items[key] = [_comment, None, None, None] + + def append_deps_from_path_with_comment(path, comment): + reqs = yaml.load(path.read_text()) + for dep in reqs['dependencies']: + append_dep_with_comment(dep, comment) + + append_deps_from_path_with_comment(REQ_WINDOWS, '[win]') + append_dep_with_comment('ptyprocess >=0.5', '[win]') + append_deps_from_path_with_comment(REQ_MAC, '[osx]') + append_deps_from_path_with_comment(REQ_LINUX, '[linux]') + + run_reqs.sort() return meta @@ -325,9 +335,6 @@ class SpyderKernelsCondaPkg(BuildCondaPkg): logger.info(f"Building local conda packages {list(args.build)}...") t0 = time() - yaml = YAML() - yaml.indent(mapping=2, sequence=4, offset=2) - if SPECS.exists(): specs = yaml.load(SPECS.read_text()) else: