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
4 changes: 4 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# mcpd

<img src="assets/mcpd-logo.png" alt="mcpd" width="200">

> *Run your agents, not your infrastructure.*

<!-- version-badge -->

---

`mcpd` is a toolchain and runtime developed by [Mozilla AI](https://mozilla.ai) that simplifies the configuration,
Expand Down
39 changes: 15 additions & 24 deletions scripts/prepare_gitbook_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,29 +70,20 @@ def render_summary_commands(template: str, entries: list[str]) -> str:
return template[:begin] + block + template[end:]


def _inject_version_badge(content: str, docs_version: str, mcpd_version: str = "") -> str:
"""Insert a version indicator after the first top-level heading."""
version_line = f"Version: {docs_version}"
if mcpd_version:
version_line += f" (documents mcpd {mcpd_version})"
lines = content.split("\n")
in_fence = False
for i, line in enumerate(lines):
if line.lstrip().startswith("```"):
in_fence = not in_fence
continue
if not in_fence and line.startswith("# "):
j = i + 1
while j < len(lines) and not lines[j].strip():
j += 1
lines[j:j] = [
'{% hint style="info" icon="tag" %}',
version_line,
"{% endhint %}",
"",
]
break
return "\n".join(lines)
VERSION_MARKER = "<!-- version-badge -->"


def _render_version_badge(docs_version: str, mcpd_version: str) -> str:
"""Return the version hint block, leading with the mcpd release when known."""
label = f"mcpd {mcpd_version} (docs {docs_version})" if mcpd_version else f"docs {docs_version}"
return f'{{% hint style="info" icon="tag" %}}\n{label}\n{{% endhint %}}'


def _apply_version_badge(content: str, docs_version: str, mcpd_version: str) -> str:
"""Replace the version marker with the rendered badge."""
if VERSION_MARKER not in content:
raise ValueError(f"missing {VERSION_MARKER} marker")
return content.replace(VERSION_MARKER, _render_version_badge(docs_version, mcpd_version))


def generate_summary() -> None:
Expand All @@ -112,7 +103,7 @@ def stamp_version(docs_version: str, mcpd_version: str) -> None:
index = SITE_DIR / "index.md"
if index.exists():
index.write_text(
_inject_version_badge(index.read_text(encoding="utf-8"), docs_version, mcpd_version),
_apply_version_badge(index.read_text(encoding="utf-8"), docs_version, mcpd_version),
encoding="utf-8",
)

Expand Down
64 changes: 30 additions & 34 deletions scripts/test_prepare_gitbook_site.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import pytest

from prepare_gitbook_site import (
_inject_version_badge,
_apply_version_badge,
_render_version_badge,
command_nav_entries,
command_title,
render_summary_commands,
Expand Down Expand Up @@ -61,37 +62,32 @@ def test_missing_markers_raises(self) -> None:
render_summary_commands("no markers here\n", ["* [x](commands/x.md)"])


class TestInjectVersionBadge:
def test_inserts_after_heading_with_blank_line(self) -> None:
content = "# Title\n\nBody text"
result = _inject_version_badge(content, "1.2.3")
expected = (
'# Title\n\n{% hint style="info" icon="tag" %}\n'
"Version: 1.2.3\n{% endhint %}\n\nBody text"
class TestRenderVersionBadge:
def test_leads_with_mcpd_version(self) -> None:
assert _render_version_badge("v0.1.0", "v0.5.0") == (
'{% hint style="info" icon="tag" %}\n'
"mcpd v0.5.0 (docs v0.1.0)\n"
"{% endhint %}"
)
assert result == expected

def test_no_heading_returns_unchanged(self) -> None:
content = "No heading here"
assert _inject_version_badge(content, "1.0.0") == content

def test_only_first_heading_is_modified(self) -> None:
content = "# First\n\nText\n\n# Second\n\nMore text"
result = _inject_version_badge(content, "2.0.0")
assert result.count("Version: ") == 1

def test_heading_inside_code_fence_is_skipped(self) -> None:
content = "```\n# Not a heading\n```\n\n# Real heading\n\nBody"
result = _inject_version_badge(content, "1.0.0")
assert "Version: 1.0.0" in result
assert result.index("Version: 1.0.0") > result.index("# Real heading")

def test_heading_inside_indented_code_fence_is_skipped(self) -> None:
content = " ```\n# Not a heading\n ```\n\n# Real heading\n\nBody"
result = _inject_version_badge(content, "1.0.0")
assert "Version: 1.0.0" in result
assert result.index("Version: 1.0.0") > result.index("# Real heading")

def test_includes_mcpd_version_when_provided(self) -> None:
result = _inject_version_badge("# Title\n\nBody", "v1.2.3", "v0.4.0")
assert "Version: v1.2.3 (documents mcpd v0.4.0)" in result

def test_docs_only_when_no_mcpd_version(self) -> None:
assert _render_version_badge("v0.1.0", "") == (
'{% hint style="info" icon="tag" %}\n'
"docs v0.1.0\n"
"{% endhint %}"
)


class TestApplyVersionBadge:
def test_replaces_marker_in_place(self) -> None:
content = "# mcpd\n\n> tagline\n\n<!-- version-badge -->\n\n---\n"
assert _apply_version_badge(content, "v0.1.0", "v0.5.0") == (
"# mcpd\n\n> tagline\n\n"
'{% hint style="info" icon="tag" %}\n'
"mcpd v0.5.0 (docs v0.1.0)\n"
"{% endhint %}\n\n---\n"
)

def test_raises_when_marker_missing(self) -> None:
with pytest.raises(ValueError):
_apply_version_badge("# mcpd\n\nno marker here\n", "v0.1.0", "v0.5.0")
Loading