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
35 changes: 34 additions & 1 deletion crates/cargo-wdk/src/actions/build/build_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::path::{Path, PathBuf};
use anyhow::Result;
use cargo_metadata::Message;
use clap_cargo::Features;
use mockall::automock;
use mockall_double::double;
use tracing::debug;
use wdk_build::CpuArchitecture;
Expand All @@ -24,6 +25,7 @@ use crate::{
};

/// Parameters for constructing a [`BuildTask`].
#[derive(Clone, Copy)]
pub struct BuildTaskParams<'a> {
/// The name of the package to build
pub package_name: &'a str,
Expand All @@ -41,6 +43,32 @@ pub struct BuildTaskParams<'a> {
pub verbosity_level: clap_verbosity_flag::Verbosity,
}

#[derive(Debug, Default)]
#[cfg_attr(test, allow(dead_code))]
pub struct BuildTaskRunner {}

#[automock]
#[allow(clippy::unused_self, clippy::elidable_lifetime_names)]
#[cfg_attr(test, allow(dead_code))]
impl BuildTaskRunner {
// Returns `Box<dyn Iterator<...>>` rather than `impl Iterator<...>` because
// this method is `#[automock]`ed. mockall must be able to *name* the return
// type to generate the mock's expectation storage, and it cannot mock an
// opaque `impl Trait` return. Boxing into a trait object gives mockall a
// concrete, nameable type while still forwarding `BuildTask::run`'s lazy
// message stream, so consumers like `get_target_dir_from_output` can
// short-circuit instead of parsing/allocating every cargo message up front.
pub fn run<'a>(
&self,
params: &BuildTaskParams<'a>,
command_exec: &CommandExec,
) -> Result<Box<dyn Iterator<Item = Result<Message, std::io::Error>>>, BuildTaskError> {
BuildTask::new(*params, command_exec).run().map(|messages| {
Box::new(messages) as Box<dyn Iterator<Item = Result<Message, std::io::Error>>>
})
}
Comment thread
krishnakumar4a4 marked this conversation as resolved.
Comment thread
krishnakumar4a4 marked this conversation as resolved.
}

/// Builds specified package by running `cargo build`
pub struct BuildTask<'a> {
params: BuildTaskParams<'a>,
Expand Down Expand Up @@ -90,9 +118,14 @@ impl<'a> BuildTask<'a> {
/// not a valid unicode
/// * `BuildTaskError::CargoBuild` - If there is an error running the `cargo
/// build` command
// `+ use<>` opts this RPIT out of capturing the `&self` lifetime (edition
// 2024 captures in-scope lifetimes by default). The returned iterator owns
// its buffer (`Cursor<Vec<u8>>`), so it is effectively `'static`; opting out
// of the capture lets `BuildTaskRunner::run` move it out of the temporary
// `BuildTask` and box it as a `'static` trait object.
pub fn run(
&self,
) -> Result<impl Iterator<Item = Result<Message, std::io::Error>>, BuildTaskError> {
) -> Result<impl Iterator<Item = Result<Message, std::io::Error>> + use<>, BuildTaskError> {
debug!("Running cargo build");
let mut args = vec!["build".to_string()];
args.push("--message-format=json-render-diagnostics".to_string());
Expand Down
46 changes: 36 additions & 10 deletions crates/cargo-wdk/src/actions/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ use std::{
};

use anyhow::Result;
use build_task::{BuildTask, BuildTaskParams};
use build_task::BuildTaskParams;
#[double]
use build_task::BuildTaskRunner;
use cargo_metadata::{CrateType, Message, Metadata as CargoMetadata, Package, TargetKind};
use clap_cargo::Features;
use error::BuildActionError;
use mockall_double::double;
use package_task::PackageTaskParams;
#[double]
use package_task::PackageTaskRunner;
pub use package_task::SignMode;
use package_task::{PackageTask, PackageTaskParams};
use tracing::{debug, error as err, info, trace, warn};
use wdk_build::{
CpuArchitecture,
Expand Down Expand Up @@ -63,6 +67,8 @@ pub struct BuildAction<'a> {
command_exec: &'a CommandExec,
fs: &'a Fs,
metadata: &'a Metadata,
build_task_runner: BuildTaskRunner,
package_task_runner: PackageTaskRunner,
}

impl<'a> BuildAction<'a> {
Expand All @@ -89,6 +95,26 @@ impl<'a> BuildAction<'a> {
command_exec: &'a CommandExec,
fs: &'a Fs,
metadata: &'a Metadata,
) -> Result<Self> {
Self::new_with_runners(
params,
wdk_build,
command_exec,
fs,
metadata,
BuildTaskRunner::default(),
PackageTaskRunner::default(),
)
}

fn new_with_runners(
params: &BuildActionParams<'a>,
wdk_build: &'a WdkBuild,
command_exec: &'a CommandExec,
fs: &'a Fs,
metadata: &'a Metadata,
build_task_runner: BuildTaskRunner,
package_task_runner: PackageTaskRunner,
) -> Result<Self> {
// TODO: validate params
anyhow::ensure!(
Expand All @@ -108,6 +134,8 @@ impl<'a> BuildAction<'a> {
command_exec,
fs,
metadata,
build_task_runner,
package_task_runner,
})
}

Expand Down Expand Up @@ -345,8 +373,8 @@ impl<'a> BuildAction<'a> {
let package_name = package.name.as_str();
info!("Building package {package_name}");

let build_task = BuildTask::new(
BuildTaskParams {
let output_message_iter = self.build_task_runner.run(
&BuildTaskParams {
package_name,
working_dir,
profile: self.profile,
Expand All @@ -356,8 +384,7 @@ impl<'a> BuildAction<'a> {
verbosity_level: self.verbosity_level,
},
self.command_exec,
);
let output_message_iter = build_task.run()?;
)?;

let wdk_metadata = if let Ok(wdk_metadata) = wdk_metadata {
debug!("Found wdk metadata in package: {}", package_name);
Expand Down Expand Up @@ -398,8 +425,8 @@ impl<'a> BuildAction<'a> {
target_dir.display()
);

PackageTask::new(
PackageTaskParams {
self.package_task_runner.run(
&PackageTaskParams {
package_name,
working_dir,
target_dir: &target_dir,
Expand All @@ -411,8 +438,7 @@ impl<'a> BuildAction<'a> {
self.wdk_build,
self.command_exec,
self.fs,
)
.run()?;
)?;

info!("Finished building {package_name}");
Ok(())
Expand Down
Loading
Loading