Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion constructor/nsis/main.nsi.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1638,8 +1638,8 @@ Section "Install"
SetOutPath "{{ env.conda_meta }}"
File "{{ env.history_abspath }}"

# Add frozen marker file if configured
{%- if env.frozen_abspath %}
# Add frozen marker file if configured
SetOutPath "{{ env.conda_meta }}"
File "{{ env.frozen_abspath }}"
{%- endif %}
Expand Down
11 changes: 8 additions & 3 deletions examples/protected_base/construct.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ specs:
- python
- conda

freeze_base:
conda: {}

extra_envs:
default:
env1:
specs:
- python
- pip
- conda
freeze_env:
conda:
message: This environment is frozen.

extra_files:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Currently, your construct.yaml file is the one that's broken. It would be much nicer if you committed the one that's working to the repository and then add this later for the negative test case.

- frozen.json: conda-meta/frozen
- frozen.json: envs/default/conda-meta/frozen
- frozen.json: envs/env2/conda-meta/frozen
2 changes: 1 addition & 1 deletion examples/protected_base/frozen.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{}
{"message": "This env is frozen via extra_files."}
61 changes: 37 additions & 24 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from conda.core.prefix_data import PrefixData
from conda.models.version import VersionOrder as Version
from ruamel.yaml import YAML
from contextlib import nullcontext

from constructor.utils import (
StandaloneExe,
Expand Down Expand Up @@ -1509,32 +1510,44 @@ def test_not_in_installed_menu_list_(tmp_path, request, no_registry):
CONDA_EXE == StandaloneExe.CONDA
and check_version(CONDA_EXE_VERSION, min_version="25.5.0", max_version="25.7.0")
),
reason="conda-standalone 25.5.x fails with protected environments and older versions ignore frozen files",
reason="conda-standalone 25.5.x fails with protected environments",
strict=True,
)
def test_frozen_environment(tmp_path, request):
input_path = _example_path("protected_base")
for installer, install_dir in create_installer(input_path, tmp_path):
_run_installer(
input_path,
installer,
install_dir,
request=request,
uninstall=False,
)
@pytest.mark.parametrize(
"has_conflict",
(
pytest.param(True, id="with-conflict"),
pytest.param(False, id="without-conflict"),
),
)
def test_frozen_environment(tmp_path, request, has_conflict):
example_path = _example_path("protected_base")
input_path = tmp_path / "input"

expected_frozen_paths = {
install_dir / "conda-meta" / "frozen",
install_dir / "envs" / "default" / "conda-meta" / "frozen",
}
context = pytest.raises(subprocess.CalledProcessError) if has_conflict else nullcontext()

actual_frozen_paths = set()
for env in install_dir.glob("**/conda-meta/history"):
frozen_file = env.parent / "frozen"
assert frozen_file.exists()
actual_frozen_paths.add(frozen_file)
shutil.copytree(str(example_path), str(input_path))

assert expected_frozen_paths == actual_frozen_paths, (
f"Expected: {sorted(str(p) for p in expected_frozen_paths)}\n"
f"Found: {sorted(str(p) for p in actual_frozen_paths)}"
)
with open(input_path / "construct.yaml") as f:
config = YAML().load(f)

if has_conflict:
config.setdefault("extra_files", []).append({"frozen.json": "conda-meta/frozen"})
with open(input_path / "construct.yaml", "w") as f:
YAML().dump(config, f)

with context as c:
for installer, install_dir in create_installer(input_path, tmp_path):
_run_installer(input_path, installer, install_dir, request=request, uninstall=False)

expected_frozen = {
install_dir / "conda-meta" / "frozen": config["freeze_base"]["conda"],
install_dir / "envs" / "env1" / "conda-meta" / "frozen": config["extra_envs"]["env1"]["freeze_env"]["conda"],
}

for frozen_path, expected_content in expected_frozen.items():
assert frozen_path.exists()
assert json.loads(frozen_path.read_text()) == expected_content

if has_conflict:
assert all(s in c.value.stderr for s in ("RuntimeError", "freeze_base / freeze_env", "extra_files", "base"))
Loading