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

Update conda inspect channels #5033

Merged
merged 15 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from 12 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: 7 additions & 9 deletions conda_build/cli/main_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,10 @@ def parse_args(args):
"--test-installable",
"-t",
action="store_true",
help="""Test every package in the channel to see if it is installable
by conda.""",
help=(
"DEPRECATED. This is the default (and only) behavior. "
"Test every package in the channel to see if it is installable by conda."
),
)
channels.add_argument(
"channel",
Expand Down Expand Up @@ -184,13 +186,9 @@ def execute(args):

if not args.subcommand:
parser.print_help()
exit()

sys.exit(0)
elif args.subcommand == "channels":
if not args.test_installable:
parser.error("At least one option (--test-installable) is required.")
else:
print(api.test_installable(args.channel))
print(api.test_installable(args.channel))
elif args.subcommand == "linkages":
print(
api.inspect_linkages(
Expand Down Expand Up @@ -219,7 +217,7 @@ def execute(args):
elif args.subcommand == "hash-inputs":
pprint(api.inspect_hash_inputs(args.packages))
else:
raise ValueError(f"Unrecognized subcommand: {args.subcommand}.")
parser.error(f"Unrecognized subcommand: {args.subcommand}.")


@deprecated("3.26.0", "4.0.0", addendum="Use `conda inspect` instead.")
Expand Down
96 changes: 36 additions & 60 deletions conda_build/inspect_pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
Expand All @@ -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)
Expand Down Expand Up @@ -110,23 +110,21 @@ def __str__(self):
untracked_package = _untracked_package()


@deprecated.argument("3.28.0", "4.0.0", "platform", rename="subdir")
@deprecated.argument("3.28.0", "4.0.0", "prepend")
@deprecated.argument("3.28.0", "4.0.0", "minimal_hint")
kenodegard marked this conversation as resolved.
Show resolved Hide resolved
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(
Expand Down Expand Up @@ -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"]:
Copy link
Contributor

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 in conda.somewhere.constants?

Copy link
Contributor Author

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.

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)}"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Where did additional_packages go? Can you explain why is it being removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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 pyNN build string pattern fails (e.g. https://anaconda.org/conda-test/itsdangerous/files).

See conda inpsect channels conda-test --test-installable.

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

Expand Down
22 changes: 22 additions & 0 deletions news/5033-update-conda-inspect-channels
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>
Loading