diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index b193131a927..93d9319b3e9 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -174,14 +174,30 @@ fn install_one( )? } else if source_id.is_path() { let mut src = path_source(source_id, config)?; - src.update().chain_err(|| { - failure::format_err!( - "`{}` is not a crate root; specify a crate to \ - install from crates.io, or use --path or --git to \ - specify an alternate source", + if !src.path().is_dir() { + failure::bail!( + "`{}` is not a directory. \ + --path must point to a directory containing a Cargo.toml file.", src.path().display() ) - })?; + } + if !src.path().join("Cargo.toml").exists() { + if from_cwd { + failure::bail!( + "`{}` is not a crate root; specify a crate to \ + install from crates.io, or use --path or --git to \ + specify an alternate source", + src.path().display() + ); + } else { + failure::bail!( + "`{}` does not contain a Cargo.toml file. \ + --path must point to a directory containing a Cargo.toml file.", + src.path().display() + ) + } + } + src.update()?; select_pkg(src, krate, vers, config, false, &mut |path| { path.read_packages() })? diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index 5c202ee3b07..b7955461f68 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -160,20 +160,27 @@ fn bad_version() { } #[test] -fn no_crate() { +fn bad_paths() { cargo_process("install") .with_status(101) - .with_stderr( - "\ -[ERROR] `[..]` is not a crate root; specify a crate to install [..] + .with_stderr("[ERROR] `[CWD]` is not a crate root; specify a crate to install [..]") + .run(); -Caused by: - failed to read `[..]Cargo.toml` + cargo_process("install --path .") + .with_status(101) + .with_stderr("[ERROR] `[CWD]` does not contain a Cargo.toml file[..]") + .run(); -Caused by: - [..] (os error [..]) -", - ) + let toml = paths::root().join("Cargo.toml"); + fs::write(toml, "").unwrap(); + cargo_process("install --path Cargo.toml") + .with_status(101) + .with_stderr("[ERROR] `[CWD]/Cargo.toml` is not a directory[..]") + .run(); + + cargo_process("install --path .") + .with_status(101) + .with_stderr_contains("[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`") .run(); } diff --git a/tests/testsuite/support/mod.rs b/tests/testsuite/support/mod.rs index 404439ea416..ea5b8751f59 100644 --- a/tests/testsuite/support/mod.rs +++ b/tests/testsuite/support/mod.rs @@ -1249,6 +1249,8 @@ enum MatchKind { /// - There is a wide range of macros (such as `[COMPILING]` or `[WARNING]`) /// to match cargo's "status" output and allows you to ignore the alignment. /// See `substitute_macros` for a complete list of macros. +/// - `[ROOT]` is `/` or `[..]:\` on Windows. +/// - `[CWD]` is the working directory of the process that was run. pub fn lines_match(expected: &str, actual: &str) -> bool { // Let's not deal with / vs \ (windows...) // First replace backslash-escaped backslashes with forward slashes