Skip to main content

cargo_options/
run.rs

1use std::ops::{Deref, DerefMut};
2use std::path::PathBuf;
3use std::process::Command;
4
5use clap::{ArgAction, Parser};
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10use crate::common::CommonOptions;
11use crate::heading;
12
13/// Run a binary or example of the local package
14#[derive(Clone, Debug, Default, Parser)]
15#[command(
16    display_order = 1,
17    after_help = "Run `cargo help run` for more detailed information.\nTo pass `--help` to the specified binary, use `-- --help`."
18)]
19#[group(skip)]
20#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
21pub struct Run {
22    #[command(flatten)]
23    #[cfg_attr(feature = "serde", serde(flatten))]
24    pub common: CommonOptions,
25
26    /// Path to Cargo.toml
27    #[arg(long, value_name = "PATH", help_heading = heading::MANIFEST_OPTIONS)]
28    #[cfg_attr(feature = "serde", serde(default))]
29    pub manifest_path: Option<PathBuf>,
30
31    /// Build artifacts in release mode, with optimizations
32    #[arg(
33        short = 'r',
34        long,
35        conflicts_with = "profile",
36        help_heading = heading::COMPILATION_OPTIONS,
37    )]
38    #[cfg_attr(feature = "serde", serde(default))]
39    pub release: bool,
40
41    /// Ignore `rust-version` specification in packages
42    #[arg(long, help_heading = heading::MANIFEST_OPTIONS)]
43    #[cfg_attr(feature = "serde", serde(default))]
44    pub ignore_rust_version: bool,
45
46    /// Output build graph in JSON (unstable)
47    #[arg(long, help_heading = heading::COMPILATION_OPTIONS)]
48    #[cfg_attr(feature = "serde", serde(default))]
49    pub unit_graph: bool,
50
51    /// Package with the target to run
52    #[arg(
53        short = 'p',
54        long = "package",
55        value_name = "SPEC",
56        action = ArgAction::Append,
57        num_args=0..=1,
58        help_heading = heading::PACKAGE_SELECTION,
59    )]
60    #[cfg_attr(feature = "serde", serde(default))]
61    pub packages: Vec<String>,
62
63    /// Name of the bin target to run
64    #[arg(
65        long,
66        value_name = "NAME",
67        action = ArgAction::Append,
68        num_args=0..=1,
69        help_heading = heading::TARGET_SELECTION,
70    )]
71    #[cfg_attr(feature = "serde", serde(default))]
72    pub bin: Vec<String>,
73
74    /// Name of the example target to run
75    #[arg(
76        long,
77        value_name = "NAME",
78        action = ArgAction::Append,
79        num_args=0..=1,
80        help_heading = heading::TARGET_SELECTION,
81    )]
82    #[cfg_attr(feature = "serde", serde(default))]
83    pub example: Vec<String>,
84
85    /// Arguments for the binary or example to run
86    #[arg(value_name = "ARGS", trailing_var_arg = true, num_args = 0..)]
87    #[cfg_attr(feature = "serde", serde(default))]
88    pub args: Vec<String>,
89}
90
91impl Run {
92    /// Build a `cargo run` command
93    pub fn command(&self) -> Command {
94        let mut cmd = CommonOptions::cargo_command();
95        cmd.arg("run");
96
97        self.common.apply(&mut cmd);
98
99        if let Some(path) = self.manifest_path.as_ref() {
100            cmd.arg("--manifest-path").arg(path);
101        }
102        if self.release {
103            cmd.arg("--release");
104        }
105        if self.ignore_rust_version {
106            cmd.arg("--ignore-rust-version");
107        }
108        if self.unit_graph {
109            cmd.arg("--unit-graph");
110        }
111        for pkg in &self.packages {
112            cmd.arg("--package").arg(pkg);
113        }
114        for bin in &self.bin {
115            cmd.arg("--bin").arg(bin);
116        }
117        for example in &self.example {
118            cmd.arg("--example").arg(example);
119        }
120        if !self.args.is_empty() {
121            cmd.arg("--");
122            cmd.args(&self.args);
123        }
124
125        cmd
126    }
127}
128
129impl Deref for Run {
130    type Target = CommonOptions;
131
132    fn deref(&self) -> &Self::Target {
133        &self.common
134    }
135}
136
137impl DerefMut for Run {
138    fn deref_mut(&mut self) -> &mut Self::Target {
139        &mut self.common
140    }
141}
142
143#[cfg(test)]
144mod test {
145    use super::Run;
146    use clap::CommandFactory;
147
148    #[test]
149    fn verify_cli() {
150        <Run as CommandFactory>::command().debug_assert()
151    }
152}