Skip to content

Add Rust and Cargo provider - #9

Merged
markoa merged 19 commits into
mainfrom
cursor/rust-provider-2f7a
Aug 19, 2026
Merged

markoa merged 19 commits into
mainfrom
cursor/rust-provider-2f7a

Conversation

@markoa

@markoa markoa commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor

Detect Cargo projects and emit an evidence-backed plan for setup, build, test, and lint.

Rebased onto latest main (Composer PHP provider). The README supported list now includes both stacks: Rust and Cargo alongside PHP, Laravel, Symfony, and Composer.

This follows the Go provider’s convention-first model:

  • Discover Cargo.toml as a project root
  • Report rust / cargo, workspace roots (including dotted workspace.members keys), and well-known frameworks (axum, actix-web, rocket), including renamed crates, axum.workspace = true, and inherited workspace aliases such as web.workspace = true → package = "axum", with evidence on both the member declaration and the workspace package value
  • Read rust-version as an MSRV (>=N) from Cargo.toml, plus exact pins from rust-toolchain / rust-toolchain.toml (including files that start with comments, dotted toolchain.channel assignments, and inline toolchain = { channel = ... } tables) and .tool-versions. A plain rust-version file is not a rustup pin.
  • For rust-version.workspace = true, attach member-inheritance evidence and the workspace declaration that supplies the value
  • Conflict exact toolchain pins that are older than Cargo rust-version, disagreeing exact pins, and a non-matrix CI toolchain that contradicts a numeric exact pin even when it satisfies the MSRV
  • Treat symbolic channels (stable, nightly) as unevaluable so a numeric CI toolchain can still fold into the MSRV range
  • Infer cargo fetch, cargo test (when real tests exist — #[test] attributes or Cargo tests/ targets, not _test.rs filenames, comments, strings, or quote character literals), and cargo build
  • Report Clippy, rustfmt, nextest, and cargo-deny config without inventing commands; the renderer reports a configured tool only when no command invokes it, including through declared wrappers such as npm run lint → ESLint
  • Interpret Cargo invocations in CI, including global options before the subcommand (cargo --locked test, cargo -Zunstable-options check); treat rustup, rustc -V/-vV, and remote cargo install as plumbing
  • Recognize dtolnay/rust-toolchain, actions-rs/toolchain, and actions-rust-lang/setup-rust-toolchain (including that action’s stable default and expression-valued toolchain-file inputs)
  • Preserve observed --manifest-path invocations exactly (Cargo reads .cargo/config.toml from the original working directory)
  • Preserve cargo -C when the statement has redirects or pipes so shell-relative paths stay at the original cwd; rewrite -C only for simple commands
  • Leave the original --manifest-path / -C text intact when Semaphore cannot relocate to that directory during static inspection (for example a path generated by an earlier CI step)
  • Leave variable- or expression-valued Cargo paths unresolved with the original command intact

Goldens cover rust-simple, rust-gha, rust-workspace, and clap-rs/clap at a pinned commit.

Rust was previously listed as post-v0; idea.md and plan.md now include it alongside the milestone 7 language work.

Open in Web Open in Cursor 

@markoa
markoa marked this pull request as ready for review August 18, 2026 20:34
cursoragent and others added 18 commits August 18, 2026 23:45
Detect Cargo.toml project roots, infer cargo fetch/test/build, read
rust-version and rust-toolchain pins, and reconcile GitHub Actions
rust-toolchain setup plus cargo invocations.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Normalize ./Cargo.toml to the project directory, keep workspace
dependency evidence honest, reject action SHAs as toolchain pins,
prefer the nearest rust-toolchain file, and conflict disagreeing
exact version pins. Recognize cargo/rustc -V probes, unwrap rustup
run, detect parameterized test attributes, and render cargo-deny.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Cargo rust-version is a minimum, not an exact pin. Emit >=N so CI
toolchains above the MSRV corroborate instead of conflicting, including
inherited workspace values. Thread Cargo --manifest-path and -C into
Semaphore command directories so member commands can reconcile.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Regenerate rust fixtures and clap so rust-version is emitted as >=N.
Clap CI 1.87 now corroborates the MSRV instead of remaining a matrix fact.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Conflict toolchain pins older than Cargo rust-version, honor
setup-rust-toolchain's stable default, keep expression toolchain-file
inputs instead of guessing a repo file, treat rustc -vV as plumbing,
and resolve Cargo package aliases before framework detection.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
unparam flagged the helper because every caller asked for rust.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Rewrite Cargo -C and --manifest-path in stored runs so the command is
executable from the member directory. Ignore test attributes inside
comments and strings. Parse dotted workspace inheritance keys. Strip
Cargo global options before naming and interpretation.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
staticcheck QF1001 flagged the negated compound condition.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Strip Cargo directory flags from the raw run so quoted arguments stay
one token. Parse rust-toolchain.toml after leading comments instead of
treating [toolchain] as a version. Match non-matrix CI observations
against exact Rust pins before MSRV ranges so a newer CI toolchain
conflicts with rust-toolchain.toml.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
The run rewriter only needs the remaining tokens.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Rewrite -C and --manifest-path through rustup run wrappers so the
stored command is executable from the member directory. Leave
variable- and expression-valued Cargo paths unresolved. Treat
workspace.members and other dotted workspace keys as a workspace.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Parse dotted and inline rust-toolchain TOML instead of treating
assignments as a legacy version line. Skip character and byte
character literals when scanning for #[test] so a quote literal
cannot hide a following test. Rewrite Semaphore Cargo directory
flags only after the target directory is found.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Resolve --manifest-path relative to -C so cargo -C crates/tool
test --manifest-path Cargo.toml stays on crates/tool. Stop treating
_test.rs filenames as Cargo tests; infer cargo test only from
#[test] attributes or the tests/ integration-test target.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Leave --manifest-path on observed commands so Cargo still reads
.cargo/config.toml from the original working directory. Treat
symbolic toolchain channels such as stable as unevaluable when
folding CI pins. Report nextest as a configured tool unless a
command actually invokes it. Stop reading a rust-version file as
a rustup pin.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Leave cargo -C in place when the statement has redirects or pipes
so shell-relative paths stay at the original cwd. Resolve
workspace.dependencies package aliases before framework detection.
Match configured tools through wrapper script interpretations and
check every configured tool for an invoking command, including
cargo-deny.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Recognize attached short Cargo globals such as -Zunstable-options
so cargo check is still interpreted. Cite both the member
inheritance and the workspace package= value for renamed
workspace frameworks, and the same two-sided evidence for
inherited rust-version.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
packageFrameworks dropped AliasSource and the workspace flag, so
inherited package = "axum" evidence never reached the plan.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
Member crates now cite both rust-version.workspace = true and the
workspace declaration that supplies the value.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
@cursor
cursor Bot force-pushed the cursor/rust-provider-2f7a branch from 59da189 to 17a8102 Compare August 18, 2026 23:47
WorkingDirectory now recovers Composer -d/--working-dir after exec
unwrap, while Cargo -C with redirects still stays at the shell cwd.
Recognize Composer equality, inequality, hyphen, and union forms as
constraints so they fold or conflict instead of looking unevaluable.
Refresh the koel golden so CI 8.4 next to an exact 8.3.0 platform pin
is recorded as a matrix extra rather than attached to >=8.3.

Co-authored-by: Marko Anastasov <markoa@users.noreply.github.com>
@markoa
markoa merged commit 20aa8d1 into main Aug 19, 2026
1 check passed
@markoa
markoa deleted the cursor/rust-provider-2f7a branch August 19, 2026 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants