cli_xtask/subcommand/
udeps.rs

1use std::process::Command;
2
3use crate::{
4    args::{EnvArgs, FeatureArgs},
5    config::Config,
6    process::CommandExt,
7    Result, Run,
8};
9
10/// Arguments definition of the `udeps` subcommand.
11#[cfg_attr(doc, doc = include_str!("../../doc/cargo-xtask-udeps.md"))]
12#[derive(Debug, Clone, Default, clap::Args)]
13#[non_exhaustive]
14pub struct Udeps {
15    /// Environment variables to set for `cargo udeps`.
16    #[clap(flatten)]
17    pub env_args: EnvArgs,
18    /// Features to run the `cargo udeps` with
19    #[clap(flatten)]
20    pub feature_args: FeatureArgs,
21    /// Options to pass to the `cargo udeps`
22    pub extra_options: Vec<String>,
23}
24
25impl Run for Udeps {
26    fn run(&self, config: &Config) -> Result<()> {
27        self.run(config)
28    }
29}
30
31impl Udeps {
32    /// Runs the `udeps` subcommand.
33    #[tracing::instrument(name = "udeps", skip_all, err)]
34    pub fn run(&self, _config: &Config) -> Result<()> {
35        let Self {
36            env_args,
37            feature_args,
38            extra_options,
39        } = self;
40
41        for res in feature_args.features() {
42            let (workspace, package, features) = res?;
43            // rustup run nightly cargo udeps --package <pkg> <features> <extra_options>
44            // `cargo +nightly udeps` fails on windows, so use rustup instead
45            Command::new("rustup")
46                .args([
47                    "run",
48                    "nightly",
49                    "cargo",
50                    "udeps",
51                    "--package",
52                    &package.name,
53                    // workaround: on windows, `cargo udeps` fails for some packages with following error:
54                    // error[E0514]: found crate `<crate>` compiled by an incompatible version of rustc
55                    "--target-dir",
56                    workspace.target_directory.join("nightly").as_str(),
57                ])
58                .args(features.map(|f| f.to_args()).unwrap_or_default())
59                .args(extra_options)
60                .envs(env_args.env.clone())
61                .workspace_spawn(workspace)?;
62        }
63
64        Ok(())
65    }
66}