cargo_subcommand/
args.rs

1use crate::profile::Profile;
2#[cfg(feature = "clap")]
3use clap::Parser;
4use std::path::PathBuf;
5use std::process::Command;
6
7#[derive(Clone, Debug, Eq, PartialEq)]
8#[cfg_attr(feature = "clap", derive(Parser))]
9pub struct Args {
10    /// No output printed to stdout
11    #[cfg_attr(feature = "clap", clap(long, short))]
12    pub quiet: bool,
13
14    /// Package to build
15    #[cfg_attr(feature = "clap", clap(long, short))]
16    pub package: Vec<String>,
17    /// Build all packages in the workspace
18    #[cfg_attr(feature = "clap", clap(long, visible_alias = "all"))]
19    pub workspace: bool,
20    /// Exclude packages from the build
21    #[cfg_attr(feature = "clap", clap(long))]
22    pub exclude: Vec<String>,
23
24    /// Build only this package's library
25    #[cfg_attr(feature = "clap", clap(long))]
26    pub lib: bool,
27    /// Build only the specified binary
28    #[cfg_attr(feature = "clap", clap(long))]
29    pub bin: Vec<String>,
30    /// Build all binaries
31    #[cfg_attr(feature = "clap", clap(long, conflicts_with = "bin"))]
32    pub bins: bool,
33    /// Build only the specified example
34    #[cfg_attr(feature = "clap", clap(long))]
35    pub example: Vec<String>,
36    /// Build all examples
37    #[cfg_attr(feature = "clap", clap(long, conflicts_with = "example"))]
38    pub examples: bool,
39
40    /// Build artifacts in release mode, with optimizations
41    #[cfg_attr(feature = "clap", clap(long, short))]
42    pub release: bool,
43    /// Build artifacts with the specified profile
44    #[cfg_attr(feature = "clap", clap(long, conflicts_with = "release"))]
45    pub profile: Option<Profile>,
46    /// Space or comma separated list of features to activate
47    #[cfg_attr(feature = "clap", clap(long, short = 'F'))]
48    pub features: Vec<String>,
49    /// Activate all available features
50    #[cfg_attr(feature = "clap", clap(long))]
51    pub all_features: bool,
52    /// Do not activate the `default` feature
53    #[cfg_attr(feature = "clap", clap(long))]
54    pub no_default_features: bool,
55    /// Build for the target triple
56    #[cfg_attr(feature = "clap", clap(long))]
57    pub target: Option<String>,
58    /// Directory for all generated artifacts
59    #[cfg_attr(feature = "clap", clap(long))]
60    pub target_dir: Option<PathBuf>,
61    /// Path to Cargo.toml
62    #[cfg_attr(feature = "clap", clap(long))]
63    pub manifest_path: Option<PathBuf>,
64}
65
66impl Args {
67    pub fn apply(&self, cmd: &mut Command) {
68        if self.quiet {
69            cmd.arg("--quiet");
70        }
71
72        for package in &self.package {
73            cmd.arg("--package").arg(package);
74        }
75        if self.workspace {
76            cmd.arg("--workspace");
77        }
78        for exclude in &self.exclude {
79            cmd.arg("--exclude").arg(exclude);
80        }
81
82        if self.lib {
83            cmd.arg("--lib");
84        }
85        for bin in &self.bin {
86            cmd.arg("--bin").arg(bin);
87        }
88        if self.bins {
89            cmd.arg("--bins");
90        }
91        for example in &self.example {
92            cmd.arg("--example").arg(example);
93        }
94        if self.examples {
95            cmd.arg("--examples");
96        }
97
98        if self.release {
99            cmd.arg("--release");
100        }
101        if let Some(profile) = self.profile.as_ref() {
102            cmd.arg("--profile").arg(profile.to_string());
103        }
104        for features in &self.features {
105            cmd.arg("--features").arg(features);
106        }
107        if self.all_features {
108            cmd.arg("--all-features");
109        }
110        if self.no_default_features {
111            cmd.arg("--no-default-features");
112        }
113        if let Some(target) = self.target.as_ref() {
114            cmd.arg("--target").arg(target);
115        }
116        if let Some(target_dir) = self.target_dir.as_ref() {
117            cmd.arg("--target-dir").arg(target_dir);
118        }
119        if let Some(manifest_path) = self.manifest_path.as_ref() {
120            cmd.arg("--manifest-path").arg(manifest_path);
121        }
122    }
123
124    pub fn profile(&self) -> Profile {
125        if let Some(profile) = self.profile.as_ref() {
126            profile.clone()
127        } else if self.release {
128            Profile::Release
129        } else {
130            Profile::Dev
131        }
132    }
133
134    /// Returns [`true`] when one or more target selection options are active.
135    /// This is generally used to deduce whether to default to binary and
136    /// library targets, in accordance with [`cargo build`].
137    ///
138    /// [`cargo build`]: https://doc.rust-lang.org/cargo/commands/cargo-build.html#target-selection
139    pub fn specific_target_selected(&self) -> bool {
140        self.lib || self.bins || self.examples || !self.bin.is_empty() || !self.example.is_empty()
141    }
142}