Skip to content

Commit

Permalink
feat: Add ability to specify create command and disable environment c…
Browse files Browse the repository at this point in the history
…reation (#69)

* Add ability to specify create command and disable environment creation

* Add another test

* Update README.md and tweak help output

* Fix type
  • Loading branch information
mattkram authored May 10, 2024
1 parent 83103c6 commit 7875255
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ An example usage is shown below:
--internal-pip-index-url=https://pypi.anaconda.org/my-organization/simple,
--internal-pip-package=my-private-package,
--internal-pip-package=my-other-private-package,
--create-command="make setup", # Default value
--environment-selector="-p ./env", # Default value
--disable-environment-creation # Creation enabled by default
]
```

Expand Down
2 changes: 2 additions & 0 deletions environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ dependencies:
- pytest=7.4.0
# renovate: datasource=conda depName=main/pytest-cov
- pytest-cov=4.1.0
# renovate: datasource=conda depName=main/pytest-mock
- pytest-mock=3.10.0
- pip:
# renovate: datasource=pypi
- cog==0.9.7
Expand Down
21 changes: 17 additions & 4 deletions src/anaconda_pre_commit_hooks/add_renovate_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

import typer

DEFAULT_ENVIRONMENT_SELECTOR = "-p ./env"
DEFAULT_CREATE_COMMAND = "make setup"

CondaOrPip = str
PackageName = str
PackageVersion = str
Expand Down Expand Up @@ -66,8 +69,8 @@ def list_packages_in_conda_environment(environment_selector: str) -> list[dict]:

def load_dependencies(
project_directory: Optional[Path] = None,
create_command: str = "make setup",
environment_selector: str = "-p ./env",
create_command: Optional[str] = DEFAULT_CREATE_COMMAND,
environment_selector: str = DEFAULT_ENVIRONMENT_SELECTOR,
) -> Dependencies:
"""Load the dependencies from a live conda environment.
Expand All @@ -80,7 +83,8 @@ def load_dependencies(
An object containing all dependencies in the installed environment, split between conda and pip packages.
"""
setup_conda_environment(create_command, cwd=project_directory or Path.cwd())
if create_command is not None:
setup_conda_environment(create_command, cwd=project_directory or Path.cwd())

data = list_packages_in_conda_environment(environment_selector)

Expand Down Expand Up @@ -213,6 +217,11 @@ def cli(
env_files: list[Path],
internal_pip_package: Annotated[Optional[list[str]], typer.Option()] = None,
internal_pip_index_url: Annotated[str, typer.Option()] = "",
create_command: Annotated[str, typer.Option()] = DEFAULT_CREATE_COMMAND,
environment_selector: Annotated[str, typer.Option()] = DEFAULT_ENVIRONMENT_SELECTOR,
disable_environment_creation: Annotated[
bool, typer.Option("--disable-environment-creation")
] = False,
) -> None:
# Construct a mapping of package name to index URL based on CLI options
pip_index_overrides = parse_pip_index_overrides(
Expand All @@ -223,7 +232,11 @@ def cli(
# `make setup` for each file, and only once per project.
project_dirs = sorted({env_file.parent for env_file in env_files})
for project_dir in project_dirs:
deps = load_dependencies(project_dir)
deps = load_dependencies(
project_dir,
create_command=create_command if not disable_environment_creation else None,
environment_selector=environment_selector,
)
project_env_files = (e for e in env_files if e.parent == project_dir)
for env_file in project_env_files:
add_comments_to_env_file(
Expand Down
39 changes: 35 additions & 4 deletions tests/test_generate_renovate_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@

import pytest
import yaml
from anaconda_pre_commit_hooks import add_renovate_annotations
from anaconda_pre_commit_hooks.add_renovate_annotations import (
Dependencies,
Dependency,
add_comments_to_env_file,
cli,
load_dependencies,
parse_pip_index_overrides,
setup_conda_environment,
)

# Mock out subprocess run for all tests
pytestmark = pytest.mark.usefixtures("mock_subprocess_run")

DEFAULT_FILES_REGEX_STRING = r"environment[\w-]*\.ya?ml"

ENVIRONMENT_YAML = dedent("""\
Expand Down Expand Up @@ -113,7 +118,7 @@ def mock_subprocess_run(monkeypatch):
old_subprocess_run = subprocess.run

def f(args, *posargs, **kwargs):
if args == ["make", "setup"]:
if args == ["make", "setup"] or args[:3] == ["conda", "env", "create"]:
return subprocess.CompletedProcess(
args,
0,
Expand Down Expand Up @@ -156,13 +161,11 @@ def f(args, *posargs, **kwargs):
monkeypatch.setattr(subprocess, "run", f)


@pytest.mark.usefixtures("mock_subprocess_run")
def test_setup_conda_environment():
result = setup_conda_environment("make setup")
assert result is None


@pytest.mark.usefixtures("mock_subprocess_run")
def test_load_dependencies():
dependencies = load_dependencies(Path.cwd())
assert dependencies == Dependencies(
Expand All @@ -171,7 +174,6 @@ def test_load_dependencies():
)


@pytest.mark.usefixtures("mock_subprocess_run")
def test_add_comments_to_env_file(tmp_path):
env_file_path = tmp_path / "environment.yml"
with env_file_path.open("w") as fp:
Expand Down Expand Up @@ -208,3 +210,32 @@ def test_add_comments_to_env_file(tmp_path):
- -e .
name: some-environment-name
""")


def test_disable_environment_creation(mocker):
mock = mocker.spy(add_renovate_annotations, "setup_conda_environment")
load_dependencies(create_command=None)
assert mock.call_count == 0


def test_cli_disable_environment_creation(tmp_path, mocker):
env_file_path = tmp_path / "environment.yml"
with env_file_path.open("w") as fp:
fp.write(ENVIRONMENT_YAML)

mock = mocker.spy(add_renovate_annotations, "setup_conda_environment")
cli(env_files=[env_file_path], disable_environment_creation=True)
assert mock.call_count == 0


def test_cli_override_create_command(tmp_path, mocker):
env_file_path = tmp_path / "environment.yml"
with env_file_path.open("w") as fp:
fp.write(ENVIRONMENT_YAML)

mock = mocker.spy(add_renovate_annotations, "setup_conda_environment")
create_command = "conda env create -n some-environment-name -f environment.yml"
cli(env_files=[env_file_path], create_command=create_command)
assert mock.call_count == 1
args, kwargs = mock.call_args
assert args[0] == create_command

1 comment on commit 7875255

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage

Coverage Report
FileStmtsMissCoverMissing
src/anaconda_pre_commit_hooks
   __init__.py00100% 
   add_renovate_annotations.py1181190%49–52, 63–65, 111, 145, 154, 169
tests
   test_generate_renovate_annotations.py810100% 
TOTAL1991194% 

Please sign in to comment.