2 use std
::fs
::{self, File}
;
3 use std
::io
::prelude
::*;
4 use std
::path
::{Path, PathBuf}
;
7 use crate::support
::cargo_process
;
8 use crate::support
::paths
::{self, CargoPathExt}
;
9 use crate::support
::registry
::Package
;
10 use crate::support
::{basic_bin_manifest, basic_manifest, cargo_exe, project, Project}
;
13 #[cfg_attr(windows, allow(dead_code))]
16 Symlink { target: &'a Path }
,
19 /// Adds an empty file with executable flags (and platform-dependent suffix).
21 // TODO: move this to `Project` if other cases using this emerge.
22 fn fake_file(proj
: Project
, dir
: &Path
, name
: &str, kind
: &FakeKind
<'_
>) -> Project
{
26 .join(&format
!("{}{}", name
, env
::consts
::EXE_SUFFIX
));
27 path
.parent().unwrap().mkdir_p();
29 FakeKind
::Executable
=> {
30 File
::create(&path
).unwrap();
31 make_executable(&path
);
33 FakeKind
::Symlink { target }
=> {
34 make_symlink(&path
, target
);
40 fn make_executable(p
: &Path
) {
41 use std
::os
::unix
::prelude
::*;
43 let mut perms
= fs
::metadata(p
).unwrap().permissions();
44 let mode
= perms
.mode();
45 perms
.set_mode(mode
| 0o111);
46 fs
::set_permissions(p
, perms
).unwrap();
49 fn make_executable(_
: &Path
) {}
51 fn make_symlink(p
: &Path
, t
: &Path
) {
52 ::std
::os
::unix
::fs
::symlink(t
, p
).expect("Failed to create symlink");
55 fn make_symlink(_
: &Path
, _
: &Path
) {
56 panic
!("Not supported")
60 fn path() -> Vec
<PathBuf
> {
61 env
::split_paths(&env
::var_os("PATH").unwrap_or_default()).collect()
65 fn list_commands_with_descriptions() {
66 let p
= project().build();
68 .with_stdout_contains(
69 " build Compile a local package and all of its dependencies",
71 // Assert that `read-manifest` prints the right one-line description followed by another
73 .with_stdout_contains(
74 " read-manifest Print a JSON representation of a Cargo.toml manifest.",
80 fn list_command_looks_at_path() {
81 let proj
= project().build();
84 Path
::new("path-test"),
86 &FakeKind
::Executable
,
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 "),
104 // Windows and symlinks don't currently mix well.
107 fn list_command_resolves_symlinks() {
108 let proj
= project().build();
109 let proj
= fake_file(
111 Path
::new("path-test"),
114 target
: &cargo_exe(),
118 let mut path
= path();
119 path
.push(proj
.root().join("path-test"));
120 let path
= env
::join_paths(path
.iter()).unwrap();
121 let output
= cargo_process("-v --list")
125 let output
= str::from_utf8(&output
.stdout
).unwrap();
127 output
.contains("\n 2 "),
134 fn find_closest_biuld_to_build() {
135 cargo_process("biuld")
137 .with_stderr_contains(
139 error: no such subcommand: `biuld`
141 <tab>Did you mean `build`?
146 // But, if we actually have `biuld`, it must work!
147 // https://github.com/rust-lang/cargo/issues/5201
148 Package
::new("cargo-biuld", "1.0.0")
153 println!("Similar, but not identical to, build");
159 cargo_process("install cargo-biuld").run();
160 cargo_process("biuld")
161 .with_stdout("Similar, but not identical to, build\n")
163 cargo_process("--list")
164 .with_stdout_contains(
165 " build Compile a local package and all of its dependencies\n",
167 .with_stdout_contains(" biuld\n")
171 // If a subcommand is more than an edit distance of 3 away, we don't make a suggestion.
173 fn find_closest_dont_correct_nonsense() {
174 cargo_process("there-is-no-way-that-there-is-a-command-close-to-this")
178 "[ERROR] no such subcommand: \
179 `there-is-no-way-that-there-is-a-command-close-to-this`
186 fn displays_subcommand_on_error() {
187 cargo_process("invalid-command")
189 .with_stderr("[ERROR] no such subcommand: `invalid-command`\n")
194 fn override_cargo_home() {
195 let root
= paths
::root();
196 let my_home
= root
.join("my_home");
197 fs
::create_dir(&my_home
).unwrap();
198 File
::create(&my_home
.join("config"))
210 cargo_process("new foo")
212 .env("CARGO_HOME", &my_home
)
215 let toml
= paths
::root().join("foo/Cargo.toml");
216 let mut contents
= String
::new();
219 .read_to_string(&mut contents
)
221 assert
!(contents
.contains(r
#"authors = ["foo <bar>"]"#));
225 fn cargo_subcommand_env() {
231 println!("{{}}", env::var("{}").unwrap());
239 .file("Cargo.toml", &basic_bin_manifest("cargo-envtest"))
240 .file("src/main.rs", &src
)
243 let target_dir
= p
.target_debug_dir();
245 p
.cargo("build").run();
246 assert
!(p
.bin("cargo-envtest").is_file());
248 let cargo
= cargo_exe().canonicalize().unwrap();
249 let mut path
= path();
250 path
.push(target_dir
);
251 let path
= env
::join_paths(path
.iter()).unwrap();
253 cargo_process("envtest")
255 .with_stdout(cargo
.to_str().unwrap())
260 fn cargo_subcommand_args() {
263 .file("Cargo.toml", &basic_manifest("cargo-foo", "0.0.1"))
268 let args: Vec<_> = ::std::env::args().collect();
269 println!("{:?}", args);
275 p
.cargo("build").run();
276 let cargo_foo_bin
= p
.bin("cargo-foo");
277 assert
!(cargo_foo_bin
.is_file());
279 let mut path
= path();
280 path
.push(p
.target_debug_dir());
281 let path
= env
::join_paths(path
.iter()).unwrap();
283 cargo_process("foo bar -v --help")
286 r
#"["[CWD]/cargo-foo/target/debug/cargo-foo[EXE]", "foo", "bar", "-v", "--help"]"#,
293 cargo_process("").run();
294 cargo_process("help").run();
295 cargo_process("-h").run();
296 cargo_process("help build").run();
297 cargo_process("build -h").run();
298 cargo_process("help help").run();
302 fn cargo_help_external_subcommand() {
303 Package
::new("cargo-fake-help", "1.0.0")
308 if ::std::env::args().nth(2) == Some(String::from("--help")) {
309 println!("fancy help output");
314 cargo_process("install cargo-fake-help").run();
315 cargo_process("help fake-help")
316 .with_stdout("fancy help output\n")
322 cargo_process("--explain E0001")
323 .with_stdout_contains(
324 "This error suggests that the expression arm corresponding to the noted pattern",
329 // Test that the output of `cargo -Z help` shows a different help screen with
330 // all the `-Z` flags.
333 cargo_process("-Z help")
334 .with_stdout_contains(
335 " -Z unstable-options -- Allow the usage of unstable options such as --registry",