-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
cli.rs
188 lines (168 loc) · 5.94 KB
/
cli.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
extern crate clap;
use clap::{AppSettings, Arg, ArgMatches};
use cargo::{self, CliResult, Config};
use super::list_commands;
use super::commands;
use command_prelude::*;
pub fn main(config: &mut Config) -> CliResult {
let args = cli().get_matches_safe()?;
if args.value_of("unstable-features") == Some("help") {
println!(
"
Available unstable (nightly-only) flags:
-Z avoid-dev-deps -- Avoid installing dev-dependencies if possible
-Z minimal-versions -- Install minimal dependency versions instead of maximum
-Z no-index-update -- Do not update the registry, avoids a network request for benchmarking
-Z offline -- Offline mode that does not perform network requests
-Z unstable-options -- Allow the usage of unstable options such as --registry
Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
);
return Ok(());
}
let is_verbose = args.occurrences_of("verbose") > 0;
if args.is_present("version") {
let version = cargo::version();
println!("{}", version);
if is_verbose {
println!(
"release: {}.{}.{}",
version.major, version.minor, version.patch
);
if let Some(ref cfg) = version.cfg_info {
if let Some(ref ci) = cfg.commit_info {
println!("commit-hash: {}", ci.commit_hash);
println!("commit-date: {}", ci.commit_date);
}
}
}
return Ok(());
}
if let Some(ref code) = args.value_of("explain") {
let mut procss = config.rustc()?.process();
procss.arg("--explain").arg(code).exec()?;
return Ok(());
}
if args.is_present("list") {
println!("Installed Commands:");
for command in list_commands(config) {
let (command, path) = command;
if is_verbose {
match path {
Some(p) => println!(" {:<20} {}", command, p),
None => println!(" {:<20}", command),
}
} else {
println!(" {}", command);
}
}
return Ok(());
}
execute_subcommand(config, args)
}
fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult {
config.configure(
args.occurrences_of("verbose") as u32,
if args.is_present("quiet") {
Some(true)
} else {
None
},
&args.value_of("color").map(|s| s.to_string()),
args.is_present("frozen"),
args.is_present("locked"),
&args.values_of_lossy("unstable-features")
.unwrap_or_default(),
)?;
let (cmd, args) = match args.subcommand() {
(cmd, Some(args)) => (cmd, args),
_ => {
cli().print_help()?;
return Ok(());
}
};
if let Some(exec) = commands::builtin_exec(cmd) {
return exec(config, args);
}
if let Some(mut alias) = super::aliased_command(config, cmd)? {
alias.extend(
args.values_of("")
.unwrap_or_default()
.map(|s| s.to_string()),
);
let args = cli()
.setting(AppSettings::NoBinaryName)
.get_matches_from_safe(alias)?;
return execute_subcommand(config, args);
}
let mut ext_args: Vec<&str> = vec![cmd];
ext_args.extend(args.values_of("").unwrap_or_default());
super::execute_external_subcommand(config, cmd, &ext_args)
}
fn cli() -> App {
let app = App::new("cargo")
.settings(&[
AppSettings::UnifiedHelpMessage,
AppSettings::DeriveDisplayOrder,
AppSettings::VersionlessSubcommands,
AppSettings::AllowExternalSubcommands,
])
.about("")
.template(
"\
Rust's package manager
USAGE:
{usage}
OPTIONS:
{unified}
Some common cargo commands are (see all commands with --list):
build Compile the current project
check Analyze the current project and report errors, but don't build object files
clean Remove the target directory
doc Build this project's and its dependencies' documentation
new Create a new cargo project
init Create a new cargo project in an existing directory
run Build and execute src/main.rs
test Run the tests
bench Run the benchmarks
update Update dependencies listed in Cargo.lock
search Search registry for crates
publish Package and upload this project to the registry
install Install a Rust binary
uninstall Uninstall a Rust binary
See 'cargo help <command>' for more information on a specific command.\n",
)
.arg(opt("version", "Print version info and exit").short("V"))
.arg(opt("list", "List installed commands"))
.arg(opt("explain", "Run `rustc --explain CODE`").value_name("CODE"))
.arg(
opt(
"verbose",
"Use verbose output (-vv very verbose/build.rs output)",
).short("v")
.multiple(true)
.global(true),
)
.arg(
opt("quiet", "No output printed to stdout")
.short("q")
.global(true),
)
.arg(
opt("color", "Coloring: auto, always, never")
.value_name("WHEN")
.global(true),
)
.arg(opt("frozen", "Require Cargo.lock and cache are up to date").global(true))
.arg(opt("locked", "Require Cargo.lock is up to date").global(true))
.arg(
Arg::with_name("unstable-features")
.help("Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details")
.short("Z")
.value_name("FLAG")
.multiple(true)
.number_of_values(1)
.global(true),
)
.subcommands(commands::builtin());
app
}