The Workshop
How the workspace is laid out, and what cargo xtask gives a maintainer.
This chapter is for contributors. End users only need The First
Incantation and Binding the Rune.
The five crates and one xtask
xrune/
├─ crates/
│ ├─ xrune-sigil ← derive macro: `#[derive(DsRef)]`
│ ├─ xrune-nexus ← AST + DsRune trait + decipher
│ ├─ xrune-incant ← proc-macro: `ui! { … }`
│ ├─ xrune ← umbrella: re-exports nexus + ui!, plus default_rune
│ └─ xrune-fmt ← CLI binary: the scribe
├─ examples/
│ └─ example0 ← canonical hello-world fixture
└─ xtask/ ← CI/build/test/lint/doctest/bump/publish/release
All five published crates live on one workspace and ship one moving
version. cargo install xrune and you also get xrune-incant and
xrune-nexus linked in transitively.
xtask is publish = false — it never reaches crates.io. It exists
only to drive the workspace itself.
cargo xtask commands
cargo xtask <ci|build|test|lint|doctest|bump <level>|publish [--dry-run]|release>
ci—build+test+lint+doctest, in that order. This is what.github/workflows/ci.ymlruns. Locally green = CI green.build—cargo build --workspace.test—cargo test --workspace.lint—cargo +stable clippy --workspace -- -D warnings, followed bycargo +stable fmt --all --check. The+stabletoolchain pin matches CI.doctest— extract every```rustblock fromdocs/src/anddocs/src-zh-CN/into a throwaway test crate atdocs/test/andcargo build --tests. Catches drift between docs and reality.bump <major|minor|patch>— rewrite the version in everyCargo.toml(workspace + the fiveversion = "=X.Y.Z"pins under[workspace.dependencies]). Hand-editing the version is forbidden.publish [--dry-run]— push to crates.io in fixed order:xrune-sigil → xrune-nexus → xrune-incant → xrune → xrune-fmt, with a 30-second sleep between to let the index settle. Already- uploaded crates are skipped. Don’t run this directly; userelease.release— the only path to a real release. Requires a clean tree, then internally: pushmain→ wait for CI green viagh run list(10-minute timeout) → tagvX.Y.Z→ push the tag →gh release create --generate-notes→ runpublish.
Workspace conventions
[workspace.package].versionis the single source of truth.[workspace.dependencies]pins each internal crate withversion = "=X.Y.Z"so all five always march in lock-step.Cargo.lockis gitignored — this is a deliberate choice for the workspace, not an oversight.default-members = ["crates/*"]—cargo buildfrom the root builds the published crates, notxtaskorexamples/.edition = "2024"workspace-wide.resolver = "2"for cargo’s modern feature unification.
Source-of-truth
- Workspace manifest:
Cargo.toml - xtask:
xtask/src/main.rs - CI:
.github/workflows/ci.yml