diff --git a/src/bin/cargo-build.rs b/src/bin/cargo-build.rs old mode 100644 new mode 100755 index c3d3c96fe..f88cf5405 --- a/src/bin/cargo-build.rs +++ b/src/bin/cargo-build.rs @@ -16,7 +16,7 @@ use cargo::{execute_main_without_stdin}; use cargo::ops; use cargo::core::MultiShell; use cargo::util::{CliResult, CliError}; -use cargo::util::important_paths::find_project; +use cargo::util::important_paths::find_project_manifest; #[deriving(PartialEq,Clone,Decodable,Encodable)] pub struct Options { @@ -37,8 +37,7 @@ fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { let root = match options.manifest_path { Some(path) => Path::new(path), - None => try!(find_project(os::getcwd(), "Cargo.toml") - .map(|path| path.join("Cargo.toml")) + None => try!(find_project_manifest(&os::getcwd(), "Cargo.toml") .map_err(|_| { CliError::new("Could not find Cargo.toml in this \ directory or any parent directory", diff --git a/src/bin/cargo-test.rs b/src/bin/cargo-test.rs old mode 100644 new mode 100755 index 8849b2d72..5adb71120 --- a/src/bin/cargo-test.rs +++ b/src/bin/cargo-test.rs @@ -16,7 +16,7 @@ use cargo::{execute_main_without_stdin}; use cargo::core::{MultiShell}; use cargo::util; use cargo::util::{CliResult, CliError}; -use cargo::util::important_paths::find_project; +use cargo::util::important_paths::find_project_manifest; #[deriving(PartialEq,Clone,Decodable)] struct Options { @@ -33,8 +33,7 @@ fn main() { fn execute(options: Options, shell: &mut MultiShell) -> CliResult> { let root = match options.manifest_path { Some(path) => Path::new(path), - None => try!(find_project(os::getcwd(), "Cargo.toml") - .map(|path| path.join("Cargo.toml")) + None => try!(find_project_manifest(&os::getcwd(), "Cargo.toml") .map_err(|_| { CliError::new("Could not find Cargo.toml in this \ directory or any parent directory", diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs old mode 100644 new mode 100755 index 454e84e6b..ed3a12d32 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -142,7 +142,7 @@ fn config_list(args: ConfigListFlags, _: &mut MultiShell) -> CliResult CliResult> { - let root = try!(find_project(os::getcwd(), "Cargo.toml").map_err(|e| { + let root = try!(find_project(&os::getcwd(), "Cargo.toml").map_err(|e| { CliError::from_boxed(e, 1) })); diff --git a/src/cargo/ops/cargo_read_manifest.rs b/src/cargo/ops/cargo_read_manifest.rs index 324085734..262e502af 100644 --- a/src/cargo/ops/cargo_read_manifest.rs +++ b/src/cargo/ops/cargo_read_manifest.rs @@ -1,7 +1,7 @@ use std::io::File; use util; use core::{Package,Manifest,SourceId}; -use util::{CargoResult, human}; +use util::{CargoResult, human, important_paths}; pub fn read_manifest(contents: &[u8], source_id: &SourceId) -> CargoResult<(Manifest, Vec)> @@ -24,7 +24,8 @@ pub fn read_package(path: &Path, source_id: &SourceId) pub fn read_packages(path: &Path, source_id: &SourceId) -> CargoResult> { - let (pkg, nested) = try!(read_package(&path.join("Cargo.toml"), source_id)); + let manifest = try!(important_paths::find_project_manifest_exact(path, "Cargo.toml")); + let (pkg, nested) = try!(read_package(&manifest, source_id)); let mut ret = vec!(pkg); for p in nested.iter() { diff --git a/src/cargo/util/important_paths.rs b/src/cargo/util/important_paths.rs index 7bcc9a551..df7a6bd7a 100644 --- a/src/cargo/util/important_paths.rs +++ b/src/cargo/util/important_paths.rs @@ -1,15 +1,42 @@ use util::{CargoResult, human}; -pub fn find_project(pwd: Path, file: &str) -> CargoResult { +/// Iteratively search for `file` in `pwd` and its parents, returning +/// the path of the directory. +pub fn find_project(pwd: &Path, file: &str) -> CargoResult { + find_project_manifest(pwd, file) + .map(|mut p| { + // remove the file, leaving just the directory + p.pop(); + p + }) +} + +/// Iteratively search for `file` in `pwd` and its parents, returning +/// the path to the file. +pub fn find_project_manifest(pwd: &Path, file: &str) -> CargoResult { let mut current = pwd.clone(); loop { - if current.join(file.clone()).exists() { - return Ok(current) + let manifest = current.join(file); + if manifest.exists() { + return Ok(manifest) } if !current.pop() { break; } } - Err(human(format!("no manifest found in `{}`", pwd.display()))) + Err(human(format!("Could not find `{}` in `{}` or any parent directory", + file, pwd.display()))) +} + +/// Return the path to the `file` in `pwd`, if it exists. +pub fn find_project_manifest_exact(pwd: &Path, file: &str) -> CargoResult { + let manifest = pwd.join(file); + + if manifest.exists() { + Ok(manifest) + } else { + Err(human(format!("Could not find `{}` in `{}`", + file, pwd.display()))) + } } diff --git a/tests/test_cargo_compile_path_deps.rs b/tests/test_cargo_compile_path_deps.rs index f01a18549..7b4406eb9 100644 --- a/tests/test_cargo_compile_path_deps.rs +++ b/tests/test_cargo_compile_path_deps.rs @@ -354,3 +354,26 @@ test!(nested_deps_recompile { FRESH, bar.display(), COMPILING, p.root().display()))); }) + +test!(error_message_for_missing_manifest { + let p = project("foo") + .file("Cargo.toml", r#" + [project] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + + path = "src/bar" + "#) + .file("src/bar/not-a-manifest", ""); + + assert_that(p.cargo_process("cargo-build"), + execs() + .with_status(101) + .with_stderr(format!("Could not find `Cargo.toml` in `{}`\n", + p.root().join_many(&["src", "bar"]).display()))); + +})