use std::env;
use std::path::{Path, PathBuf};
use duct::cmd;
use shell_words::join;
use command;
const CARGO_CMD: &str = "cargo";
#[derive(Debug)]
pub struct Build<'c> {
pub manifest_path: &'c PathBuf,
pub args: Vec<String>,
}
impl<'c> Build<'c> {
fn compile_sources(&self) {
self.compile_crate(vec!["build"]);
}
fn compile_tests(&self) {
self.compile_crate(vec!["test", "--no-run"]);
}
fn compile_examples(&self) {
self.compile_crate(vec!["build", "--examples"]);
}
fn compile_crate(&self, base_args: Vec<&'static str>) {
let mut args = base_args;
args.append(
&mut self
.args
.iter()
.map(|arg| arg.as_str())
.collect::<Vec<&str>>(),
);
println!("Running command: `{} {}`", CARGO_CMD, join(&args));
let exit_status = cmd(CARGO_CMD, &args)
.dir(self.manifest_path.parent().unwrap())
.run()
.expect("Failed to run command.")
.status;
if !exit_status.success() {
panic!("Failed to execute command.");
}
}
}
struct PopDir<P: AsRef<Path>>(P);
impl<P: AsRef<Path>> Drop for PopDir<P> {
fn drop(&mut self) {
env::set_current_dir(&self.0).expect("Failed to pop directory.")
}
}
impl<'c> command::Command for Build<'c> {
fn run(&mut self) -> Result<(), ()> {
let current_dir = env::current_dir().expect("Failed to get current directory.");
let _pop_dir = PopDir(current_dir);
env::set_current_dir(
self.manifest_path
.parent()
.expect("Failed to get parent directory of manifest path."),
).expect("Failed to set current directory for Build command.");
self.compile_sources();
self.compile_tests();
self.compile_examples();
Ok(())
}
}