pub mod ffi;
pub mod providers;
use command::CommandResult;
use error::Result;
use host::Host;
use self::providers::*;
#[cfg_attr(feature = "local-run", doc = "let path: Option<String> = None;")]
#[cfg_attr(feature = "local-run", doc = "let mut host = Host::local(path).unwrap();")]
#[cfg_attr(feature = "remote-run", doc = "let mut host = Host::connect(\"hosts/myhost.json\").unwrap();")]
#[cfg_attr(feature = "local-run", doc = "# let path: Option<String> = None;")]
#[cfg_attr(feature = "local-run", doc = "# let mut host = Host::local(path).unwrap();")]
#[cfg_attr(feature = "remote-run", doc = "# let mut host = Host::connect(\"hosts/myhost.json\").unwrap();")]
#[cfg_attr(feature = "local-run", doc = "# let path: Option<String> = None;")]
#[cfg_attr(feature = "local-run", doc = "# let mut host = Host::local(path).unwrap();")]
#[cfg_attr(feature = "remote-run", doc = "# let mut host = Host::connect(\"hosts/myhost.json\").unwrap();")]
pub struct Package {
name: String,
provider: Box<Provider + 'static>,
installed: bool,
}
impl Package {
pub fn new(host: &mut Host, name: &str, providers: Option<Providers>) -> Result<Package> {
let provider = try!(ProviderFactory::create(host, providers));
let installed = try!(provider.is_installed(host, name));
Ok(Package {
name: name.to_string(),
provider: provider,
installed: installed,
})
}
pub fn is_installed(&self) -> bool {
self.installed
}
pub fn install(&mut self, host: &mut Host) -> Result<Option<CommandResult>> {
if self.installed {
Ok(None)
} else {
let result = try!(self.provider.install(host, &self.name));
if result.exit_code == 0 {
self.installed = true;
}
Ok(Some(result))
}
}
pub fn uninstall(&mut self, host: &mut Host) -> Result<Option<CommandResult>> {
if self.installed {
let result = try!(self.provider.uninstall(host, &self.name));
if result.exit_code == 0 {
self.installed = false;
}
Ok(Some(result))
} else {
Ok(None)
}
}
}
pub trait PackageTarget {
fn default_provider(host: &mut Host) -> Result<Providers>;
}
#[cfg(test)]
mod tests {
use Host;
#[cfg(feature = "remote-run")]
use czmq::{ZMsg, ZSys};
use super::*;
#[cfg(feature = "remote-run")]
use super::providers::Providers;
#[cfg(feature = "remote-run")]
use std::thread;
#[cfg(feature = "remote-run")]
#[test]
fn test_new_homebrew() {
ZSys::init();
let (client, mut server) = ZSys::create_pipe().unwrap();
client.set_rcvtimeo(Some(500));
server.set_rcvtimeo(Some(500));
let agent_mock = thread::spawn(move || {
let req = ZMsg::recv(&mut server).unwrap();
assert_eq!("command::exec", req.popstr().unwrap().unwrap());
assert_eq!("type brew", req.popstr().unwrap().unwrap());
let rep = ZMsg::new();
rep.addstr("Ok").unwrap();
rep.addstr("0").unwrap();
rep.addstr("/usr/local/bin/brew").unwrap();
rep.addstr("").unwrap();
rep.send(&mut server).unwrap();
let req = ZMsg::recv(&mut server).unwrap();
assert_eq!("command::exec", req.popstr().unwrap().unwrap());
assert_eq!("brew list", req.popstr().unwrap().unwrap());
let rep = ZMsg::new();
rep.addstr("Ok").unwrap();
rep.addstr("0").unwrap();
rep.addstr("nginx-filesystem").unwrap();
rep.addstr("").unwrap();
rep.send(&mut server).unwrap();
});
let mut host = Host::test_new(None, Some(client), None, None);
let pkg = Package::new(&mut host, "nginx", Some(Providers::Homebrew)).unwrap();
assert_eq!(pkg.name, "nginx");
assert!(!pkg.is_installed());
agent_mock.join().unwrap();
}
#[cfg(feature = "local-run")]
#[test]
fn test_new_default() {
let path: Option<String> = None;
let mut host = Host::local(path).unwrap();
let pkg = Package::new(&mut host, "nginx", None);
assert!(pkg.is_ok());
}
#[cfg(feature = "remote-run")]
#[test]
fn test_new_default() {
ZSys::init();
let (client, mut server) = ZSys::create_pipe().unwrap();
client.set_rcvtimeo(Some(500));
server.set_rcvtimeo(Some(500));
let agent_mock = thread::spawn(move || {
assert_eq!("package::default_provider", server.recv_str().unwrap().unwrap());
let rep = ZMsg::new();
rep.addstr("Ok").unwrap();
rep.addstr("Homebrew").unwrap();
rep.send(&mut server).unwrap();
let req = ZMsg::recv(&mut server).unwrap();
assert_eq!("command::exec", req.popstr().unwrap().unwrap());
assert_eq!("type brew", req.popstr().unwrap().unwrap());
let rep = ZMsg::new();
rep.addstr("Ok").unwrap();
rep.addstr("0").unwrap();
rep.addstr("/usr/local/bin/brew").unwrap();
rep.addstr("").unwrap();
rep.send(&mut server).unwrap();
let req = ZMsg::recv(&mut server).unwrap();
assert_eq!("command::exec", req.popstr().unwrap().unwrap());
assert_eq!("brew list", req.popstr().unwrap().unwrap());
let rep = ZMsg::new();
rep.addstr("Ok").unwrap();
rep.addstr("0").unwrap();
rep.addstr("abc def nginx pkg").unwrap();
rep.addstr("").unwrap();
rep.send(&mut server).unwrap();
});
let mut host = Host::test_new(None, Some(client), None, None);
let pkg = Package::new(&mut host, "nginx", None);
assert!(pkg.is_ok());
agent_mock.join().unwrap();
}
}