Skip to main content

max / makenotwork

3.1 KB · 71 lines History Blame Raw
1 //! Loading the published documentation tree (`site-docs/public`).
2 //!
3 //! Lives in the library rather than in `main.rs` so the test harness builds the
4 //! loader the same way production does. It used to be a private binary
5 //! function, and the harness could only construct a `DocLoader` with
6 //! `sections: vec![]`, so under test the site had no doc pages at all: nothing
7 //! could cover `/docs`, and the two integration tests that would have proven
8 //! the docs half of the sitemap and the search index had to be dropped.
9 //!
10 //! One definition means the harness cannot drift from the server the way an
11 //! imitation of this config would.
12
13 use docengine::{DocLoader, DocLoaderConfig};
14 use mnw_assumptions::Assumptions;
15 use std::sync::Arc;
16
17 /// Where the published docs live. `DOCS_PATH` overrides for a deployment whose
18 /// working directory is not the crate root.
19 pub fn docs_path() -> String {
20 std::env::var("DOCS_PATH").unwrap_or_else(|_| "site-docs/public".to_string())
21 }
22
23 /// Where the business assumptions live, substituted into doc bodies.
24 pub fn assumptions_path() -> String {
25 std::env::var("ASSUMPTIONS_PATH")
26 .unwrap_or_else(|_| "docs/business/assumptions.toml".to_string())
27 }
28
29 /// Load and validate business assumptions. `Err` carries a human-readable
30 /// message; normal startup turns it into a panic, the check modes into a
31 /// sentinel line. Shared so the two paths validate identically.
32 pub fn load_assumptions() -> Result<Arc<Assumptions>, String> {
33 let path = assumptions_path();
34 let a = Assumptions::load(&path)
35 .map_err(|e| format!("failed to load assumptions from {path}: {e}"))?;
36 a.validate()
37 .map_err(|e| format!("assumptions validation failed:\n{e}"))?;
38 tracing::info!(path = %path, "assumptions loaded and validated");
39 Ok(Arc::new(a))
40 }
41
42 /// Build the documentation loader from disk with the production config.
43 ///
44 /// Shared by normal startup, the `MNW_CHECK_DOCS` integrity check, and the test
45 /// harness, so all three see the exact same sections, link prefix, examples
46 /// path, and assumption substitution. The broken-link report cannot drift from
47 /// what is served, and a test asserting over `/docs` is asserting over the real
48 /// tree.
49 pub fn build_doc_loader(assumptions: Arc<Assumptions>) -> DocLoader {
50 let docs_path = docs_path();
51 DocLoader::load(
52 std::path::Path::new(&docs_path),
53 &DocLoaderConfig {
54 sections: vec![
55 ("about".to_string(), "About".to_string()),
56 ("guide".to_string(), "Guide".to_string()),
57 ("developer".to_string(), "Developer".to_string()),
58 ("legal".to_string(), "Legal".to_string()),
59 ("support".to_string(), "Support".to_string()),
60 ("tech".to_string(), "Tech".to_string()),
61 ],
62 link_prefix: "/docs".to_string(),
63 unpublished_pattern: Some("unpublished/".to_string()),
64 examples_path: Some(std::path::Path::new(&docs_path).join("../examples")),
65 pre_process: Some(Box::new(move |md: &str| {
66 assumptions.substitute(md).map_err(|e| e.to_string())
67 })),
68 },
69 )
70 }
71