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

Replace sys.exit calls in conda_build/inspect_pkg.py #5393

Merged
merged 5 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
15 changes: 11 additions & 4 deletions conda_build/inspect_pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from conda.core.prefix_data import PrefixData
from conda.models.records import PrefixRecord

from .exceptions import CondaBuildUserError
from .os_utils.ldd import (
get_linkages,
get_package_obj_files,
Expand Down Expand Up @@ -219,9 +220,13 @@ def inspect_linkages(
sysroot: str = "",
) -> str:
if not packages and not untracked and not all_packages:
sys.exit("At least one package or --untracked or --all must be provided")
raise CondaBuildUserError(
"At least one package or --untracked or --all must be provided"
)
elif on_win:
sys.exit("Error: conda inspect linkages is only implemented in Linux and OS X")
raise CondaBuildUserError(
"`conda inspect linkages` is only implemented on Linux and macOS"
)

prefix = Path(prefix)
installed = {prec.name: prec for prec in PrefixData(str(prefix)).iter_records()}
Expand All @@ -237,7 +242,7 @@ def inspect_linkages(
if name == untracked_package:
obj_files = get_untracked_obj_files(prefix)
elif name not in installed:
sys.exit(f"Package {name} is not installed in {prefix}")
raise CondaBuildUserError(f"Package {name} is not installed in {prefix}")
else:
obj_files = get_package_obj_files(installed[name], prefix)

Expand Down Expand Up @@ -308,7 +313,9 @@ def inspect_objects(
groupby: str = "package",
):
if not on_mac:
sys.exit("Error: conda inspect objects is only implemented in OS X")
raise CondaBuildUserError(
"`conda inspect objects` is only implemented on macOS"
)

prefix = Path(prefix)
installed = {prec.name: prec for prec in PrefixData(str(prefix)).iter_records()}
Expand Down
5 changes: 3 additions & 2 deletions tests/cli/test_main_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from conda_build import api
from conda_build.cli import main_inspect
from conda_build.exceptions import CondaBuildUserError
from conda_build.utils import on_win

from ..utils import metadata_dir
Expand All @@ -23,7 +24,7 @@ def test_inspect_linkages(testing_workdir, capfd):
# get a package that has known object output
args = ["linkages", "python"]
if on_win:
with pytest.raises(SystemExit) as exc:
with pytest.raises(CondaBuildUserError) as exc:
main_inspect.execute(args)
assert "conda inspect linkages is only implemented in Linux and OS X" in exc
else:
Expand All @@ -36,7 +37,7 @@ def test_inspect_objects(testing_workdir, capfd):
# get a package that has known object output
args = ["objects", "python"]
if sys.platform != "darwin":
with pytest.raises(SystemExit) as exc:
with pytest.raises(CondaBuildUserError) as exc:
main_inspect.execute(args)
assert "conda inspect objects is only implemented in OS X" in exc
else:
Expand Down
5 changes: 3 additions & 2 deletions tests/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
import pytest

from conda_build import api
from conda_build.exceptions import CondaBuildUserError


def test_inspect_linkages():
if sys.platform == "win32":
with pytest.raises(SystemExit) as exc:
with pytest.raises(CondaBuildUserError) as exc:
out_string = api.inspect_linkages("python")
assert "conda inspect linkages is only implemented in Linux and OS X" in exc
else:
Expand All @@ -20,7 +21,7 @@ def test_inspect_linkages():

def test_inspect_objects():
if sys.platform != "darwin":
with pytest.raises(SystemExit) as exc:
with pytest.raises(CondaBuildUserError) as exc:
out_string = api.inspect_objects("python")
assert "conda inspect objects is only implemented in OS X" in exc
else:
Expand Down
28 changes: 26 additions & 2 deletions tests/test_inspect_pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@
import pytest
from conda.core.prefix_data import PrefixData

from conda_build.inspect_pkg import which_package
from conda_build.utils import on_win
from conda_build.exceptions import CondaBuildUserError
from conda_build.inspect_pkg import inspect_linkages, inspect_objects, which_package
from conda_build.utils import on_mac, on_win


def test_which_package(tmp_path: Path):
Expand Down Expand Up @@ -271,3 +272,26 @@ def test_which_package_battery(tmp_path: Path):

# missing files should return no packages
assert not len(list(which_package(tmp_path / "missing", tmp_path)))


def test_inspect_linkages_no_packages():
with pytest.raises(CondaBuildUserError):
inspect_linkages([])


@pytest.mark.skipif(not on_win, reason="inspect_linkages is available")
def test_inspect_linkages_on_win():
with pytest.raises(CondaBuildUserError):
inspect_linkages(["packages"])


@pytest.mark.skipif(on_win, reason="inspect_linkages is not available")
def test_inspect_linkages_not_installed():
with pytest.raises(CondaBuildUserError):
inspect_linkages(["not_installed_pkg"])


@pytest.mark.skipif(on_mac, reason="inspect_objects is only available on macOS")
def test_inspect_objects_not_on_mac():
with pytest.raises(CondaBuildUserError):
inspect_objects([])
38 changes: 31 additions & 7 deletions tests/test_post.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import pytest

import conda_build.utils
from conda_build import api, post
from conda_build.utils import (
get_site_packages,
Expand Down Expand Up @@ -138,7 +139,7 @@ def test_menuinst_validation_fails_bad_schema(testing_config, caplog, tmp_path):
assert "ValidationError" in captured_text


def test_menuinst_validation_fails_bad_json(testing_config, caplog, tmp_path):
def test_menuinst_validation_fails_bad_json(testing_config, monkeypatch, tmp_path):
"3rd check - non-parsable JSON fails validation"
recipe = Path(metadata_dir, "_menu_json_validation")
recipe_tmp = tmp_path / "_menu_json_validation"
Expand All @@ -147,13 +148,36 @@ def test_menuinst_validation_fails_bad_json(testing_config, caplog, tmp_path):
menu_json_contents = menu_json.read_text()
menu_json.write_text(menu_json_contents + "Make this an invalid JSON")

with caplog.at_level(logging.WARNING):
api.build(str(recipe_tmp), config=testing_config, notest=True)
# suspect caplog fixture may fail; use monkeypatch instead.
records = []

captured_text = caplog.text
assert "Found 'Menu/*.json' files but couldn't validate:" not in captured_text
assert "not a valid menuinst JSON document" in captured_text
assert "JSONDecodeError" in captured_text
class MonkeyLogger:
def __getattr__(self, name):
return self.warning

def warning(self, *args, **kwargs):
records.append((*args, kwargs))

monkeylogger = MonkeyLogger()

def get_monkey_logger(*args, **kwargs):
return monkeylogger

# For some reason it uses get_logger in the individual functions, instead of
# a module-level global that we could easily patch.
monkeypatch.setattr(conda_build.utils, "get_logger", get_monkey_logger)

api.build(str(recipe_tmp), config=testing_config, notest=True)

# without %s substitution
messages = [record[0] for record in records]

assert "Found 'Menu/*.json' files but couldn't validate: %s" not in messages
assert "'%s' is not a valid menuinst JSON document!" in messages
assert any(
isinstance(record[-1].get("exc_info"), json.JSONDecodeError)
for record in records
)


def test_file_hash(testing_config, caplog, tmp_path):
Expand Down
Loading