///|
/// Convenience entry point that runs `mo_build` with the given `rules`
/// against `options` (defaulting to `Options::default()` if not
/// provided).
pub async fn mopress(
rules : Rules,
options? : Options = Options::default(),
) -> Unit {
let args = @env.args()
let cmd = if args.length() > 1 { args[1] } else { "" }
match cmd {
"build" => options |> mo_build(rules)
"serve" => options |> mo_serve
opts =>
@c.chalk().modifier(Bold).color(Red).render("Unknown command: \{opts}")
|> println
}
}
///|
/// Like `mopress`, but allows deriving the set of rules from some
/// intermediate value `E` computed from `options`: `setup` is called with
/// `options` to produce a value of type `E`, which is then passed
/// (together with `options`) to `build_rules` to produce the final list of
/// rules to run.
///
/// This is useful when the rule set itself depends on some computation or
/// resource derived from `options` (e.g. parsed configuration or a parsed
/// summary/table of contents) that would otherwise need to be recomputed
/// independently by the caller before constructing `rules`.
pub async fn[E] mopress_with(
options? : Options = Options::default(),
init : (Options) -> E,
rules : (Options, E) -> Rules,
) -> Unit {
mopress(options |> rules(options |> init), options~)
}
///|
/// Serves the site described by `options` locally, e.g. for development
/// and live preview, rather than writing output to disk.
pub async fn mo_serve(options : Options) -> Unit {
serve_static_dir(options.dest)
}
///|
/// Runs the build pipeline described by `rules` against the given
/// `options` (source/destination directories), writing all resulting
/// output to `options.dest`.
///
/// Each rule's glob pattern (and, for `Guard` rules, its predicate) is
/// matched against files discovered under `options.src`; matching files
/// are processed according to the rule's `Mode` and the result is written
/// to disk via `Thing::write`.
pub async fn mo_build(options : Options, rules : Rules) -> Unit {
println("Emitting files from \{options.src} to \{options.dest}")
for rule in rules {
for
path in (match rule {
Glob(glob, _) => @glob.scan_files(options.src, glob)
Guard(glob, f, _) => @glob.scan_files_with(options.src, glob, f)
}) {
let item = rule.handler().run(options, path)
item.data.write(options.dest, item.location())
}
}
@c.chalk().modifier(Bold).color(Green).render("√ Build finished.")
|> println
}