use docker_compose::v2 as dc;
use glob;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};
pub type Error = dc::Error;
#[macro_export]
macro_rules! err {
($( $e:expr ),*) => ($crate::Error::from(format!($( $e ),*)));
}
pub trait ToStrOrErr {
fn to_str_or_err(&self) -> Result<&str, Error>;
}
impl ToStrOrErr for OsStr {
fn to_str_or_err(&self) -> Result<&str, Error> {
self.to_str().ok_or_else(|| {
err!("the string {:?} contains non-Unicode characters",
self)
})
}
}
impl ToStrOrErr for Path {
fn to_str_or_err(&self) -> Result<&str, Error> {
self.to_str().ok_or_else(|| {
err!("the path {} contains non-Unicode characters",
self.display())
})
}
}
pub trait ConductorPathExt: ToStrOrErr {
fn glob(&self, pattern: &str) -> Result<glob::Paths, Error>;
fn with_guaranteed_parent(&self) -> Result<PathBuf, Error>;
fn to_absolute(&self) -> Result<PathBuf, Error>;
}
impl ConductorPathExt for Path {
fn glob(&self, pattern: &str) -> Result<glob::Paths, Error> {
let opts = glob::MatchOptions {
case_sensitive: true,
require_literal_separator: true,
require_literal_leading_dot: true,
};
let pat = format!("{}/{}", try!(self.to_str_or_err()), pattern);
Ok(try!(glob::glob_with(&pat, &opts)))
}
fn with_guaranteed_parent(&self) -> Result<PathBuf, Error> {
try!(fs::create_dir_all(try!(self.parent().ok_or_else(|| {
err!("can't find parent of {}", self.display())
}))));
Ok(self.to_owned())
}
fn to_absolute(&self) -> Result<PathBuf, Error> {
let path = try!(env::current_dir()).join(self);
assert!(path.is_absolute());
Ok(path)
}
}
#[test]
fn path_glob_uses_path_as_base() {
let base = Path::new("examples/hello/pods/overrides");
let paths: Vec<_> = base.glob("test/*.env").unwrap()
.map(|p| p.unwrap().strip_prefix(base).unwrap().to_owned())
.collect();
assert_eq!(paths, vec!(Path::new("test/common.env")));
}