|
42 | 42 | # --------------------------------------------------------------------------- |
43 | 43 |
|
44 | 44 |
|
| 45 | +def _format_bytes(n: int) -> str: |
| 46 | + for unit in ("B", "KB", "MB", "GB"): |
| 47 | + if n < 1024 or unit == "GB": |
| 48 | + return f"{n:,.1f} {unit}" if unit != "B" else f"{n:,} B" |
| 49 | + n = n / 1024 |
| 50 | + return f"{n:,.1f} GB" |
| 51 | + |
| 52 | + |
| 53 | +def _print_export_summary( |
| 54 | + output_html: str, |
| 55 | + output_archive: str, |
| 56 | + output_report_json: str | None, |
| 57 | + record_names: list[str], |
| 58 | +) -> None: |
| 59 | + """Print a one-shot end-of-run summary so users can see what was written. |
| 60 | +
|
| 61 | + Uses ``print`` rather than ``logging.info`` because the default Python log |
| 62 | + level is WARNING, which silently swallows info-level messages. A visible |
| 63 | + summary matters here: without it, the CLI ends immediately after the last |
| 64 | + "Running fast-sugiyama layout..." line, which reads like the run hung. |
| 65 | + """ |
| 66 | + lines = ["[Observatory CLI] Session complete. Wrote:"] |
| 67 | + for path in (output_html, output_archive, output_report_json): |
| 68 | + if not path: |
| 69 | + continue |
| 70 | + try: |
| 71 | + size = os.path.getsize(path) |
| 72 | + size_str = _format_bytes(size) |
| 73 | + except OSError: |
| 74 | + size_str = "missing" |
| 75 | + lines.append(f" {path} ({size_str})") |
| 76 | + lines.append( |
| 77 | + f" {len(record_names)} record(s): {', '.join(record_names)}" |
| 78 | + ) |
| 79 | + print("\n".join(lines)) |
| 80 | + |
| 81 | + |
45 | 82 | def make_collect_parser(prog=None): |
46 | 83 | """Create the base argparse parser for collection mode. |
47 | 84 |
|
@@ -173,10 +210,11 @@ def run_visualize(input_archive: str, output_html: str, *, setup_fn=None) -> Non |
173 | 210 | if setup_fn is not None: |
174 | 211 | setup_fn(Observatory) |
175 | 212 | Observatory.generate_html_from_json(input_archive, output_html) |
176 | | - logging.info( |
177 | | - "[Observatory CLI] visualize: html=%s from archive=%s", |
178 | | - output_html, |
179 | | - input_archive, |
| 213 | + _print_export_summary( |
| 214 | + output_html=output_html, |
| 215 | + output_archive="", # visualize consumes an archive, does not produce one |
| 216 | + output_report_json=None, |
| 217 | + record_names=[f"←{os.path.basename(input_archive)}"], |
180 | 218 | ) |
181 | 219 |
|
182 | 220 |
|
@@ -286,15 +324,14 @@ def run_observatory( |
286 | 324 | Observatory.export_report_json(output_report_json, title=title) |
287 | 325 | collected = Observatory.list_collected() |
288 | 326 | if collected: |
289 | | - logging.info( |
290 | | - "[Observatory CLI] Reports: html=%s archive=%s (%d records: %s)", |
291 | | - output_html, |
292 | | - output_archive, |
293 | | - len(collected), |
294 | | - ", ".join(collected), |
| 327 | + _print_export_summary( |
| 328 | + output_html=output_html, |
| 329 | + output_archive=output_archive, |
| 330 | + output_report_json=output_report_json, |
| 331 | + record_names=collected, |
295 | 332 | ) |
296 | 333 | else: |
297 | | - logging.warning("[Observatory CLI] No records collected") |
| 334 | + print("[Observatory CLI] No records collected — no report written.") |
298 | 335 |
|
299 | 336 |
|
300 | 337 | # --------------------------------------------------------------------------- |
@@ -341,10 +378,11 @@ def run_compare( |
341 | 378 | # config is not threaded through compare mode (compare_archives drives |
342 | 379 | # analysis). Pass None so export_report_json uses an empty config. |
343 | 380 | Observatory.export_report_json(output_report_json, title=title, config=None) |
344 | | - logging.info( |
345 | | - "[Observatory CLI] compare: html=%s from %d archives", |
346 | | - output_html, |
347 | | - len(input_archives), |
| 381 | + _print_export_summary( |
| 382 | + output_html=output_html, |
| 383 | + output_archive="", # compare has no output archive of its own |
| 384 | + output_report_json=output_report_json, |
| 385 | + record_names=[f"{lbl}←{os.path.basename(pth)}" for lbl, pth in zip(labels, input_archives)], |
348 | 386 | ) |
349 | 387 |
|
350 | 388 |
|
|
0 commit comments