From 6b3bab306d7dedb4940e33e80c5e613fa953e197 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Tue, 25 Sep 2018 12:08:37 +0200 Subject: [PATCH] Used the clean version with boxes --- src/client.rs | 1 - src/lib.rs | 151 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 101 insertions(+), 51 deletions(-) diff --git a/src/client.rs b/src/client.rs index 7420a81..9b23e6b 100644 --- a/src/client.rs +++ b/src/client.rs @@ -20,7 +20,6 @@ fn main() { }; let url = format!("http://localhost:1500{}", current_dir); - println!("{:?}", url); let url = url.parse::().unwrap(); rt::run(fetch_url(url)); diff --git a/src/lib.rs b/src/lib.rs index 85d9fa8..2e1b918 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,19 @@ use std::io; use std::process::{Command, ExitStatus}; use std::path::PathBuf; use std::ffi::OsStr; +use std::fs::create_dir_all; + +macro_rules! destroy { + ($e: expr) => { + match $e { + Err(_) => { + let err: Result<(), ()> = Err(()); + return err; + }, + _ => (), + } + } +} /// Tests if a file is in a directory. pub fn contains_file(path: &str, file: &str) -> bool { @@ -28,19 +41,17 @@ pub fn run_command(command: &str, path: &str) -> Result { pub fn run_command_with_args(command: &str, path: &str, args: I) -> Result where I: IntoIterator, S: AsRef { - let mut child = match Command::new(command) + + let mut child = Command::new(command) .current_dir(path) .args(args) - .spawn() { - Err(x) => return Err(x), - Ok(child) => child, - }; + .spawn()?; child.wait() } /// Tries to build a certain directory using the specified builders. -pub fn build(path: &PathBuf, builders: &Vec) -> Result<(), ()> { +pub fn build(path: &PathBuf, builders: &Vec>) -> Result<(), ()> { let mut path = path.clone(); @@ -74,10 +85,9 @@ pub fn destroy(result: Result) -> Result<(), ()> { } /// A general builders that contains many builders and can build any type of code. -#[derive(Clone)] pub struct GeneralBuilder { /// The builders contained. - builders: Vec, + builders: Vec>, } impl GeneralBuilder { @@ -85,8 +95,9 @@ impl GeneralBuilder { pub fn new() -> GeneralBuilder { GeneralBuilder { builders: vec![ - Builder::make(), - Builder::cargo(), + Box::new(MakeBuilder::new()), + Box::new(CMakeBuilder::new()), + Box::new(CargoBuilder::new()), ], } } @@ -97,50 +108,90 @@ impl GeneralBuilder { } } -/// The builder that looks for makefiles. -#[derive(Clone)] -pub struct Builder { - /// The file to lookup to check build. - file: String, - - /// The command to launch to build. - command: String, - - /// The arguments to the command. - args: Vec, -} - -impl Builder { - /// Creates a new make builder. - pub fn make() -> Builder { - Builder { - file: "Makefile".to_string(), - command: "make".to_string(), - args: vec![], - } - } - - /// Creates a new cargo builder. - pub fn cargo() -> Builder { - Builder { - file: "Cargo.toml".to_string(), - command: "cargo".to_string(), - args: vec!["build".to_string()], - } - } - +/// A generic builder. It can build some projects. +pub trait Builder { /// Checks if a directory has corresponding files so it can build it. /// e.g.: if there is a Makefile - fn is_buildable(&self, path: &str) -> bool { - contains_file(path, &self.file) - } + fn is_buildable(&self, path: &str) -> bool; /// Trigger all the commands to build the project. - fn build(&self, path: &str) -> Result<(), ()> { - match run_command_with_args(&self.command, path, &self.args) { - Ok(_) => Ok(()), - Err(_) => Err(()), - } + fn build(&self, path: &str) -> Result<(), ()>; +} + +/// The builder that looks for makefiles. +pub struct MakeBuilder; + +impl MakeBuilder { + /// Creates a new make builder. + pub fn new() -> MakeBuilder { + MakeBuilder } } +impl Builder for MakeBuilder { + fn is_buildable(&self, path: &str) -> bool { + contains_file(path, "Makefile") + } + + fn build(&self, path: &str) -> Result<(), ()> { + destroy!(run_command("make", path)); + Ok(()) + } +} + +/// The builder that builds cmake projects. +pub struct CMakeBuilder; + +impl CMakeBuilder { + /// Creates a new cmake builder. + pub fn new() -> CMakeBuilder { + CMakeBuilder + } +} + +impl Builder for CMakeBuilder { + fn is_buildable(&self, path: &str) -> bool { + contains_file(path, "CMakeLists.txt") + } + + fn build(&self, path: &str) -> Result<(), ()> { + + let mut build = PathBuf::from(path); + build.push("build"); + + // If there's a build/Makefile, we'll only make + if ! contains_file(path, "build/Makefile") { + + // Create build directory + destroy!(create_dir_all(&build)); + + // Run cmake .. in build directory + destroy!(run_command_with_args("cmake", build.to_str().unwrap(), [".."].iter())); + } + + // Run make in build directory + destroy!(run_command("make", build.to_str().unwrap())); + Ok(()) + } + +} + +/// The builder that looks for Cargo.toml. +pub struct CargoBuilder; + +impl CargoBuilder { + /// Creates a new cargo builder. + pub fn new() -> CargoBuilder { + CargoBuilder + } +} + +impl Builder for CargoBuilder { + fn is_buildable(&self, path: &str) -> bool { + contains_file(path, "Cargo.toml") + } + + fn build(&self, path: &str) -> Result<(), ()> { + destroy(run_command_with_args("cargo", path, ["build"].iter())) + } +}