Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store lockfile-relative sources in lockfiles #328

Merged
Merged
Show file tree
Hide file tree
Changes from 5 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
16 changes: 10 additions & 6 deletions conda_lock/conda_lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,15 +808,15 @@ def create_lockfile_from_spec(
for dep in deps:
locked[(dep.manager, dep.name, dep.platform)] = dep

spec_sources: Dict[str, pathlib.Path] = {}
meta_sources: Dict[str, pathlib.Path] = {}
for source in spec.sources:
try:
path = relative_path(lockfile_path.parent, source)
except ValueError as e:
if "Paths don't have the same drive" not in str(e):
raise e
path = str(source.resolve())
spec_sources[path] = source
meta_sources[path] = source

if MetadataOption.TimeStamp in metadata_choices:
time_metadata = TimeMeta.create()
Expand All @@ -841,10 +841,10 @@ def create_lockfile_from_spec(

if metadata_choices & {MetadataOption.InputSha, MetadataOption.InputMd5}:
inputs_metadata: Optional[Dict[str, InputMeta]] = {
relative_path: InputMeta.create(
meta_src: InputMeta.create(
metadata_choices=metadata_choices, src_file=src_file
)
for relative_path, src_file in spec_sources.items()
for meta_src, src_file in meta_sources.items()
}
else:
inputs_metadata = None
Expand All @@ -857,7 +857,7 @@ def create_lockfile_from_spec(
content_hash=spec.content_hash(),
channels=[c for c in spec.channels],
platforms=spec.platforms,
sources=[str(source.resolve()) for source in spec.sources],
sources=list(meta_sources.keys()),
git_metadata=git_metadata,
time_metadata=time_metadata,
inputs_metadata=inputs_metadata,
Expand Down Expand Up @@ -1055,7 +1055,11 @@ def run_lock(
lock_content = parse_conda_lock_file(lockfile_path)
# reconstruct native paths
locked_environment_files = [
pathlib.Path(
pathlib.Path(p)
# absolute paths could be locked for both flavours
if pathlib.PurePosixPath(p).is_absolute()
or pathlib.PureWindowsPath(p).is_absolute()
else pathlib.Path(
pathlib.PurePosixPath(lockfile_path).parent
/ pathlib.PurePosixPath(p)
)
Expand Down
8 changes: 8 additions & 0 deletions tests/test-source-paths/sources/environment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
channels:
- conda-forge
platforms:
- linux-64
dependencies:
- python ==3.9.6
- pydantic ==1.7
- flask <2
30 changes: 30 additions & 0 deletions tests/test_conda_lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,36 @@ def test_run_lock_with_locked_environment_files(
]


@pytest.fixture
def source_paths(tmp_path: Path) -> Path:
return clone_test_dir("test-source-paths", tmp_path)


def test_run_lock_relative_source_path(
monkeypatch: "pytest.MonkeyPatch", source_paths: Path, conda_exe: str
):
"""run_lock() stores and restores lockfile-relative source paths"""
source_paths.joinpath("lockfile").mkdir()
monkeypatch.chdir(source_paths)
environment = Path("sources/environment.yaml")
lockfile = Path("lockfile/conda-lock.yml")
run_lock([environment], lockfile_path=lockfile, conda_exe="mamba")
lock_content = parse_conda_lock_file(lockfile)
locked_environment = lock_content.metadata.sources[0]
assert Path(locked_environment) == Path("../sources/environment.yaml")
make_lock_files = MagicMock()
monkeypatch.setattr("conda_lock.conda_lock.make_lock_files", make_lock_files)
run_lock(
DEFAULT_FILES, lockfile_path=lockfile, conda_exe=conda_exe, update=["pydantic"]
)
if sys.version_info < (3, 8):
# backwards compat
src_files = make_lock_files.call_args_list[0][1]["src_files"]
else:
src_files = make_lock_files.call_args.kwargs["src_files"]
assert [p.resolve() for p in src_files] == [environment.resolve()]


def test_run_lock_with_pip(
monkeypatch: "pytest.MonkeyPatch", pip_environment: Path, conda_exe: str
):
Expand Down