Skip to content
mlavrinenkoPublic

About

Memoized command runner

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

174 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mmz
mmz

A MIT-licensed memoized command runner.


CI crates.io License: MIT

Prefix any command with mmz. When the matched rule’s declared inputs are byte-for-byte unchanged since that command last succeeded, mmz skips it and exits 0. Otherwise it runs the command, streams its output, and records the result on success.

It answers one question per invocation: is this rule’s work still done? The comparison page places it beside the build systems, task runners and compiler caches you might reach for instead.

# .mmz/config.yaml
scopes:
  rust: ["**/*.rs", "Cargo.toml", "Cargo.lock", "rust-toolchain.toml"]

commands:
  - name: cargo test
    inputs: [rust]
validate: 4 orders, 2 customers OK
mmz: skipped ./bin/validate.sh (inputs unchanged)

Installation

cargo install mmz

Quickstart covers the prebuilt binaries, nix run, and scaffolding a manifest.

Usage

mmz --init                # write a starter .mmz/config.yaml
mmz cargo test            # skipped when the declared inputs are unchanged
mmz --status              # each rule's freshness and record age
mmz --is-fresh --tag gate # exit 0 if every gate-tagged rule is fresh; runs nothing
mmz --prune               # drop records whose rule no longer exists
mmz --import ../wt        # take the gate passes recorded in another checkout of this repo

A git worktree keeps its own cache, so a gate that passed there reads stale in the primary checkout after you land it. --import fixes that without trusting anything: records for rules you still have are copied, and the input digest is checked against this tree as usual, so a stale one stays stale. Run it from the primary checkout, pointed at the worktree you are landing. With [worktrunk](https://worktrunk.dev) that is one hook line in the primary’s .config/wt.toml, firing as the worktree goes away. The hook runs inside that worktree, so it steps into the primary first.

pre-remove = "cd {{ primary_worktree_path }} && mmz --import {{ worktree_path }}"

The trade

mmz cannot see a dependency you did not declare, so the asymmetry is the whole contract:

  • Under-declaring a rule’s inputs skips a command that should have run — a false green, and dangerous.
  • Over-declaring buys an unnecessary re-run — and nothing else.

Broaden the scope when in doubt. mmz fails closed everywhere else: a missing or invalid manifest always errors, and so do an unmatched command and a matched rule with no inputs, unless strict relaxes them.

Documentation

  • Quickstart — Install mmz, scaffold a manifest, and watch a command skip itself.
  • Concepts — The model behind mmz: rules, records, freshness, and the asymmetry that decides every design question.
  • Inputs: scopes and probes — Named glob sets, the gitignore filter and how to opt one scope out of it, leaving paths out with exclude, and probes for the inputs that are not files.
  • Code inputs: matching source with AST patterns — The `ast:` selector — depending on a function, a type or an impl block instead of a whole file — what it hashes, how `capture:` narrows a match to the parts that matter, and which grammars a build carries.
  • Matching and parametric rules — How an invocation is matched to a rule, how the cache identity follows from that, and how one rule can fan over a scope's files.
  • Declared outputs — A producer command's record can be undone without touching an input. Declaring what a run leaves behind is how mmz notices.
  • Gating with tags — Use --is-fresh to require that an expensive check already passed, and tags to decide which rules a gate is allowed to ask about.
  • Composing a manifest from imports — Why imports: merges files instead of overriding them, the one path rule that trips everyone the first time, and how to debug what a composed manifest actually resolved to.
  • Manifest reference — Every key .mmz/config.yaml can declare, generated from the JSON Schema the binary ships.
  • CLI reference — Every action mmz accepts, every exit code it returns, and the JSON it can be asked for — generated from the binary's own help text.
  • Rust library — mmz ships as a library crate as well as a binary; the binary is a thin wrapper over it.
  • For AI agents — Driving mmz from an agent: machine-readable state, honest exit codes, and the one mistake an agent is most likely to make with it.
  • Comparison — Where mmz sits among build systems, task runners and compiler caches — and which of them you should reach for instead.

Contributing

See CONTRIBUTING.md. mmz memoizes its own checks, so just check is itself the worked example — and closing a task asserts those checks already passed with mmz --is-fresh --tag gate.

License

MIT.

About

Memoized command runner

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages