-
Notifications
You must be signed in to change notification settings - Fork 429
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
Update conda inspect channels
#5033
Changes from all commits
bf82c42
6b0efa7
db9691f
44f6c96
1a1ca4e
9c1100f
e5ba600
2e57946
fd96c8b
44222cf
432d5a4
423bc5f
c4745bb
bb4e818
e956c99
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,26 +4,24 @@ | |
|
||
import json | ||
import os | ||
import re | ||
import sys | ||
import tempfile | ||
from collections import defaultdict | ||
from functools import lru_cache | ||
from itertools import groupby | ||
from operator import itemgetter | ||
from os.path import abspath, basename, dirname, exists, join | ||
from pathlib import Path | ||
from tempfile import TemporaryDirectory | ||
from typing import Iterable, Literal | ||
|
||
from conda.api import Solver | ||
from conda.core.index import get_index | ||
from conda.core.prefix_data import PrefixData | ||
from conda.models.dist import Dist | ||
from conda.models.records import PrefixRecord | ||
from conda.resolve import MatchSpec | ||
|
||
from conda_build.conda_interface import ( | ||
display_actions, | ||
get_index, | ||
install_actions, | ||
linked_data, | ||
specs_from_args, | ||
) | ||
|
@@ -39,12 +37,14 @@ | |
ensure_list, | ||
get_logger, | ||
package_has_file, | ||
rm_rf, | ||
) | ||
|
||
from . import conda_interface | ||
from .deprecations import deprecated | ||
from .utils import on_mac, on_win | ||
|
||
log = get_logger(__name__) | ||
|
||
|
||
@deprecated("3.28.0", "4.0.0") | ||
@lru_cache(maxsize=None) | ||
|
@@ -110,23 +110,21 @@ def __str__(self): | |
untracked_package = _untracked_package() | ||
|
||
|
||
@deprecated.argument("24.1.0", "24.3.0", "platform", rename="subdir") | ||
@deprecated.argument("24.1.0", "24.3.0", "prepend") | ||
@deprecated.argument("24.1.0", "24.3.0", "minimal_hint") | ||
def check_install( | ||
packages, platform=None, channel_urls=(), prepend=True, minimal_hint=False | ||
): | ||
prefix = tempfile.mkdtemp("conda") | ||
try: | ||
specs = specs_from_args(packages) | ||
index = get_index( | ||
channel_urls=channel_urls, prepend=prepend, platform=platform, prefix=prefix | ||
) | ||
actions = install_actions( | ||
prefix, index, specs, pinned=False, minimal_hint=minimal_hint | ||
) | ||
display_actions(actions, index) | ||
return actions | ||
finally: | ||
rm_rf(prefix) | ||
return None | ||
packages: Iterable[str], | ||
subdir: str | None = None, | ||
channel_urls: Iterable[str] = (), | ||
) -> None: | ||
with TemporaryDirectory() as prefix: | ||
Solver( | ||
prefix, | ||
channel_urls, | ||
[subdir or conda_interface.subdir], | ||
specs_from_args(packages), | ||
).solve_for_transaction(ignore_pinned=True).print_transaction_summary() | ||
|
||
|
||
def print_linkages( | ||
|
@@ -190,61 +188,39 @@ def replace_path(binary, path, prefix): | |
return "not found" | ||
|
||
|
||
def test_installable(channel="defaults"): | ||
def test_installable(channel: str = "defaults") -> bool: | ||
success = True | ||
log = get_logger(__name__) | ||
has_py = re.compile(r"py(\d)(\d)") | ||
for platform in ["osx-64", "linux-32", "linux-64", "win-32", "win-64"]: | ||
log.info("######## Testing platform %s ########", platform) | ||
channels = [channel] | ||
index = get_index(channel_urls=channels, prepend=False, platform=platform) | ||
for _, rec in index.items(): | ||
# If we give channels at the command line, only look at | ||
# packages from those channels (not defaults). | ||
if channel != "defaults" and rec.get("schannel", "defaults") == "defaults": | ||
continue | ||
name = rec["name"] | ||
for subdir in ["osx-64", "linux-32", "linux-64", "win-32", "win-64"]: | ||
log.info("######## Testing subdir %s ########", subdir) | ||
for prec in get_index(channel_urls=[channel], prepend=False, platform=subdir): | ||
name = prec["name"] | ||
if name in {"conda", "conda-build"}: | ||
# conda can only be installed in the root environment | ||
continue | ||
if name.endswith("@"): | ||
elif name.endswith("@"): | ||
# this is a 'virtual' feature record that conda adds to the index for the solver | ||
# and should be ignored here | ||
continue | ||
# Don't fail just because the package is a different version of Python | ||
# than the default. We should probably check depends rather than the | ||
# build string. | ||
build = rec["build"] | ||
match = has_py.search(build) | ||
assert match if "py" in build else True, build | ||
if match: | ||
additional_packages = [f"python={match.group(1)}.{match.group(2)}"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where did There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I understood (and from my testing) this doesn't make a difference. The package already defines its Python dependency so theres no need for us to also define it here. This was actually prompted by the removal of the regex search on 183. Packages that do not follow the See |
||
else: | ||
additional_packages = [] | ||
|
||
version = rec["version"] | ||
version = prec["version"] | ||
log.info("Testing %s=%s", name, version) | ||
|
||
try: | ||
install_steps = check_install( | ||
[name + "=" + version] + additional_packages, | ||
channel_urls=channels, | ||
check_install( | ||
[f"{name}={version}"], | ||
channel_urls=[channel], | ||
prepend=False, | ||
platform=platform, | ||
subdir=subdir, | ||
) | ||
success &= bool(install_steps) | ||
except KeyboardInterrupt: | ||
raise | ||
# sys.exit raises an exception that doesn't subclass from Exception | ||
except BaseException as e: | ||
except Exception as err: | ||
kenodegard marked this conversation as resolved.
Show resolved
Hide resolved
|
||
success = False | ||
log.error( | ||
"FAIL: %s %s on %s with %s (%s)", | ||
"[%s/%s::%s=%s] %s", | ||
channel, | ||
subdir, | ||
name, | ||
version, | ||
platform, | ||
additional_packages, | ||
e, | ||
repr(err), | ||
) | ||
return success | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
### Enhancements | ||
|
||
* Update `conda inspect channels` to use updated solver/transaction logic. (#5033) | ||
|
||
### Bug fixes | ||
|
||
* <news item> | ||
|
||
### Deprecations | ||
|
||
* Mark `conda inspect channels --test-installable` as pending deprecation. (#5033) | ||
* Mark `conda_build.inspect_pkg.check_install(package)` as pending deprecation in favor of `conda_build.inspect_pkg.check_install(subdir)`. (#5033) | ||
* Mark `conda_build.inspect_pkg.check_install(prepend)` as pending deprecation. (#5033) | ||
* Mark `conda_build.inspect_pkg.check_install(minimal_hint)` as pending deprecation. (#5033) | ||
|
||
### Docs | ||
|
||
* <news item> | ||
|
||
### Other | ||
|
||
* <news item> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this use
KNOWN_SUBDIRS
inconda.somewhere.constants
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered this, but opted to leave that as a separate exercise since the primary goal was to stop using legacy solve stuff, not to fix
conda inspect channels
. Ideally this should be a customizable field from the CLI.