Skip to content
Draft
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
20 changes: 20 additions & 0 deletions src/compwa_policy/repo/poe.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def check(session: Session, args: Arguments, ctx: CheckContext) -> None:
_set_doc_group(config)
_set_test_group(config)
_set_notebook_group(config, ctx.has_notebooks)
_set_quarto_linkcheck(config)
_check_no_uv_run(config)
if config.has_table("tool.poe.tasks"):
_set_all_task(config)
Expand Down Expand Up @@ -212,6 +213,25 @@ def _set_notebook_group(pyproject: ModifiablePyproject, /, has_notebooks: bool)
pyproject.changelog.append(msg)


def _set_quarto_linkcheck(pyproject: ModifiablePyproject, /) -> None:
if not is_committed("_quarto.yml", "**/_quarto.yml", ":!:tests", untracked=True):
return
pyproject.add_dependency("lychee-bin", dependency_group="doc")
tasks = _get_or_create_group_tasks(pyproject, "doc")
existing = cast("Mapping", tasks.get("linkcheck", {}))
if "lychee" in existing.get("cmd", "") or "lychee" in existing.get("shell", ""):
return
expected = {
"executor": to_inline_table({"group": "doc"}),
"help": "Check external links in the documentation (requires internet connection)",
"shell": "lychee --root-dir . . && lychee --root-dir . --extensions qmd .",
}
if existing != expected:
tasks["linkcheck"] = expected
msg = f"Set Poe the Poet linkcheck task in {CONFIG_PATH.pyproject}"
pyproject.changelog.append(msg)


def _check_no_uv_run(pyproject: Pyproject) -> None:
poe_table = pyproject.get_table("tool.poe")
all_task_tables: list[Mapping] = [
Expand Down
2 changes: 1 addition & 1 deletion src/compwa_policy/utilities/toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def to_toml_array(items: Iterable[Any], multiline: bool | None = None) -> Array:
return array


def to_inline_table(value: Mapping[str, Any]) -> InlineTable:
def to_inline_table(value: Mapping[str, Any], /) -> InlineTable:
table = tomlkit.inline_table()
if value:
table.append(None, tomlkit.ws(" "))
Expand Down
109 changes: 109 additions & 0 deletions tests/repo/test_poe.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,115 @@ def is_noop_without_pyproject(
# no pyproject
run_check(check, session, has_notebooks=False, package_manager="uv")

def configures_lychee_for_quarto(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
git_init: Callable[[Path], None],
git_add: Callable[[Path], None],
run_check,
):
git_init(tmp_path)
(tmp_path / "_quarto.yml").touch()
(tmp_path / "index.qmd").touch()
(tmp_path / "pyproject.toml").write_text(
dedent("""
[dependency-groups]
dev = [{ include-group = "doc" }]
doc = []

[tool.poe.tasks.doc]
cmd = "quarto render"

[tool.poe.tasks.doclive]
cmd = "quarto preview"

[tool.poe.tasks.linkcheck]
cmd = "echo linkcheck-not-supported"
""").lstrip()
)
git_add(tmp_path)
monkeypatch.chdir(tmp_path)
with Session.load() as session:
run_check(check, session, has_notebooks=False, package_manager="uv")
pyproject = Pyproject.load(tmp_path / "pyproject.toml")
assert "lychee-bin" in pyproject.get_table("dependency-groups.doc")
linkcheck = pyproject.get_table("tool.poe.groups.doc.tasks.linkcheck")
assert linkcheck == {
"executor": {"group": "doc"},
"help": (
"Check external links in the documentation (requires internet connection)"
),
"shell": "lychee --root-dir . . && lychee --root-dir . --extensions qmd .",
}

def preserves_custom_lychee_extensions(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
git_init: Callable[[Path], None],
git_add: Callable[[Path], None],
run_check,
):
git_init(tmp_path)
(tmp_path / "_quarto.yml").touch()
config_path = tmp_path / "pyproject.toml"
config_path.write_text(
dedent("""
[dependency-groups]
doc = []

[tool.poe.tasks.doc]
cmd = "quarto render"

[tool.poe.tasks.doclive]
cmd = "quarto preview"

[tool.poe.tasks.linkcheck]
cmd = "lychee --extensions md,qmd,typ ."
""").lstrip()
)
git_add(tmp_path)
monkeypatch.chdir(tmp_path)
with Session.load() as session:
run_check(check, session, has_notebooks=False, package_manager="uv")
linkcheck = Pyproject.load(config_path).get_table(
"tool.poe.groups.doc.tasks.linkcheck"
)
assert linkcheck["cmd"] == "lychee --extensions md,qmd,typ ."

def preserves_custom_lychee_shell(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
git_init: Callable[[Path], None],
git_add: Callable[[Path], None],
run_check,
):
git_init(tmp_path)
(tmp_path / "_quarto.yml").touch()
config_path = tmp_path / "pyproject.toml"
config_path.write_text(
dedent("""
[dependency-groups]
doc = []

[tool.poe.tasks.doc]
cmd = "quarto render"

[tool.poe.tasks.doclive]
cmd = "quarto preview"

[tool.poe.tasks.linkcheck]
shell = "lychee . && lychee --extensions qmd ."
""").lstrip()
)
git_add(tmp_path)
monkeypatch.chdir(tmp_path)
with Session.load() as session:
run_check(check, session, has_notebooks=False, package_manager="uv")
linkcheck = Pyproject.load(config_path).get_table(
"tool.poe.groups.doc.tasks.linkcheck"
)
assert linkcheck["shell"] == "lychee . && lychee --extensions qmd ."


def describe_update_doclive():
def adds_executor():
Expand Down
Loading