Skip to content
Open
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
13 changes: 13 additions & 0 deletions src/envoic/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ def scan(
include_dotenv=include_dotenv,
include_artifacts=include_artifacts,
)
if show_artifacts and not include_artifacts:
typer.echo(
Copy link
Contributor

Choose a reason for hiding this comment

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

@Riyaa-Bajpai please intent the statements

"Error: --show-artifacts cannot be used together with --no-artifacts.",
err=True,
)
raise typer.Exit(code=1)
Comment on lines +177 to +182
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical indentation bug — every scan invocation is broken

The typer.echo(...) and raise typer.Exit(code=1) lines are not indented inside the if block. Python raises an IndentationError here (confirmed by the Ruff invalid-syntax hint), so the module cannot even be imported and the entire CLI is non-functional.

Even if the indentation were accepted, both statements would execute unconditionally — every call to scan would print the error and exit with code 1.

Additionally, the guard fires after _build_scan_result() has already completed a full filesystem scan. Moving it above the scan call avoids wasted work.

🐛 Proposed fix
 ) -> None:
     """Scan a filesystem path for Python environments."""
+    if show_artifacts and not include_artifacts:
+        typer.echo(
+            "Error: --show-artifacts cannot be used together with --no-artifacts.",
+            err=True,
+        )
+        raise typer.Exit(code=1)
+
     result = _build_scan_result(
         path,
         depth,
         deep=deep,
         stale_days=stale_days,
         include_dotenv=include_dotenv,
         include_artifacts=include_artifacts,
     )
-    if show_artifacts and not include_artifacts:
-    typer.echo(
-        "Error: --show-artifacts cannot be used together with --no-artifacts.",
-        err=True,
-    )
-    raise typer.Exit(code=1)
🧰 Tools
🪛 Ruff (0.15.1)

[warning] 178-178: Expected an indented block after if statement

(invalid-syntax)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/envoic/cli.py` around lines 177 - 182, The indentation around the
artifact-guard is wrong and the check runs (or causes a syntax error) after the
scan; move and fix it so the condition if show_artifacts and not
include_artifacts: encloses both typer.echo(...) and raise typer.Exit(code=1),
and relocate this entire if-block to run before calling _build_scan_result() so
the CLI doesn't perform the full filesystem scan when the incompatible flags are
provided; ensure the variables show_artifacts and include_artifacts are used
exactly as named and that the typer.echo and raise typer.Exit are indented to be
inside that if block.


if json_output:
typer.echo(json.dumps(to_serializable_dict(result), indent=2))
Expand Down Expand Up @@ -373,6 +379,13 @@ def clean(
yes=yes,
)

def test_conflicting_artifact_flags_error():
Copy link
Contributor

Choose a reason for hiding this comment

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

@Riyaa-Bajpai move the test to /tests directory

result = runner.invoke(
app,
["scan", "--show-artifacts", "--no-artifacts"],
)
assert result.exit_code != 0
assert "cannot be used together" in result.output.lower()
Comment on lines +382 to +388
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

runner is undefined — NameError at test runtime; test belongs in a dedicated test file

Three issues with this test:

  1. NameError: runner is referenced on line 383 but is never imported or instantiated in cli.py. The test will raise NameError: name 'runner' is not defined immediately. A typer.testing.CliRunner instance must be created (and typically the import added).

  2. Test in production module: test_conflicting_artifact_flags_error is defined directly in cli.py. This couples test infrastructure to production code and is non-idiomatic. It should live in a dedicated test file (e.g., tests/test_cli.py).

  3. Stderr vs stdout assertion: The error is emitted with err=True (stderr). The assertion checks result.output (stdout). This works only when the CliRunner is created with mix_stderr=True (the default), but is fragile and should be explicit — or the assertion should use result.stderr when the runner is configured with mix_stderr=False.

🛠️ Proposed fix (move to a test file)

In tests/test_cli.py:

+from typer.testing import CliRunner
+from envoic.cli import app
+
+runner = CliRunner()
+
+
+def test_conflicting_artifact_flags_error():
+    result = runner.invoke(
+        app,
+        ["scan", "--show-artifacts", "--no-artifacts"],
+    )
+    assert result.exit_code != 0
+    assert "cannot be used together" in result.output
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/envoic/cli.py` around lines 382 - 388, The test function
test_conflicting_artifact_flags_error should be moved out of production module
and into a proper test file (e.g., tests/test_cli.py); in that test file import
typer.testing.CliRunner and the app symbol from src.envoic.cli, create a
CliRunner instance (explicitly set mix_stderr=True or False), invoke the app
with ["scan", "--show-artifacts", "--no-artifacts"], and assert non-zero
exit_code and that the error text is checked against result.stderr if you set
mix_stderr=False (or result.output if you keep mix_stderr=True); finally remove
the test function from src/envoic/cli.py to avoid runtime NameError from
undefined runner.


def main() -> None:
"""Console-script entrypoint."""
Expand Down