Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ permissions:
contents: read

on:
workflow_dispatch:
pull_request:
push:
branches:
- main
- dev

jobs:
smoke:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Cargo.lock

# Repo-local agent context (internal pilot details)
AGENTS.md
.claude/logs/
17 changes: 16 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
# Changelog

## 0.1.0 — Unreleased
## 0.1.1 — 2026-05-08

Bug fixes for two consumer-surfaced defects in 0.1.0.

- Pin the cargo package name on every inferred target. Previously the cargo
executor fell back to the Nx project name, so when another plugin (e.g.
`@nx/js` for napi-rs bindings) renamed the project from the cargo crate
name to a scoped JS package name, cargo received `-p @scope/name` and
rejected the invocation with `unexpected prerelease field`.
- Filter executor options against a per-subcommand allowlist before
forwarding to cargo. Nx merges unrelated CLI args (e.g. `--run`,
`--coverage` from `nx run-many -t test` in mixed JS+Rust workspaces) into
the test executor's options; without filtering, those landed on cargo's
argv as `cargo test --run --coverage [object Object]`.

## 0.1.0 — 2026-05-08

Initial release.

Expand Down
46 changes: 26 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,36 @@
and parses `cargo metadata` into the Nx project graph so `nx affected` works
across your Rust crates.

Spiritual successor to [`@monodon/rust`](https://github.com/Cammisuli/monodon) —
same shape, explicitly Apache-2.0 licensed, targeting Nx 22.
Inspired by the public API shape of
[`@monodon/rust`](https://github.com/Cammisuli/monodon), with an Apache-2.0
codebase targeting Nx 22.

## Install

```sh
pnpm add -D nxrust
# or: npm i -D nxrust / yarn add -D nxrust
pnpm add -D @eddacraft/nxrust
# or: npm i -D @eddacraft/nxrust / yarn add -D @eddacraft/nxrust
```

Register in `nx.json`:

```json
{
"plugins": ["nxrust"]
"plugins": ["@eddacraft/nxrust"]
}
```

## Executors

| Executor | Wraps | Cache |
| ----------------------- | ---------------------- | ----- |
| `nxrust:build` | `cargo build` | yes |
| `nxrust:check` | `cargo check` | yes |
| `nxrust:clippy` / `lint`| `cargo clippy` | yes |
| `nxrust:fmt` | `cargo fmt` | yes |
| `nxrust:run` | `cargo run` | no |
| `nxrust:test` | `cargo test` | yes |
| `nxrust:release-publish`| `cargo publish` | no (use via `nx release publish`) |
| `@eddacraft/nxrust:build` | `cargo build` | yes |
| `@eddacraft/nxrust:check` | `cargo check` | yes |
| `@eddacraft/nxrust:clippy` / `lint`| `cargo clippy` | yes |
| `@eddacraft/nxrust:fmt` | `cargo fmt` | yes |
| `@eddacraft/nxrust:run` | `cargo run` | no |
| `@eddacraft/nxrust:test` | `cargo test` | yes |
| `@eddacraft/nxrust:release-publish`| `cargo publish` | no (use via `nx release publish`) |

All executors accept a shared option set:

Expand All @@ -53,15 +54,15 @@ Individual executors add specialised flags — see each schema.

```sh
# Library crate
nx g nxrust:crate my-crate
nx g @eddacraft/nxrust:crate my-crate

# Binary crate
nx g nxrust:crate my-cli --bin
nx g @eddacraft/nxrust:crate my-cli --bin
# or alias:
nx g nxrust:binary my-cli
nx g @eddacraft/nxrust:binary my-cli

# Library alias
nx g nxrust:library my-lib
nx g @eddacraft/nxrust:library my-lib
```

Generated crates are added to the root `Cargo.toml` `[workspace.members]`
Expand All @@ -87,8 +88,13 @@ This is what makes `nx affected -t test` correct across your Rust crates.

## License

Apache-2.0 © EddaCraft. See [LICENSE](./LICENSE).
Apache-2.0 © eddacraft. See [LICENSE](./LICENSE).

This project does not contain any code copied from `@monodon/rust` — it
references its public API shape only. `cargo metadata` is the official
Rust tooling contract.
This project does not contain code copied from `@monodon/rust`; it references
the public API shape only. `cargo metadata` is the official Rust tooling
contract.

## Acknowledgements

Thanks to the author of `@monodon/rust`; that project established the shape of
Rust support many Nx users expect.
7 changes: 5 additions & 2 deletions e2e/fixture/nx.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"plugins": ["nxrust"]
}
"plugins": [
"@eddacraft/nxrust"
],
"analytics": true
}
2 changes: 1 addition & 1 deletion generators.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "http://json-schema.org/schema",
"name": "nxrust",
"name": "@eddacraft/nxrust",
"version": "0.1.0",
"generators": {
"init": {
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nxrust",
"version": "0.1.0",
"name": "@eddacraft/nxrust",
"version": "0.1.1",
"description": "Nx plugin that wraps Cargo — executors, generators, and project-graph integration for Rust workspaces inside Nx monorepos.",
"keywords": [
"nx",
Expand All @@ -10,13 +10,13 @@
"monorepo",
"workspace"
],
"homepage": "https://github.com/EddaCraft/nxrust",
"homepage": "https://github.com/eddacraft/nxrust",
"repository": {
"type": "git",
"url": "https://github.com/EddaCraft/nxrust.git"
"url": "git+https://github.com/eddacraft/nxrust.git"
},
"license": "Apache-2.0",
"author": "EddaCraft",
"author": "eddacraft",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
Expand All @@ -36,6 +36,8 @@
"build": "tsc -p tsconfig.json && node ./tools/copy-assets.mjs",
"clean": "rm -rf dist",
"e2e": "node ./tools/e2e-smoke.mjs",
"prepublishOnly": "node ./tools/assert-release-branch.mjs && pnpm build && pnpm test && pnpm e2e",
"release:dry-run": "pnpm build && pnpm pack --dry-run",
"typecheck": "tsc -p tsconfig.json --noEmit",
"test": "vitest run",
"test:watch": "vitest"
Expand Down
35 changes: 21 additions & 14 deletions plans/index.aps.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
| Field | Value |
|-------|-------|
| Status | In Progress |
| Owner | @joshuaboys |
| Owner | eddacraft |
| Created | 2026-04-21 |
| Licence | Apache-2.0 |

Expand Down Expand Up @@ -39,14 +39,14 @@ TypeScript + Rust monorepos.
- [x] Project-graph plugin (`createNodesV2` + `createDependencies`) emits
Rust crate nodes + cross-crate edges from `cargo metadata`
- [x] Unit test suite green via Vitest
- [x] Council + adversarial review findings addressed or documented
- [ ] End-to-end pilot against a real Rust crate in a real Nx 22
- [x] Review findings addressed or documented
- [ ] End-to-end validation against a real Rust crate in a real Nx 22
workspace passes and caches
- [ ] Rollout to every crate in the pilot workspace completes green on
- [ ] Rollout to every crate in the validation workspace completes green on
`nx run-many`
- [ ] CI smoke test job in nxrust + dependent-repo smoke in the pilot
- [ ] CI smoke test job in nxrust + dependent-repo smoke in the validation
workspace
- [ ] First `[email protected]` published to npm (final scope TBD)
- [ ] First `@eddacraft/[email protected]` published to npm

## Constraints

Expand All @@ -60,15 +60,15 @@ TypeScript + Rust monorepos.
not failure.
- UK English in plan and README text; user-facing CLI output stays
locale-neutral.
- Zero regressions on the pilot consumer: every
- Zero regressions on the validation consumer: every
`cargo check/test/clippy/fmt` invocation that passed before must
still pass after the plugin wraps it.

## Modules

| Module | Purpose | Status | Dependencies |
|--------|---------|--------|--------------|
| [01-v0.1-shakedown](./modules/01-v0.1-shakedown.aps.md) | Prove the plugin end-to-end on a pilot consumer, ship first npm release | In Progress | — |
| [01-v0.1-shakedown](./modules/01-v0.1-shakedown.aps.md) | Prove the plugin end-to-end on a consumer workspace, ship first npm release | In Progress | — |

Deferred (not yet active modules):

Expand All @@ -87,23 +87,24 @@ Deferred (not yet active modules):

| Risk | Impact | Mitigation |
|------|--------|------------|
| `target/` caching yields stale artefacts under remote cache | high | Narrow `outputs` — cache test/clippy reports and binaries, not the whole `target/` tree; verify second-run cache hits on the pilot crate before rollout |
| `target/` caching yields stale artefacts under remote cache | high | Narrow `outputs` — cache test/clippy reports and binaries, not the whole `target/` tree; verify second-run cache hits before rollout |
| Nx 22 project-graph plugin API drifts on minor upgrades | medium | Small public surface (`createNodesV2` + `createDependencies` only); CI smoke test pins the contract |
| `cargo metadata` performance on large workspaces | medium | Mtime-keyed `Cargo.lock` cache already in `graph.ts`; re-evaluate if the pilot hits a slowdown |
| Pilot switchover breaks the consumer's pnpm graph mid-flight | medium | Switch only after pilot + rollout + CI smoke are all green; keep a revert commit ready |
| `cargo metadata` performance on large workspaces | medium | Mtime-keyed `Cargo.lock` cache already in `graph.ts`; re-evaluate if validation hits a slowdown |
| Consumer switchover breaks the consumer's pnpm graph mid-flight | medium | Switch only after validation + rollout + CI smoke are all green; keep a revert commit ready |

## Open Questions

- [ ] Final npm scope for v0.1 publish — scoped vs unscoped. Default:
scoped, re-evaluate at v0.2.
- [x] Final npm scope for v0.1 publish — use scoped
`@eddacraft/nxrust`. The package is published under the eddacraft
npm organisation.
- [ ] Keep the `release-publish` executor in v0.1, or defer until a
crate actually publishes to crates.io? Implemented and tested —
keep it, but document as "unvalidated against a real crates.io
token" until a consumer exercises it.
- [ ] Should the project-graph plugin emit external nodes for workspace
dev-dependencies, or only runtime deps? Current behaviour skips
`kind === 'dev'`; revisit if `nx affected -t test` misses edges
in the pilot.
in validation.

## Decisions

Expand All @@ -121,3 +122,9 @@ Deferred (not yet active modules):
- **D-004:** Build target — CommonJS to `./dist`. Nx devkit plugins are
consumed by Nx's Node runtime; ESM offers no win here.
*Accepted.*
- **D-005:** Distribution channel — publish `@eddacraft/nxrust` to npm,
not crates.io.
Nx plugins are JavaScript packages discovered through npm metadata
(`executors.json`, `generators.json`, and JS entrypoints). Cargo/crates.io
remains relevant for Rust consumers, not for this Nx plugin.
*Accepted 2026-05-07.*
Loading
Loading