diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d5e48fb..a81d771 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,6 +1,6 @@ variables: - deps.space: 'conda requests xonsh lazyasd tqdm ruamel.yaml pytest pytest-timeout virtualenv pip pytest-azurepipelines' - deps.comma: 'conda,requests,xonsh,lazyasd,tqdm,ruamel.yaml,pytest,pytest-timeout,virtualenv,pip,pytest-azurepipelines' + deps.space: 'conda requests xonsh lazyasd tqdm ruamel.yaml pytest pytest-timeout virtualenv pip pytest-azurepipelines dataclasses' + deps.comma: 'conda,requests,xonsh,lazyasd,tqdm,ruamel.yaml,pytest,pytest-timeout,virtualenv,pip,pytest-azurepipelines,dataclasses' jobs: - job: windows diff --git a/conda_press/condatools.xsh b/conda_press/condatools.xsh index f9b5345..2d02122 100644 --- a/conda_press/condatools.xsh +++ b/conda_press/condatools.xsh @@ -644,9 +644,11 @@ class ArtifactInfo: with ${...}.swap(RAISE_SUBPROC_ERROR=True): ![strip --strip-all --preserve-dates --enable-deterministic-archives @(absname)] - def replace_symlinks(self, strip_symbols=self.config.strip_symbols): + def replace_symlinks(self, strip_symbols=None): # this is needed because of https://github.com/pypa/pip/issues/5919 # this has to walk the package deps in some cases. + if strip_symbols is None: + strip_symbols = self.config.strip_symbols for f in self.files: absname = os.path.join(self.artifactdir, f) if not os.path.islink(absname): @@ -770,7 +772,7 @@ def artifact_ref_dependency_tree_to_wheels(artifact_ref, config=None, seen=None) top_name = name_from_ref(artifact_ref) top_found = False - solver = Solver("", config.channels, subdirs=config.subdirs, specs_to_add=(artifact_ref,)) + solver = Solver("", config.channels, subdirs=config.subdir, specs_to_add=(artifact_ref,)) package_recs = solver.solve_final_state() if config.skip_python: diff --git a/conda_press/config.py b/conda_press/config.py index 34e3d6c..053bfdc 100644 --- a/conda_press/config.py +++ b/conda_press/config.py @@ -2,8 +2,7 @@ import platform import tempfile from dataclasses import dataclass, field -from pathlib import Path -from typing import List, Set +from typing import Union, List, Set, Tuple CACHE_DIR = os.path.join(tempfile.gettempdir(), "artifact-cache") DEFAULT_CHANNELS = ("conda-forge", "anaconda", "main", "r") @@ -20,11 +19,11 @@ @dataclass(init=True, repr=True, eq=True, order=False) class Config: - subdir: (str, tuple) - _subdir: tuple = field(init=False, repr=False) - output: (str, Path) = field(default=None) - _channels: List[str] = field(init=False, repr=False) - channels: List[str] = field(default=None) + subdir: Union[str, Tuple[str, ...]] + channels: List[str] + output: str = field(default=None) + _subdir: Tuple[str, ...] = field(init=False, repr=False) + _channels: List[str] = field(init=False, repr=False, default_factory=list) exclude_deps: Set[str] = field(default_factory=set) add_deps: Set[str] = field(default_factory=set) skip_python: bool = False @@ -43,14 +42,28 @@ def channels(self, list_channels: List[str]): self._channels = list_channels @property - def subdir(self) -> tuple: + def subdir(self) -> Tuple[str, ...]: return self._subdir + ("noarch",) @subdir.setter - def subdir(self, new_subdir: (tuple, str)): + def subdir(self, new_subdir: Union[Tuple[str, ...], str]): if isinstance(new_subdir, str): - new_subdir = (new_subdir,) - self._subdir = new_subdir + self._subdir = (new_subdir,) + else: + self._subdir = new_subdir - def clean_deps(self, list_deps): + def clean_deps(self, list_deps: Union[Set[str], List[str]]) -> Set[str]: + """This method is responsible to remove the excluded dependencies and + add the new dependencies in a list of dependencies received. + + Parameters + ---------- + list_deps : array_like + Receives a set or a list of dependencies + + Returns + ------- + set + Returns a set with the dependencies. + """ return set(list_deps).union(self.add_deps).difference(self.exclude_deps) diff --git a/setup.py b/setup.py index 761d963..2b3f601 100755 --- a/setup.py +++ b/setup.py @@ -30,8 +30,8 @@ def main(): package_dir={'conda_press': 'conda_press'}, package_data={'conda_press': ['*.xsh']}, scripts=scripts, - install_requires=['xonsh', 'lazyasd', 'ruamel.yaml', 'tqdm', 'requests'], - python_requires=">=3.5", + install_requires=['xonsh', 'lazyasd', 'ruamel.yaml', 'tqdm', 'requests', 'dataclasses'], + python_requires=">=3.6", zip_safe=False, ) setup(**skw) diff --git a/tests/test_config.py b/tests/test_config.py index 253b289..5d52c45 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,10 +1,12 @@ -from conda_press.config import Config +import pytest +from conda_press.config import Config -def test_fields(tmpdir): - config_press = Config( - subdir=str(tmpdir), - output=str(tmpdir), +@pytest.fixture +def config_obj(tmpdir): + return Config( + subdir="SUBDIR", + output="OUTPUT", channels=["FOO-CHANNEL", "CHANNEL2"], fatten=True, skip_python=True, @@ -15,17 +17,27 @@ def test_fields(tmpdir): only_pypi=True, include_requirements=False, ) + + +def test_fields(config_obj): assert ( - config_press.channels.sort() + config_obj.channels.sort() == ["FOO-CHANNEL", "conda-forge", "anaconda", "main", "r"].sort() ) - assert config_press.subdir == (str(tmpdir), "noarch") - assert config_press.output == str(tmpdir) - assert config_press.fatten - assert config_press.skip_python - assert not config_press.strip_symbols - assert config_press.merge - assert config_press.exclude_deps == {"EXCLUDE1", "EXCLUDE2"} - assert config_press.add_deps == {"ADD1", "ADD2"} - assert config_press.only_pypi - assert not config_press.include_requirements + assert config_obj.subdir == ("SUBDIR", "noarch") + assert config_obj.output == "OUTPUT" + assert config_obj.fatten + assert config_obj.skip_python + assert not config_obj.strip_symbols + assert config_obj.merge + assert config_obj.exclude_deps == {"EXCLUDE1", "EXCLUDE2"} + assert config_obj.add_deps == {"ADD1", "ADD2"} + assert config_obj.only_pypi + assert not config_obj.include_requirements + + +def test_clean_deps(config_obj): + config_obj.add_deps = {"DEP1", "DEP2", "DEP3", "DEP4"} + config_obj.exclude_deps = {"DEP2", "DEP4"} + all_deps = ["DEP0", "DEP1", "DEP2", "DEP5"] + assert config_obj.clean_deps(all_deps) == {"DEP0", "DEP1", "DEP3", "DEP5"}