extern crate rustc_serialize;
use std::env;
use std::fs;
use std::path::PathBuf;
use err::ProfError;
use std::process::Command;
use std::path::Path;
use self::rustc_serialize::json::Json;
pub fn find_target() -> Option<PathBuf> {
fn contains_manifest(path: &PathBuf) -> bool {
fs::read_dir(path)
.map(|entries| {
entries.filter_map(|res| res.ok())
.any(|ent| ent.path().ends_with("target"))
})
.unwrap_or(false)
}
env::current_dir().ok().and_then(|mut wd| {
for _ in 0..10 {
if contains_manifest(&mut wd) {
return Some(wd);
}
if !wd.pop() {
break;
}
}
None
})
}
pub fn get_package_name() -> Result<String, ProfError> {
let manifest = Command::new("cargo")
.arg("read-manifest")
.output()
.unwrap_or_else(|e| panic!("failed to execute process: {}", e));
let out = String::from_utf8(manifest.stdout).unwrap_or("".to_string());
let data = Json::from_str(&out).or(Err(ProfError::ReadManifestError));
data.and_then(|x| {
x.as_object()
.expect("Could not extract object from read manifest JSON. Please submit bug.")
.get("name")
.ok_or(ProfError::NoNameError)
.and_then(|x| Ok(x.to_string().replace("\"", "")))
})
}
pub fn build_binary(release: bool) -> Result<String, ProfError> {
let package_name = try!(get_package_name());
let (out, binary_dir) = match release {
true => {
println!("\n\x1b[1;33mCompiling \x1b[1;0m{} in release mode...",
package_name);
(Command::new("cargo")
.args(&["build", "--release"])
.output()
.unwrap_or_else(|e| panic!("failed to execute process: {}", e)),
"/target/release/")
}
false => {
println!("\n\x1b[1;33mCompiling \x1b[1;0m{} in debug mode...",
package_name);
(Command::new("cargo")
.arg("build")
.output()
.unwrap_or_else(|e| panic!("failed to execute process: {}", e)),
"/target/debug/")
}
};
let target_dir = find_target()
.ok_or(ProfError::NoTargetDirectory)
.and_then(|x| {
Ok(x.to_str()
.expect("target directory could not be converted to string.")
.to_string())
});
let path = target_dir.and_then(|x| Ok(x + binary_dir + &package_name))
.unwrap_or("".to_string());
if !Path::new(&path).exists() {
return Err(ProfError::CompilationError(package_name.to_string(),
String::from_utf8(out.stderr)
.unwrap_or("".to_string())));
}
Ok(path)
}
#[cfg(test)]
mod test {
#[test]
fn test_find_target() {
assert_eq!(1, 1);
}
#[test]
fn test_get_package_name() {
assert_eq!(1, 1);
assert_eq!(1, 1);
}
#[test]
fn test_build_binary() {
assert_eq!(1, 1);
}
}