]>
git.proxmox.com Git - cargo.git/blob - tests/testsuite/cargo_command.rs
1 //! Tests for custom cargo commands and other global command features.
6 use std
::path
::{Path, PathBuf}
;
7 use std
::process
::Stdio
;
10 use cargo_test_support
::registry
::Package
;
11 use cargo_test_support
::tools
::echo_subcommand
;
12 use cargo_test_support
::{
13 basic_bin_manifest
, cargo_exe
, cargo_process
, paths
, project
, project_in_home
,
16 fn path() -> Vec
<PathBuf
> {
17 env
::split_paths(&env
::var_os("PATH").unwrap_or_default()).collect()
21 fn list_commands_with_descriptions() {
22 let p
= project().build();
24 .with_stdout_contains(
25 " build Compile a local package and all of its dependencies",
27 // Assert that `read-manifest` prints the right one-line description followed by another
29 .with_stdout_contains(
30 " read-manifest Print a JSON representation of a Cargo.toml manifest.",
36 fn list_builtin_aliases_with_descriptions() {
37 let p
= project().build();
39 .with_stdout_contains(" b alias: build")
40 .with_stdout_contains(" c alias: check")
41 .with_stdout_contains(" r alias: run")
42 .with_stdout_contains(" t alias: test")
47 fn list_custom_aliases_with_descriptions() {
48 let p
= project_in_home("proj")
50 &paths
::home().join(".cargo").join("config"),
53 myaliasstr = "foo --bar"
54 myaliasvec = ["foo", "--bar"]
60 .with_stdout_contains(" myaliasstr alias: foo --bar")
61 .with_stdout_contains(" myaliasvec alias: foo --bar")
68 .executable(Path
::new("path-test-1").join("cargo-dupe"), "")
69 .executable(Path
::new("path-test-2").join("cargo-dupe"), "")
72 let mut path
= path();
73 path
.push(p
.root().join("path-test-1"));
74 path
.push(p
.root().join("path-test-2"));
75 let path
= env
::join_paths(path
.iter()).unwrap();
79 .with_stdout_contains_n(" dupe", 1)
84 fn list_command_looks_at_path() {
86 .executable(Path
::new("path-test").join("cargo-1"), "")
89 let mut path
= path();
90 path
.push(proj
.root().join("path-test"));
91 let path
= env
::join_paths(path
.iter()).unwrap();
92 let output
= cargo_process("-v --list")
96 let output
= str::from_utf8(&output
.stdout
).unwrap();
98 output
.contains("\n 1 "),
105 fn list_command_handles_known_external_commands() {
107 .executable(Path
::new("path-test").join("cargo-fmt"), "")
110 let fmt_desc
= " fmt Formats all bin and lib files of the current crate using rustfmt.";
112 // Without path - fmt isn't there
115 .with_stdout_does_not_contain(fmt_desc
)
118 // With path - fmt is there with known description
119 let mut path
= path();
120 path
.push(p
.root().join("path-test"));
121 let path
= env
::join_paths(path
.iter()).unwrap();
125 .with_stdout_contains(fmt_desc
)
130 fn list_command_resolves_symlinks() {
132 .symlink(cargo_exe(), Path
::new("path-test").join("cargo-2"))
135 let mut path
= path();
136 path
.push(proj
.root().join("path-test"));
137 let path
= env
::join_paths(path
.iter()).unwrap();
138 let output
= cargo_process("-v --list")
142 let output
= str::from_utf8(&output
.stdout
).unwrap();
144 output
.contains("\n 2 "),
151 fn find_closest_capital_c_to_c() {
154 .with_stderr_contains(
156 error: no such subcommand: `C`
158 <tab>Did you mean `c`?
165 fn find_closest_capital_b_to_b() {
168 .with_stderr_contains(
170 error: no such subcommand: `B`
172 <tab>Did you mean `b`?
179 fn find_closest_biuld_to_build() {
180 cargo_process("biuld")
182 .with_stderr_contains(
184 error: no such subcommand: `biuld`
186 <tab>Did you mean `build`?
191 // But, if we actually have `biuld`, it must work!
192 // https://github.com/rust-lang/cargo/issues/5201
193 Package
::new("cargo-biuld", "1.0.0")
198 println!("Similar, but not identical to, build");
204 cargo_process("install cargo-biuld").run();
205 cargo_process("biuld")
206 .with_stdout("Similar, but not identical to, build\n")
208 cargo_process("--list")
209 .with_stdout_contains(
210 " build Compile a local package and all of its dependencies\n",
212 .with_stdout_contains(" biuld\n")
217 fn find_closest_alias() {
218 let root
= paths
::root();
219 let my_home
= root
.join("my_home");
220 fs
::create_dir(&my_home
).unwrap();
222 &my_home
.join("config"),
230 cargo_process("myalais")
231 .env("CARGO_HOME", &my_home
)
233 .with_stderr_contains(
235 error: no such subcommand: `myalais`
237 <tab>Did you mean `myalias`?
242 // But, if no alias is defined, it must not suggest one!
243 cargo_process("myalais")
245 .with_stderr_contains(
247 error: no such subcommand: `myalais`
250 .with_stderr_does_not_contain(
252 <tab>Did you mean `myalias`?
258 // If a subcommand is more than an edit distance of 3 away, we don't make a suggestion.
260 fn find_closest_dont_correct_nonsense() {
261 cargo_process("there-is-no-way-that-there-is-a-command-close-to-this")
266 [ERROR] no such subcommand: `there-is-no-way-that-there-is-a-command-close-to-this`
268 <tab>View all installed commands with `cargo --list`",
274 fn displays_subcommand_on_error() {
275 cargo_process("invalid-command")
279 [ERROR] no such subcommand: `invalid-command`
281 <tab>View all installed commands with `cargo --list`",
287 fn override_cargo_home() {
288 let root
= paths
::root();
289 let my_home
= root
.join("my_home");
290 fs
::create_dir(&my_home
).unwrap();
292 &my_home
.join("config"),
300 cargo_process("new foo").env("CARGO_HOME", &my_home
).run();
302 assert
!(!paths
::root().join("foo/.git").is_dir());
304 cargo_process("new foo2").run();
306 assert
!(paths
::root().join("foo2/.git").is_dir());
310 fn cargo_subcommand_env() {
316 println!("{{}}", env::var("{}").unwrap());
324 .file("Cargo.toml", &basic_bin_manifest("cargo-envtest"))
325 .file("src/main.rs", &src
)
328 let target_dir
= p
.target_debug_dir();
330 p
.cargo("build").run();
331 assert
!(p
.bin("cargo-envtest").is_file());
333 let cargo
= cargo_exe().canonicalize().unwrap();
334 let mut path
= path();
335 path
.push(target_dir
);
336 let path
= env
::join_paths(path
.iter()).unwrap();
338 cargo_process("envtest")
340 .with_stdout(cargo
.to_str().unwrap())
345 fn cargo_subcommand_args() {
346 let p
= echo_subcommand();
347 let cargo_foo_bin
= p
.bin("cargo-echo");
348 assert
!(cargo_foo_bin
.is_file());
350 let mut path
= path();
351 path
.push(p
.target_debug_dir());
352 let path
= env
::join_paths(path
.iter()).unwrap();
354 cargo_process("echo bar -v --help")
356 .with_stdout("echo bar -v --help")
362 cargo_process("--explain E0001")
363 .with_stdout_contains(
364 "This error suggests that the expression arm corresponding to the noted pattern",
370 fn closed_output_ok() {
371 // Checks that closed output doesn't cause an error.
372 let mut p
= cargo_process("--list").build_command();
373 p
.stdout(Stdio
::piped()).stderr(Stdio
::piped());
374 let mut child
= p
.spawn().unwrap();
376 drop(child
.stdout
.take());
378 let mut s
= String
::new();
383 .read_to_string(&mut s
)
385 let status
= child
.wait().unwrap();
386 assert
!(status
.success());
387 assert
!(s
.is_empty(), "{}", s
);
391 fn subcommand_leading_plus_output_contains() {
392 cargo_process("+nightly")
396 error: no such subcommand: `+nightly`
398 <tab>Cargo does not handle `+toolchain` directives.
399 <tab>Did you mean to invoke `cargo` through `rustup` instead?",
405 fn full_did_you_mean() {
406 cargo_process("bluid")
410 error: no such subcommand: `bluid`
412 <tab>Did you mean `build`?
414 <tab>View all installed commands with `cargo --list`",