1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::fs;
use std::path::{Path, PathBuf};
use util::{CargoResult, human};

/// Iteratively search for `file` in `pwd` and its parents, returning
/// the path of the directory.
pub fn find_project(pwd: &Path, file: &str) -> CargoResult<PathBuf> {
    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<PathBuf> {
    let mut current = pwd;

    loop {
        let manifest = current.join(file);
        if fs::metadata(&manifest).is_ok() {
            return Ok(manifest)
        }

        match current.parent() {
            Some(p) => current = p,
            None => break,
        }
    }

    bail!("could not find `{}` in `{}` or any parent directory",
          file, pwd.display())
}

/// Find the root Cargo.toml
pub fn find_root_manifest_for_wd(manifest_path: Option<String>, cwd: &Path)
                                  -> CargoResult<PathBuf> {
    match manifest_path {
        Some(path) => {
            let absolute_path = cwd.join(&path);
            if !absolute_path.ends_with("Cargo.toml") {
                bail!("the manifest-path must be a path to a Cargo.toml file")
            }
            if !fs::metadata(&absolute_path).is_ok() {
                bail!("manifest path `{}` does not exist", path)
            }
            Ok(absolute_path)
        },
        None => find_project_manifest(&cwd, "Cargo.toml"),
    }
}

/// Return the path to the `file` in `pwd`, if it exists.
pub fn find_project_manifest_exact(pwd: &Path, file: &str) -> CargoResult<PathBuf> {
    let manifest = pwd.join(file);

    if fs::metadata(&manifest).is_ok() {
        Ok(manifest)
    } else {
        Err(human(format!("Could not find `{}` in `{}`",
                          file, pwd.display())))
    }
}