Skip to content
Open
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
13 changes: 12 additions & 1 deletion crates/cargo-wdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@ Options:
--sample Build sample class driver project
-h, --help Print help

Manifest Options:
--locked Require Cargo.lock is up to date
--offline Run without accessing the network
--frozen Require Cargo.lock and cache are up to date

Verbosity:
-v, --verbose... Increase logging verbosity
-q, --quiet... Decrease logging verbosity
```

`build` takes a number of inputs specifying build profile (`dev` or `release`), target architecture (`amd64` or `arm64`), a flag enabling signature verification and a flag indicating a sample driver along with verbosity flags.
`build` takes a number of inputs specifying build profile (`dev` or `release`), target architecture (`amd64` or `arm64`), a flag enabling signature verification and a flag indicating a sample driver along with verbosity flags. It also accepts the cargo manifest flags `--locked`, `--offline` and `--frozen`, which are forwarded to the underlying `cargo` invocations (e.g. `cargo build`, `cargo metadata`).
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.

Suggested change
`build` takes a number of inputs specifying build profile (`dev` or `release`), target architecture (`amd64` or `arm64`), a flag enabling signature verification and a flag indicating a sample driver along with verbosity flags. It also accepts the cargo manifest flags `--locked`, `--offline` and `--frozen`, which are forwarded to the underlying `cargo` invocations (e.g. `cargo build`, `cargo metadata`).
`build` takes a number of inputs specifying build profile (`dev` or `release`), target architecture (`amd64` or `arm64`), a flag enabling signature verification and a flag indicating a sample driver along with verbosity flags. It also accepts cargo manifest flags `--locked`, `--offline` and `--frozen`, which are forwarded to `cargo`.

Slightly shorter


When the command completes the packaged driver artifacts are emitted at the path `target\<profile>\<project-name>-package`.

Expand Down Expand Up @@ -113,3 +118,9 @@ If the `--verify-signature` flag is provided, the signatures are verified after
```pwsh
cargo wdk build --target-arch amd64
```

- To build a driver project with a strict, reproducible dependency lockfile (e.g. for CI), navigate to the root of the project and run:

```pwsh
cargo wdk build --locked
```
Comment on lines +121 to +126
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 is example is not needed. We don't need to add examples for every commandline line arg

109 changes: 107 additions & 2 deletions crates/cargo-wdk/src/actions/build/build_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use wdk_build::CpuArchitecture;
#[double]
use crate::providers::exec::CommandExec;
use crate::{
actions::{Profile, build::error::BuildTaskError, to_target_triple},
actions::{ManifestOptions, Profile, build::error::BuildTaskError, to_target_triple},
providers::error::CommandError,
trace,
};
Expand All @@ -27,6 +27,7 @@ pub struct BuildTask<'a> {
profile: Option<&'a Profile>,
target_arch: Option<CpuArchitecture>,
verbosity_level: clap_verbosity_flag::Verbosity,
manifest_options: ManifestOptions,
manifest_path: PathBuf,
command_exec: &'a CommandExec,
working_dir: &'a Path,
Expand All @@ -41,6 +42,8 @@ impl<'a> BuildTask<'a> {
/// * `profile` - An optional profile for the build
/// * `target_arch` - The target architecture for the build
/// * `verbosity_level` - The verbosity level for logging
/// * `manifest_options` - Cargo manifest options (`--locked`, `--frozen`,
/// `--offline`) to forward to the underlying `cargo build` invocation
/// * `command_exec` - The command execution provider
///
/// # Returns
Expand All @@ -54,6 +57,7 @@ impl<'a> BuildTask<'a> {
profile: Option<&'a Profile>,
target_arch: Option<CpuArchitecture>,
verbosity_level: clap_verbosity_flag::Verbosity,
manifest_options: ManifestOptions,
command_exec: &'a CommandExec,
) -> Self {
assert!(
Expand All @@ -66,6 +70,7 @@ impl<'a> BuildTask<'a> {
profile,
target_arch,
verbosity_level,
manifest_options,
manifest_path: working_dir.join("Cargo.toml"),
command_exec,
working_dir,
Expand Down Expand Up @@ -109,6 +114,7 @@ impl<'a> BuildTask<'a> {
args.push("--target".to_string());
args.push(to_target_triple(target_arch));
}
args.extend(self.manifest_options.cargo_args().map(String::from));
if let Some(flag) = trace::get_cargo_verbose_flags(self.verbosity_level) {
args.push(flag.to_string());
}
Expand Down Expand Up @@ -149,7 +155,7 @@ mod tests {

use super::*;
use crate::{
actions::Profile,
actions::{ManifestOptions, Profile},
providers::{error::CommandError, exec::MockCommandExec},
};

Expand All @@ -168,6 +174,7 @@ mod tests {
Some(&profile),
target_arch,
verbosity_level,
ManifestOptions::default(),
&command_exec,
);

Expand Down Expand Up @@ -201,6 +208,7 @@ mod tests {
profile.as_ref(),
target_arch,
verbosity_level,
ManifestOptions::default(),
&command_exec,
);
}
Expand Down Expand Up @@ -257,6 +265,7 @@ mod tests {
Some(&profile),
Some(target_arch),
verbosity,
ManifestOptions::default(),
&mock,
);

Expand Down Expand Up @@ -298,6 +307,7 @@ mod tests {
None,
None,
clap_verbosity_flag::Verbosity::default(),
ManifestOptions::default(),
&mock,
);

Expand Down Expand Up @@ -339,6 +349,7 @@ mod tests {
None,
None,
clap_verbosity_flag::Verbosity::default(),
ManifestOptions::default(),
&mock,
);

Expand All @@ -356,4 +367,98 @@ mod tests {
);
assert_eq!(io_err.kind(), std::io::ErrorKind::NotFound);
}

#[test]
fn run_forwards_manifest_options_to_cargo_invocations_in_build_task() {
let working_dir = PathBuf::from("C:/abs/driver");
let manifest_options = ManifestOptions {
frozen: true,
locked: true,
offline: true,
};
let mut expected_stdout = br#"{"reason":"build-finished","success":true}"#.to_vec();
expected_stdout.push(b'\n');
let expected_stdout_for_mock = expected_stdout.clone();

let mut mock = MockCommandExec::new();
mock.expect_run()
.withf(|command, args, _env, _wd| {
command == "cargo"
&& args.contains(&"--frozen")
&& args.contains(&"--locked")
&& args.contains(&"--offline")
&& {
// Confirm fixed ordering: locked before offline before frozen
let locked_idx = args.iter().position(|a| *a == "--locked").unwrap();
let offline_idx = args.iter().position(|a| *a == "--offline").unwrap();
let frozen_idx = args.iter().position(|a| *a == "--frozen").unwrap();
Comment on lines +391 to +394
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.

Why does order matter?

locked_idx < offline_idx && offline_idx < frozen_idx
}
})
.return_once(move |_, _, _, _| {
Ok(Output {
status: ExitStatus::default(),
stdout: expected_stdout_for_mock,
stderr: Vec::new(),
})
});

let task = BuildTask::new(
"my-driver",
&working_dir,
None,
None,
clap_verbosity_flag::Verbosity::default(),
manifest_options,
&mock,
);

task.run()
.expect("expected an iterator over parsed cargo message objects")
.collect::<std::result::Result<Vec<_>, _>>()
.expect("expected valid cargo messages");
}

#[test]
fn run_forwards_locked_only_when_only_locked_is_set() {
let working_dir = PathBuf::from("C:/abs/driver");
let manifest_options = ManifestOptions {
locked: true,
..ManifestOptions::default()
};
let mut expected_stdout = br#"{"reason":"build-finished","success":true}"#.to_vec();
expected_stdout.push(b'\n');
let expected_stdout_for_mock = expected_stdout.clone();

let mut mock = MockCommandExec::new();
mock.expect_run()
.withf(|command, args, _env, _wd| {
command == "cargo"
&& args.contains(&"--locked")
&& !args.contains(&"--frozen")
&& !args.contains(&"--offline")
})
.return_once(move |_, _, _, _| {
Ok(Output {
status: ExitStatus::default(),
stdout: expected_stdout_for_mock,
stderr: Vec::new(),
})
});

let task = BuildTask::new(
"my-driver",
&working_dir,
None,
None,
clap_verbosity_flag::Verbosity::default(),
manifest_options,
&mock,
);

task.run()
.expect("expected an iterator over parsed cargo message objects")
.collect::<std::result::Result<Vec<_>, _>>()
.expect("expected valid cargo messages");
}
}
13 changes: 10 additions & 3 deletions crates/cargo-wdk/src/actions/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use wdk_build::{
metadata::{TryFromCargoMetadataError, Wdk},
};

use crate::actions::Profile;
use crate::actions::{ManifestOptions, Profile};
#[double]
use crate::providers::{exec::CommandExec, fs::Fs, metadata::Metadata, wdk_build::WdkBuild};

Expand All @@ -40,6 +40,7 @@ pub struct BuildActionParams<'a> {
pub verify_signature: bool,
pub is_sample_class: bool,
pub verbosity_level: clap_verbosity_flag::Verbosity,
pub manifest_options: ManifestOptions,
}

/// Action that orchestrates the build and package of a driver project. Build is
Expand All @@ -51,6 +52,7 @@ pub struct BuildAction<'a> {
verify_signature: bool,
is_sample_class: bool,
verbosity_level: clap_verbosity_flag::Verbosity,
manifest_options: ManifestOptions,

// Injected deps
wdk_build: &'a WdkBuild,
Expand Down Expand Up @@ -96,6 +98,7 @@ impl<'a> BuildAction<'a> {
verify_signature: params.verify_signature,
is_sample_class: params.is_sample_class,
verbosity_level: params.verbosity_level,
manifest_options: params.manifest_options,
wdk_build,
command_exec,
fs,
Expand Down Expand Up @@ -315,9 +318,10 @@ impl<'a> BuildAction<'a> {
.to_string_lossy()
.trim_start_matches("\\\\?\\")
.into();
let other_options: Vec<&str> = self.manifest_options.cargo_args().collect();
let cargo_metadata = self
.metadata
.get_cargo_metadata_at_path(&working_dir_path_trimmed)?;
.get_cargo_metadata_at_path(&working_dir_path_trimmed, &other_options)?;
Ok(cargo_metadata)
}

Expand All @@ -337,6 +341,7 @@ impl<'a> BuildAction<'a> {
self.profile,
self.target_arch,
self.verbosity_level,
self.manifest_options,
self.command_exec,
);
let output_message_iter = build_task.run()?;
Expand Down Expand Up @@ -503,7 +508,9 @@ impl<'a> BuildAction<'a> {
&self,
working_dir: &Path,
) -> Result<CpuArchitecture, BuildActionError> {
let args = ["rustc", "--", "--print", "cfg"];
let mut args: Vec<&str> = vec!["rustc"];
args.extend(self.manifest_options.cargo_args());
args.extend(["--", "--print", "cfg"]);
let output = self
.command_exec
.run("cargo", &args, None, Some(working_dir))?;
Expand Down
Loading
Loading