forked from rust-lang/cargo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.rs
135 lines (121 loc) · 5.23 KB
/
run.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use std::iter::FromIterator;
use cargo::core::Workspace;
use cargo::ops::{self, MessageFormat, Packages};
use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct Options {
flag_bin: Option<String>,
flag_example: Option<String>,
flag_package: Option<String>,
flag_jobs: Option<u32>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_release: bool,
flag_frozen: bool,
flag_locked: bool,
arg_args: Vec<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Run the main binary of the local package (src/main.rs)
Usage:
cargo run [options] [--] [<args>...]
Options:
-h, --help Print this message
--bin NAME Name of the bin target to run
--example NAME Name of the example target to run
-p SPEC, --package SPEC Package with the target to run
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--release Build artifacts in release mode, with optimizations
--features FEATURES Space-separated list of features to also build
--all-features Build all available features
--no-default-features Do not build the `default` feature
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to execute
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
If neither `--bin` nor `--example` are given, then if the project only has one
bin target it will be run. Otherwise `--bin` specifies the bin target to run,
and `--example` specifies the example target to run. At most one of `--bin` or
`--example` can be provided.
All of the trailing arguments are passed to the binary to run. If you're passing
arguments to both Cargo and the binary, the ones after `--` go to the binary,
the ones before go to Cargo.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let (mut examples, mut bins) = (Vec::new(), Vec::new());
if let Some(s) = options.flag_bin {
bins.push(s);
}
if let Some(s) = options.flag_example {
examples.push(s);
}
let packages = Vec::from_iter(options.flag_package.iter().cloned());
let spec = Packages::Packages(&packages);
let compile_opts = ops::CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| &t[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec,
release: options.flag_release,
mode: ops::CompileMode::Build,
filter: if examples.is_empty() && bins.is_empty() {
ops::CompileFilter::Default { required_features_filterable: false, }
} else {
ops::CompileFilter::new(false,
&bins, false,
&[], false,
&examples, false,
&[], false,
false)
},
message_format: options.flag_message_format,
target_rustdoc_args: None,
target_rustc_args: None,
};
let ws = Workspace::new(&root, config)?;
match ops::run(&ws, &compile_opts, &options.arg_args)? {
None => Ok(()),
Some(err) => {
// If we never actually spawned the process then that sounds pretty
// bad and we always want to forward that up.
let exit = match err.exit {
Some(exit) => exit,
None => return Err(CliError::new(err.into(), 101)),
};
// If `-q` was passed then we suppress extra error information about
// a failed process, we assume the process itself printed out enough
// information about why it failed so we don't do so as well
let exit_code = exit.code().unwrap_or(101);
Err(if options.flag_quiet == Some(true) {
CliError::code(exit_code)
} else {
CliError::new(err.into(), exit_code)
})
}
}
}