Skip to content

Commit b839854

Browse files
authored
Support GIT packages through conda-lock (#48)
* Support GIT packages through conda-lock This will now build packages coming from GIT just like in the pure PYPI path. * Black
1 parent e2b07ee commit b839854

File tree

2 files changed

+56
-28
lines changed

2 files changed

+56
-28
lines changed

metaflow_extensions/netflix_ext/plugins/conda/resolvers/conda_lock_resolver.py

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
# pyright: strict, reportTypeCommentUsage=false, reportMissingTypeStubs=false
2-
import json
32
import os
4-
import subprocess
5-
import sys
63
import tempfile
7-
import uuid
84

95
from itertools import chain
106
from typing import Dict, List, Optional, Set, Tuple, cast
117

8+
from urllib.parse import urlparse
129
from metaflow.debug import debug
13-
from metaflow.metaflow_config import CONDA_LOCAL_PATH
1410

1511
from metaflow._vendor.packaging.requirements import Requirement
1612

@@ -27,14 +23,14 @@
2723

2824
from ..utils import (
2925
CondaException,
30-
WithDir,
3126
arch_id,
3227
channel_or_url,
3328
parse_explicit_url_conda,
3429
parse_explicit_url_pypi,
3530
pypi_tags_from_arch,
3631
)
3732
from . import Resolver
33+
from .pip_resolver import _FAKE_WHEEL
3834

3935

4036
class CondaLockResolver(Resolver):
@@ -204,8 +200,13 @@ def resolve(
204200
for pypi_name, info in pypi_dep_lines.items():
205201
if "url" in info:
206202
toml_lines.append(
207-
'"%s" = {url = "%s", %s source="pypi"}\n'
208-
% (pypi_name, info["url"], info["url_extras"])
203+
'"%s" = {%s = "%s", %s source="pypi"}\n'
204+
% (
205+
pypi_name,
206+
"git" if info["url"].startswith("git+") else "url",
207+
info["url"],
208+
info["url_extras"],
209+
)
209210
)
210211
else:
211212
toml_lines.append(
@@ -298,6 +299,34 @@ def resolve(
298299
raise CondaException(
299300
"Unexpected package specification line: %s" % l
300301
)
302+
debug.conda_exec("Got PYPI package %s" % l)
303+
if components[4].startswith("git+"):
304+
# This is a GIT URL so we have to build the package
305+
# See pip_resolver.py for vcs_info on an explanation
306+
# on how we deal with git packages
307+
# Looks like gi+https://<url>@<commit>
308+
base_build_url = components[4]
309+
parse = urlparse(base_build_url)
310+
clean_path, clean_commit = parse.path.split("@")
311+
clean_url = parse.scheme[4:] + parse.netloc + clean_path
312+
base_pkg_url = "%s/%s" % (clean_url, clean_commit)
313+
# TODO: Do we need to handle subdirectories
314+
cache_base_url = (
315+
PypiCachePackage.make_partial_cache_url(
316+
base_pkg_url, is_real_url=False
317+
)
318+
)
319+
packages_to_build[cache_base_url] = PackageToBuild(
320+
base_build_url,
321+
PypiPackageSpecification(
322+
_FAKE_WHEEL,
323+
base_pkg_url,
324+
is_real_url=False,
325+
url_format=".whl",
326+
),
327+
)
328+
continue
329+
# Non-GIT URL
301330
parse_result = parse_explicit_url_pypi(components[4])
302331
if parse_result.url_format != ".whl":
303332
cache_base_url = (
@@ -375,27 +404,24 @@ def resolve(
375404
supported_tags = pypi_tags_from_arch(
376405
python_version, architecture, glibc_version
377406
)
378-
if self._conda.storage:
379-
built_pypi_packages, builder_envs = build_pypi_packages(
380-
self._conda,
381-
self._conda.storage,
382-
python_version,
383-
packages_to_build,
384-
builder_envs,
385-
build_dir,
386-
architecture,
387-
supported_tags,
388-
sources.get("pypi", []),
389-
)
390-
packages.extend(built_pypi_packages)
391-
else:
392-
# Here it was just URLs so we are good
393-
packages.extend(
394-
[
395-
cast(PackageSpecification, v.spec)
396-
for v in packages_to_build.values()
397-
]
407+
if not self._conda.storage:
408+
raise CondaException(
409+
"Cannot create a relocatable environment as it depends on "
410+
"local files or non wheels and no storage backend is defined: %s"
411+
% ", ".join([v.url for v in packages_to_build.values()])
398412
)
413+
built_pypi_packages, builder_envs = build_pypi_packages(
414+
self._conda,
415+
self._conda.storage,
416+
python_version,
417+
packages_to_build,
418+
builder_envs,
419+
build_dir,
420+
architecture,
421+
supported_tags,
422+
sources.get("pypi", []),
423+
)
424+
packages.extend(built_pypi_packages)
399425
return (
400426
ResolvedEnvironment(
401427
deps,

metaflow_extensions/netflix_ext/plugins/conda/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,10 @@ def parse_explicit_url_pypi(url: str) -> ParseExplicitResult:
362362
# - the URL (without the hash)
363363
# - the format for the URL
364364
# - the hash
365+
365366
url_clean, temp_url_hash = url.rsplit("#", 1)
366367
url_hash: Optional[str] = temp_url_hash
368+
367369
if url_hash:
368370
if not url_hash.startswith("sha256="):
369371
raise CondaException("URL '%s' has a SHA type which is not supported" % url)

0 commit comments

Comments
 (0)