Skip to content

feat: add cargo wdk clean command#638

Open
svasista-ms wants to merge 30 commits intomicrosoft:mainfrom
svasista-ms:clean-command
Open

feat: add cargo wdk clean command#638
svasista-ms wants to merge 30 commits intomicrosoft:mainfrom
svasista-ms:clean-command

Conversation

@svasista-ms
Copy link
Copy Markdown
Contributor

@svasista-ms svasista-ms commented Apr 1, 2026

Adds clean subcommand to cargo-wdk. The command can be used to remove artifacts produced by the build command.

Closes #636

Behavior:

The command works for standalone, workspaces and emulated workspaces (with a known issue).
Standalone packages / workspace: If a Cargo.toml (manifest) is present, runs cargo clean directly. This cleans standalone packages and workspaces (excluding the directories that are mentioned in the exclude list in workspace manifest)
Emulated workspace: If Cargo.toml is not found in the current working directory, it Scans immediate subdirectories for Rust projects and cleans each one. Continues on failure and reports all errors at the end.
Known Issue: Due to the current emulated workspaces detection logic, the clean command also suffers from the same issue as #477.

Summary of changes:

  • CleanAction added with error types and tests
  • CLI integration via the clean subcommand
  • Integration test in build_command_test.rs that tests the behavior for standalone packages, workspaces and emulated workspaces. Replaced vanilla cargo clean with cargo wdk clean

cargo wdk clean in /examples:
cargo-wdk clean in examples folder

cargo wdk clean in the samples repo:
samples-repo build and clean

clean and build commands suffer with the sample problem in nested folders inside a workspace:
image

Copilot AI review requested due to automatic review settings April 1, 2026 13:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new cargo wdk clean subcommand to cargo-wdk, with logic mirroring the existing “standalone/workspace vs emulated workspace” detection approach used by the build flow.

Changes:

  • Introduces CleanAction (plus error types and unit tests) that runs cargo clean either in the current workspace root or across immediate subdirectories (emulated workspace).
  • Wires the new action into the CLI as a clean subcommand.
  • Adds integration tests for cargo wdk clean, and updates test utilities to allow invoking the new command.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
crates/cargo-wdk/src/cli.rs Adds clean subcommand and dispatches into CleanAction.
crates/cargo-wdk/src/actions/mod.rs Exposes the new clean action module.
crates/cargo-wdk/src/actions/clean/mod.rs Implements clean logic (workspace vs emulated workspace) and runs cargo clean.
crates/cargo-wdk/src/actions/clean/error.rs Defines CleanActionError error types for clean flow.
crates/cargo-wdk/src/actions/clean/tests.rs Adds unit tests for CleanAction.
crates/cargo-wdk/tests/clean_command_test.rs Adds integration tests for cargo wdk clean.
crates/cargo-wdk/tests/test_utils/mod.rs Allows create_cargo_wdk_cmd to invoke clean.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/cargo-wdk/src/actions/clean/mod.rs
Comment thread crates/cargo-wdk/src/actions/clean/mod.rs
Comment thread crates/cargo-wdk/src/actions/clean/error.rs Outdated
Comment thread crates/cargo-wdk/tests/test_utils/mod.rs
Comment thread crates/cargo-wdk/tests/clean_command_test.rs Outdated
Comment thread crates/cargo-wdk/src/actions/clean/tests.rs Outdated
@svasista-ms svasista-ms changed the title Clean command feat: add cargo wdk clean command Apr 2, 2026
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 2, 2026

Codecov Report

❌ Patch coverage is 92.28070% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.45%. Comparing base (ebc705a) to head (3fd27e4).

Files with missing lines Patch % Lines
crates/cargo-wdk/src/actions/clean/mod.rs 94.11% 5 Missing and 10 partials ⚠️
crates/cargo-wdk/src/actions/build/mod.rs 69.23% 2 Missing and 2 partials ⚠️
crates/cargo-wdk/src/providers/fs.rs 86.66% 0 Missing and 2 partials ⚠️
crates/cargo-wdk/src/cli.rs 50.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #638      +/-   ##
==========================================
+ Coverage   78.69%   79.45%   +0.75%     
==========================================
  Files          25       26       +1     
  Lines        5234     5500     +266     
  Branches     5234     5500     +266     
==========================================
+ Hits         4119     4370     +251     
- Misses        995     1001       +6     
- Partials      120      129       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@svasista-ms svasista-ms marked this pull request as ready for review April 6, 2026 04:41
Copilot AI review requested due to automatic review settings April 6, 2026 04:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/cargo-wdk/tests/build_command_test.rs Outdated
Comment thread crates/cargo-wdk/src/cli.rs
Comment thread crates/cargo-wdk/src/actions/clean/tests.rs Outdated
Copilot AI review requested due to automatic review settings April 6, 2026 08:58
@svasista-ms svasista-ms requested a review from a team April 6, 2026 09:00
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/cargo-wdk/src/actions/clean/error.rs Outdated
Comment thread crates/cargo-wdk/src/actions/clean/tests.rs Outdated
Comment thread crates/cargo-wdk/src/actions/clean/mod.rs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/cargo-wdk/src/actions/clean/mod.rs
Comment thread crates/cargo-wdk/src/actions/clean/mod.rs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/cargo-wdk/src/actions/clean/mod.rs
Comment thread crates/cargo-wdk/src/actions/clean/mod.rs Outdated
Comment thread crates/cargo-wdk/src/actions/clean/mod.rs Outdated
Co-authored-by: Copilot <copilot@github.com>
Copilot AI review requested due to automatic review settings May 4, 2026 13:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/cargo-wdk/src/providers/fs.rs Outdated
Comment thread crates/cargo-wdk/src/actions/build/mod.rs Outdated
Comment thread crates/cargo-wdk/src/cli.rs Outdated
krishnakumar4a4 and others added 8 commits May 5, 2026 18:46
…icrosoft#641)

This pull request updates the documentation to inform users about a new
build tool in development for Rust drivers. The most important change is
the addition of a preview notice about the upcoming `cargo-wdk` tool.

Documentation update:

* Added a preview notice in `README.md` announcing the development of
the `cargo-wdk` cargo-extension, which is intended to replace
`cargo-make` as the recommended tool for building Rust drivers, and
encouraged users to try it out and provide feedback.

---------

Signed-off-by: Krishna Kumar Thokala <krishna.thokala2010@gmail.com>
Co-authored-by: Gurinder Singh <frederick.the.fool@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…bilization (microsoft#643)

Fixes `collapsable_if` lint failing in CI pipelines.

The `assert_matches` stabilization that was expected to ship with Rust
1.95.0 was [reverted from the 1.95
beta](rust-lang/rust#154999) due to an
[inconsistency in temporary scoping
behavior](rust-lang/rust#154406) between
`assert_matches!`/`assert_eq!` and their `debug_` variants.

We gated `assert_matches` usage based on the nightly compiler warning
that the feature was "stable since 1.95.0" (see microsoft#612). Since the
stabilization was reverted before the actual release, this gate now
fires on stable 1.95 and tries to use an unstable API, breaking CI
pipelines.

This bumps the gate to `1.96.0`. Beta 1.96 currently still has
`assert_matches` available, though that may change if the
destabilization propagates.

---------

Co-authored-by: leon-xd <leondu@microsoft.com>
Adds and integrates `wdk::fmt::FormatBuffer`.

## Summary
- Introduced `crates/wdk/src/fmt.rs` with a public `wdk::fmt` module
containing two types:
- `FormatBuffer<N>` — a fixed-size, stack-allocated formatting buffer
implementing `fmt::Write`
- `FlushableFormatBuffer<F, N>` — a wrapper that auto-flushes via
closure on overflow and on drop
- Swapped `print.rs` WDM/KMDF path to use `FlushableFormatBuffer`
instead of `DbgPrintBufWriter`; removed that module and its tests.
- Turns the `alloc` feature from the `wdk` crate into a no-op — it had
no remaining uses after the stack-buffer migration. Avoids removal of
feature to prevent a breaking change
- Bumps MSRV from 1.85 to 1.91 due to use of
[`str::char_floor_boundary`](https://doc.rust-lang.org/core/primitive.str.html#method.floor_char_boundary)


## Details
- `FormatBuffer<N>` stores a zero-initialized `[u8; N]` and tracks
`used` bytes. The last byte is reserved for a NUL terminator, so usable
capacity is `N - 1`. `N` must be at least 2; smaller values will not
compile (`const { assert!(N >= 2) }`).
- All buffer mutations go through a single `append_bytes` helper that
copies data and sets `buffer[used] = 0`, centralizing the NUL terminator
invariant.
- `as_str()` returns an infallible UTF-8 view — only valid UTF-8 enters
via `write_str` (both `FormatBuffer::write_str` and
`FlushableFormatBuffer::write_str` copy from `&str` sources).
- `as_c_str()` returns a `&CStr` view up to the first NUL. Infallible in
practice since the NUL invariant is always maintained.
- `fmt::Write` clamps overflow writes at a UTF-8 char boundary via
`floor_char_boundary` and signals truncation via `fmt::Error`.
- `FlushableFormatBuffer<F, N>` wraps `FormatBuffer` and auto-flushes
via a closure when the buffer fills. Remaining content is flushed on
drop. This allows arbitrarily long formatted output to be processed in
fixed-size chunks.
- `print.rs` WDM/KMDF path now formats into `FlushableFormatBuffer<_,
512>` and calls `DbgPrint` via `%s` using the resulting `CStr`.
- Removed the `alloc` feature gate from the WDM/KMDF print path —
`print!`/`println!` no longer require heap allocation and work at any
IRQL where `DbgPrint` is valid.
- Custom `Debug` impl on `FormatBuffer` shows only the used content, not
stale bytes after `clear()`.


## Testing
29 tests covering:
- basic write, `as_str()`, `as_c_str()` usage
- overflow, multi-write, and exact-fit scenarios
- empty writes and min-sized buffers (`N = 2`)
- clear-then-shorter-write regression (NUL terminator correctness)
- multi-byte UTF-8 char boundary handling in both buffer types
- explicit `flush()` mid-stream and flush-on-drop
- interior NUL truncation via `as_c_str()`
- `compile_fail` doctest for `N < 2`

```pwsh
cargo test --package wdk --lib --all-features -- fmt --nocapture
```

## Notes / Follow-ups
- `_print` ignores `fmt::write` errors — partial output is acceptable
for debug printing. Errors from individual `Display` impls are silently
dropped.
- The old `DbgPrintBufWriter` stripped interior NUL bytes and continued
printing. The new WDM/KMDF path truncates each chunk at the first NUL
(via `as_c_str`). UMDF still strips NULs and prints the remainder.

---------

Signed-off-by: Leon Durrenberger <leon.durrenberger@gmail.com>
Co-authored-by: leon-xd <leondu@microsoft.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
… build command to render compiler errors instead of the plain `json` option (microsoft#645)

Fixes microsoft#613 

## Problem

When `cargo wdk build` encounters a compilation error, the error output
is hard to debug:

1. JSON wall — `--message-format=json` sends even the compiler
diagnostics as JSON to `stdout` instead of redirecting it to `stderr`.
So, compiler errors are not directly visible instead they are buried
deep in the output json. This is affecting test outputs because in case
of failures, the errors cannot be seen easily in the `json` output.
2. Redundant error content — `BuildTaskError::CargoBuild` wraps the full
`CommandError` (containing `stdout` JSON), even though the user may have
already seen the real compiler errors on `stderr` in real time.

## Fixes

The following changes fix the above problems:

1. Switch to `--message-format=json-render-diagnostics`
This option instructs cargo to render diagnostics from `rustc` directly
to `stderr` instead of putting it in the `json` output.
stdout: only machine-parseable JSON (artifacts, build-finished) — no
diagnostic messages
stderr: human-readable compiler errors and warnings, rendered by Cargo
(visible to the user in real time since stderr is inherited)

2. Omit `stdout` from `CommandError::CommandFailed` before returning
from `BuildTask`:
When cargo build fails, `BuildTask::run()` now maps the error to a new
instance of `CommandFailed` but with the `stdout` field set to
`String::new()` to avoid printing machine-readable (`json`) output on
the screen.

## Before

Running `kmdf_driver_cross_compiles_with_cli_option_successfully` test
after removing `aarch64-pc-windows-msvc` target:

<img width="947" height="572" alt="image"
src="https://github.com/user-attachments/assets/efb391d3-02e8-47fd-907e-91ffe5c1d4ba"
/>

_____

Compiler diagnostics not printed to `stderr`, instead it is buried in
the json output when `cargo wdk build` fails:

<img width="1547" height="822" alt="image"
src="https://github.com/user-attachments/assets/4a0cf5c0-a9d4-4a8c-be63-c1237d6ed835"
/>

_____

Output seen when tests fail due to compilation errors:

<img width="1936" height="1162" alt="image"
src="https://github.com/user-attachments/assets/ac4a5e53-5a95-483d-898c-0e751e790c36"
/>


## After

Running `kmdf_driver_cross_compiles_with_cli_option_successfully` test
after removing `aarch64-pc-windows-msvc` target:

<img width="1344" height="824" alt="image"
src="https://github.com/user-attachments/assets/f95f94a9-9076-46e3-a706-c07c7ca95b65"
/>

_____

Compiler diagnostics available on terminal:

<img width="1028" height="576" alt="image"
src="https://github.com/user-attachments/assets/39d6ba3f-5b6f-4fdb-bbb9-0b39c21874be"
/>

_____

Output seen when tests fail due to compilation errors:
<img width="1867" height="1231" alt="image"
src="https://github.com/user-attachments/assets/b282efcd-c748-4129-b2c1-4f5c6b297900"
/>

---------

Co-authored-by: Copilot <copilot@github.com>
### Summary
This PR fixes three clippy lint failures in wdk-build that were
[blocking
CI](https://github.com/microsoft/windows-drivers-rs/actions/runs/25316776664/job/74241285479):

1. `useless_borrows_in_formatting` — removed redundant `&` from `panic!`
arguments in `cargo_make.rs`.
2. `uninlined_format_args` — inlined the constant names directly into
the `panic!` format strings.
3. `manual_assert_eq` — replaced `assert!(a == b)` with `assert_eq!(a,
b)` in `utils.rs`.

No functional changes; lint fixes only.

### Validation
`cargo make wdk-pre-commit-flow` passes locally with the following
`rustc` versions:
1. Stable - `rustc 1.95.0 (59807616e 2026-04-14)`
2. Nightly - `rustc 1.97.0-nightly (cb40c25f6 2026-05-04)`
3. Beta - `rustc 1.96.0-beta.5 (a5a9a5438 2026-05-01)`

This PR fixes the issue.

Co-authored-by: Copilot <copilot@github.com>
…tead of `ReadDirError`

Co-authored-by: Copilot <copilot@github.com>
Copilot AI review requested due to automatic review settings May 5, 2026 13:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

#[error("Failed to rename file from {0} to {1}")]
RenameError(PathBuf, PathBuf, #[source] io::Error),
#[error("Failed to get file type for directory entry {0:#?}")]
#[error("Failed to get file type for directory entry {0}")]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While adding this variant back, I noticed it was using {0:#?} whereas every other FileError variant uses plain {0}. Switched it to {0} so the PathBuf is rendered via Display instead of Debug to keep it consistent with the rest of the enum

gurry
gurry previously approved these changes May 6, 2026
@gurry gurry enabled auto-merge May 6, 2026 03:49
.unwrap_or_default();

if !found_at_least_one_project {
info!("Cleaning package(s) in {}", self.working_dir.display());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: to make it more readable, Add a comment on top of this to clarify that this conditional is required to have one log per entire emulated workspace. it threw me off a bit if I didn't pay close attention to the argument being logged.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment 👍

continue;
}

let working_dir_path = entry.path;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this variable name, as the working_dir variable is already used to refer to the emulated workspace itself. A better name would be cargo_package_path or rust_package_path.

More generally, we may need to standardise the terminology and refer to these as Cargo projects rather than Rust projects, since we depend on Cargo.toml. I originally introduced the term Rust projects in the build flow, assuming this tool would majorly be used by first‑time Rust adopters for driver development. On reflection, however, Cargo project is the more technically accurate term.

Copy link
Copy Markdown
Contributor

@gurry gurry May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Package" is a cargo concept not a rustc one so cargo_package_path is better.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed it to cargo_package_path 👍

}

let working_dir_path = dir.path(); // Avoids a short-lived temporary
let working_dir_path = entry.path;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment even applies here as we are not really switching into the directory during this loop.

https://github.com/microsoft/windows-drivers-rs/pull/638/changes#r3199700749

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to cargo_package_path 👍

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.

Add cargo wdk clean subcommand to mirror cargo make clean

7 participants