fix: save comparison HTML artifacts
This commit is contained in:
@@ -97,11 +97,13 @@ def save_output(
|
|||||||
save_dir: str,
|
save_dir: str,
|
||||||
suffix: str = "",
|
suffix: str = "",
|
||||||
synthesis_md: str | None = None,
|
synthesis_md: str | None = None,
|
||||||
|
topic_override: str | None = None,
|
||||||
|
rendered_content: str | None = None,
|
||||||
) -> Path:
|
) -> Path:
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
path = Path(save_dir).expanduser().resolve()
|
path = Path(save_dir).expanduser().resolve()
|
||||||
path.mkdir(parents=True, exist_ok=True)
|
path.mkdir(parents=True, exist_ok=True)
|
||||||
slug = slugify(report.topic)
|
slug = slugify(topic_override or report.topic)
|
||||||
extension = "json" if emit == "json" else "html" if emit == "html" else "md"
|
extension = "json" if emit == "json" else "html" if emit == "html" else "md"
|
||||||
raw_label = "raw-html" if emit == "html" else "raw"
|
raw_label = "raw-html" if emit == "html" else "raw"
|
||||||
suffix_part = f"-{suffix}" if suffix else ""
|
suffix_part = f"-{suffix}" if suffix else ""
|
||||||
@@ -110,7 +112,9 @@ def save_output(
|
|||||||
out_path = path / f"{slug}-{raw_label}{suffix_part}-{datetime.now().strftime('%Y-%m-%d')}.{extension}"
|
out_path = path / f"{slug}-{raw_label}{suffix_part}-{datetime.now().strftime('%Y-%m-%d')}.{extension}"
|
||||||
# Markdown saves keep the complete debug artifact. JSON and HTML preserve
|
# Markdown saves keep the complete debug artifact. JSON and HTML preserve
|
||||||
# their requested wire format so file extensions match their content.
|
# their requested wire format so file extensions match their content.
|
||||||
if emit in {"json", "html"}:
|
if rendered_content is not None:
|
||||||
|
content = rendered_content
|
||||||
|
elif emit in {"json", "html"}:
|
||||||
content = emit_output(report, emit, synthesis_md=synthesis_md)
|
content = emit_output(report, emit, synthesis_md=synthesis_md)
|
||||||
else:
|
else:
|
||||||
content = render.render_full(report)
|
content = render.render_full(report)
|
||||||
@@ -171,6 +175,10 @@ def emit_comparison_output(
|
|||||||
raise SystemExit(f"Unsupported emit mode: {emit}")
|
raise SystemExit(f"Unsupported emit mode: {emit}")
|
||||||
|
|
||||||
|
|
||||||
|
def comparison_topic(entity_reports: list[tuple[str, schema.Report]]) -> str:
|
||||||
|
return " vs ".join(label for label, _ in entity_reports)
|
||||||
|
|
||||||
|
|
||||||
def compute_save_path_display(save_dir: str, topic: str, suffix: str, emit: str) -> str:
|
def compute_save_path_display(save_dir: str, topic: str, suffix: str, emit: str) -> str:
|
||||||
"""Compute the user-friendly save path string that will be shown in the footer.
|
"""Compute the user-friendly save path string that will be shown in the footer.
|
||||||
|
|
||||||
@@ -875,8 +883,13 @@ def main() -> int:
|
|||||||
fun_level = config.get("FUN_LEVEL", "medium").lower()
|
fun_level = config.get("FUN_LEVEL", "medium").lower()
|
||||||
footer_save_path = None
|
footer_save_path = None
|
||||||
if args.save_dir:
|
if args.save_dir:
|
||||||
|
save_topic = (
|
||||||
|
comparison_topic(entity_reports)
|
||||||
|
if entity_reports and args.emit == "html"
|
||||||
|
else report.topic
|
||||||
|
)
|
||||||
footer_save_path = compute_save_path_display(
|
footer_save_path = compute_save_path_display(
|
||||||
args.save_dir, report.topic, args.save_suffix or "", args.emit
|
args.save_dir, save_topic, args.save_suffix or "", args.emit
|
||||||
)
|
)
|
||||||
|
|
||||||
# Signal to render_compact whether pre-research flags were supplied.
|
# Signal to render_compact whether pre-research flags were supplied.
|
||||||
@@ -911,12 +924,19 @@ def main() -> int:
|
|||||||
)
|
)
|
||||||
if args.save_dir:
|
if args.save_dir:
|
||||||
# Save the main topic's raw file (single-entity or comparison main).
|
# Save the main topic's raw file (single-entity or comparison main).
|
||||||
|
save_topic = (
|
||||||
|
comparison_topic(entity_reports)
|
||||||
|
if entity_reports and args.emit == "html"
|
||||||
|
else None
|
||||||
|
)
|
||||||
save_path = save_output(
|
save_path = save_output(
|
||||||
report,
|
report,
|
||||||
args.emit,
|
args.emit,
|
||||||
args.save_dir,
|
args.save_dir,
|
||||||
suffix=args.save_suffix or "",
|
suffix=args.save_suffix or "",
|
||||||
synthesis_md=synthesis_md,
|
synthesis_md=synthesis_md,
|
||||||
|
topic_override=save_topic,
|
||||||
|
rendered_content=rendered if entity_reports and args.emit == "html" else None,
|
||||||
)
|
)
|
||||||
sys.stderr.write(f"[last30days] Saved output to {save_path}\n")
|
sys.stderr.write(f"[last30days] Saved output to {save_path}\n")
|
||||||
# Competitor / vs-mode: also save a per-entity raw file for each peer.
|
# Competitor / vs-mode: also save a per-entity raw file for each peer.
|
||||||
|
|||||||
@@ -277,6 +277,26 @@ class HtmlCliIntegrationTests(unittest.TestCase):
|
|||||||
path = cli.compute_save_path_display("/tmp", report.topic, "v3", "html")
|
path = cli.compute_save_path_display("/tmp", report.topic, "v3", "html")
|
||||||
self.assertTrue(path.endswith("/ai-agent-frameworks-raw-html-v3.html"))
|
self.assertTrue(path.endswith("/ai-agent-frameworks-raw-html-v3.html"))
|
||||||
|
|
||||||
|
def test_save_output_can_persist_comparison_html(self):
|
||||||
|
reports = [
|
||||||
|
("OpenClaw", _report("OpenClaw", ["Containers"])),
|
||||||
|
("Hermes", _report("Hermes", ["Memory"])),
|
||||||
|
]
|
||||||
|
rendered = cli.emit_comparison_output(reports, "html")
|
||||||
|
with tempfile.TemporaryDirectory() as tmpdir:
|
||||||
|
path = cli.save_output(
|
||||||
|
reports[0][1],
|
||||||
|
"html",
|
||||||
|
tmpdir,
|
||||||
|
topic_override=cli.comparison_topic(reports),
|
||||||
|
rendered_content=rendered,
|
||||||
|
)
|
||||||
|
self.assertEqual("openclaw-vs-hermes-raw-html.html", path.name)
|
||||||
|
saved = path.read_text(encoding="utf-8")
|
||||||
|
self.assertIn("last30days · OpenClaw vs Hermes", saved)
|
||||||
|
self.assertIn("comparing 2: OpenClaw, Hermes", saved)
|
||||||
|
self.assertNotIn("last30days · OpenClaw</title>", saved)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user