Generalise find_project to not always search parents.

Also, add a helper around `find_project` that returns `dir/file` rather
than just `dir`.
This commit is contained in:
Huon Wilson 2014-06-28 19:24:15 +10:00
parent 9288b6e618
commit 97d1d358af
4 changed files with 36 additions and 11 deletions

5
src/bin/cargo-build.rs Normal file → Executable file
View file

@ -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<Option<()>> {
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",

5
src/bin/cargo-test.rs Normal file → Executable file
View file

@ -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<Option<()>> {
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",

2
src/bin/cargo.rs Normal file → Executable file
View file

@ -142,7 +142,7 @@ fn config_list(args: ConfigListFlags, _: &mut MultiShell) -> CliResult<Option<Co
}
fn locate_project(_: NoFlags, _: &mut MultiShell) -> CliResult<Option<ProjectLocation>> {
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)
}));

View file

@ -1,15 +1,42 @@
use util::{CargoResult, human};
pub fn find_project(pwd: Path, file: &str) -> CargoResult<Path> {
/// Iteratively search for `file` in `pwd` and its parents, returning
/// the path of the directory.
pub fn find_project(pwd: &Path, file: &str) -> CargoResult<Path> {
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<Path> {
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<Path> {
let manifest = pwd.join(file);
if manifest.exists() {
Ok(manifest)
} else {
Err(human(format!("Could not find `{}` in `{}`",
file, pwd.display())))
}
}