]> git.proxmox.com Git - rustc.git/blame - src/tools/cargo/tests/testsuite/install.rs
bump version to 1.82.0+dfsg1-1~bpo12+pve2
[rustc.git] / src / tools / cargo / tests / testsuite / install.rs
CommitLineData
0a29b90c
FG
1//! Tests for the `cargo install` command.
2
04c3a46a 3use std::env;
0a29b90c
FG
4use std::fs::{self, OpenOptions};
5use std::io::prelude::*;
6use std::path::Path;
04c3a46a 7use std::path::PathBuf;
4b012472 8use std::thread;
0a29b90c 9
31ef2f64 10use cargo_test_support::compare::assert_e2e;
0a29b90c
FG
11use cargo_test_support::cross_compile;
12use cargo_test_support::git;
04c3a46a
FG
13use cargo_test_support::prelude::*;
14use cargo_test_support::registry::{self, Package};
31ef2f64 15use cargo_test_support::str;
0a29b90c 16use cargo_test_support::{
04c3a46a 17 basic_manifest, cargo_process, project, project_in, symlink_supported, t,
0a29b90c 18};
4b012472 19use cargo_util::{ProcessBuilder, ProcessError};
0a29b90c 20
04c3a46a
FG
21use cargo_test_support::install::{assert_has_installed_exe, assert_has_not_installed_exe, exe};
22use cargo_test_support::paths;
0a29b90c
FG
23
24fn pkg(name: &str, vers: &str) {
25 Package::new(name, vers)
26 .file("src/lib.rs", "")
27 .file(
28 "src/main.rs",
29 &format!("extern crate {}; fn main() {{}}", name),
30 )
31 .publish();
32}
33
34#[cargo_test]
35fn simple() {
36 pkg("foo", "0.0.1");
37
04c3a46a
FG
38 cargo_process("install foo").with_stderr_data(str![[r#"
39[UPDATING] `dummy-registry` index
0a29b90c 40[DOWNLOADING] crates ...
04c3a46a 41[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
0a29b90c
FG
42[INSTALLING] foo v0.0.1
43[COMPILING] foo v0.0.1
04c3a46a
FG
44[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
45[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
0a29b90c 46[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
04c3a46a
FG
47[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
48
49"#]]).run();
50 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
51
52 cargo_process("uninstall foo")
04c3a46a
FG
53 .with_stderr_data(str![[r#"
54[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
55
56"#]])
0a29b90c 57 .run();
04c3a46a 58 assert_has_not_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
59}
60
ed00b5ec
FG
61#[cargo_test]
62fn install_the_same_version_twice() {
63 pkg("foo", "0.0.1");
64
65 cargo_process("install foo foo")
04c3a46a
FG
66 .with_stderr_data(str![[r#"
67[UPDATING] `dummy-registry` index
ed00b5ec 68[DOWNLOADING] crates ...
04c3a46a 69[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
ed00b5ec
FG
70[INSTALLING] foo v0.0.1
71[COMPILING] foo v0.0.1
04c3a46a
FG
72[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
73[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
ed00b5ec 74[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
04c3a46a
FG
75[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
76
77"#]])
ed00b5ec 78 .run();
04c3a46a 79 assert_has_installed_exe(paths::cargo_home(), "foo");
ed00b5ec
FG
80}
81
fe692bf9
FG
82#[cargo_test]
83fn toolchain() {
84 pkg("foo", "0.0.1");
85
86 cargo_process("install +nightly")
87 .with_status(101)
04c3a46a 88 .with_stderr_data(str![[r#"
fe692bf9 89[ERROR] invalid character `+` in package name: `+nightly`
04c3a46a
FG
90 Use `cargo +nightly install` if you meant to use the `nightly` toolchain.
91
92"#]])
fe692bf9
FG
93 .run();
94}
95
781aab86
FG
96#[cargo_test]
97fn url() {
98 pkg("foo", "0.0.1");
99 cargo_process("install https://github.com/bar/foo")
100 .with_status(101)
04c3a46a 101 .with_stderr_data(str![[r#"
781aab86 102[ERROR] invalid package name: `https://github.com/bar/foo`
04c3a46a
FG
103 Use `cargo install --git https://github.com/bar/foo` if you meant to install from a git repository.
104
105"#]])
781aab86
FG
106 .run();
107}
108
0a29b90c
FG
109#[cargo_test]
110fn simple_with_message_format() {
111 pkg("foo", "0.0.1");
112
113 cargo_process("install foo --message-format=json")
04c3a46a
FG
114 .with_stderr_data(str![[r#"
115[UPDATING] `dummy-registry` index
0a29b90c 116[DOWNLOADING] crates ...
04c3a46a 117[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
0a29b90c
FG
118[INSTALLING] foo v0.0.1
119[COMPILING] foo v0.0.1
04c3a46a
FG
120[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
121[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
0a29b90c
FG
122[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
123[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries
04c3a46a
FG
124
125"#]])
126 .with_stdout_data(
127 str![[r#"
128[
129 {
130 "executable": null,
131 "features": [],
132 "filenames": "{...}",
133 "fresh": false,
134 "manifest_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/foo-0.0.1/Cargo.toml",
135 "package_id": "registry+https://github.com/rust-lang/crates.io-index#foo@0.0.1",
136 "profile": "{...}",
137 "reason": "compiler-artifact",
138 "target": {
139 "crate_types": [
140 "lib"
141 ],
142 "doc": true,
143 "doctest": true,
144 "edition": "2015",
145 "kind": [
146 "lib"
147 ],
148 "name": "foo",
149 "src_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/foo-0.0.1/src/lib.rs",
150 "test": true
151 }
152 },
153 {
154 "executable": "[..]",
155 "features": [],
156 "filenames": "{...}",
157 "fresh": false,
158 "manifest_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/foo-0.0.1/Cargo.toml",
159 "package_id": "registry+https://github.com/rust-lang/crates.io-index#foo@0.0.1",
160 "profile": "{...}",
161 "reason": "compiler-artifact",
162 "target": {
163 "crate_types": [
164 "bin"
165 ],
166 "doc": true,
167 "doctest": false,
168 "edition": "2015",
169 "kind": [
170 "bin"
171 ],
172 "name": "foo",
173 "src_path": "[ROOT]/home/.cargo/registry/src/-[HASH]/foo-0.0.1/src/main.rs",
174 "test": true
175 }
176 },
177 {
178 "reason": "build-finished",
179 "success": true
180 }
181]
182"#]]
183 .is_json()
184 .against_jsonlines(),
0a29b90c
FG
185 )
186 .run();
04c3a46a 187 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
188}
189
190#[cargo_test]
191fn with_index() {
192 let registry = registry::init();
193 pkg("foo", "0.0.1");
194
195 cargo_process("install foo --index")
196 .arg(registry.index_url().as_str())
04c3a46a
FG
197 .with_stderr_data(str![[r#"
198[UPDATING] `[ROOT]/registry` index
0a29b90c 199[DOWNLOADING] crates ...
04c3a46a
FG
200[DOWNLOADED] foo v0.0.1 (registry `[ROOT]/registry`)
201[INSTALLING] foo v0.0.1 (registry `[ROOT]/registry`)
202[COMPILING] foo v0.0.1 (registry `[ROOT]/registry`)
203[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
204[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
205[INSTALLED] package `foo v0.0.1 (registry `[ROOT]/registry`)` (executable `foo[EXE]`)
206[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
207
208"#]])
0a29b90c 209 .run();
04c3a46a 210 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
211
212 cargo_process("uninstall foo")
04c3a46a
FG
213 .with_stderr_data(str![[r#"
214[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
215
216"#]])
0a29b90c 217 .run();
04c3a46a 218 assert_has_not_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
219}
220
221#[cargo_test]
222fn multiple_pkgs() {
223 pkg("foo", "0.0.1");
224 pkg("bar", "0.0.2");
225
226 cargo_process("install foo bar baz")
227 .with_status(101)
04c3a46a
FG
228 .with_stderr_data(str![[r#"
229[UPDATING] `dummy-registry` index
0a29b90c
FG
230[DOWNLOADING] crates ...
231[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
232[DOWNLOADING] crates ...
233[DOWNLOADED] bar v0.0.2 (registry `dummy-registry`)
04c3a46a 234[ERROR] could not find `baz` in registry `crates-io` with version `*`
0a29b90c
FG
235[INSTALLING] foo v0.0.1
236[COMPILING] foo v0.0.1
04c3a46a
FG
237[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
238[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
0a29b90c
FG
239[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
240[INSTALLING] bar v0.0.2
241[COMPILING] bar v0.0.2
04c3a46a
FG
242[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
243[INSTALLING] [ROOT]/home/.cargo/bin/bar[EXE]
0a29b90c
FG
244[INSTALLED] package `bar v0.0.2` (executable `bar[EXE]`)
245[SUMMARY] Successfully installed foo, bar! Failed to install baz (see error(s) above).
04c3a46a 246[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
0a29b90c 247[ERROR] some crates failed to install
04c3a46a
FG
248
249"#]])
0a29b90c 250 .run();
04c3a46a
FG
251 assert_has_installed_exe(paths::cargo_home(), "foo");
252 assert_has_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
253
254 cargo_process("uninstall foo bar")
04c3a46a
FG
255 .with_stderr_data(str![[r#"
256[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
257[REMOVING] [ROOT]/home/.cargo/bin/bar[EXE]
0a29b90c 258[SUMMARY] Successfully uninstalled foo, bar!
04c3a46a
FG
259
260"#]])
0a29b90c
FG
261 .run();
262
04c3a46a
FG
263 assert_has_not_installed_exe(paths::cargo_home(), "foo");
264 assert_has_not_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
265}
266
267fn path() -> Vec<PathBuf> {
268 env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect()
269}
270
271#[cargo_test]
272fn multiple_pkgs_path_set() {
273 // confirm partial failure results in 101 status code and does not have the
274 // '[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries'
275 // even if CARGO_HOME/bin is in the PATH
276 pkg("foo", "0.0.1");
277 pkg("bar", "0.0.2");
278
279 // add CARGO_HOME/bin to path
280 let mut path = path();
04c3a46a 281 path.push(paths::cargo_home().join("bin"));
0a29b90c
FG
282 let new_path = env::join_paths(path).unwrap();
283 cargo_process("install foo bar baz")
284 .env("PATH", new_path)
285 .with_status(101)
04c3a46a
FG
286 .with_stderr_data(str![[r#"
287[UPDATING] `dummy-registry` index
0a29b90c
FG
288[DOWNLOADING] crates ...
289[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
290[DOWNLOADING] crates ...
291[DOWNLOADED] bar v0.0.2 (registry `dummy-registry`)
04c3a46a 292[ERROR] could not find `baz` in registry `crates-io` with version `*`
0a29b90c
FG
293[INSTALLING] foo v0.0.1
294[COMPILING] foo v0.0.1
04c3a46a
FG
295[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
296[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
0a29b90c
FG
297[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
298[INSTALLING] bar v0.0.2
299[COMPILING] bar v0.0.2
04c3a46a
FG
300[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
301[INSTALLING] [ROOT]/home/.cargo/bin/bar[EXE]
0a29b90c
FG
302[INSTALLED] package `bar v0.0.2` (executable `bar[EXE]`)
303[SUMMARY] Successfully installed foo, bar! Failed to install baz (see error(s) above).
304[ERROR] some crates failed to install
04c3a46a
FG
305
306"#]])
0a29b90c 307 .run();
04c3a46a
FG
308 assert_has_installed_exe(paths::cargo_home(), "foo");
309 assert_has_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
310
311 cargo_process("uninstall foo bar")
04c3a46a
FG
312 .with_stderr_data(str![[r#"
313[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
314[REMOVING] [ROOT]/home/.cargo/bin/bar[EXE]
0a29b90c 315[SUMMARY] Successfully uninstalled foo, bar!
04c3a46a
FG
316
317"#]])
0a29b90c
FG
318 .run();
319
04c3a46a
FG
320 assert_has_not_installed_exe(paths::cargo_home(), "foo");
321 assert_has_not_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
322}
323
324#[cargo_test]
325fn pick_max_version() {
326 pkg("foo", "0.1.0");
327 pkg("foo", "0.2.0");
328 pkg("foo", "0.2.1");
329 pkg("foo", "0.2.1-pre.1");
330 pkg("foo", "0.3.0-pre.2");
331
04c3a46a
FG
332 cargo_process("install foo").with_stderr_data(str![[r#"
333[UPDATING] `dummy-registry` index
0a29b90c 334[DOWNLOADING] crates ...
04c3a46a 335[DOWNLOADED] foo v0.2.1 (registry `dummy-registry`)
0a29b90c
FG
336[INSTALLING] foo v0.2.1
337[COMPILING] foo v0.2.1
04c3a46a
FG
338[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
339[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
0a29b90c 340[INSTALLED] package `foo v0.2.1` (executable `foo[EXE]`)
04c3a46a
FG
341[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
342
343"#]]).run();
344 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
345}
346
347#[cargo_test]
348fn installs_beta_version_by_explicit_name_from_git() {
349 let p = git::repo(&paths::root().join("foo"))
350 .file("Cargo.toml", &basic_manifest("foo", "0.3.0-beta.1"))
351 .file("src/main.rs", "fn main() {}")
352 .build();
353
354 cargo_process("install --git")
355 .arg(p.url().to_string())
356 .arg("foo")
357 .run();
04c3a46a 358 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
359}
360
361#[cargo_test]
362fn missing() {
363 pkg("foo", "0.0.1");
364 cargo_process("install bar")
365 .with_status(101)
04c3a46a
FG
366 .with_stderr_data(str![[r#"
367[UPDATING] `dummy-registry` index
368[ERROR] could not find `bar` in registry `crates-io` with version `*`
369
370"#]])
0a29b90c
FG
371 .run();
372}
373
374#[cargo_test]
375fn missing_current_working_directory() {
376 cargo_process("install .")
377 .with_status(101)
04c3a46a
FG
378 .with_stderr_data(str![[r#"
379[ERROR] To install the binaries for the package in current working directory use `cargo install --path .`.
380Use `cargo build` if you want to simply build the package.
381
382"#]])
0a29b90c
FG
383 .run();
384}
385
386#[cargo_test]
387fn bad_version() {
388 pkg("foo", "0.0.1");
389 cargo_process("install foo --version=0.2.0")
390 .with_status(101)
04c3a46a
FG
391 .with_stderr_data(str![[r#"
392[UPDATING] `dummy-registry` index
393[ERROR] could not find `foo` in registry `crates-io` with version `=0.2.0`
394
395"#]])
0a29b90c
FG
396 .run();
397}
398
399#[cargo_test]
400fn bad_paths() {
401 cargo_process("install")
402 .with_status(101)
04c3a46a
FG
403 .with_stderr_data(str![[r#"
404[ERROR] `[ROOT]` is not a crate root; specify a crate to install from crates.io, or use --path or --git to specify an alternate source
405
406"#]])
0a29b90c
FG
407 .run();
408
409 cargo_process("install --path .")
410 .with_status(101)
04c3a46a
FG
411 .with_stderr_data(str![[r#"
412[ERROR] `[ROOT]` does not contain a Cargo.toml file. --path must point to a directory containing a Cargo.toml file.
413
414"#]])
0a29b90c
FG
415 .run();
416
417 let toml = paths::root().join("Cargo.toml");
418 fs::write(toml, "").unwrap();
419 cargo_process("install --path Cargo.toml")
420 .with_status(101)
04c3a46a
FG
421 .with_stderr_data(str![[r#"
422[ERROR] `[ROOT]/Cargo.toml` is not a directory. --path must point to a directory containing a Cargo.toml file.
423
424"#]])
0a29b90c
FG
425 .run();
426
427 cargo_process("install --path .")
428 .with_status(101)
04c3a46a
FG
429 .with_stderr_data(str![[r#"
430[ERROR] failed to parse manifest at `[ROOT]/Cargo.toml`
431...
432"#]])
0a29b90c
FG
433 .run();
434}
435
436#[cargo_test]
437fn install_location_precedence() {
438 pkg("foo", "0.0.1");
439
440 let root = paths::root();
441 let t1 = root.join("t1");
442 let t2 = root.join("t2");
443 let t3 = root.join("t3");
04c3a46a 444 let t4 = paths::cargo_home();
0a29b90c
FG
445
446 fs::create_dir(root.join(".cargo")).unwrap();
447 fs::write(
c620b35d 448 root.join(".cargo/config.toml"),
0a29b90c
FG
449 &format!(
450 "[install]
451 root = '{}'
452 ",
453 t3.display()
454 ),
455 )
456 .unwrap();
457
458 println!("install --root");
459
460 cargo_process("install foo --root")
461 .arg(&t1)
462 .env("CARGO_INSTALL_ROOT", &t2)
463 .run();
464 assert_has_installed_exe(&t1, "foo");
465 assert_has_not_installed_exe(&t2, "foo");
466
467 println!("install CARGO_INSTALL_ROOT");
468
469 cargo_process("install foo")
470 .env("CARGO_INSTALL_ROOT", &t2)
471 .run();
472 assert_has_installed_exe(&t2, "foo");
473 assert_has_not_installed_exe(&t3, "foo");
474
475 println!("install install.root");
476
477 cargo_process("install foo").run();
478 assert_has_installed_exe(&t3, "foo");
479 assert_has_not_installed_exe(&t4, "foo");
480
c620b35d 481 fs::remove_file(root.join(".cargo/config.toml")).unwrap();
0a29b90c
FG
482
483 println!("install cargo home");
484
485 cargo_process("install foo").run();
486 assert_has_installed_exe(&t4, "foo");
487}
488
489#[cargo_test]
490fn install_path() {
491 let p = project().file("src/main.rs", "fn main() {}").build();
492
493 cargo_process("install --path").arg(p.root()).run();
04c3a46a 494 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c 495 // path-style installs force a reinstall
04c3a46a
FG
496 p.cargo("install --path .").with_stderr_data(str![[r#"
497[INSTALLING] foo v0.0.1 ([ROOT]/foo)
498[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
499[REPLACING] [ROOT]/home/.cargo/bin/foo[EXE]
500[REPLACED] package `foo v0.0.1 ([ROOT]/foo)` with `foo v0.0.1 ([ROOT]/foo)` (executable `foo[EXE]`)
501[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
502
503"#]]).run();
0a29b90c
FG
504}
505
506#[cargo_test]
507fn install_target_dir() {
508 let p = project().file("src/main.rs", "fn main() {}").build();
509
510 p.cargo("install --target-dir td_test")
04c3a46a
FG
511 .with_stderr_data(str![[r#"
512[WARNING] Using `cargo install` to install the binaries from the package in current working directory is deprecated, use `cargo install --path .` instead. Use `cargo build` if you want to simply build the package.
513[INSTALLING] foo v0.0.1 ([ROOT]/foo)
514[COMPILING] foo v0.0.1 ([ROOT]/foo)
515[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
516[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
517[INSTALLED] package `foo v0.0.1 ([ROOT]/foo)` (executable `foo[EXE]`)
518[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
519
520"#]])
0a29b90c
FG
521 .run();
522
523 let mut path = p.root();
524 path.push("td_test");
525 assert!(path.exists());
526
527 #[cfg(not(windows))]
528 path.push("release/foo");
529 #[cfg(windows)]
530 path.push("release/foo.exe");
531 assert!(path.exists());
532}
533
534#[cargo_test]
535#[cfg(target_os = "linux")]
536fn install_path_with_lowercase_cargo_toml() {
537 let toml = paths::root().join("cargo.toml");
538 fs::write(toml, "").unwrap();
539
540 cargo_process("install --path .")
541 .with_status(101)
04c3a46a
FG
542 .with_stderr_data(str![[r#"
543[ERROR] `[ROOT]` does not contain a Cargo.toml file, but found cargo.toml please try to rename it to Cargo.toml. --path must point to a directory containing a Cargo.toml file.
544
545"#]]
0a29b90c
FG
546 )
547 .run();
548}
549
550#[cargo_test]
551fn install_relative_path_outside_current_ws() {
552 let p = project()
553 .file(
554 "Cargo.toml",
555 r#"
556 [package]
557 name = "bar"
558 version = "0.1.0"
559 authors = []
560
561 [workspace]
562 members = ["baz"]
563 "#,
564 )
565 .file("src/main.rs", "fn main() {}")
566 .file(
567 "baz/Cargo.toml",
568 r#"
569 [package]
570 name = "baz"
571 version = "0.1.0"
572 authors = []
573 edition = "2021"
574
575 [dependencies]
576 foo = "1"
577 "#,
578 )
579 .file("baz/src/lib.rs", "")
580 .build();
581
582 let _bin_project = project_in("bar")
583 .file("src/main.rs", "fn main() {}")
584 .build();
585
586 p.cargo("install --path ../bar/foo")
04c3a46a
FG
587 .with_stderr_data(str![[r#"
588[INSTALLING] foo v0.0.1 ([ROOT]/bar/foo)
589[COMPILING] foo v0.0.1 ([ROOT]/bar/foo)
590[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
591[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
592[INSTALLED] package `foo v0.0.1 ([ROOT]/bar/foo)` (executable `foo[EXE]`)
593[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
594
595"#]])
0a29b90c
FG
596 .run();
597
598 // Validate the workspace error message to display available targets.
599 p.cargo("install --path ../bar/foo --bin")
600 .with_status(101)
04c3a46a
FG
601 .with_stderr_data(str![[r#"
602[ERROR] "--bin" takes one argument.
0a29b90c
FG
603Available binaries:
604 foo
605
04c3a46a
FG
606
607"#]])
0a29b90c
FG
608 .run();
609}
610
611#[cargo_test]
612fn multiple_packages_containing_binaries() {
613 let p = git::repo(&paths::root().join("foo"))
614 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
615 .file("src/main.rs", "fn main() {}")
616 .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0"))
617 .file("a/src/main.rs", "fn main() {}")
618 .build();
619
0a29b90c
FG
620 cargo_process("install --git")
621 .arg(p.url().to_string())
622 .with_status(101)
04c3a46a
FG
623 .with_stderr_data(str![[r#"
624[UPDATING] git repository `[ROOTURL]/foo`
625[ERROR] multiple packages with binaries found: bar, foo. When installing a git repository, cargo will always search the entire repo for any Cargo.toml.
626Please specify a package, e.g. `cargo install --git [ROOTURL]/foo bar`.
627
628"#]])
0a29b90c
FG
629 .run();
630}
631
632#[cargo_test]
633fn multiple_packages_matching_example() {
634 let p = git::repo(&paths::root().join("foo"))
635 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
636 .file("src/lib.rs", "")
637 .file("examples/ex1.rs", "fn main() {}")
638 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
639 .file("bar/src/lib.rs", "")
640 .file("bar/examples/ex1.rs", "fn main() {}")
641 .build();
642
0a29b90c
FG
643 cargo_process("install --example ex1 --git")
644 .arg(p.url().to_string())
645 .with_status(101)
04c3a46a
FG
646 .with_stderr_data(str![[r#"
647[UPDATING] git repository `[ROOTURL]/foo`
648[ERROR] multiple packages with examples found: bar, foo. When installing a git repository, cargo will always search the entire repo for any Cargo.toml.
649Please specify a package, e.g. `cargo install --git [ROOTURL]/foo bar`.
650
651"#]])
0a29b90c
FG
652 .run();
653}
654
655#[cargo_test]
656fn multiple_binaries_deep_select_uses_package_name() {
657 let p = git::repo(&paths::root().join("foo"))
658 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
659 .file("src/main.rs", "fn main() {}")
660 .file("bar/baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
661 .file("bar/baz/src/main.rs", "fn main() {}")
662 .build();
663
664 cargo_process("install --git")
665 .arg(p.url().to_string())
666 .arg("baz")
667 .run();
668}
669
670#[cargo_test]
671fn multiple_binaries_in_selected_package_installs_all() {
672 let p = git::repo(&paths::root().join("foo"))
673 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
674 .file("src/lib.rs", "")
675 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
676 .file("bar/src/bin/bin1.rs", "fn main() {}")
677 .file("bar/src/bin/bin2.rs", "fn main() {}")
678 .build();
679
680 cargo_process("install --git")
681 .arg(p.url().to_string())
682 .arg("bar")
683 .run();
684
04c3a46a 685 let cargo_home = paths::cargo_home();
0a29b90c
FG
686 assert_has_installed_exe(&cargo_home, "bin1");
687 assert_has_installed_exe(&cargo_home, "bin2");
688}
689
690#[cargo_test]
691fn multiple_binaries_in_selected_package_with_bin_option_installs_only_one() {
692 let p = git::repo(&paths::root().join("foo"))
693 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
694 .file("src/lib.rs", "")
695 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
696 .file("bar/src/bin/bin1.rs", "fn main() {}")
697 .file("bar/src/bin/bin2.rs", "fn main() {}")
698 .build();
699
700 cargo_process("install --bin bin1 --git")
701 .arg(p.url().to_string())
702 .arg("bar")
703 .run();
704
04c3a46a 705 let cargo_home = paths::cargo_home();
0a29b90c
FG
706 assert_has_installed_exe(&cargo_home, "bin1");
707 assert_has_not_installed_exe(&cargo_home, "bin2");
708}
709
710#[cargo_test]
711fn multiple_crates_select() {
712 let p = git::repo(&paths::root().join("foo"))
713 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
714 .file("src/main.rs", "fn main() {}")
715 .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0"))
716 .file("a/src/main.rs", "fn main() {}")
717 .build();
718
719 cargo_process("install --git")
720 .arg(p.url().to_string())
721 .arg("foo")
722 .run();
04c3a46a
FG
723 assert_has_installed_exe(paths::cargo_home(), "foo");
724 assert_has_not_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
725
726 cargo_process("install --git")
727 .arg(p.url().to_string())
728 .arg("bar")
729 .run();
04c3a46a 730 assert_has_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
731}
732
733#[cargo_test]
734fn multiple_crates_git_all() {
735 let p = git::repo(&paths::root().join("foo"))
736 .file(
737 "Cargo.toml",
738 r#"
739 [workspace]
740 members = ["bin1", "bin2"]
741 "#,
742 )
743 .file("bin1/Cargo.toml", &basic_manifest("bin1", "0.1.0"))
744 .file("bin2/Cargo.toml", &basic_manifest("bin2", "0.1.0"))
745 .file(
746 "bin1/src/main.rs",
747 r#"fn main() { println!("Hello, world!"); }"#,
748 )
749 .file(
750 "bin2/src/main.rs",
751 r#"fn main() { println!("Hello, world!"); }"#,
752 )
753 .build();
754
755 cargo_process(&format!("install --git {} bin1 bin2", p.url().to_string())).run();
756}
757
758#[cargo_test]
759fn multiple_crates_auto_binaries() {
760 let p = project()
761 .file(
762 "Cargo.toml",
763 r#"
764 [package]
765 name = "foo"
766 version = "0.1.0"
767 authors = []
768
769 [dependencies]
770 bar = { path = "a" }
771 "#,
772 )
773 .file("src/main.rs", "extern crate bar; fn main() {}")
774 .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0"))
775 .file("a/src/lib.rs", "")
776 .build();
777
778 cargo_process("install --path").arg(p.root()).run();
04c3a46a 779 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
780}
781
782#[cargo_test]
783fn multiple_crates_auto_examples() {
784 let p = project()
785 .file(
786 "Cargo.toml",
787 r#"
788 [package]
789 name = "foo"
790 version = "0.1.0"
791 authors = []
792
793 [dependencies]
794 bar = { path = "a" }
795 "#,
796 )
797 .file("src/lib.rs", "extern crate bar;")
798 .file(
799 "examples/foo.rs",
800 "
801 extern crate bar;
802 extern crate foo;
803 fn main() {}
804 ",
805 )
806 .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0"))
807 .file("a/src/lib.rs", "")
808 .build();
809
810 cargo_process("install --path")
811 .arg(p.root())
812 .arg("--example=foo")
813 .run();
04c3a46a 814 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
815}
816
817#[cargo_test]
818fn no_binaries_or_examples() {
819 let p = project()
820 .file(
821 "Cargo.toml",
822 r#"
823 [package]
824 name = "foo"
825 version = "0.1.0"
826 authors = []
827
828 [dependencies]
829 bar = { path = "a" }
830 "#,
831 )
832 .file("src/lib.rs", "")
833 .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0"))
834 .file("a/src/lib.rs", "")
835 .build();
836
837 cargo_process("install --path")
838 .arg(p.root())
839 .with_status(101)
04c3a46a
FG
840 .with_stderr_data(str![[r#"
841[ERROR] no packages found with binaries or examples
842
843"#]])
0a29b90c
FG
844 .run();
845}
846
847#[cargo_test]
848fn no_binaries() {
849 let p = project()
850 .file("src/lib.rs", "")
851 .file("examples/foo.rs", "fn main() {}")
852 .build();
853
854 cargo_process("install --path")
855 .arg(p.root())
856 .arg("foo")
857 .with_status(101)
04c3a46a
FG
858 .with_stderr_data(str![[r#"
859[ERROR] there is nothing to install in `foo v0.0.1 ([ROOT]/foo)`, because it has no binaries
860`cargo install` is only for installing programs, and can't be used with libraries.
861To use a library crate, add it as a dependency to a Cargo project with `cargo add`.
862
863"#]])
0a29b90c
FG
864 .run();
865}
866
867#[cargo_test]
868fn examples() {
869 let p = project()
870 .file("src/lib.rs", "")
871 .file("examples/foo.rs", "extern crate foo; fn main() {}")
872 .build();
873
874 cargo_process("install --path")
875 .arg(p.root())
876 .arg("--example=foo")
877 .run();
04c3a46a 878 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
879}
880
881#[cargo_test]
882fn install_force() {
883 let p = project().file("src/main.rs", "fn main() {}").build();
884
885 cargo_process("install --path").arg(p.root()).run();
886
887 let p = project()
888 .at("foo2")
889 .file("Cargo.toml", &basic_manifest("foo", "0.2.0"))
890 .file("src/main.rs", "fn main() {}")
891 .build();
892
893 cargo_process("install --force --path")
894 .arg(p.root())
04c3a46a
FG
895 .with_stderr_data(str![[r#"
896[INSTALLING] foo v0.2.0 ([ROOT]/foo2)
897[COMPILING] foo v0.2.0 ([ROOT]/foo2)
898[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
899[REPLACING] [ROOT]/home/.cargo/bin/foo[EXE]
900[REPLACED] package `foo v0.0.1 ([ROOT]/foo)` with `foo v0.2.0 ([ROOT]/foo2)` (executable `foo[EXE]`)
901[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
902
903"#]])
0a29b90c
FG
904 .run();
905
906 cargo_process("install --list")
04c3a46a
FG
907 .with_stdout_data(str![[r#"
908foo v0.2.0 ([ROOT]/foo2):
909 foo[EXE]
910
911"#]])
0a29b90c
FG
912 .run();
913}
914
915#[cargo_test]
916fn install_force_partial_overlap() {
917 let p = project()
918 .file("src/bin/foo-bin1.rs", "fn main() {}")
919 .file("src/bin/foo-bin2.rs", "fn main() {}")
920 .build();
921
922 cargo_process("install --path").arg(p.root()).run();
923
924 let p = project()
925 .at("foo2")
926 .file("Cargo.toml", &basic_manifest("foo", "0.2.0"))
927 .file("src/bin/foo-bin2.rs", "fn main() {}")
928 .file("src/bin/foo-bin3.rs", "fn main() {}")
929 .build();
930
931 cargo_process("install --force --path")
932 .arg(p.root())
04c3a46a
FG
933 .with_stderr_data(str![[r#"
934[INSTALLING] foo v0.2.0 ([ROOT]/foo2)
935[COMPILING] foo v0.2.0 ([ROOT]/foo2)
936[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
937[INSTALLING] [ROOT]/home/.cargo/bin/foo-bin3[EXE]
938[REPLACING] [ROOT]/home/.cargo/bin/foo-bin2[EXE]
939[REMOVING] executable `[ROOT]/home/.cargo/bin/foo-bin1[EXE]` from previous version foo v0.0.1 ([ROOT]/foo)
940[INSTALLED] package `foo v0.2.0 ([ROOT]/foo2)` (executable `foo-bin3[EXE]`)
941[REPLACED] package `foo v0.0.1 ([ROOT]/foo)` with `foo v0.2.0 ([ROOT]/foo2)` (executable `foo-bin2[EXE]`)
942[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
943
944"#]])
0a29b90c
FG
945 .run();
946
947 cargo_process("install --list")
04c3a46a
FG
948 .with_stdout_data(str![[r#"
949foo v0.2.0 ([ROOT]/foo2):
950 foo-bin2[EXE]
951 foo-bin3[EXE]
952
953"#]])
0a29b90c
FG
954 .run();
955}
956
957#[cargo_test]
958fn install_force_bin() {
959 let p = project()
960 .file("src/bin/foo-bin1.rs", "fn main() {}")
961 .file("src/bin/foo-bin2.rs", "fn main() {}")
962 .build();
963
964 cargo_process("install --path").arg(p.root()).run();
965
966 let p = project()
967 .at("foo2")
968 .file("Cargo.toml", &basic_manifest("foo", "0.2.0"))
969 .file("src/bin/foo-bin1.rs", "fn main() {}")
970 .file("src/bin/foo-bin2.rs", "fn main() {}")
971 .build();
972
973 cargo_process("install --force --bin foo-bin2 --path")
974 .arg(p.root())
04c3a46a
FG
975 .with_stderr_data(str![[r#"
976[INSTALLING] foo v0.2.0 ([ROOT]/foo2)
977[COMPILING] foo v0.2.0 ([ROOT]/foo2)
978[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
979[REPLACING] [ROOT]/home/.cargo/bin/foo-bin2[EXE]
980[REPLACED] package `foo v0.0.1 ([ROOT]/foo)` with `foo v0.2.0 ([ROOT]/foo2)` (executable `foo-bin2[EXE]`)
981[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
982
983"#]])
0a29b90c
FG
984 .run();
985
986 cargo_process("install --list")
04c3a46a
FG
987 .with_stdout_data(str![[r#"
988foo v0.0.1 ([ROOT]/foo):
989 foo-bin1[EXE]
990foo v0.2.0 ([ROOT]/foo2):
991 foo-bin2[EXE]
992
993"#]])
0a29b90c
FG
994 .run();
995}
996
997#[cargo_test]
998fn compile_failure() {
999 let p = project().file("src/main.rs", "").build();
1000
1001 cargo_process("install --path")
1002 .arg(p.root())
1003 .with_status(101)
04c3a46a
FG
1004 .with_stderr_data(str![[r#"
1005...
1006[ERROR] could not compile `foo` (bin "foo") due to 1 previous error
1007[ERROR] failed to compile `foo v0.0.1 ([ROOT]/foo)`, intermediate artifacts can be found at `[ROOT]/foo/target`.
1008To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.
1009...
1010"#]])
0a29b90c
FG
1011 .run();
1012}
1013
1014#[cargo_test]
1015fn git_repo() {
1016 let p = git::repo(&paths::root().join("foo"))
1017 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
1018 .file("src/main.rs", "fn main() {}")
1019 .build();
1020
1021 // Use `--locked` to test that we don't even try to write a lock file.
1022 cargo_process("install --locked --git")
1023 .arg(p.url().to_string())
04c3a46a
FG
1024 .with_stderr_data(str![[r#"
1025[UPDATING] git repository `[ROOTURL]/foo`
1026[WARNING] no Cargo.lock file published in foo v0.1.0 ([ROOTURL]/foo#[..])
1027[INSTALLING] foo v0.1.0 ([ROOTURL]/foo#[..])
1028[COMPILING] foo v0.1.0 ([ROOT]/home/.cargo/git/checkouts/foo-[HASH]/[..])
1029[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
1030[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
1031[INSTALLED] package `foo v0.1.0 ([ROOTURL]/foo#[..])` (executable `foo[EXE]`)
1032[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
1033
1034"#]])
0a29b90c 1035 .run();
04c3a46a
FG
1036 assert_has_installed_exe(paths::cargo_home(), "foo");
1037 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1038}
1039
1040#[cargo_test]
1041#[cfg(target_os = "linux")]
1042fn git_repo_with_lowercase_cargo_toml() {
1043 let p = git::repo(&paths::root().join("foo"))
1044 .file("cargo.toml", &basic_manifest("foo", "0.1.0"))
1045 .file("src/main.rs", "fn main() {}")
1046 .build();
1047
1048 cargo_process("install --git")
1049 .arg(p.url().to_string())
1050 .with_status(101)
04c3a46a 1051 .with_stderr_data(str![[r#"
0a29b90c
FG
1052[UPDATING] git repository [..]
1053[ERROR] Could not find Cargo.toml in `[..]`, but found cargo.toml please try to rename it to Cargo.toml
04c3a46a
FG
1054
1055"#]]
0a29b90c
FG
1056 )
1057 .run();
1058}
1059
1060#[cargo_test]
1061fn list() {
1062 pkg("foo", "0.0.1");
1063 pkg("bar", "0.2.1");
1064 pkg("bar", "0.2.2");
1065
04c3a46a 1066 cargo_process("install --list").with_stdout_data("").run();
0a29b90c
FG
1067
1068 cargo_process("install bar --version =0.2.1").run();
1069 cargo_process("install foo").run();
1070 cargo_process("install --list")
04c3a46a 1071 .with_stdout_data(str![[r#"
0a29b90c 1072bar v0.2.1:
04c3a46a 1073 bar[EXE]
0a29b90c 1074foo v0.0.1:
04c3a46a
FG
1075 foo[EXE]
1076
1077"#]])
0a29b90c
FG
1078 .run();
1079}
1080
1081#[cargo_test]
1082fn list_error() {
1083 pkg("foo", "0.0.1");
1084 cargo_process("install foo").run();
1085 cargo_process("install --list")
04c3a46a 1086 .with_stdout_data(str![[r#"
0a29b90c 1087foo v0.0.1:
04c3a46a
FG
1088 foo[EXE]
1089
1090"#]])
0a29b90c 1091 .run();
04c3a46a 1092 let mut worldfile_path = paths::cargo_home();
0a29b90c
FG
1093 worldfile_path.push(".crates.toml");
1094 let mut worldfile = OpenOptions::new()
1095 .write(true)
1096 .open(worldfile_path)
1097 .expect(".crates.toml should be there");
1098 worldfile.write_all(b"\x00").unwrap();
1099 drop(worldfile);
1100 cargo_process("install --list --verbose")
1101 .with_status(101)
04c3a46a
FG
1102 .with_stderr_data(str![[r#"
1103[ERROR] failed to parse crate metadata at `[ROOT]/home/.cargo/.crates.toml`
0a29b90c
FG
1104
1105Caused by:
1106 invalid TOML found for metadata
1107
1108Caused by:
1109 TOML parse error at line 1, column 1
1110 |
04c3a46a 1111 1 | v1]
0a29b90c
FG
1112 | ^
1113 invalid key
04c3a46a
FG
1114
1115"#]])
0a29b90c
FG
1116 .run();
1117}
1118
1119#[cargo_test]
1120fn uninstall_pkg_does_not_exist() {
1121 cargo_process("uninstall foo")
1122 .with_status(101)
04c3a46a
FG
1123 .with_stderr_data(str![[r#"
1124[ERROR] package ID specification `foo` did not match any packages
1125
1126"#]])
0a29b90c
FG
1127 .run();
1128}
1129
1130#[cargo_test]
1131fn uninstall_bin_does_not_exist() {
1132 pkg("foo", "0.0.1");
1133
1134 cargo_process("install foo").run();
1135 cargo_process("uninstall foo --bin=bar")
1136 .with_status(101)
04c3a46a
FG
1137 .with_stderr_data(str![[r#"
1138[ERROR] binary `bar[EXE]` not installed as part of `foo v0.0.1`
1139
1140"#]])
0a29b90c
FG
1141 .run();
1142}
1143
1144#[cargo_test]
1145fn uninstall_piecemeal() {
1146 let p = project()
1147 .file("src/bin/foo.rs", "fn main() {}")
1148 .file("src/bin/bar.rs", "fn main() {}")
1149 .build();
1150
1151 cargo_process("install --path").arg(p.root()).run();
04c3a46a
FG
1152 assert_has_installed_exe(paths::cargo_home(), "foo");
1153 assert_has_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
1154
1155 cargo_process("uninstall foo --bin=bar")
04c3a46a
FG
1156 .with_stderr_data(str![[r#"
1157[REMOVING] [ROOT]/home/.cargo/bin/bar[EXE]
1158
1159"#]])
0a29b90c
FG
1160 .run();
1161
04c3a46a
FG
1162 assert_has_installed_exe(paths::cargo_home(), "foo");
1163 assert_has_not_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
1164
1165 cargo_process("uninstall foo --bin=foo")
04c3a46a
FG
1166 .with_stderr_data(str![[r#"
1167[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
1168
1169"#]])
0a29b90c 1170 .run();
04c3a46a 1171 assert_has_not_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1172
1173 cargo_process("uninstall foo")
1174 .with_status(101)
04c3a46a
FG
1175 .with_stderr_data(str![[r#"
1176[ERROR] package ID specification `foo` did not match any packages
1177
1178"#]])
0a29b90c
FG
1179 .run();
1180}
1181
1182#[cargo_test]
1183fn subcommand_works_out_of_the_box() {
1184 Package::new("cargo-foo", "1.0.0")
1185 .file("src/main.rs", r#"fn main() { println!("bar"); }"#)
1186 .publish();
1187 cargo_process("install cargo-foo").run();
04c3a46a
FG
1188 cargo_process("foo")
1189 .with_stdout_data(str![[r#"
1190bar
1191
1192"#]])
1193 .run();
0a29b90c 1194 cargo_process("--list")
04c3a46a
FG
1195 .with_stdout_data(str![[r#"
1196...
1197 foo
1198...
1199"#]])
0a29b90c
FG
1200 .run();
1201}
1202
1203#[cargo_test]
1204fn installs_from_cwd_by_default() {
1205 let p = project().file("src/main.rs", "fn main() {}").build();
1206
04c3a46a
FG
1207 p.cargo("install").with_stderr_data(str![[r#"
1208[WARNING] Using `cargo install` to install the binaries from the package in current working directory is deprecated, use `cargo install --path .` instead. Use `cargo build` if you want to simply build the package.
1209...
1210"#]]).run();
1211 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1212}
1213
1214#[cargo_test]
1215fn installs_from_cwd_with_2018_warnings() {
1216 let p = project()
1217 .file(
1218 "Cargo.toml",
1219 r#"
1220 [package]
1221 name = "foo"
1222 version = "0.1.0"
1223 authors = []
1224 edition = "2018"
1225 "#,
1226 )
1227 .file("src/main.rs", "fn main() {}")
1228 .build();
1229
1230 p.cargo("install")
1231 .with_status(101)
04c3a46a
FG
1232 .with_stderr_data(str![[r#"
1233[ERROR] Using `cargo install` to install the binaries from the package in current working directory is no longer supported, use `cargo install --path .` instead. Use `cargo build` if you want to simply build the package.
1234
1235"#]])
0a29b90c 1236 .run();
04c3a46a 1237 assert_has_not_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1238}
1239
1240#[cargo_test]
1241fn uninstall_cwd() {
1242 let p = project().file("src/main.rs", "fn main() {}").build();
04c3a46a
FG
1243 p.cargo("install --path .").with_stderr_data(str![[r#"
1244[INSTALLING] foo v0.0.1 ([ROOT]/foo)
1245[COMPILING] foo v0.0.1 ([ROOT]/foo)
1246[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
1247[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
1248[INSTALLED] package `foo v0.0.1 ([ROOT]/foo)` (executable `foo[EXE]`)
1249[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
1250
1251"#]]).run();
1252 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1253
1254 p.cargo("uninstall")
04c3a46a
FG
1255 .with_stdout_data("")
1256 .with_stderr_data(str![[r#"
1257[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
1258
1259"#]])
0a29b90c 1260 .run();
04c3a46a 1261 assert_has_not_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1262}
1263
1264#[cargo_test]
1265fn uninstall_cwd_not_installed() {
1266 let p = project().file("src/main.rs", "fn main() {}").build();
1267 p.cargo("uninstall")
1268 .with_status(101)
04c3a46a
FG
1269 .with_stdout_data("")
1270 .with_stderr_data(str![[r#"
1271[ERROR] package `foo v0.0.1 ([ROOT]/foo)` is not installed
1272
1273"#]])
0a29b90c
FG
1274 .run();
1275}
1276
1277#[cargo_test]
1278fn uninstall_cwd_no_project() {
1279 cargo_process("uninstall")
1280 .with_status(101)
04c3a46a
FG
1281 .with_stdout_data("")
1282 .with_stderr_data(str![[r#"
1283[ERROR] failed to read `[ROOT]/Cargo.toml`
0a29b90c
FG
1284
1285Caused by:
04c3a46a
FG
1286 [NOT_FOUND]
1287
1288"#]])
0a29b90c
FG
1289 .run();
1290}
1291
1292#[cargo_test]
1293fn do_not_rebuilds_on_local_install() {
1294 let p = project().file("src/main.rs", "fn main() {}").build();
1295
1296 p.cargo("build --release").run();
1297 cargo_process("install --path")
1298 .arg(p.root())
04c3a46a
FG
1299 .with_stderr_data(str![[r#"
1300[INSTALLING] foo v0.0.1 ([ROOT]/foo)
1301[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
1302[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
1303[INSTALLED] package `foo v0.0.1 ([ROOT]/foo)` (executable `foo[EXE]`)
1304[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
1305
1306"#]])
0a29b90c
FG
1307 .run();
1308
1309 assert!(p.build_dir().exists());
1310 assert!(p.release_bin("foo").exists());
04c3a46a 1311 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1312}
1313
1314#[cargo_test]
1315fn reports_unsuccessful_subcommand_result() {
1316 Package::new("cargo-fail", "1.0.0")
1317 .file("src/main.rs", "fn main() { panic!(); }")
1318 .publish();
1319 cargo_process("install cargo-fail").run();
1320 cargo_process("--list")
04c3a46a
FG
1321 .with_stdout_data(str![[r#"
1322...
1323 fail
1324...
1325"#]])
0a29b90c
FG
1326 .run();
1327 cargo_process("fail")
1328 .with_status(101)
04c3a46a
FG
1329 .with_stderr_data(str![[r#"
1330thread 'main' panicked at [ROOT]/home/.cargo/registry/src/-[HASH]/cargo-fail-1.0.0/src/main.rs:1:13:
1331explicit panic
1332[NOTE] run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1333
1334"#]])
0a29b90c
FG
1335 .run();
1336}
1337
1338#[cargo_test]
1339fn git_with_lockfile() {
1340 let p = git::repo(&paths::root().join("foo"))
1341 .file(
1342 "Cargo.toml",
1343 r#"
1344 [package]
1345 name = "foo"
1346 version = "0.1.0"
1347 authors = []
1348
1349 [dependencies]
1350 bar = { path = "bar" }
1351 "#,
1352 )
1353 .file("src/main.rs", "fn main() {}")
1354 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1355 .file("bar/src/lib.rs", "fn main() {}")
1356 .file(
1357 "Cargo.lock",
1358 r#"
1359 [[package]]
1360 name = "foo"
1361 version = "0.1.0"
1362 dependencies = [ "bar 0.1.0" ]
1363
1364 [[package]]
1365 name = "bar"
1366 version = "0.1.0"
1367 "#,
1368 )
1369 .build();
1370
1371 cargo_process("install --git")
1372 .arg(p.url().to_string())
1373 .run();
1374}
1375
1376#[cargo_test]
1377fn q_silences_warnings() {
1378 let p = project().file("src/main.rs", "fn main() {}").build();
1379
1380 cargo_process("install -q --path")
1381 .arg(p.root())
04c3a46a 1382 .with_stderr_data("")
0a29b90c
FG
1383 .run();
1384}
1385
1386#[cargo_test]
1387fn readonly_dir() {
1388 pkg("foo", "0.0.1");
1389
1390 let root = paths::root();
1391 let dir = &root.join("readonly");
1392 fs::create_dir(root.join("readonly")).unwrap();
1393 let mut perms = fs::metadata(dir).unwrap().permissions();
1394 perms.set_readonly(true);
1395 fs::set_permissions(dir, perms).unwrap();
1396
1397 cargo_process("install foo").cwd(dir).run();
04c3a46a 1398 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1399}
1400
1401#[cargo_test]
1402fn use_path_workspace() {
1403 Package::new("foo", "1.0.0").publish();
1404 let p = project()
1405 .file(
1406 "Cargo.toml",
1407 r#"
1408 [package]
1409 name = "bar"
1410 version = "0.1.0"
1411 authors = []
1412
1413 [workspace]
1414 members = ["baz"]
1415 "#,
1416 )
1417 .file("src/main.rs", "fn main() {}")
1418 .file(
1419 "baz/Cargo.toml",
1420 r#"
1421 [package]
1422 name = "baz"
1423 version = "0.1.0"
1424 authors = []
1425
1426 [dependencies]
1427 foo = "1"
1428 "#,
1429 )
1430 .file("baz/src/lib.rs", "")
1431 .build();
1432
1433 p.cargo("build").run();
1434 let lock = p.read_lockfile();
1435 p.cargo("install").run();
1436 let lock2 = p.read_lockfile();
1437 assert_eq!(lock, lock2, "different lockfiles");
1438}
1439
04c3a46a 1440#[allow(deprecated)]
0a29b90c
FG
1441#[cargo_test]
1442fn path_install_workspace_root_despite_default_members() {
1443 let p = project()
1444 .file(
1445 "Cargo.toml",
1446 r#"
1447 [package]
1448 name = "ws-root"
1449 version = "0.1.0"
1450 authors = []
1451
1452 [workspace]
1453 members = ["ws-member"]
1454 default-members = ["ws-member"]
1455 "#,
1456 )
1457 .file("src/main.rs", "fn main() {}")
1458 .file(
1459 "ws-member/Cargo.toml",
1460 r#"
1461 [package]
1462 name = "ws-member"
1463 version = "0.1.0"
1464 authors = []
1465 "#,
1466 )
1467 .file("ws-member/src/main.rs", "fn main() {}")
1468 .build();
1469
1470 p.cargo("install --path")
1471 .arg(p.root())
1472 .arg("ws-root")
04c3a46a
FG
1473 .with_stderr_data(str![[r#"
1474[INSTALLING] ws-root v0.1.0 ([ROOT]/foo)
1475[COMPILING] ws-root v0.1.0 ([ROOT]/foo)
1476[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
1477[INSTALLING] [ROOT]/home/.cargo/bin/ws-root[EXE]
1478[INSTALLED] package `ws-root v0.1.0 ([ROOT]/foo)` (executable `ws-root[EXE]`)
1479[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
1480
1481"#]])
0a29b90c
FG
1482 // Particularly avoid "Installed package `ws-root v0.1.0 ([..]])` (executable `ws-member`)":
1483 .with_stderr_does_not_contain("ws-member")
1484 .run();
1485}
1486
04c3a46a 1487#[allow(deprecated)]
49aad941
FG
1488#[cargo_test]
1489fn git_install_workspace_root_despite_default_members() {
1490 let p = git::repo(&paths::root().join("foo"))
1491 .file(
1492 "Cargo.toml",
1493 r#"
1494 [package]
1495 name = "ws-root"
1496 version = "0.1.0"
1497 authors = []
1498
1499 [workspace]
1500 members = ["ws-member"]
1501 default-members = ["ws-member"]
1502 "#,
1503 )
1504 .file("src/main.rs", "fn main() {}")
1505 .file(
1506 "ws-member/Cargo.toml",
1507 r#"
1508 [package]
1509 name = "ws-member"
1510 version = "0.1.0"
1511 authors = []
1512 "#,
1513 )
1514 .file("ws-member/src/main.rs", "fn main() {}")
1515 .build();
1516
1517 cargo_process("install --git")
1518 .arg(p.url().to_string())
1519 .arg("ws-root")
04c3a46a
FG
1520 .with_stderr_data(str![[r#"
1521...
1522[INSTALLED] package `ws-root v0.1.0 ([ROOTURL]/foo#[..])` (executable `ws-root[EXE]`)
1523...
1524"#]])
49aad941
FG
1525 // Particularly avoid "Installed package `ws-root v0.1.0 ([..]])` (executable `ws-member`)":
1526 .with_stderr_does_not_contain("ws-member")
1527 .run();
1528}
1529
0a29b90c
FG
1530#[cargo_test]
1531fn dev_dependencies_no_check() {
1532 Package::new("foo", "1.0.0").publish();
1533 let p = project()
1534 .file(
1535 "Cargo.toml",
1536 r#"
1537 [package]
1538 name = "bar"
1539 version = "0.1.0"
1540 authors = []
1541
1542 [dev-dependencies]
1543 baz = "1.0.0"
1544 "#,
1545 )
1546 .file("src/main.rs", "fn main() {}")
1547 .build();
1548
1549 p.cargo("build")
1550 .with_status(101)
04c3a46a
FG
1551 .with_stderr_data(str![[r#"
1552...
1553[ERROR] no matching package named `baz` found
1554...
1555"#]])
0a29b90c
FG
1556 .run();
1557 p.cargo("install").run();
1558}
1559
1560#[cargo_test]
1561fn dev_dependencies_lock_file_untouched() {
1562 Package::new("foo", "1.0.0").publish();
1563 let p = project()
1564 .file(
1565 "Cargo.toml",
1566 r#"
1567 [package]
1568 name = "foo"
1569 version = "0.1.0"
1570 authors = []
1571
1572 [dev-dependencies]
1573 bar = { path = "a" }
1574 "#,
1575 )
1576 .file("src/main.rs", "fn main() {}")
1577 .file("a/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1578 .file("a/src/lib.rs", "")
1579 .build();
1580
1581 p.cargo("build").run();
1582 let lock = p.read_lockfile();
1583 p.cargo("install").run();
1584 let lock2 = p.read_lockfile();
1585 assert!(lock == lock2, "different lockfiles");
1586}
1587
1588#[cargo_test]
1589fn install_target_native() {
1590 pkg("foo", "0.1.0");
1591
1592 cargo_process("install foo --target")
1593 .arg(cargo_test_support::rustc_host())
1594 .run();
04c3a46a 1595 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1596}
1597
1598#[cargo_test]
1599fn install_target_foreign() {
1600 if cross_compile::disabled() {
1601 return;
1602 }
1603
1604 pkg("foo", "0.1.0");
1605
1606 cargo_process("install foo --target")
1607 .arg(cross_compile::alternate())
1608 .run();
04c3a46a 1609 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
1610}
1611
1612#[cargo_test]
1613fn vers_precise() {
1614 pkg("foo", "0.1.1");
1615 pkg("foo", "0.1.2");
1616
1617 cargo_process("install foo --vers 0.1.1")
04c3a46a
FG
1618 .with_stderr_data(str![[r#"
1619...
1620[DOWNLOADED] foo v0.1.1 (registry `dummy-registry`)
1621...
1622"#]])
0a29b90c
FG
1623 .run();
1624}
1625
1626#[cargo_test]
1627fn version_precise() {
1628 pkg("foo", "0.1.1");
1629 pkg("foo", "0.1.2");
1630
1631 cargo_process("install foo --version 0.1.1")
04c3a46a
FG
1632 .with_stderr_data(str![[r#"
1633...
1634[DOWNLOADED] foo v0.1.1 (registry `dummy-registry`)
1635...
1636"#]])
0a29b90c
FG
1637 .run();
1638}
1639
1640#[cargo_test]
1641fn inline_version_precise() {
1642 pkg("foo", "0.1.1");
1643 pkg("foo", "0.1.2");
1644
1645 cargo_process("install foo@0.1.1")
04c3a46a
FG
1646 .with_stderr_data(str![[r#"
1647...
1648[DOWNLOADED] foo v0.1.1 (registry `dummy-registry`)
1649...
1650"#]])
0a29b90c
FG
1651 .run();
1652}
1653
1654#[cargo_test]
1655fn inline_version_multiple() {
1656 pkg("foo", "0.1.0");
1657 pkg("foo", "0.1.1");
1658 pkg("foo", "0.1.2");
1659 pkg("bar", "0.2.0");
1660 pkg("bar", "0.2.1");
1661 pkg("bar", "0.2.2");
1662
1663 cargo_process("install foo@0.1.1 bar@0.2.1")
04c3a46a
FG
1664 .with_stderr_data(str![[r#"
1665...
1666[DOWNLOADED] foo v0.1.1 (registry `dummy-registry`)
1667...
1668[DOWNLOADED] bar v0.2.1 (registry `dummy-registry`)
1669...
1670"#]])
0a29b90c
FG
1671 .run();
1672}
1673
1674#[cargo_test]
1675fn inline_version_without_name() {
1676 pkg("foo", "0.1.1");
1677 pkg("foo", "0.1.2");
1678
1679 cargo_process("install @0.1.1")
781aab86 1680 .with_status(1)
04c3a46a
FG
1681 .with_stderr_data(str![[r#"
1682[ERROR] invalid value '@0.1.1' for '[CRATE[@<VER>]]...': missing crate name before '@'
781aab86
FG
1683
1684For more information, try '--help'.
04c3a46a
FG
1685
1686"#]])
0a29b90c
FG
1687 .run();
1688}
1689
1690#[cargo_test]
1691fn inline_and_explicit_version() {
1692 pkg("foo", "0.1.1");
1693 pkg("foo", "0.1.2");
1694
1695 cargo_process("install foo@0.1.1 --version 0.1.1")
1696 .with_status(101)
04c3a46a
FG
1697 .with_stderr_data(str![[r#"
1698[ERROR] cannot specify both `@<VERSION>` and `--version <VERSION>`
1699
1700"#]])
0a29b90c
FG
1701 .run();
1702}
1703
1704#[cargo_test]
1705fn not_both_vers_and_version() {
1706 pkg("foo", "0.1.1");
1707 pkg("foo", "0.1.2");
1708
1709 cargo_process("install foo --version 0.1.1 --vers 0.1.2")
1710 .with_status(1)
04c3a46a 1711 .with_stderr_data(str![[r#"
0a29b90c 1712[ERROR] the argument '--version <VERSION>' cannot be used multiple times
04c3a46a
FG
1713
1714Usage: cargo[EXE] install [OPTIONS] [CRATE[@<VER>]]...
1715
1716For more information, try '--help'.
1717
1718"#]])
0a29b90c
FG
1719 .run();
1720}
1721
1722#[cargo_test]
1723fn test_install_git_cannot_be_a_base_url() {
1724 cargo_process("install --git github.com:rust-lang/rustfmt.git")
1725 .with_status(101)
04c3a46a
FG
1726 .with_stderr_data(str![[r#"
1727[ERROR] invalid url `github.com:rust-lang/rustfmt.git`: cannot-be-a-base-URLs are not supported
1728
1729"#]])
0a29b90c
FG
1730 .run();
1731}
1732
1733#[cargo_test]
1734fn uninstall_multiple_and_specifying_bin() {
1735 cargo_process("uninstall foo bar --bin baz")
1736 .with_status(101)
04c3a46a
FG
1737 .with_stderr_data(str![[r#"
1738[ERROR] A binary can only be associated with a single installed package, specifying multiple specs with --bin is redundant.
1739
1740"#]])
0a29b90c
FG
1741 .run();
1742}
1743
1744#[cargo_test]
1745fn uninstall_with_empty_package_option() {
1746 cargo_process("uninstall -p")
1747 .with_status(101)
04c3a46a
FG
1748 .with_stderr_data(str![[r#"
1749[ERROR] "--package <SPEC>" requires a SPEC format value.
0a29b90c 1750Run `cargo help pkgid` for more information about SPEC format.
04c3a46a
FG
1751
1752"#]])
0a29b90c
FG
1753 .run();
1754}
1755
1756#[cargo_test]
1757fn uninstall_multiple_and_some_pkg_does_not_exist() {
1758 pkg("foo", "0.0.1");
1759
1760 cargo_process("install foo").run();
1761
1762 cargo_process("uninstall foo bar")
1763 .with_status(101)
04c3a46a
FG
1764 .with_stderr_data(str![[r#"
1765[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
1766[ERROR] package ID specification `bar` did not match any packages
0a29b90c 1767[SUMMARY] Successfully uninstalled foo! Failed to uninstall bar (see error(s) above).
04c3a46a
FG
1768[ERROR] some packages failed to uninstall
1769
1770"#]])
0a29b90c
FG
1771 .run();
1772
04c3a46a
FG
1773 assert_has_not_installed_exe(paths::cargo_home(), "foo");
1774 assert_has_not_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
1775}
1776
1777#[cargo_test]
1778fn custom_target_dir_for_git_source() {
1779 let p = git::repo(&paths::root().join("foo"))
1780 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
1781 .file("src/main.rs", "fn main() {}")
1782 .build();
1783
1784 cargo_process("install --git")
1785 .arg(p.url().to_string())
1786 .run();
1787 assert!(!paths::root().join("target/release").is_dir());
1788
1789 cargo_process("install --force --git")
1790 .arg(p.url().to_string())
1791 .env("CARGO_TARGET_DIR", "target")
1792 .run();
1793 assert!(paths::root().join("target/release").is_dir());
1794}
1795
1796#[cargo_test]
1797fn install_respects_lock_file() {
1798 // `cargo install` now requires --locked to use a Cargo.lock.
1799 Package::new("bar", "0.1.0").publish();
1800 Package::new("bar", "0.1.1")
1801 .file("src/lib.rs", "not rust")
1802 .publish();
1803 Package::new("foo", "0.1.0")
1804 .dep("bar", "0.1")
1805 .file("src/lib.rs", "")
1806 .file(
1807 "src/main.rs",
1808 "extern crate foo; extern crate bar; fn main() {}",
1809 )
1810 .file(
1811 "Cargo.lock",
1812 r#"
1813[[package]]
1814name = "bar"
1815version = "0.1.0"
1816source = "registry+https://github.com/rust-lang/crates.io-index"
1817
1818[[package]]
1819name = "foo"
1820version = "0.1.0"
1821dependencies = [
1822 "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1823]
1824"#,
1825 )
1826 .publish();
1827
1828 cargo_process("install foo")
04c3a46a
FG
1829 .with_stderr_data(str![[r#"
1830...
1831[..]not rust[..]
1832...
1833"#]])
0a29b90c
FG
1834 .with_status(101)
1835 .run();
1836 cargo_process("install --locked foo").run();
1837}
1838
1839#[cargo_test]
1840fn install_path_respects_lock_file() {
1841 // --path version of install_path_respects_lock_file, --locked is required
1842 // to use Cargo.lock.
1843 Package::new("bar", "0.1.0").publish();
1844 Package::new("bar", "0.1.1")
1845 .file("src/lib.rs", "not rust")
1846 .publish();
1847 let p = project()
1848 .file(
1849 "Cargo.toml",
1850 r#"
1851 [package]
1852 name = "foo"
1853 version = "0.1.0"
1854
1855 [dependencies]
1856 bar = "0.1"
1857 "#,
1858 )
1859 .file("src/main.rs", "extern crate bar; fn main() {}")
1860 .file(
1861 "Cargo.lock",
1862 r#"
1863[[package]]
1864name = "bar"
1865version = "0.1.0"
1866source = "registry+https://github.com/rust-lang/crates.io-index"
1867
1868[[package]]
1869name = "foo"
1870version = "0.1.0"
1871dependencies = [
1872 "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1873]
1874"#,
1875 )
1876 .build();
1877
1878 p.cargo("install --path .")
04c3a46a
FG
1879 .with_stderr_data(str![[r#"
1880...
1881[..]not rust[..]
1882...
1883"#]])
0a29b90c
FG
1884 .with_status(101)
1885 .run();
1886 p.cargo("install --path . --locked").run();
1887}
1888
1889#[cargo_test]
1890fn lock_file_path_deps_ok() {
1891 Package::new("bar", "0.1.0").publish();
1892
1893 Package::new("foo", "0.1.0")
1894 .dep("bar", "0.1")
1895 .file("src/lib.rs", "")
1896 .file(
1897 "src/main.rs",
1898 "extern crate foo; extern crate bar; fn main() {}",
1899 )
1900 .file(
1901 "Cargo.lock",
1902 r#"
1903 [[package]]
1904 name = "bar"
1905 version = "0.1.0"
1906
1907 [[package]]
1908 name = "foo"
1909 version = "0.1.0"
1910 dependencies = [
1911 "bar 0.1.0",
1912 ]
1913 "#,
1914 )
1915 .publish();
1916
1917 cargo_process("install foo").run();
1918}
1919
1920#[cargo_test]
1921fn install_empty_argument() {
1922 // Bug 5229
1923 cargo_process("install")
1924 .arg("")
1925 .with_status(1)
04c3a46a
FG
1926 .with_stderr_data(str![[r#"
1927[ERROR] invalid value '' for '[CRATE[@<VER>]]...': crate name is empty
1928
1929For more information, try '--help'.
1930
1931"#]])
0a29b90c
FG
1932 .run();
1933}
1934
1935#[cargo_test]
1936fn git_repo_replace() {
1937 let p = git::repo(&paths::root().join("foo"))
1938 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
1939 .file("src/main.rs", "fn main() {}")
1940 .build();
1941 let repo = git2::Repository::open(&p.root()).unwrap();
1942 let old_rev = repo.revparse_single("HEAD").unwrap().id();
1943 cargo_process("install --git")
1944 .arg(p.url().to_string())
1945 .run();
1946 git::commit(&repo);
1947 let new_rev = repo.revparse_single("HEAD").unwrap().id();
1948 let mut path = paths::home();
1949 path.push(".cargo/.crates.toml");
1950
1951 assert_ne!(old_rev, new_rev);
1952 assert!(fs::read_to_string(path.clone())
1953 .unwrap()
1954 .contains(&format!("{}", old_rev)));
1955 cargo_process("install --force --git")
1956 .arg(p.url().to_string())
1957 .run();
1958 assert!(fs::read_to_string(path)
1959 .unwrap()
1960 .contains(&format!("{}", new_rev)));
1961}
1962
1963#[cargo_test]
1964fn workspace_uses_workspace_target_dir() {
1965 let p = project()
1966 .file(
1967 "Cargo.toml",
1968 r#"
1969 [package]
1970 name = "foo"
1971 version = "0.1.0"
1972 authors = []
1973
1974 [workspace]
1975
1976 [dependencies]
1977 bar = { path = 'bar' }
1978 "#,
1979 )
1980 .file("src/main.rs", "fn main() {}")
1981 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
1982 .file("bar/src/main.rs", "fn main() {}")
1983 .build();
1984
1985 p.cargo("build --release").cwd("bar").run();
1986 cargo_process("install --path")
1987 .arg(p.root().join("bar"))
04c3a46a
FG
1988 .with_stderr_data(str![[r#"
1989[INSTALLING] bar v0.1.0 ([ROOT]/foo/bar)
1990[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
1991[INSTALLING] [ROOT]/home/.cargo/bin/bar[EXE]
1992[INSTALLED] package `bar v0.1.0 ([ROOT]/foo/bar)` (executable `bar[EXE]`)
1993[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
1994
1995"#]])
0a29b90c
FG
1996 .run();
1997}
1998
1999#[cargo_test]
2000fn install_ignores_local_cargo_config() {
2001 pkg("bar", "0.0.1");
2002
2003 let p = project()
2004 .file(
c620b35d 2005 ".cargo/config.toml",
0a29b90c
FG
2006 r#"
2007 [build]
2008 target = "non-existing-target"
2009 "#,
2010 )
2011 .file("src/main.rs", "fn main() {}")
2012 .build();
2013
2014 p.cargo("install bar").run();
04c3a46a 2015 assert_has_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
2016}
2017
2018#[cargo_test]
2019fn install_ignores_unstable_table_in_local_cargo_config() {
2020 pkg("bar", "0.0.1");
2021
2022 let p = project()
2023 .file(
c620b35d 2024 ".cargo/config.toml",
0a29b90c
FG
2025 r#"
2026 [unstable]
2027 build-std = ["core"]
2028 "#,
2029 )
2030 .file("src/main.rs", "fn main() {}")
2031 .build();
2032
2033 p.cargo("install bar")
2034 .masquerade_as_nightly_cargo(&["build-std"])
2035 .run();
04c3a46a 2036 assert_has_installed_exe(paths::cargo_home(), "bar");
0a29b90c
FG
2037}
2038
2039#[cargo_test]
2040fn install_global_cargo_config() {
2041 pkg("bar", "0.0.1");
2042
04c3a46a 2043 let config = paths::cargo_home().join("config.toml");
0a29b90c
FG
2044 let mut toml = fs::read_to_string(&config).unwrap_or_default();
2045
2046 toml.push_str(
2047 r#"
2048 [build]
2049 target = 'nonexistent'
2050 "#,
2051 );
2052 fs::write(&config, toml).unwrap();
2053
2054 cargo_process("install bar")
2055 .with_status(101)
04c3a46a
FG
2056 .with_stderr_data(
2057 str![[r#"
2058[INSTALLING] bar v0.0.1
2059Caused by:
2060 process didn't exit successfully: `rustc [..]--target nonexistent[..]` ([EXIT_STATUS]: 1)
2061...
2062"#]]
2063 .unordered(),
2064 )
0a29b90c
FG
2065 .run();
2066}
2067
2068#[cargo_test]
2069fn install_path_config() {
2070 project()
2071 .file(
c620b35d 2072 ".cargo/config.toml",
0a29b90c
FG
2073 r#"
2074 [build]
2075 target = 'nonexistent'
2076 "#,
2077 )
2078 .file("src/main.rs", "fn main() {}")
2079 .build();
2080 cargo_process("install --path foo")
2081 .with_status(101)
04c3a46a
FG
2082 .with_stderr_data(str![[r#"
2083...
2084 process didn't exit successfully: `rustc [..]--target nonexistent[..]` ([EXIT_STATUS]: 1)
2085...
2086"#]])
0a29b90c
FG
2087 .run();
2088}
2089
04c3a46a 2090#[allow(deprecated)]
0a29b90c
FG
2091#[cargo_test]
2092fn install_version_req() {
2093 // Try using a few versionreq styles.
2094 pkg("foo", "0.0.3");
2095 pkg("foo", "1.0.4");
2096 pkg("foo", "1.0.5");
2097 cargo_process("install foo --version=*")
2098 .with_stderr_does_not_contain("[WARNING][..]is not a valid semver[..]")
04c3a46a
FG
2099 .with_stderr_data(str![[r#"
2100...
2101[INSTALLING] foo v1.0.5
2102...
2103"#]])
0a29b90c
FG
2104 .run();
2105 cargo_process("uninstall foo").run();
2106 cargo_process("install foo --version=^1.0")
2107 .with_stderr_does_not_contain("[WARNING][..]is not a valid semver[..]")
04c3a46a
FG
2108 .with_stderr_data(str![[r#"
2109...
2110[INSTALLING] foo v1.0.5
2111...
2112"#]])
0a29b90c
FG
2113 .run();
2114 cargo_process("uninstall foo").run();
2115 cargo_process("install foo --version=0.0.*")
2116 .with_stderr_does_not_contain("[WARNING][..]is not a valid semver[..]")
04c3a46a
FG
2117 .with_stderr_data(str![[r#"
2118...
2119[INSTALLING] foo v0.0.3
2120...
2121"#]])
0a29b90c
FG
2122 .run();
2123}
2124
2125#[cargo_test]
2126fn git_install_reads_workspace_manifest() {
2127 let p = git::repo(&paths::root().join("foo"))
2128 .file(
2129 "Cargo.toml",
2130 r#"
2131 [workspace]
2132 members = ["bin1"]
2133
2134 [profile.release]
2135 incremental = 3
2136 "#,
2137 )
2138 .file("bin1/Cargo.toml", &basic_manifest("bin1", "0.1.0"))
2139 .file(
2140 "bin1/src/main.rs",
2141 r#"fn main() { println!("Hello, world!"); }"#,
2142 )
2143 .build();
2144
2145 cargo_process(&format!("install --git {}", p.url().to_string()))
2146 .with_status(101)
04c3a46a
FG
2147 .with_stderr_data(str![[r#"
2148[UPDATING] git repository `[ROOTURL]/foo`
2149[ERROR] invalid type: integer `3`, expected a boolean
2150 --> home/.cargo/git/checkouts/foo-[HASH]/[..]/Cargo.toml:6:27
2151 |
21526 | incremental = 3
2153 | ^
2154 |
2155[ERROR] invalid type: integer `3`, expected a boolean
2156 --> home/.cargo/git/checkouts/foo-[HASH]/[..]/Cargo.toml:6:27
2157 |
21586 | incremental = 3
2159 | ^
2160 |
2161
2162"#]])
0a29b90c
FG
2163 .run();
2164}
2165
2166#[cargo_test]
2167fn install_git_with_symlink_home() {
2168 // Ensure that `cargo install` with a git repo is OK when CARGO_HOME is a
2169 // symlink, and uses an build script.
2170 if !symlink_supported() {
2171 return;
2172 }
2173 let p = git::new("foo", |p| {
2174 p.file("Cargo.toml", &basic_manifest("foo", "1.0.0"))
2175 .file("src/main.rs", "fn main() {}")
2176 // This triggers discover_git_and_list_files for detecting changed files.
2177 .file("build.rs", "fn main() {}")
2178 });
2179 #[cfg(unix)]
2180 use std::os::unix::fs::symlink;
2181 #[cfg(windows)]
2182 use std::os::windows::fs::symlink_dir as symlink;
2183
2184 let actual = paths::root().join("actual-home");
2185 t!(std::fs::create_dir(&actual));
2186 t!(symlink(&actual, paths::home().join(".cargo")));
2187 cargo_process("install --git")
2188 .arg(p.url().to_string())
04c3a46a
FG
2189 .with_stderr_data(str![[r#"
2190[UPDATING] git repository `[ROOTURL]/foo`
2191[INSTALLING] foo v1.0.0 ([ROOTURL]/foo#[..])
2192[COMPILING] foo v1.0.0 ([ROOT]/home/.cargo/git/checkouts/foo-[HASH]/[..])
2193[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
2194[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
2195[INSTALLED] package `foo v1.0.0 ([ROOTURL]/foo#[..])` (executable `foo[EXE]`)
2196[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2197
2198"#]])
0a29b90c
FG
2199 .run();
2200}
2201
2202#[cargo_test]
2203fn install_yanked_cargo_package() {
2204 Package::new("baz", "0.0.1").yanked(true).publish();
2205 cargo_process("install baz --version 0.0.1")
2206 .with_status(101)
04c3a46a
FG
2207 .with_stderr_data(str![[r#"
2208[UPDATING] `dummy-registry` index
0a29b90c 2209[ERROR] cannot install package `baz`, it has been yanked from registry `crates-io`
04c3a46a
FG
2210
2211"#]])
0a29b90c
FG
2212 .run();
2213}
2214
2215#[cargo_test]
2216fn install_cargo_package_in_a_patched_workspace() {
2217 pkg("foo", "0.1.0");
2218 pkg("fizz", "1.0.0");
2219
2220 let p = project()
2221 .file(
2222 "Cargo.toml",
2223 r#"
2224 [package]
2225 name = "bar"
2226 version = "0.1.0"
2227 authors = []
2228
2229 [workspace]
2230 members = ["baz"]
2231 "#,
2232 )
2233 .file("src/main.rs", "fn main() {}")
2234 .file(
2235 "baz/Cargo.toml",
2236 r#"
2237 [package]
2238 name = "baz"
2239 version = "0.1.0"
2240 authors = []
2241
2242 [dependencies]
2243 fizz = "1"
2244
2245 [patch.crates-io]
2246 fizz = { version = "=1.0.0" }
2247 "#,
2248 )
2249 .file("baz/src/lib.rs", "")
2250 .build();
2251
04c3a46a
FG
2252 p.cargo("check")
2253 .with_stderr_data(str![[r#"
0a29b90c 2254[WARNING] patch for the non root package will be ignored, specify patch at the workspace root:
04c3a46a
FG
2255package: [ROOT]/foo/baz/Cargo.toml
2256workspace: [ROOT]/foo/Cargo.toml
2257...
2258"#]])
2259 .run();
0a29b90c
FG
2260
2261 // A crate installation must not emit any message from a workspace under
2262 // current working directory.
2263 // See https://github.com/rust-lang/cargo/issues/8619
04c3a46a
FG
2264 p.cargo("install foo").with_stderr_data(str![[r#"
2265[UPDATING] `dummy-registry` index
0a29b90c 2266[DOWNLOADING] crates ...
04c3a46a 2267[DOWNLOADED] foo v0.1.0 (registry `dummy-registry`)
0a29b90c
FG
2268[INSTALLING] foo v0.1.0
2269[COMPILING] foo v0.1.0
04c3a46a
FG
2270[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
2271[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
0a29b90c 2272[INSTALLED] package `foo v0.1.0` (executable `foo[EXE]`)
04c3a46a
FG
2273[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2274
2275"#]]).run();
2276 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
2277}
2278
2279#[cargo_test]
2280fn locked_install_without_published_lockfile() {
2281 Package::new("foo", "0.1.0")
2282 .file("src/main.rs", "//! Some docs\nfn main() {}")
2283 .publish();
2284
2285 cargo_process("install foo --locked")
04c3a46a
FG
2286 .with_stderr_data(str![[r#"
2287...
2288[WARNING] no Cargo.lock file published in foo v0.1.0
2289...
2290"#]])
0a29b90c
FG
2291 .run();
2292}
2293
2294#[cargo_test]
2295fn install_semver_metadata() {
2296 // Check trying to install a package that uses semver metadata.
2297 // This uses alt registry because the bug this is exercising doesn't
2298 // trigger with a replaced source.
2299 registry::alt_init();
2300 Package::new("foo", "1.0.0+abc")
2301 .alternative(true)
2302 .file("src/main.rs", "fn main() {}")
2303 .publish();
2304
2305 cargo_process("install foo --registry alternative --version 1.0.0+abc").run();
2306 cargo_process("install foo --registry alternative")
04c3a46a 2307 .with_stderr_data(str![[r#"
0a29b90c
FG
2308[UPDATING] `alternative` index
2309[IGNORED] package `foo v1.0.0+abc (registry `alternative`)` is already installed, use --force to override
04c3a46a
FG
2310[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2311
2312"#]])
0a29b90c
FG
2313 .run();
2314 // "Updating" is not displayed here due to the --version fast-path.
2315 cargo_process("install foo --registry alternative --version 1.0.0+abc")
04c3a46a 2316 .with_stderr_data(str![[r#"
0a29b90c 2317[IGNORED] package `foo v1.0.0+abc (registry `alternative`)` is already installed, use --force to override
04c3a46a
FG
2318[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2319
2320"#]])
0a29b90c
FG
2321 .run();
2322 cargo_process("install foo --registry alternative --version 1.0.0 --force")
04c3a46a 2323 .with_stderr_data(str![[r#"
0a29b90c
FG
2324[UPDATING] `alternative` index
2325[INSTALLING] foo v1.0.0+abc (registry `alternative`)
2326[COMPILING] foo v1.0.0+abc (registry `alternative`)
04c3a46a 2327[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
0a29b90c 2328[REPLACING] [ROOT]/home/.cargo/bin/foo[EXE]
04c3a46a
FG
2329[REPLACED] package `foo v1.0.0+abc (registry `alternative`)` with `foo v1.0.0+abc (registry `alternative`)` (executable `foo[EXE]`)
2330[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2331
2332"#]])
0a29b90c
FG
2333 .run();
2334 // Check that from a fresh cache will work without metadata, too.
2335 paths::home().join(".cargo/registry").rm_rf();
2336 paths::home().join(".cargo/bin").rm_rf();
2337 cargo_process("install foo --registry alternative --version 1.0.0")
04c3a46a 2338 .with_stderr_data(str![[r#"
0a29b90c
FG
2339[UPDATING] `alternative` index
2340[DOWNLOADING] crates ...
2341[DOWNLOADED] foo v1.0.0+abc (registry `alternative`)
2342[INSTALLING] foo v1.0.0+abc (registry `alternative`)
2343[COMPILING] foo v1.0.0+abc (registry `alternative`)
04c3a46a 2344[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
0a29b90c
FG
2345[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
2346[INSTALLED] package `foo v1.0.0+abc (registry `alternative`)` (executable `foo[EXE]`)
04c3a46a
FG
2347[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2348
2349"#]])
0a29b90c
FG
2350 .run();
2351}
2352
2353#[cargo_test]
2354fn no_auto_fix_note() {
2355 Package::new("auto_fix", "0.0.1")
2356 .file("src/lib.rs", "use std::io;")
2357 .file(
2358 "src/main.rs",
2359 &format!("extern crate {}; use std::io; fn main() {{}}", "auto_fix"),
2360 )
2361 .publish();
2362
2363 // This should not contain a suggestion to run `cargo fix`
2364 //
2365 // This is checked by matching the full output as `with_stderr_does_not_contain`
2366 // can be brittle
2367 cargo_process("install auto_fix")
04c3a46a
FG
2368 .with_stderr_data(str![[r#"
2369[UPDATING] `dummy-registry` index
0a29b90c 2370[DOWNLOADING] crates ...
04c3a46a 2371[DOWNLOADED] auto_fix v0.0.1 (registry `dummy-registry`)
0a29b90c
FG
2372[INSTALLING] auto_fix v0.0.1
2373[COMPILING] auto_fix v0.0.1
04c3a46a
FG
2374[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
2375[INSTALLING] [ROOT]/home/.cargo/bin/auto_fix[EXE]
0a29b90c 2376[INSTALLED] package `auto_fix v0.0.1` (executable `auto_fix[EXE]`)
04c3a46a
FG
2377[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2378
2379"#]])
0a29b90c 2380 .run();
04c3a46a 2381 assert_has_installed_exe(paths::cargo_home(), "auto_fix");
0a29b90c
FG
2382
2383 cargo_process("uninstall auto_fix")
04c3a46a
FG
2384 .with_stderr_data(str![[r#"
2385[REMOVING] [ROOT]/home/.cargo/bin/auto_fix[EXE]
2386
2387"#]])
0a29b90c 2388 .run();
04c3a46a 2389 assert_has_not_installed_exe(paths::cargo_home(), "auto_fix");
0a29b90c
FG
2390}
2391
2392#[cargo_test]
2393fn failed_install_retains_temp_directory() {
2394 // Verifies that the temporary directory persists after a build failure.
2395 Package::new("foo", "0.0.1")
2396 .file("src/main.rs", "x")
2397 .publish();
2398 let err = cargo_process("install foo").exec_with_output().unwrap_err();
2399 let err = err.downcast::<ProcessError>().unwrap();
2400 let stderr = String::from_utf8(err.stderr.unwrap()).unwrap();
31ef2f64 2401 assert_e2e().eq(&stderr, str![[r#"
0a29b90c
FG
2402[UPDATING] `dummy-registry` index
2403[DOWNLOADING] crates ...
2404[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
2405[INSTALLING] foo v0.0.1
2406[COMPILING] foo v0.0.1
31ef2f64
FG
2407[ERROR] expected one of `!` or `::`, found `<eof>`
2408 --> [ROOT]/home/.cargo/registry/src/-[..]/foo-0.0.1/src/main.rs:1:1
2409 |
24101 | x
2411 | ^ expected one of `!` or `::`
2412
2413[ERROR] could not compile `foo` (bin "foo") due to 1 previous error
2414[ERROR] failed to compile `foo v0.0.1`, intermediate artifacts can be found at `[..]`.
2415To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.
2416
2417"#]]);
0a29b90c
FG
2418
2419 // Find the path in the output.
781aab86
FG
2420 let stderr = stderr.split_once("found at `").unwrap().1;
2421 let end = stderr.find('.').unwrap() - 1;
2422 let path = Path::new(&stderr[..end]);
0a29b90c
FG
2423 assert!(path.exists());
2424 assert!(path.join("release/deps").exists());
2425}
2426
2427#[cargo_test]
2428fn sparse_install() {
2429 // Checks for an issue where uninstalling something corrupted
2430 // the SourceIds of sparse registries.
2431 // See https://github.com/rust-lang/cargo/issues/11751
2432 let _registry = registry::RegistryBuilder::new().http_index().build();
2433
2434 pkg("foo", "0.0.1");
2435 pkg("bar", "0.0.1");
2436
2437 cargo_process("install foo --registry dummy-registry")
04c3a46a 2438 .with_stderr_data(str![[r#"
0a29b90c
FG
2439[UPDATING] `dummy-registry` index
2440[DOWNLOADING] crates ...
2441[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
2442[INSTALLING] foo v0.0.1 (registry `dummy-registry`)
2443[UPDATING] `dummy-registry` index
2444[COMPILING] foo v0.0.1 (registry `dummy-registry`)
04c3a46a 2445[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
0a29b90c
FG
2446[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
2447[INSTALLED] package `foo v0.0.1 (registry `dummy-registry`)` (executable `foo[EXE]`)
04c3a46a
FG
2448[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2449
2450"#]])
0a29b90c 2451 .run();
04c3a46a 2452 assert_has_installed_exe(paths::cargo_home(), "foo");
0a29b90c
FG
2453 let assert_v1 = |expected| {
2454 let v1 = fs::read_to_string(paths::home().join(".cargo/.crates.toml")).unwrap();
31ef2f64 2455 assert_e2e().eq(&v1, expected);
0a29b90c 2456 };
31ef2f64
FG
2457 assert_v1(str![[r#"
2458[v1]
0a29b90c 2459"foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"]
31ef2f64
FG
2460
2461"#]]);
0a29b90c 2462 cargo_process("install bar").run();
04c3a46a 2463 assert_has_installed_exe(paths::cargo_home(), "bar");
31ef2f64
FG
2464 assert_v1(str![[r#"
2465[v1]
0a29b90c
FG
2466"bar 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = ["bar[EXE]"]
2467"foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"]
31ef2f64
FG
2468
2469"#]]);
0a29b90c
FG
2470
2471 cargo_process("uninstall bar")
04c3a46a
FG
2472 .with_stderr_data(str![[r#"
2473[REMOVING] [ROOT]/home/.cargo/bin/bar[EXE]
2474
2475"#]])
0a29b90c 2476 .run();
04c3a46a 2477 assert_has_not_installed_exe(paths::cargo_home(), "bar");
31ef2f64
FG
2478 assert_v1(str![[r#"
2479[v1]
0a29b90c 2480"foo 0.0.1 (sparse+http://127.0.0.1:[..]/index/)" = ["foo[EXE]"]
31ef2f64
FG
2481
2482"#]]);
0a29b90c 2483 cargo_process("uninstall foo")
04c3a46a
FG
2484 .with_stderr_data(str![[r#"
2485[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
2486
2487"#]])
0a29b90c 2488 .run();
04c3a46a 2489 assert_has_not_installed_exe(paths::cargo_home(), "foo");
31ef2f64
FG
2490 assert_v1(str![[r#"
2491[v1]
2492
2493"#]]);
0a29b90c 2494}
49aad941
FG
2495
2496#[cargo_test]
2497fn self_referential() {
2498 // Some packages build-dep on prior versions of themselves.
2499 Package::new("foo", "0.0.1")
2500 .file("src/lib.rs", "fn hello() {}")
2501 .file("src/main.rs", "fn main() {}")
2502 .file("build.rs", "fn main() {}")
2503 .publish();
2504 Package::new("foo", "0.0.2")
2505 .file("src/lib.rs", "fn hello() {}")
2506 .file("src/main.rs", "fn main() {}")
2507 .file("build.rs", "fn main() {}")
2508 .build_dep("foo", "0.0.1")
2509 .publish();
2510
04c3a46a
FG
2511 cargo_process("install foo").with_stderr_data(str![[r#"
2512[UPDATING] `dummy-registry` index
49aad941 2513[DOWNLOADING] crates ...
04c3a46a 2514[DOWNLOADED] foo v0.0.2 (registry `dummy-registry`)
49aad941 2515[INSTALLING] foo v0.0.2
e8be2606
FG
2516[LOCKING] 2 packages to latest compatible versions
2517[ADDING] foo v0.0.1 (latest: v0.0.2)
49aad941 2518[DOWNLOADING] crates ...
04c3a46a 2519[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
49aad941
FG
2520[COMPILING] foo v0.0.1
2521[COMPILING] foo v0.0.2
04c3a46a
FG
2522[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
2523[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
49aad941 2524[INSTALLED] package `foo v0.0.2` (executable `foo[EXE]`)
04c3a46a
FG
2525[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2526
2527"#]]).run();
2528 assert_has_installed_exe(paths::cargo_home(), "foo");
49aad941
FG
2529}
2530
2531#[cargo_test]
2532fn ambiguous_registry_vs_local_package() {
2533 // Correctly install 'foo' from a local package, even if that package also
2534 // depends on a registry dependency named 'foo'.
2535 Package::new("foo", "0.0.1")
2536 .file("src/lib.rs", "fn hello() {}")
2537 .publish();
2538
2539 let p = project()
2540 .file("src/main.rs", "fn main() {}")
2541 .file(
2542 "Cargo.toml",
2543 r#"
2544 [package]
2545 name = "foo"
2546 version = "0.1.0"
2547 authors = []
2548 edition = "2021"
2549
2550 [dependencies]
2551 foo = "0.0.1"
2552 "#,
2553 )
2554 .build();
2555
2556 cargo_process("install --path")
2557 .arg(p.root())
04c3a46a
FG
2558 .with_stderr_data(str![[r#"
2559[INSTALLING] foo v0.1.0 ([ROOT]/foo)
2560[UPDATING] `dummy-registry` index
e8be2606 2561[LOCKING] 2 packages to latest compatible versions
49aad941 2562[DOWNLOADING] crates ...
04c3a46a 2563[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
49aad941 2564[COMPILING] foo v0.0.1
04c3a46a
FG
2565[COMPILING] foo v0.1.0 ([ROOT]/foo)
2566[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
2567[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
2568[INSTALLED] package `foo v0.1.0 ([ROOT]/foo)` (executable `foo[EXE]`)
2569[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2570
2571"#]])
49aad941 2572 .run();
04c3a46a 2573 assert_has_installed_exe(paths::cargo_home(), "foo");
49aad941 2574}
781aab86
FG
2575
2576#[cargo_test]
2577fn install_with_redundant_default_mode() {
2578 pkg("foo", "0.0.1");
2579
2580 cargo_process("install foo --release")
04c3a46a
FG
2581 .with_stderr_data(str![[r#"
2582[ERROR] unexpected argument '--release' found
781aab86
FG
2583
2584 tip: `--release` is the default for `cargo install`; instead `--debug` is supported
2585
ed00b5ec 2586Usage: cargo[EXE] install [OPTIONS] [CRATE[@<VER>]]...
781aab86
FG
2587
2588For more information, try '--help'.
04c3a46a
FG
2589
2590"#]])
781aab86
FG
2591 .with_status(1)
2592 .run();
2593}
ed00b5ec
FG
2594
2595#[cargo_test]
2596fn install_incompat_msrv() {
2597 Package::new("foo", "0.1.0")
2598 .file("src/main.rs", "fn main() {}")
2599 .rust_version("1.30")
2600 .publish();
2601 Package::new("foo", "0.2.0")
2602 .file("src/main.rs", "fn main() {}")
2603 .rust_version("1.9876.0")
2604 .publish();
2605
2606 cargo_process("install foo")
04c3a46a 2607 .with_stderr_data(str![[r#"
ed00b5ec
FG
2608[UPDATING] `dummy-registry` index
2609[ERROR] cannot install package `foo 0.2.0`, it requires rustc 1.9876.0 or newer, while the currently active rustc version is [..]
2610`foo 0.1.0` supports rustc 1.30
04c3a46a
FG
2611
2612"#]])
2613 .with_status(101)
2614 .run();
ed00b5ec 2615}
4b012472
FG
2616
2617fn assert_tracker_noexistence(key: &str) {
2618 let v1_data: toml::Value =
04c3a46a 2619 toml::from_str(&fs::read_to_string(paths::cargo_home().join(".crates.toml")).unwrap())
4b012472 2620 .unwrap();
04c3a46a
FG
2621 let v2_data: serde_json::Value = serde_json::from_str(
2622 &fs::read_to_string(paths::cargo_home().join(".crates2.json")).unwrap(),
2623 )
2624 .unwrap();
4b012472
FG
2625
2626 assert!(v1_data["v1"].get(key).is_none());
2627 assert!(v2_data["installs"][key].is_null());
2628}
2629
2630#[cargo_test]
2631fn uninstall_running_binary() {
2632 use std::io::Write;
2633
2634 Package::new("foo", "0.0.1")
2635 .file(
2636 "Cargo.toml",
2637 r#"
2638 [package]
2639 name = "foo"
2640 version = "0.0.1"
2641 "#,
2642 )
2643 .file(
2644 "src/main.rs",
2645 r#"
2646 use std::net::TcpStream;
2647 use std::env::var;
2648 use std::io::Read;
2649 fn main() {
2650 for i in 0..2 {
2651 TcpStream::connect(&var("__ADDR__").unwrap()[..])
2652 .unwrap()
2653 .read_to_end(&mut Vec::new())
2654 .unwrap();
2655 }
2656 }
2657 "#,
2658 )
2659 .publish();
2660
04c3a46a
FG
2661 cargo_process("install foo").with_stderr_data(str![[r#"
2662[UPDATING] `dummy-registry` index
4b012472 2663[DOWNLOADING] crates ...
04c3a46a 2664[DOWNLOADED] foo v0.0.1 (registry `dummy-registry`)
4b012472
FG
2665[INSTALLING] foo v0.0.1
2666[COMPILING] foo v0.0.1
04c3a46a
FG
2667[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
2668[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
4b012472 2669[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
04c3a46a
FG
2670[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2671
2672"#]]).run();
2673 assert_has_installed_exe(paths::cargo_home(), "foo");
4b012472 2674
04c3a46a 2675 let foo_bin = paths::cargo_home().join("bin").join(exe("foo"));
4b012472
FG
2676 let l = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
2677 let addr = l.local_addr().unwrap().to_string();
2678 let t = thread::spawn(move || {
2679 ProcessBuilder::new(foo_bin)
2680 .env("__ADDR__", addr)
2681 .exec()
2682 .unwrap();
2683 });
2684 let key = "foo 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)";
2685
2686 #[cfg(windows)]
2687 {
2688 // Ensure foo is running before the first `cargo uninstall` call
2689 l.accept().unwrap().0.write_all(&[1]).unwrap();
2690 cargo_process("uninstall foo")
2691 .with_status(101)
04c3a46a
FG
2692 .with_stderr_data(str![[r#"
2693...
2694[ERROR] failed to remove file `[ROOT]/home/.cargo/bin/foo[EXE]`
2695...
2696"#]])
4b012472
FG
2697 .run();
2698 // Ensure foo is stopped before the second `cargo uninstall` call
2699 l.accept().unwrap().0.write_all(&[1]).unwrap();
2700 t.join().unwrap();
2701 cargo_process("uninstall foo")
04c3a46a
FG
2702 .with_stderr_data(str![[r#"
2703[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
2704
2705"#]])
4b012472
FG
2706 .run();
2707 };
2708
2709 #[cfg(not(windows))]
2710 {
2711 // Ensure foo is running before the first `cargo uninstall` call
2712 l.accept().unwrap().0.write_all(&[1]).unwrap();
2713 cargo_process("uninstall foo")
04c3a46a
FG
2714 .with_stderr_data(str![[r#"
2715[REMOVING] [ROOT]/home/.cargo/bin/foo[EXE]
2716
2717"#]])
4b012472
FG
2718 .run();
2719 l.accept().unwrap().0.write_all(&[1]).unwrap();
2720 t.join().unwrap();
2721 };
2722
04c3a46a 2723 assert_has_not_installed_exe(paths::cargo_home(), "foo");
4b012472
FG
2724 assert_tracker_noexistence(key);
2725
04c3a46a
FG
2726 cargo_process("install foo").with_stderr_data(str![[r#"
2727[UPDATING] `dummy-registry` index
4b012472
FG
2728[INSTALLING] foo v0.0.1
2729[COMPILING] foo v0.0.1
04c3a46a
FG
2730[FINISHED] `release` profile [optimized] target(s) in [ELAPSED]s
2731[INSTALLING] [ROOT]/home/.cargo/bin/foo[EXE]
4b012472 2732[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`)
04c3a46a
FG
2733[WARNING] be sure to add `[ROOT]/home/.cargo/bin` to your PATH to be able to run the installed binaries
2734
2735"#]]).run();
4b012472 2736}