Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion src/specify_cli/integrations/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,10 @@ def _render_toml_string(value: str) -> str:

escaped = value.replace("\\", "\\\\")
if '"""' not in escaped:
if escaped.endswith('"'):
return '"""\n' + escaped + '\\\n"""'
return '"""\n' + escaped + '"""'
if "'''" not in value:
if "'''" not in value and not value.endswith("'"):
Comment thread
mnriem marked this conversation as resolved.
return "'''\n" + value + "'''"

return '"' + (
Expand Down
55 changes: 55 additions & 0 deletions tests/integrations/test_integration_base_toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,61 @@ def test_toml_prompt_excludes_frontmatter(self, tmp_path, monkeypatch):
assert "scripts:" not in parsed["prompt"]
assert "---" not in parsed["prompt"]

def test_toml_no_ambiguous_closing_quotes(self, tmp_path, monkeypatch):
"""Multiline body ending with `"` must not produce `""""` (#2113)."""
i = get_integration(self.KEY)
template = tmp_path / "sample.md"
template.write_text(
"---\n"
"description: Test\n"
"scripts:\n"
" sh: echo ok\n"
"---\n"
"Check the following:\n"
'- Correct: "Is X clearly specified?"\n',
encoding="utf-8",
)
monkeypatch.setattr(i, "list_command_templates", lambda: [template])

m = IntegrationManifest(self.KEY, tmp_path)
created = i.setup(tmp_path, m)
cmd_files = [f for f in created if "scripts" not in f.parts]
assert len(cmd_files) == 1

raw = cmd_files[0].read_text(encoding="utf-8")
assert '""""' not in raw, "closing delimiter must not merge with body quote"
assert '"""\n' in raw, "body must use multiline basic string"
parsed = tomllib.loads(raw)
assert parsed["prompt"].endswith('specified?"')
assert not parsed["prompt"].endswith("\n"), "parsed value must not gain a trailing newline"

Comment thread
mnriem marked this conversation as resolved.
def test_toml_closing_delimiter_inline_when_safe(self, tmp_path, monkeypatch):
"""Body NOT ending with `"` keeps closing `\"\"\"` inline (no extra newline)."""
i = get_integration(self.KEY)
template = tmp_path / "sample.md"
template.write_text(
"---\n"
"description: Test\n"
"scripts:\n"
" sh: echo ok\n"
"---\n"
"Line one\n"
"Plain body content\n",
encoding="utf-8",
)
monkeypatch.setattr(i, "list_command_templates", lambda: [template])

m = IntegrationManifest(self.KEY, tmp_path)
created = i.setup(tmp_path, m)
cmd_files = [f for f in created if "scripts" not in f.parts]
assert len(cmd_files) == 1

raw = cmd_files[0].read_text(encoding="utf-8")
parsed = tomllib.loads(raw)
assert parsed["prompt"] == "Line one\nPlain body content"
assert raw.rstrip().endswith('content"""'), \
"closing delimiter should be inline when body does not end with a quote"

def test_toml_is_valid(self, tmp_path):
"""Every generated TOML file must parse without errors."""
i = get_integration(self.KEY)
Expand Down
Loading