Skip to content

Commit 58b0465

Browse files
authored
Feat: declutter artifact (#15)
* feat: updatd cli to show artifacts on demand * docs: updated artifact * refactor: rename --artifact to --show-artifacts for clarity - Renamed CLI option to avoid confusion with --artifacts/--no-artifacts - Updated documentation with new flag name - Added test coverage for show_artifact_details parameter
1 parent 267c46e commit 58b0465

File tree

4 files changed

+107
-32
lines changed

4 files changed

+107
-32
lines changed

docs/reference/commands.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Scans a path for Python environments and Python artifacts, then prints the full
1212
| `--stale-days` | | `90` | Days threshold for stale marking |
1313
| `--include-dotenv` | | `false` | Include plain `.env` directories |
1414
| `--artifacts/--no-artifacts` | | `true` | Enable/disable Python artifact detection |
15+
| `--show-artifacts` | `-a` | `false` | Show detailed artifact-level sections in report output |
1516
| `--path-mode` | | `name` | Path column rendering: `name`, `relative`, `absolute` |
1617
| `--rich` | | `false` | Use rich-rendered output |
1718

@@ -20,6 +21,8 @@ Examples:
2021
```bash
2122
envoic scan .
2223
envoic scan ~/projects --deep
24+
envoic scan ~/projects --deep --show-artifacts
25+
envoic scan ~/projects --deep -a
2326
envoic scan ~/projects --no-artifacts
2427
envoic scan . --json
2528
envoic scan . --path-mode relative

src/envoic/cli.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ def scan(
150150
"--artifacts/--no-artifacts",
151151
help="Include Python artifact detection.",
152152
),
153+
show_artifacts: bool = typer.Option(
154+
False,
155+
"--show-artifacts",
156+
"-a",
157+
help="Show detailed artifact-level report sections.",
158+
),
153159
path_mode: PathMode = typer.Option(
154160
"name",
155161
"--path-mode",
@@ -174,7 +180,12 @@ def scan(
174180
raise typer.Exit(0)
175181

176182
_print_output(
177-
format_report(result, path_mode=path_mode, deep=deep),
183+
format_report(
184+
result,
185+
path_mode=path_mode,
186+
deep=deep,
187+
show_artifact_details=show_artifacts,
188+
),
178189
use_rich=rich_output,
179190
)
180191

src/envoic/report.py

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ def format_report(
169169
title: str = "ENVOIC - Python Environment Report",
170170
path_mode: PathMode = "name",
171171
deep: bool = False,
172+
show_artifact_details: bool = False,
172173
) -> str:
173174
stale_count = sum(1 for env in result.environments if env.is_stale)
174175
artifact_count = sum(item.count for item in result.artifact_summary)
@@ -217,40 +218,49 @@ def format_report(
217218

218219
lines.append("─" * 58)
219220
lines.append("")
220-
lines.append("ARTIFACTS")
221-
lines.append("─" * 58)
222-
lines.append(_artifact_table_header(deep))
223-
lines.append("─" * 58)
224-
if not result.artifact_summary:
225-
lines.append(" (no artifacts found)")
226-
else:
227-
for summary in result.artifact_summary:
228-
lines.append(_artifact_row(summary, deep=deep))
229-
lines.append("─" * 58)
230-
if deep and any(
231-
item.safety == SafetyLevel.CAREFUL for item in result.artifact_summary
232-
):
233-
careful_patterns = {
234-
item.pattern
235-
for item in result.artifact_summary
236-
if item.safety == SafetyLevel.CAREFUL
237-
}
238-
for pattern in sorted(careful_patterns):
239-
note = CAREFUL_NOTES.get(pattern)
240-
if note:
241-
lines.append(f" * {pattern}: {note}")
221+
if show_artifact_details:
222+
lines.append("ARTIFACTS")
242223
lines.append("─" * 58)
243-
if not deep:
244-
lines.append(" (run with --deep to include size data)")
224+
lines.append(_artifact_table_header(deep))
245225
lines.append("─" * 58)
246-
lines.append("")
247-
lines.append(
248-
_artifact_distribution(
249-
result.artifact_summary,
250-
deep=deep,
226+
if not result.artifact_summary:
227+
lines.append(" (no artifacts found)")
228+
else:
229+
for summary in result.artifact_summary:
230+
lines.append(_artifact_row(summary, deep=deep))
231+
lines.append("─" * 58)
232+
if deep and any(
233+
item.safety == SafetyLevel.CAREFUL for item in result.artifact_summary
234+
):
235+
careful_patterns = {
236+
item.pattern
237+
for item in result.artifact_summary
238+
if item.safety == SafetyLevel.CAREFUL
239+
}
240+
for pattern in sorted(careful_patterns):
241+
note = CAREFUL_NOTES.get(pattern)
242+
if note:
243+
lines.append(f" * {pattern}: {note}")
244+
lines.append("─" * 58)
245+
if not deep:
246+
lines.append(" (run with --deep to include size data)")
247+
lines.append("─" * 58)
248+
lines.append("")
249+
lines.append(
250+
_artifact_distribution(
251+
result.artifact_summary,
252+
deep=deep,
253+
)
251254
)
252-
)
253-
lines.append("")
255+
lines.append("")
256+
else:
257+
lines.append("ARTIFACT DETAILS")
258+
lines.append("─" * 58)
259+
lines.append(
260+
" (hidden by default; run with --artifact to show detailed breakdown)"
261+
)
262+
lines.append("─" * 58)
263+
lines.append("")
254264
lines.append(
255265
_size_distribution(
256266
result.environments, path_mode=path_mode, base_path=result.scan_path

tests/test_report.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,54 @@ def test_format_list_relative_paths() -> None:
8585
text = format_list([env], path_mode="relative", base_path=Path("/tmp"))
8686
assert "project" in text
8787
assert "project/.venv" not in text
88+
89+
90+
def test_format_report_show_artifact_details_false() -> None:
91+
"""Test that artifact details are hidden by default."""
92+
env = EnvInfo(
93+
path=Path("/tmp/project/.venv"),
94+
env_type=EnvType.VENV,
95+
python_version="3.12.1",
96+
size_bytes=1024 * 1024,
97+
modified=datetime.now(UTC),
98+
)
99+
result = ScanResult(
100+
scan_path=Path("/tmp"),
101+
scan_depth=5,
102+
duration_seconds=1.2,
103+
environments=[env],
104+
total_size_bytes=1024 * 1024,
105+
hostname="host-a",
106+
timestamp=datetime(2026, 2, 9, 12, 0, 0, tzinfo=UTC),
107+
)
108+
109+
text = format_report(result, show_artifact_details=False)
110+
111+
assert "ARTIFACT DETAILS" in text
112+
assert "hidden by default" in text
113+
assert "run with --show-artifacts" in text.lower() or "run with --artifact" in text.lower()
114+
115+
116+
def test_format_report_show_artifact_details_true() -> None:
117+
"""Test that artifact details are shown when flag is enabled."""
118+
env = EnvInfo(
119+
path=Path("/tmp/project/.venv"),
120+
env_type=EnvType.VENV,
121+
python_version="3.12.1",
122+
size_bytes=1024 * 1024,
123+
modified=datetime.now(UTC),
124+
)
125+
result = ScanResult(
126+
scan_path=Path("/tmp"),
127+
scan_depth=5,
128+
duration_seconds=1.2,
129+
environments=[env],
130+
total_size_bytes=1024 * 1024,
131+
hostname="host-a",
132+
timestamp=datetime(2026, 2, 9, 12, 0, 0, tzinfo=UTC),
133+
)
134+
135+
text = format_report(result, show_artifact_details=True)
136+
137+
assert "ARTIFACTS" in text
138+
assert "hidden by default" not in text

0 commit comments

Comments
 (0)