Skip to main content

Crate mdtask_core

Crate mdtask_core 

Source
Expand description

mdtask-core parses a markdown task file into a typed command tree and builds runnable invocations. It is embeddable, execution-capable, and dependency-free.

A task file is ordinary markdown (a tasks.md, a maskfile.md, or a project README.md): a heading is a task, the first fenced code block under it is the script, and Key: value lines in the body carry metadata. The format is its own grammar, a graceful superset that borrows xc’s metadata vocabulary and mask’s runtime shape (per-fence interpreter, positional args). It reads cleanly in those tools where the features overlap, but claims no compatibility.

let tf = mdtask_core::parse("\
# greet\n\
\n\
Args: name\n\
\n\
```sh\n\
echo \"hello {{ name }}\"\n\
```\n");
let task = tf.task("greet").unwrap();
assert_eq!(task.args[0].name, "name");

Parsing is pure. Task and TaskFile build an Invocation (program, args, env, cwd) that the caller runs on its own worker or thread, or executes with Invocation::run. The parser is line-based (no CommonMark dependency), so a # or Key: inside a fenced block is never mistaken for structure.

Structs§

Arg
One declared positional argument.
Invocation
A runnable command built from a task: what to exec, with what environment, in which directory. The caller runs it however it likes (on a worker, on a thread), keeping execution off any hot path.
MissingArg
A declared argument had no value supplied when building an invocation.
Task
One task: a named script with its interpreter and metadata.
TaskFile
A parsed task file: the tasks, any file-level environment hoisted to all of them (an Env: under a section heading applies to every task regardless of where in the document it appears; hoisting is not positional), and any parse warnings (an unterminated fence, a duplicate task, an unknown fence language). Parsing is infallible. A malformed file still yields what it can, so an embedder should surface warnings rather than trust silence.

Enums§

DepError
A Requires: dependency chain could not be resolved.

Functions§

dependency_order
Resolve the run order for target and its transitive Requires:: each dependency comes before the task that needs it, target comes last, and every task appears at most once (a diamond runs its shared dependency once). This is the sequencing mdtask-core does not do inside invocation; the caller supplies requires_of, which returns a task’s declared dependency names, or None if the name is not a known task (so a typo in Requires: is a hard error, not a silent skip). Pure: no filesystem or process access.
find_task_files
Search for task files from start up to the filesystem root, nearest first. In each ancestor directory the first of tasks.md, maskfile.md, README.md that parses to at least one task is taken. The CLI layers these child-first, so a nearer file shadows a farther one by task name (like just’s set fallback, letting a project inherit a baseline of tasks from a parent). Embedders with their own project root can ignore this and call parse.
parse
Parse a markdown task file. It is line-based (no CommonMark dependency): a heading starts a task, the first fenced block under it is the script, and Key: value lines set metadata. Parsing is infallible; problems are reported in TaskFile::warnings rather than dropped to silence. CRLF endings are normalized.