Skip to content

Handle conflicting --show-artifacts and --no-artifacts flags#21

Open
Riyaa-Bajpai wants to merge 2 commits intomahimailabs:mainfrom
Riyaa-Bajpai:main
Open

Handle conflicting --show-artifacts and --no-artifacts flags#21
Riyaa-Bajpai wants to merge 2 commits intomahimailabs:mainfrom
Riyaa-Bajpai:main

Conversation

@Riyaa-Bajpai
Copy link

@Riyaa-Bajpai Riyaa-Bajpai commented Feb 19, 2026

This PR fixes the behavior when --show-artifacts and --no-artifacts
are provided together. The CLI now exits with a clear error message
instead of producing empty artifact output.

A test has been added to cover this scenario.

Summary by CodeRabbit

  • New Features

    • Added conflict detection for artifact flags. The CLI now validates that --show-artifacts and --no-artifacts cannot be used simultaneously and displays a clear error message.
  • Tests

    • Added test coverage to verify conflicting flag detection works as expected.

@coderabbitai
Copy link

coderabbitai bot commented Feb 19, 2026

📝 Walkthrough

Walkthrough

Adds validation to the scan CLI command to detect and reject conflicting artifact flags (--show-artifacts with --no-artifacts). When both flags are provided simultaneously, the command prints an error message and exits with code 1. Includes a test function to verify this error handling behavior.

Changes

Cohort / File(s) Summary
Artifact Flag Validation
src/envoic/cli.py
Added conflict detection for --show-artifacts and --no-artifacts flags with error message output. Introduced test function to verify the validation rejects both flags provided simultaneously.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

Possibly related PRs

Suggested labels

enhancement

Poem

🐰 Two flags that clashed in digital strife,
Now caught by validation so rife,
With tests that ensure they don't meet,
The CLI dance is now replete! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main change: handling the conflict between two mutually exclusive CLI flags.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/envoic/cli.py`:
- Around line 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.
- Around line 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.

Comment on lines +177 to +182
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)
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.

Comment on lines +382 to +388
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.lower()
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.

@mahimairaja mahimairaja self-requested a review February 21, 2026 16:59
@mahimairaja mahimairaja added the enhancement New feature or request label Feb 21, 2026
Copy link
Contributor

@mahimairaja mahimairaja left a comment

Choose a reason for hiding this comment

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

Please check the comments and update the PR

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants