Skip to content

Commit

Permalink
Fix cache zip and expanduser errors (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbertDeFusco authored May 27, 2023
1 parent fd46c32 commit db904e1
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 150 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ on:
- "docs/**"
branches:
- main


jobs:
package:
name: Build package
Expand Down Expand Up @@ -79,6 +81,9 @@ jobs:
shell: bash
run: |
./conda.exe create -p $HOME/miniconda conda=${{ matrix.conda-version }} python=${{ matrix.python-version }}
- name: Update with test dependencies
shell: bash
run: |
if [ $RUNNER_OS == 'Windows' ]; then
source $HOME/miniconda/Scripts/activate root && conda env update -f etc/test-environment.yml -p $HOME/miniconda && $HOME/miniconda/Scripts/pip install --no-deps .
else
Expand All @@ -98,6 +103,8 @@ jobs:
fi
- name: py.test
shell: bash
env:
CONDA_DEFAULT_CHANNELS: conda-forge
run: |
if [ $RUNNER_OS == 'Windows' ]; then
source $HOME/miniconda/Scripts/activate root && \
Expand Down
9 changes: 5 additions & 4 deletions src/conda_project/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class CondaProject:
"""

def __init__(self, directory: Union[Path, str] = "."):
self.directory = Path(directory).resolve()
self.directory = Path(directory).expanduser().resolve()
logger.info(f"created Project instance at {self.directory}")

self.project_yaml_path = find_file(self.directory, PROJECT_YAML_FILENAMES)
Expand Down Expand Up @@ -148,14 +148,15 @@ def from_archive(
):
"""Extra a conda-project archive and load the project"""

if isinstance(output_directory, str):
output_directory = Path(output_directory)
output_directory = Path(output_directory).expanduser()

storage_options = {} if storage_options is None else storage_options
protocol, _ = split_protocol(fn)
if protocol is not None:
options = {protocol: storage_options}
fn = f"simplecache::{fn}"
else:
fn = Path(fn).expanduser()
options = {}

files = fsspec.open_files(f"libarchive://**::{fn}", **options)
Expand Down Expand Up @@ -243,7 +244,7 @@ def init(
"""

directory = Path(directory).resolve()
directory = Path(directory).expanduser().resolve()
if not directory.exists():
directory.mkdir(parents=True)

Expand Down
35 changes: 35 additions & 0 deletions tests/test_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from conda_project.exceptions import CondaProjectError
from conda_project.project import CondaProject
from conda_project.utils import is_windows

ASSETS_DIR = Path(__file__).parents[0] / "assets"

Expand Down Expand Up @@ -123,3 +124,37 @@ def test_archive_storage_options(mocker):
assert mocked_open_files.call_args_list[0].kwargs == {
"file": {"key1": "valueA", "key2": "valueB"}
}
assert "simplecache" in mocked_open_files.call_args_list[0].args[0]


def test_archive_path_expanduser(mocker):
from pathlib import Path

expanduser = mocker.spy(Path, "expanduser")

archive = "~__a-conda-project-user__/project.tar.gz"
if is_windows():
with pytest.raises(FileNotFoundError):
_ = CondaProject.from_archive(fn=archive)
else:
with pytest.raises(RuntimeError):
_ = CondaProject.from_archive(fn=archive)

assert expanduser.call_count == 2


def test_archive_output_directory_expanduser(mocker):
from pathlib import Path

expanduser = mocker.spy(Path, "expanduser")

archive = ASSETS_DIR / "top-level-dir.tar.gz"

output_directory = "~__a-conda-project-user__/project"
if is_windows():
_ = CondaProject.from_archive(fn=archive, output_directory=output_directory)
assert expanduser.call_count == 3
else:
with pytest.raises(RuntimeError):
_ = CondaProject.from_archive(fn=archive, output_directory=output_directory)
assert expanduser.call_count == 1
188 changes: 188 additions & 0 deletions tests/test_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# Copyright (C) 2022 Anaconda, Inc
# SPDX-License-Identifier: BSD-3-Clause
import logging
import os
from textwrap import dedent

import pytest
from ruamel.yaml import YAML

from conda_project.exceptions import CondaProjectError
from conda_project.project import DEFAULT_PLATFORMS, CondaProject
from conda_project.utils import is_windows


def test_project_init_expanduser(mocker):
from pathlib import Path

expanduser = mocker.spy(Path, "expanduser")

project_directory = "~__a-conda-project-user__/project"

if is_windows():
_ = CondaProject(project_directory)
else:
with pytest.raises(RuntimeError):
_ = CondaProject(project_directory)

assert expanduser.call_count == 1


def test_project_init_new_directory(tmp_path, capsys):
project_directory = tmp_path / "new-project"
assert not os.path.exists(project_directory)

p = CondaProject.init(project_directory, lock_dependencies=False, verbose=True)

assert os.path.exists(project_directory)
assert p.project_yaml_path.exists()
assert p.default_environment.sources[0].exists()
assert not p.default_environment.is_locked

assert p.condarc.exists()
with p.condarc.open() as f:
condarc = YAML().load(f)
assert condarc == {}

out, _ = capsys.readouterr()
assert f"Project created at {project_directory}\n" == out


def test_project_init_twice(tmp_path, capsys):
_ = CondaProject.init(tmp_path, lock_dependencies=False)
p = CondaProject.init(tmp_path, lock_dependencies=False, verbose=True)

out, _ = capsys.readouterr()
assert f"Existing project file found at {p.project_yaml_path}.\n" == out


def test_project_init_default_platforms(tmp_path):
p = CondaProject.init(tmp_path, lock_dependencies=False)

with p.default_environment.sources[0].open() as f:
env = YAML().load(f)

assert env["platforms"] == list(DEFAULT_PLATFORMS)


def test_project_init_specific_platforms(tmp_path):
p = CondaProject.init(tmp_path, platforms=["linux-64"], lock_dependencies=False)

with p.default_environment.sources[0].open() as f:
env = YAML().load(f)

assert env["platforms"] == ["linux-64"]


def test_project_init_specific_channels(tmp_path):
p = CondaProject.init(
tmp_path,
dependencies=["python=3.8", "numpy"],
channels=["conda-forge", "defaults"],
lock_dependencies=False,
)

with p.default_environment.sources[0].open() as f:
env = YAML().load(f)

assert env["dependencies"] == ["python=3.8", "numpy"]
assert env["channels"] == ["conda-forge", "defaults"]


def test_project_init_default_channel(tmp_path):
p = CondaProject.init(
tmp_path, dependencies=["python=3.8", "numpy"], lock_dependencies=False
)

with p.default_environment.sources[0].open() as f:
env = YAML().load(f)

assert env["dependencies"] == ["python=3.8", "numpy"]
assert env["channels"] == ["defaults"]


def test_project_init_conda_configs(tmp_path):
p = CondaProject.init(
tmp_path,
dependencies=["python=3.8", "numpy"],
conda_configs=["experimental_solver=libmamba"],
lock_dependencies=False,
)

with p.condarc.open() as f:
condarc = YAML().load(f)

assert condarc["experimental_solver"] == "libmamba"


@pytest.mark.slow
def test_project_init_and_lock(tmp_path):
p = CondaProject.init(tmp_path, dependencies=["python=3.8"], lock_dependencies=True)
assert p.default_environment.lockfile.exists()
assert p.default_environment.lockfile == tmp_path / "conda-lock.default.yml"


def test_project_directory_expanduser(mocker):
from pathlib import Path

expanduser = mocker.spy(Path, "expanduser")

directory = "~__a-conda-project-user__/project"
if is_windows():
_ = CondaProject(directory)
else:
with pytest.raises(RuntimeError):
_ = CondaProject(directory)

assert expanduser.call_count == 1


def test_conda_project_init_empty_dir(tmp_path, caplog):
caplog.set_level(logging.INFO)

with pytest.raises(CondaProjectError) as excinfo:
CondaProject(tmp_path)
assert "No conda environment.yml or environment.yaml file was found" in str(
excinfo.value
)

assert "No conda-project.yml or conda-project.yaml file was found" in caplog.text


def test_conda_project_init_with_env_yaml(project_directory_factory):
env_yaml = dedent(
"""\
name: test
dependencies: []
"""
)
project_path = project_directory_factory(env_yaml=env_yaml)
project = CondaProject(project_path)

assert project.default_environment == project.environments["default"]

assert (
project.default_environment.lockfile
== project.directory / "conda-lock.default.yml"
)
assert project.default_environment.sources == (
(project.directory / "environment").with_suffix(
project_directory_factory._suffix
),
)
assert project.default_environment.prefix == project.directory / "envs" / "default"


def test_project_init_resolves_cwd(monkeypatch, project_directory_factory):
project_path = project_directory_factory(env_yaml="")
monkeypatch.chdir(project_path)

project = CondaProject()
assert project.directory.samefile(project_path)


def test_project_init_path(project_directory_factory):
project_path = project_directory_factory(env_yaml="")

project = CondaProject(project_path)
assert project.directory.samefile(project_path)
Loading

0 comments on commit db904e1

Please sign in to comment.