]> git.proxmox.com Git - cargo.git/blame - tests/testsuite/cargo_command.rs
Auto merge of #9118 - bjorn3:profile_codegen_backend_option, r=joshtriplett
[cargo.git] / tests / testsuite / cargo_command.rs
CommitLineData
83571aee
EH
1//! Tests for custom cargo commands and other global command features.
2
ee5e24ff 3use std::env;
dde290e6 4use std::fs;
7274307a 5use std::io::Read;
a6dad622 6use std::path::{Path, PathBuf};
7274307a 7use std::process::Stdio;
8cce8996 8use std::str;
8cce8996 9
9115b2c3 10use cargo_test_support::cargo_process;
dde290e6 11use cargo_test_support::paths;
9115b2c3 12use cargo_test_support::registry::Package;
dde290e6 13use cargo_test_support::{basic_bin_manifest, basic_manifest, cargo_exe, project};
a3f6a404 14
a6dad622 15fn path() -> Vec<PathBuf> {
23591fe5 16 env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect()
db3823a8 17}
ee5e24ff 18
0e0d9688 19#[cargo_test]
af2c3555
DW
20fn list_commands_with_descriptions() {
21 let p = project().build();
a173fc0a 22 p.cargo("--list")
fecb7246
AC
23 .with_stdout_contains(
24 " build Compile a local package and all of its dependencies",
25 )
f7c91ba6
AR
26 // Assert that `read-manifest` prints the right one-line description followed by another
27 // command, indented.
fecb7246
AC
28 .with_stdout_contains(
29 " read-manifest Print a JSON representation of a Cargo.toml manifest.",
30 )
a173fc0a 31 .run();
af2c3555
DW
32}
33
7b16c7c1
C
34#[cargo_test]
35fn list_aliases_with_descriptions() {
36 let p = project().build();
37 p.cargo("--list")
38 .with_stdout_contains(" b alias: build")
39 .with_stdout_contains(" c alias: check")
40 .with_stdout_contains(" r alias: run")
41 .with_stdout_contains(" t alias: test")
42 .run();
43}
44
0e0d9688 45#[cargo_test]
6950bbb0 46fn list_command_looks_at_path() {
dde290e6
NK
47 let proj = project()
48 .executable(Path::new("path-test").join("cargo-1"), "")
49 .build();
a3f6a404 50
5d0cb3f2 51 let mut path = path();
db3823a8 52 path.push(proj.root().join("path-test"));
ee5e24ff 53 let path = env::join_paths(path.iter()).unwrap();
fecb7246
AC
54 let output = cargo_process("-v --list")
55 .env("PATH", &path)
56 .exec_with_output()
57 .unwrap();
63b34b64
DW
58 let output = str::from_utf8(&output.stdout).unwrap();
59 assert!(
60 output.contains("\n 1 "),
61 "missing 1: {}",
62 output
63 );
6950bbb0 64}
12f5de8e 65
0e0d9688 66#[cargo_test]
6950bbb0 67fn list_command_resolves_symlinks() {
dde290e6
NK
68 let proj = project()
69 .symlink(cargo_exe(), Path::new("path-test").join("cargo-2"))
70 .build();
974d5834
JB
71
72 let mut path = path();
73 path.push(proj.root().join("path-test"));
74 let path = env::join_paths(path.iter()).unwrap();
fecb7246
AC
75 let output = cargo_process("-v --list")
76 .env("PATH", &path)
77 .exec_with_output()
78 .unwrap();
63b34b64
DW
79 let output = str::from_utf8(&output.stdout).unwrap();
80 assert!(
81 output.contains("\n 2 "),
82 "missing 2: {}",
83 output
84 );
6950bbb0 85}
974d5834 86
0e0d9688 87#[cargo_test]
6950bbb0 88fn find_closest_biuld_to_build() {
85984a87
DW
89 cargo_process("biuld")
90 .with_status(101)
91 .with_stderr_contains(
1e682848 92 "\
a1735c7a
AK
93error: no such subcommand: `biuld`
94
95<tab>Did you mean `build`?
1e682848 96",
fecb7246
AC
97 )
98 .run();
a1735c7a
AK
99
100 // But, if we actually have `biuld`, it must work!
101 // https://github.com/rust-lang/cargo/issues/5201
102 Package::new("cargo-biuld", "1.0.0")
103 .file(
104 "src/main.rs",
105 r#"
6f8c7d5a
EH
106 fn main() {
107 println!("Similar, but not identical to, build");
108 }
109 "#,
fecb7246
AC
110 )
111 .publish();
85984a87
DW
112
113 cargo_process("install cargo-biuld").run();
114 cargo_process("biuld")
115 .with_stdout("Similar, but not identical to, build\n")
116 .run();
117 cargo_process("--list")
118 .with_stdout_contains(
119 " build Compile a local package and all of its dependencies\n",
fecb7246
AC
120 )
121 .with_stdout_contains(" biuld\n")
85984a87 122 .run();
6950bbb0 123}
12f5de8e 124
ff3e880c
ZL
125#[cargo_test]
126fn find_closest_alias() {
127 let root = paths::root();
128 let my_home = root.join("my_home");
129 fs::create_dir(&my_home).unwrap();
4ae79d2f
EH
130 fs::write(
131 &my_home.join("config"),
132 r#"
133 [alias]
134 myalias = "build"
135 "#,
136 )
137 .unwrap();
ff3e880c
ZL
138
139 cargo_process("myalais")
140 .env("CARGO_HOME", &my_home)
141 .with_status(101)
142 .with_stderr_contains(
143 "\
144error: no such subcommand: `myalais`
145
146<tab>Did you mean `myalias`?
147",
148 )
149 .run();
150
151 // But, if no alias is defined, it must not suggest one!
152 cargo_process("myalais")
153 .with_status(101)
154 .with_stderr_contains(
155 "\
156error: no such subcommand: `myalais`
157",
158 )
159 .with_stderr_does_not_contain(
160 "\
161<tab>Did you mean `myalias`?
162",
163 )
164 .run();
165}
166
f7c91ba6 167// If a subcommand is more than an edit distance of 3 away, we don't make a suggestion.
0e0d9688 168#[cargo_test]
6950bbb0 169fn find_closest_dont_correct_nonsense() {
85984a87
DW
170 cargo_process("there-is-no-way-that-there-is-a-command-close-to-this")
171 .cwd(&paths::root())
172 .with_status(101)
173 .with_stderr(
1e682848 174 "[ERROR] no such subcommand: \
1671630b 175 `there-is-no-way-that-there-is-a-command-close-to-this`
1e682848 176",
fecb7246
AC
177 )
178 .run();
79858995
KA
179}
180
0e0d9688 181#[cargo_test]
79858995 182fn displays_subcommand_on_error() {
85984a87
DW
183 cargo_process("invalid-command")
184 .with_status(101)
185 .with_stderr("[ERROR] no such subcommand: `invalid-command`\n")
186 .run();
6950bbb0 187}
2badab8c 188
b0998864
J
189#[cargo_test]
190fn override_cargo_home() {
191 let root = paths::root();
192 let my_home = root.join("my_home");
193 fs::create_dir(&my_home).unwrap();
194 fs::write(
195 &my_home.join("config"),
196 r#"
197 [cargo-new]
198 vcs = "none"
199 "#,
200 )
201 .unwrap();
202
203 cargo_process("new foo").env("CARGO_HOME", &my_home).run();
204
205 assert!(!paths::root().join("foo/.git").is_dir());
206
207 cargo_process("new foo2").run();
208
209 assert!(paths::root().join("foo2/.git").is_dir());
210}
211
0e0d9688 212#[cargo_test]
015a08a0 213fn cargo_subcommand_env() {
1e682848
AC
214 let src = format!(
215 r#"
015a08a0
VK
216 use std::env;
217
218 fn main() {{
219 println!("{{}}", env::var("{}").unwrap());
220 }}
1e682848
AC
221 "#,
222 cargo::CARGO_ENV
223 );
015a08a0 224
85984a87
DW
225 let p = project()
226 .at("cargo-envtest")
015a08a0 227 .file("Cargo.toml", &basic_bin_manifest("cargo-envtest"))
d43ee1dd
NK
228 .file("src/main.rs", &src)
229 .build();
015a08a0
VK
230
231 let target_dir = p.target_debug_dir();
232
85984a87 233 p.cargo("build").run();
570fe892 234 assert!(p.bin("cargo-envtest").is_file());
015a08a0 235
015a08a0
VK
236 let cargo = cargo_exe().canonicalize().unwrap();
237 let mut path = path();
238 path.push(target_dir);
239 let path = env::join_paths(path.iter()).unwrap();
240
85984a87
DW
241 cargo_process("envtest")
242 .env("PATH", &path)
243 .with_stdout(cargo.to_str().unwrap())
244 .run();
015a08a0
VK
245}
246
0e0d9688 247#[cargo_test]
deb1c1e1 248fn cargo_subcommand_args() {
85984a87
DW
249 let p = project()
250 .at("cargo-foo")
ab19c483 251 .file("Cargo.toml", &basic_manifest("cargo-foo", "0.0.1"))
deb1c1e1
AK
252 .file(
253 "src/main.rs",
254 r#"
6f8c7d5a
EH
255 fn main() {
256 let args: Vec<_> = ::std::env::args().collect();
aea5ca3c 257 println!("{}", args.join(" "));
6f8c7d5a
EH
258 }
259 "#,
fecb7246
AC
260 )
261 .build();
deb1c1e1 262
85984a87 263 p.cargo("build").run();
deb1c1e1 264 let cargo_foo_bin = p.bin("cargo-foo");
570fe892 265 assert!(cargo_foo_bin.is_file());
deb1c1e1
AK
266
267 let mut path = path();
268 path.push(p.target_debug_dir());
269 let path = env::join_paths(path.iter()).unwrap();
270
85984a87
DW
271 cargo_process("foo bar -v --help")
272 .env("PATH", &path)
aea5ca3c 273 .with_stdout("[CWD]/cargo-foo/target/debug/cargo-foo[EXE] foo bar -v --help")
49f73b9c 274 .run();
deb1c1e1
AK
275}
276
0e0d9688 277#[cargo_test]
6950bbb0 278fn explain() {
85984a87
DW
279 cargo_process("--explain E0001")
280 .with_stdout_contains(
b0c181d9 281 "This error suggests that the expression arm corresponding to the noted pattern",
fecb7246
AC
282 )
283 .run();
6950bbb0 284}
a4104914 285
7274307a
EH
286#[cargo_test]
287fn closed_output_ok() {
288 // Checks that closed output doesn't cause an error.
289 let mut p = cargo_process("--list").build_command();
290 p.stdout(Stdio::piped()).stderr(Stdio::piped());
291 let mut child = p.spawn().unwrap();
292 // Close stdout
293 drop(child.stdout.take());
294 // Read stderr
295 let mut s = String::new();
296 child
297 .stderr
298 .as_mut()
299 .unwrap()
300 .read_to_string(&mut s)
301 .unwrap();
302 let status = child.wait().unwrap();
303 assert!(status.success());
f5a3d559 304 assert!(s.is_empty(), "{}", s);
7274307a 305}