#![experimental]
#![allow(unstable)]
use std::iter::FromIterator;
use self::LifeCycle::{
Help,Version,Deps,SCM,Clean,Configure,Make,Test,Install,Cleanup,Build,Most,
All,Nil
};
#[experimental]
#[derive(Clone,Default)]
pub struct BuildConfig {
dir: Option<Path>,
project: Option<String>,
branch: Option<String>,
test: bool,
lifecycle: Option<Vec<String>>,
}
impl BuildConfig {
pub fn new() -> BuildConfig {
BuildConfig {
dir: {
let home = match std::os::getenv("HOME") {
Some(h) => h,
None => panic!("No home environment variable set!"),
};
let path = Path::new(home);
Some(path.join("projects"))
},
project: Some("rust".to_string()),
branch: Some("master".to_string()),
test: false,
lifecycle: Some(vec!["most".to_string()]),
}
}
pub fn dir(&mut self, dir: Path) -> &mut BuildConfig {
self.dir = Some(dir);
self
}
pub fn project(&mut self, project: &str) -> &mut BuildConfig {
self.project = Some(project.to_string());
self
}
pub fn branch(&mut self, branch: &str) -> &mut BuildConfig {
self.branch = Some(branch.to_string());
self
}
pub fn test(&mut self, test: bool) -> &mut BuildConfig {
self.test = test;
self
}
pub fn lifecycle(&mut self, lc: Vec<&str>) -> &mut BuildConfig {
let mut mylc = Vec::new();
for work in lc.iter() {
mylc.push(work.to_string());
}
self.lifecycle = Some(mylc);
self
}
pub fn get_dir<'a>(&'a self) -> &'a Path {
match self.dir {
Some(ref d) => d,
None => panic!("No directory set in BuildConfig!"),
}
}
pub fn get_project<'a>(&'a self) -> &'a str {
match self.project {
Some(ref p) => p.as_slice(),
None => panic!("No project set in BuildConfig!"),
}
}
pub fn get_branch<'a>(&'a self) -> &'a str {
match self.branch {
Some(ref b) => b.as_slice(),
None => panic!("No branch set in BuildConfig!"),
}
}
pub fn get_test(&self) -> bool {
self.test
}
pub fn get_lifecycle(&self) -> &Vec<String> {
match self.lifecycle {
Some(ref lc) => lc,
None => panic!("No lifecycle set in BuildConfig!"),
}
}
}
#[experimental]
pub trait Buildable {
fn new(&mut self, &Vec<String>) -> &mut Self;
fn get_bc(&self) -> &BuildConfig;
fn reorder<'a>(&self, &'a mut Vec<LifeCycle>) -> &'a mut Vec<LifeCycle>;
fn help(&self) -> Result<u8,u8>;
fn version(&self) -> Result<u8,u8>;
fn chkdeps(&self) -> Result<u8,u8>;
fn scm(&self) -> Result<u8,u8>;
fn clean(&self) -> Result<u8,u8>;
fn configure(&self) -> Result<u8,u8>;
fn make(&self) -> Result<u8,u8>;
fn test(&self) -> Result<u8,u8>;
fn install(&self) -> Result<u8,u8>;
fn cleanup(&self) -> Result<u8,u8>;
}
#[derive(Copy,PartialEq, Eq, PartialOrd, Ord, Show)]
pub enum LifeCycle {
Help,
Version,
Deps,
SCM,
Clean,
Configure,
Make,
Test,
Install,
Cleanup,
Build,
Most,
All,
Nil,
}
impl LifeCycle {
fn from_str(s: &str) -> LifeCycle {
match s {
"help" => Help,
"version" => Version,
"deps" => Deps,
"scm" => SCM,
"clean" => Clean,
"configure" => Configure,
"make" => Make,
"test" => Test,
"install" => Install,
"cleanup" => Cleanup,
"build" => Build,
"most" => Most,
"all" => All,
_ => Nil,
}
}
fn ensure<'a>(v: &'a mut Vec<LifeCycle>,
r: Vec<LifeCycle>) -> &'a mut Vec<LifeCycle> {
for lc in r.iter() {
if !v.contains(lc) {
v.push(*lc);
}
}
v
}
fn remove<'a>(v: &'a mut Vec<LifeCycle>,
r: Vec<LifeCycle>) -> &'a mut Vec<LifeCycle> {
for lc in r.iter() {
match v.iter().position(|x| *x == *lc) {
Some(idx) => { v.remove(idx); },
None => { ; },
}
}
v
}
fn from_vec(free: &Vec<String>) -> Vec<LifeCycle> {
let mut vec: Vec<LifeCycle> =
FromIterator::from_iter(free.iter()
.map(|s| LifeCycle::from_str(s.as_slice()))
.filter(|l| *l != Nil));
if vec.is_empty() {
vec.push(Build);
} else {
vec.dedup();
}
if vec.contains(&Help) {
LifeCycle::remove(&mut vec,
vec![Version, Deps, SCM, Clean, Configure, Make,
Test, Install, Cleanup, All, Build, Most]);
}
if vec.contains(&Version) {
LifeCycle::remove(&mut vec,
vec![Help, Deps, SCM, Clean, Configure, Make,
Test, Install, Cleanup, All, Build, Most]);
}
if vec.contains(&All) {
LifeCycle::remove(&mut vec, vec![Help, Version, All, Build, Most]);
LifeCycle::ensure(&mut vec, vec![Deps, SCM, Clean, Configure, Make,
Test, Install, Cleanup]);
}
if vec.contains(&Most) {
LifeCycle::remove(&mut vec, vec![Help, Version, Clean, All, Build,
Most]);
LifeCycle::ensure(&mut vec, vec![Deps, SCM, Configure, Make, Test,
Install, Cleanup]);
}
if vec.contains(&Build) {
LifeCycle::remove(&mut vec, vec![Help, Version, Clean, Test, Install,
All, Build, Most]);
LifeCycle::ensure(&mut vec, vec![Deps, SCM, Configure, Make,
Cleanup]);
}
vec.sort();
vec
}
pub fn run_lifecycle<T: Buildable>(args: &Vec<String>,
actor: &mut T) -> Result<u8,u8> {
actor.new(args);
let mut lc = LifeCycle::from_vec(actor.get_bc().get_lifecycle());
actor.reorder(&mut lc);
let mut res: Result<u8,u8> = Ok(0);
for l in lc.iter() {
if res.is_ok() {
match *l {
Help => { res = actor.help(); },
Version => { res = actor.version(); },
Deps => { res = actor.chkdeps(); },
SCM => { res = actor.scm(); },
Clean => { res = actor.clean(); },
Configure => { res = actor.configure(); },
Make => { res = actor.make(); },
Test => { res = actor.test(); },
Install => { res = actor.install(); },
Cleanup => { res = actor.cleanup(); },
_ => { break; },
}
} else {
break;
}
}
res
}
}
#[cfg(test)]
mod test {
use super::{BuildConfig,LifeCycle};
use super::LifeCycle::{
Help,Version,Deps,SCM,Clean,Configure,Make,Test,Install,Cleanup,Build,
Most,All,Nil
};
fn proj_dir() -> String {
let mut base = env!("HOME").to_string();
base.push_str("/projects");
base
}
#[test]
fn test_new() {
let bc = BuildConfig::new();
assert_eq!(bc.get_dir().as_str().unwrap(), proj_dir().as_slice());
assert_eq!(bc.get_project(), "rust");
assert_eq!(bc.get_branch(), "master");
assert!(!bc.get_test());
assert_eq!(*bc.get_lifecycle(), vec!["most".to_string()]);
}
#[test]
fn test_dir() {
let mut bc = BuildConfig::new();
bc.dir(Path::new("/tmp"));
assert_eq!(bc.get_dir().as_str().unwrap(), "/tmp");
assert_eq!(bc.get_project(), "rust");
assert_eq!(bc.get_branch(), "master");
assert!(!bc.get_test());
assert_eq!(*bc.get_lifecycle(), vec!["most".to_string()]);
}
#[test]
fn test_project() {
let mut bc = BuildConfig::new();
bc.project("cargo");
assert_eq!(bc.get_dir().as_str().unwrap(), proj_dir().as_slice());
assert_eq!(bc.get_project(), "cargo");
assert_eq!(bc.get_branch(), "master");
assert!(!bc.get_test());
assert_eq!(*bc.get_lifecycle(), vec!["most".to_string()]);
}
#[test]
fn test_branch() {
let mut bc = BuildConfig::new();
bc.branch("my-feature");
assert_eq!(bc.get_dir().as_str().unwrap(), proj_dir().as_slice());
assert_eq!(bc.get_project(), "rust");
assert_eq!(bc.get_branch(), "my-feature");
assert!(!bc.get_test());
assert_eq!(*bc.get_lifecycle(), vec!["most".to_string()]);
}
#[test]
fn test_test_flag() {
let mut bc = BuildConfig::new();
bc.test(true);
assert_eq!(bc.get_dir().as_str().unwrap(), proj_dir().as_slice());
assert_eq!(bc.get_project(), "rust");
assert_eq!(bc.get_branch(), "master");
assert!(bc.get_test());
assert_eq!(*bc.get_lifecycle(), vec!["most".to_string()]);
}
#[test]
fn test_lifecycle() {
let mut bc = BuildConfig::new();
bc.lifecycle(vec!["all"]);
assert_eq!(bc.get_dir().as_str().unwrap(), proj_dir().as_slice());
assert_eq!(bc.get_project(), "rust");
assert_eq!(bc.get_branch(), "master");
assert!(!bc.get_test());
assert_eq!(*bc.get_lifecycle(), vec!["all".to_string()]);
}
#[test]
fn test_lc_from_str() {
assert_eq!(Help, LifeCycle::from_str("help"));
assert_eq!(Version, LifeCycle::from_str("version"));
assert_eq!(Deps, LifeCycle::from_str("deps"));
assert_eq!(SCM, LifeCycle::from_str("scm"));
assert_eq!(Clean, LifeCycle::from_str("clean"));
assert_eq!(Configure, LifeCycle::from_str("configure"));
assert_eq!(Make, LifeCycle::from_str("make"));
assert_eq!(Test, LifeCycle::from_str("test"));
assert_eq!(Install, LifeCycle::from_str("install"));
assert_eq!(Cleanup, LifeCycle::from_str("cleanup"));
assert_eq!(Build, LifeCycle::from_str("build"));
assert_eq!(Most, LifeCycle::from_str("most"));
assert_eq!(All, LifeCycle::from_str("all"));
assert_eq!(Nil, LifeCycle::from_str("blah"));
}
#[test]
fn test_lc_from_vec() {
let mut free: Vec<String> = Vec::new();
assert_eq!(vec![Deps, SCM, Configure, Make, Cleanup],
LifeCycle::from_vec(&free));
free.push("help".to_string());
assert_eq!(vec![Help], LifeCycle::from_vec(&free));
free.clear();
free.push("version".to_string());
assert_eq!(vec![Version], LifeCycle::from_vec(&free));
free.clear();
free.push("deps".to_string());
assert_eq!(vec![Deps], LifeCycle::from_vec(&free));
free.clear();
free.push("scm".to_string());
assert_eq!(vec![SCM], LifeCycle::from_vec(&free));
free.clear();
free.push("clean".to_string());
assert_eq!(vec![Clean], LifeCycle::from_vec(&free));
free.clear();
free.push("configure".to_string());
assert_eq!(vec![Configure], LifeCycle::from_vec(&free));
free.clear();
free.push("make".to_string());
assert_eq!(vec![Make], LifeCycle::from_vec(&free));
free.clear();
free.push("test".to_string());
assert_eq!(vec![Test], LifeCycle::from_vec(&free));
free.clear();
free.push("install".to_string());
assert_eq!(vec![Install], LifeCycle::from_vec(&free));
free.clear();
free.push("cleanup".to_string());
assert_eq!(vec![Cleanup], LifeCycle::from_vec(&free));
free.clear();
free.push("build".to_string());
assert_eq!(vec![Deps, SCM, Configure, Make, Cleanup],
LifeCycle::from_vec(&free));
free.clear();
free.push("most".to_string());
assert_eq!(vec![Deps, SCM, Configure, Make, Test, Install, Cleanup],
LifeCycle::from_vec(&free));
free.clear();
free.push("all".to_string());
assert_eq!(vec![Deps, SCM, Clean, Configure, Make, Test, Install,
Cleanup], LifeCycle::from_vec(&free));
free.clear();
free.push_all(&["scm".to_string(),"clean".to_string()]);
assert_eq!(vec![SCM, Clean], LifeCycle::from_vec(&free));
}
#[test]
fn test_lc_from_vec_sort() {
let mut free: Vec<String> = Vec::new();
free.push_all(&["clean".to_string(),"scm".to_string()]);
assert_eq!(vec![SCM, Clean], LifeCycle::from_vec(&free));
free.clear();
free.push_all(&["cleanup".to_string(), "install".to_string(),
"test".to_string(), "make".to_string(),
"configure".to_string(), "clean".to_string(),
"scm".to_string(), "deps".to_string()]);
assert_eq!(vec![Deps, SCM, Clean, Configure, Make, Test, Install,
Cleanup], LifeCycle::from_vec(&free));
}
#[test]
fn test_lc_from_vec_dedup() {
let mut free: Vec<String> = Vec::new();
free.push_all(&["scm".to_string(),"scm".to_string()]);
assert_eq!(vec![SCM], LifeCycle::from_vec(&free));
free.clear();
free.push_all(&["scm".to_string(),"scm".to_string(),
"clean".to_string(), "clean".to_string()]);
assert_eq!(vec![SCM, Clean], LifeCycle::from_vec(&free));
free.clear();
free.push_all(&["scm".to_string(),"clean".to_string(),
"build".to_string(), "build".to_string()]);
assert_eq!(vec![Deps, SCM, Configure, Make, Cleanup],
LifeCycle::from_vec(&free));
}
}