|
1 | 1 | # pyright: strict, reportTypeCommentUsage=false, reportMissingTypeStubs=false
|
2 |
| -import json |
3 | 2 | import os
|
4 |
| -import subprocess |
5 |
| -import sys |
6 | 3 | import tempfile
|
7 |
| -import uuid |
8 | 4 |
|
9 | 5 | from itertools import chain
|
10 | 6 | from typing import Dict, List, Optional, Set, Tuple, cast
|
11 | 7 |
|
| 8 | +from urllib.parse import urlparse |
12 | 9 | from metaflow.debug import debug
|
13 |
| -from metaflow.metaflow_config import CONDA_LOCAL_PATH |
14 | 10 |
|
15 | 11 | from metaflow._vendor.packaging.requirements import Requirement
|
16 | 12 |
|
|
27 | 23 |
|
28 | 24 | from ..utils import (
|
29 | 25 | CondaException,
|
30 |
| - WithDir, |
31 | 26 | arch_id,
|
32 | 27 | channel_or_url,
|
33 | 28 | parse_explicit_url_conda,
|
34 | 29 | parse_explicit_url_pypi,
|
35 | 30 | pypi_tags_from_arch,
|
36 | 31 | )
|
37 | 32 | from . import Resolver
|
| 33 | +from .pip_resolver import _FAKE_WHEEL |
38 | 34 |
|
39 | 35 |
|
40 | 36 | class CondaLockResolver(Resolver):
|
@@ -204,8 +200,13 @@ def resolve(
|
204 | 200 | for pypi_name, info in pypi_dep_lines.items():
|
205 | 201 | if "url" in info:
|
206 | 202 | 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 | + ) |
209 | 210 | )
|
210 | 211 | else:
|
211 | 212 | toml_lines.append(
|
@@ -298,6 +299,34 @@ def resolve(
|
298 | 299 | raise CondaException(
|
299 | 300 | "Unexpected package specification line: %s" % l
|
300 | 301 | )
|
| 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 |
301 | 330 | parse_result = parse_explicit_url_pypi(components[4])
|
302 | 331 | if parse_result.url_format != ".whl":
|
303 | 332 | cache_base_url = (
|
@@ -375,27 +404,24 @@ def resolve(
|
375 | 404 | supported_tags = pypi_tags_from_arch(
|
376 | 405 | python_version, architecture, glibc_version
|
377 | 406 | )
|
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()]) |
398 | 412 | )
|
| 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) |
399 | 425 | return (
|
400 | 426 | ResolvedEnvironment(
|
401 | 427 | deps,
|
|
0 commit comments