Skip to content
Merged
Show file tree
Hide file tree
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
18 changes: 18 additions & 0 deletions src/vectrify/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import os
import sys
from pathlib import Path

from vectrify.cli import parse_args
from vectrify.dashboard import Dashboard
Expand Down Expand Up @@ -52,6 +53,19 @@ def determine_provider_and_model(args) -> tuple[str, str]:
return provider, model


def format_extension_warning(
output_path: str, fmt: str, expected_ext: str
) -> str | None:
"""Return a warning if the output extension doesn't match --format, else None."""
actual = Path(output_path).suffix.lower()
if actual == expected_ext:
return None
return (
f"Output path '{output_path}' has extension '{actual or '(none)'}' but "
f"--format {fmt} produces '{expected_ext}' files; writing it anyway."
)


def main():
args = parse_args()
provider, model = determine_provider_and_model(args)
Expand All @@ -71,6 +85,10 @@ def main():
else:
plugin = SvgPlugin()

mismatch = format_extension_warning(args.output, args.format, plugin.file_extension)
if mismatch:
logger.warning(mismatch)

stats = SearchStats(
strategy_name=args.strategy,
model_name=model,
Expand Down
29 changes: 28 additions & 1 deletion src/vectrify/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest

from vectrify.main import determine_provider_and_model
from vectrify.main import determine_provider_and_model, format_extension_warning

_KEYS = ("OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GEMINI_API_KEY")

Expand Down Expand Up @@ -54,3 +54,30 @@ def test_explicit_model_is_preserved(monkeypatch):
provider, model = determine_provider_and_model(_args(model="custom-model"))
assert provider == "openai"
assert model == "custom-model"


@pytest.mark.parametrize(
("output", "fmt", "ext"),
[
("out.svg", "svg", ".svg"),
("out.dot", "graphviz", ".dot"),
("OUT.SVG", "svg", ".svg"), # extension check is case-insensitive
],
)
def test_extension_match_no_warning(output, fmt, ext):
assert format_extension_warning(output, fmt, ext) is None


@pytest.mark.parametrize(
("output", "fmt", "ext"),
[
("out.svg", "graphviz", ".dot"),
("out.dot", "svg", ".svg"),
("out", "typst", ".typ"), # no extension at all
],
)
def test_extension_mismatch_warns(output, fmt, ext):
msg = format_extension_warning(output, fmt, ext)
assert msg is not None
assert fmt in msg
assert ext in msg
Loading