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
45 changes: 40 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ comline-core = { git = "https://github.com/ComlineProject/core", rev = "076cae0c
# `comline-codegen`'s types, so the rev below must be byte-identical to the
# one *they* pin - Cargo only unifies a git dependency across identical rev
# strings, and two copies of `GenRequest` are two incompatible types.
comline-codegen = { git = "https://github.com/ComlineProject/generation", rev = "7b51264b216ef4c5e2afbe36897a5b35dafe7e06" }
# The official Markdown documentation renderer (`comline doc`), linked in
# like the official generators. Same generation rev as `comline-codegen`.
comline-doc-markdown = { git = "https://github.com/ComlineProject/generation", rev = "7b51264b216ef4c5e2afbe36897a5b35dafe7e06" }
comline-codegen-rust = { git = "https://github.com/ComlineProject/comline-rust", rev = "bef9a74c028d7a44b4dc13ed677d300e061b2147", optional = true }
comline-codegen-typescript = { git = "https://github.com/ComlineProject/comline-typescript", rev = "47b54cc75b05bc52586d431d26ed4def316cf0c4", optional = true }
comline-codegen = { git = "https://github.com/ComlineProject/generation", rev = "58ff61b4a72a2bcdba6685809e615ffb614e1d8e" }
# The official Markdown and HTML documentation renderers (`comline doc`),
# linked in like the official generators. Same generation rev as
# `comline-codegen`.
comline-doc-markdown = { git = "https://github.com/ComlineProject/generation", rev = "58ff61b4a72a2bcdba6685809e615ffb614e1d8e" }
comline-doc-html = { git = "https://github.com/ComlineProject/generation", rev = "58ff61b4a72a2bcdba6685809e615ffb614e1d8e" }
comline-codegen-rust = { git = "https://github.com/ComlineProject/comline-rust", rev = "52e0eadf1c424f9486ee97d75d74cf59bbc1f191", optional = true }
comline-codegen-typescript = { git = "https://github.com/ComlineProject/comline-typescript", rev = "932edaad1fd0a0dba47f8fff132149e03c0340dc", optional = true }
# `comline conformance`: the conformance runner (corpus loading, judging,
# profile proofs) and its case format, a public spec. Pinned by git rev.
comline-runtime-conformance = { git = "https://github.com/ComlineProject/runtime", rev = "6f8f73a247f0aa4ac8b7041b2fdc4b02bce0e0d6" }
Expand Down
13 changes: 11 additions & 2 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ argument matches no stored version (the error lists the versions that exist).
### `comline doc`

```
comline doc [--out <dir>] [--version <v>] [--changelog-from <v>] [--format markdown|json]
comline doc [--out <dir>] [--version <v>] [--changelog-from <v>] [--format markdown|html|json]
```

Write the package's documentation. Nothing is written to `.comline/`.
Expand All @@ -460,6 +460,14 @@ Write the package's documentation. Nothing is written to `.comline/`.
every unit with its `///` docs, fields, arguments and each protocol's wire
summary, `changelog.md` with `--changelog-from`, and `nav.yml`, a `nav` for
mkdocs or zensical.
- **`html`** writes a self-contained static site, rendered by the official HTML
renderer, also linked in: `index.html`, one page per module
(`types/user.html`), `changelog.html` with `--changelog-from`, `style.css`
and `search.js`. It has the same content as the Markdown pages, plus a
sidebar of modules and units, a search box over the units (the index is
inlined in `search.js`), and light and dark themes that follow the OS
setting. Nothing loads from the network and every link is relative, so
`index.html` opens straight from disk or from any static host.
- **`json`** writes the documentation model itself, `model.json`, in the shape
of core's `schemas/doc-model.json`.

Expand All @@ -468,7 +476,7 @@ Write the package's documentation. Nothing is written to `.comline/`.
| `--out <dir>` | `[doc] out`, else `docs/api` | where to write, relative to the project |
| `--version <v>` | the working tree | document a built version (a version string, a commit hash, or `HEAD`) from its frozen IR, `//!` headers included |
| `--changelog-from <v>` | `[doc] changelog_from` | add what changed from built version `<v>` to the documented one |
| `--format <f>` | `[doc] format`, else `markdown` | `markdown`, `json`, or another id the `[doc] renderer` offers |
| `--format <f>` | `[doc] format`, else `markdown` | `markdown`, `html`, `json`, or another id the `[doc] renderer` offers |

A built version keeps no source, so with `--version` its protocols have no wire
summary. A version built before headers were stored has none.
Expand Down Expand Up @@ -497,6 +505,7 @@ changelog_from = "0.1.0"
comline doc
comline doc --out site/api --changelog-from 0.1.0
comline doc --version 0.2.0
comline doc --format html --out site
comline doc --format json
```

Expand Down
9 changes: 6 additions & 3 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,10 @@ version string, a commit hash or `HEAD`), which is documented from its frozen \
IR, `//!` headers included. A built version keeps no source, so its protocols \
have no wire summary.

`--format json` writes the documentation model itself (`model.json`), for \
other tools. `comline.toml`'s `[doc]` table sets the defaults: `out` \
`--format html` writes a self-contained static site instead: `index.html`, \
one page per module, `changelog.html`, a stylesheet and a search script, all \
linked relatively, so `index.html` opens straight from disk. `--format json` \
writes the documentation model itself (`model.json`), for other tools. `comline.toml`'s `[doc]` table sets the defaults: `out` \
(`docs/api`), `format` (`markdown`), `renderer` (an external renderer, run \
like an external generator), `links` (dependency docs URLs) and \
`changelog_from`.
Expand All @@ -122,6 +124,7 @@ Examples:
comline doc
comline doc --out site/api --changelog-from 0.1.0
comline doc --version 0.2.0
comline doc --format html --out site
comline doc --format json")]
Doc {
/// Output directory; default from `[doc] out`, else `docs/api`
Expand All @@ -136,7 +139,7 @@ Examples:
#[arg(long, value_name = "VERSION")]
changelog_from: Option<String>,

/// `markdown` (pages) or `json` (the model); default from `[doc] format`
/// `markdown` (pages), `html` (a static site) or `json` (the model); default from `[doc] format`
#[arg(long, value_name = "FORMAT")]
format: Option<String>,
},
Expand Down
5 changes: 3 additions & 2 deletions src/commands/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//! compiled working tree, or from a built version's frozen IR and `//!`
//! headers with `--version`. `--changelog-from` adds what changed since an
//! earlier built version. `--format json` writes the model itself; any other
//! format is a renderer's id, `markdown` being the official one, linked in
//! like the official generators. `[doc] renderer` in `comline.toml` names an
//! format is a renderer's id: `markdown` and `html` are the official ones,
//! linked in like the official generators. `[doc] renderer` in `comline.toml` names an
//! external renderer instead, run exactly like an external generator
//! ([`crate::external`]: the same sandbox, limits and path checks).
//!
Expand Down Expand Up @@ -39,6 +39,7 @@ pub struct Flags {
pub(crate) fn renderer_registry() -> Registry {
let mut registry = Registry::new();
comline_doc_markdown::register(&mut registry);
comline_doc_html::register(&mut registry);
registry
}

Expand Down
71 changes: 67 additions & 4 deletions tests/cli/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,73 @@ fn an_unknown_format_names_what_is_offered() {

comline_cmd()
.current_dir(&shop)
.args(["doc", "--format", "html"])
.args(["doc", "--format", "pdf"])
.assert()
.failure()
.stderr(predicate::str::contains(
"doesn't render `html`; it offers `markdown`",
));
.stderr(predicate::str::contains("doesn't render `pdf`; it offers"))
.stderr(predicate::str::contains("`html`"))
.stderr(predicate::str::contains("`markdown`"));
}

#[test]
fn html_writes_a_self_contained_site() {
let temp = tempfile::tempdir().unwrap();
let shop = temp.path().join("shop");
package(&shop, "//! A shop.\n\n", API);
comline_cmd()
.current_dir(&shop)
.arg("build")
.assert()
.success();

comline_cmd()
.current_dir(&shop)
.args([
"doc",
"--format",
"html",
"--out",
"site",
"--changelog-from",
"0.1.0-dev.1",
])
.assert()
.success();

let out = shop.join("site");
let index = read(&out.join("index.html"));
assert!(index.starts_with("<!doctype html>"), "{index}");
assert!(index.contains("<h1>shop</h1>\n<p>A shop.</p>"), "{index}");
assert!(index.contains("<a href=\"api.html\"><code>api</code></a>"));
let api = read(&out.join("api.html"));
assert!(
api.contains("<td><code>total</code></td><td><code>u64</code></td><td>What it costs.</td>"),
"{api}"
);
assert!(api.contains("<a href=\"#order\"><code>Order</code></a>"));
assert!(api.contains("<h3>On the wire</h3>"));
assert!(api.contains("<link rel=\"stylesheet\" href=\"style.css\">"));
assert!(read(&out.join("search.js")).contains("\"u\":\"api.html#order\""));
assert!(out.join("style.css").exists());
assert!(out.join("changelog.html").exists());
assert!(!out.join("nav.yml").exists());
}

#[test]
fn html_is_a_doc_format_in_comline_toml() {
let temp = tempfile::tempdir().unwrap();
let shop = temp.path().join("shop");
package(&shop, "", API);
fs::write(
shop.join("comline.toml"),
"[doc]\nout = \"site\"\nformat = \"html\"\n",
)
.unwrap();
comline_cmd()
.current_dir(&shop)
.arg("doc")
.assert()
.success();
assert!(shop.join("site/index.html").exists());
assert!(shop.join("site/api.html").exists());
}
27 changes: 19 additions & 8 deletions tests/cli/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,20 +287,20 @@ fn a_language_the_generator_does_not_offer_is_refused() {
)));
}

/// `[doc] renderer`: the official Markdown renderer run as an external one
/// writes what the built-in writes.
fn renderer_matches_builtin(kind: Kind) {
/// `[doc] renderer`: an official renderer (`bin`, rendering `format`) run as
/// an external one writes what the built-in writes, byte for byte.
fn renderer_matches_builtin(kind: Kind, bin: &str, format: &str) {
let temp = tempfile::tempdir().unwrap();
let project = fixture_project(temp.path());
comline_cmd()
.current_dir(&project)
.args(["doc", "--out", "builtin"])
.args(["doc", "--out", "builtin", "--format", format])
.assert()
.success();
let file = install(&project, kind, "renderer", "comline-doc-markdown");
let file = install(&project, kind, bin, &format!("comline-doc-{format}"));
fs::write(
project.join("comline.toml"),
format!("[doc]\nrenderer = \"{file}\"\nout = \"external\"\n"),
format!("[doc]\nrenderer = \"{file}\"\nout = \"external\"\nformat = \"{format}\"\n"),
)
.unwrap();
comline_cmd()
Expand All @@ -319,12 +319,23 @@ fn renderer_matches_builtin(kind: Kind) {
#[cfg(feature = "gen-wasm")]
#[test]
fn a_wasm_renderer_writes_what_the_builtin_does() {
renderer_matches_builtin(Kind::Wasm);
renderer_matches_builtin(Kind::Wasm, "renderer", "markdown");
}

#[test]
fn a_native_renderer_writes_what_the_builtin_does() {
renderer_matches_builtin(Kind::Native);
renderer_matches_builtin(Kind::Native, "renderer", "markdown");
}

#[cfg(feature = "gen-wasm")]
#[test]
fn a_wasm_html_renderer_writes_what_the_builtin_does() {
renderer_matches_builtin(Kind::Wasm, "renderer-html", "html");
}

#[test]
fn a_native_html_renderer_writes_what_the_builtin_does() {
renderer_matches_builtin(Kind::Native, "renderer-html", "html");
}

#[test]
Expand Down
Loading
Loading