Skip to content

Commit

Permalink
Add venv setting and --venv command-line option
Browse files Browse the repository at this point in the history
Hook it up to the venv_path argument to resolve_depenedencies(), to
allow the user to control which venv FawltyDeps uses to map dependencies
into import names.

For now we only accept a single venv dir here, but this might change in
the near future.

TODO: Write tests to verify that setting the command-line/config option
has the desired effect.
  • Loading branch information
jherland committed Mar 14, 2023
1 parent 73c9359 commit 27404ba
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 2 deletions.
3 changes: 2 additions & 1 deletion fawltydeps/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ def create(cls, settings: Settings) -> "Analysis":
assert ret.imports is not None # convince Mypy that these cannot
assert ret.declared_deps is not None # be None at this time.
ret.resolved_deps = resolve_dependencies(
dep.name for dep in ret.declared_deps
(dep.name for dep in ret.declared_deps),
venv_path=settings.venv,
)

if ret.is_enabled(Action.REPORT_UNDECLARED):
Expand Down
11 changes: 11 additions & 0 deletions fawltydeps/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class Settings(BaseSettings): # type: ignore
actions: Set[Action] = {Action.REPORT_UNDECLARED, Action.REPORT_UNUSED}
code: Set[PathOrSpecial] = {Path(".")}
deps: Set[Path] = {Path(".")}
venv: Optional[Path] = None
output_format: OutputFormat = OutputFormat.HUMAN_SUMMARY
ignore_undeclared: Set[str] = set()
ignore_unused: Set[str] = set()
Expand Down Expand Up @@ -325,6 +326,16 @@ def populate_parser_options(parser: argparse._ActionsContainer) -> None:
" to looking for supported files in the current directory)"
),
)
parser.add_argument(
"--venv",
type=Path,
metavar="VENV_DIR",
help=(
"Where to find a virtualenv that has the project dependencies"
" installed, defaults to the Python environment where FawltyDeps is"
" installed."
),
)
parser.add_argument(
"--ignore-undeclared",
nargs="+",
Expand Down
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def lint(session):
session.run("pylint", "fawltydeps")
session.run(
"pylint",
"--disable=missing-function-docstring,invalid-name,redefined-outer-name",
"--disable=missing-function-docstring,invalid-name,redefined-outer-name,too-many-lines",
"tests",
)

Expand Down
23 changes: 23 additions & 0 deletions tests/test_cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def test_list_imports_json__from_py_file__prints_imports_from_file(write_tmp_fil
"actions": ["list_imports"],
"code": [f"{tmp_path}/myfile.py"],
"deps": ["."],
"venv": None,
"output_format": "json",
"ignore_undeclared": [],
"ignore_unused": [],
Expand Down Expand Up @@ -302,6 +303,7 @@ def test_list_deps_json__dir__prints_deps_from_requirements_txt(
"actions": ["list_deps"],
"code": ["."],
"deps": [f"{tmp_path}"],
"venv": None,
"output_format": "json",
"ignore_undeclared": [],
"ignore_unused": [],
Expand Down Expand Up @@ -565,6 +567,7 @@ def test_check_json__simple_project__can_report_both_undeclared_and_unused(
"actions": ["check_undeclared", "check_unused"],
"code": [f"{tmp_path}"],
"deps": [f"{tmp_path}"],
"venv": None,
"output_format": "json",
"ignore_undeclared": [],
"ignore_unused": [],
Expand Down Expand Up @@ -753,6 +756,25 @@ def test__quiet_check__writes_only_names_of_unused_and_undeclared(
assert returncode == 3


def test_check__simple_project_in_fake_venv__resolves_imports_vs_deps(
fake_venv, project_with_code_and_requirements_txt
):
tmp_path = project_with_code_and_requirements_txt(
imports=["requests"],
declares=["pandas"],
)
# A venv where the "pandas" package provides a "requests" import name
# should satisfy our comparison
venv_dir = fake_venv({"pandas": {"requests"}})

output, errors, returncode = run_fawltydeps(
"--detailed", f"--code={tmp_path}", f"--deps={tmp_path}", f"--venv={venv_dir}"
)
assert output.splitlines() == []
assert errors == ""
assert returncode == 0


@pytest.mark.parametrize(
"args,imports,dependencies,expected",
[
Expand Down Expand Up @@ -892,6 +914,7 @@ def test_cmdline_on_ignored_undeclared_option(
actions = ['list_imports']
# code = ['.']
deps = ['foobar']
# venv = None
output_format = 'human_detailed'
# ignore_undeclared = []
# ignore_unused = []
Expand Down
1 change: 1 addition & 0 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
actions={Action.REPORT_UNDECLARED, Action.REPORT_UNUSED},
code={Path(".")},
deps={Path(".")},
venv=None,
output_format=OutputFormat.HUMAN_SUMMARY,
ignore_undeclared=set(),
ignore_unused=set(),
Expand Down

0 comments on commit 27404ba

Please sign in to comment.