extern crate docker_compose;
extern crate regex;
use docker_compose::v2 as dc;
use regex::Regex;
use std::env;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process;
macro_rules! err {
($( $e:expr ),*) => (From::from(format!($( $e ),*)));
}
fn git_to_local(ctx: &dc::Context) -> Result<PathBuf, dc::Error> {
match ctx {
&dc::Context::GitUrl(ref url) => {
let re = Regex::new(r#"/([^./]+)(?:\.git)?"#).unwrap();
match re.captures(url.as_ref()) {
None => Err(err!("Can't get dir name from Git URL: {}", url)),
Some(caps) => {
let path = Path::new(caps.at(1).unwrap());
Ok(path.to_owned())
}
}
}
&dc::Context::Dir(ref dir) => Ok(dir.clone()),
}
}
fn service_build_dir(service: &dc::Service) ->
Result<Option<PathBuf>, dc::Error>
{
if let Some(ref build) = service.build {
let mut path = Path::new("src").to_owned();
path.push(try!(git_to_local(try!(build.context.value()))));
Ok(Some(path))
} else {
Ok(None)
}
}
fn update(file: &mut dc::File) -> Result<(), dc::Error> {
for (_name, service) in file.services.iter_mut() {
service.env_files.insert(0, try!(dc::escape("pods/common.env")));
service.env_files.insert(1, try!(dc::raw("pods/overrides/$ENV/common.env")));
let build_dir = try!(service_build_dir(service));
if let Some(ref dir) = build_dir {
service.volumes.push(dc::value(dc::VolumeMount::host(dir, "/app")));
if let Some(ref mut build) = service.build {
build.context = dc::value(dc::Context::Dir(dir.clone()));
}
}
}
Ok(())
}
fn run() -> Result<(), dc::Error> {
let args: Vec<_> = env::args().collect();
if args.len() != 3 {
return Err(err!("Usage: miniconductor <infile> <outfile>"));
}
let in_path = Path::new(&args[1]);
let out_path = Path::new(&args[2]);
let mut file = try!(dc::File::read_from_path(in_path));
try!(update(&mut file));
try!(file.write_to_path(out_path));
Ok(())
}
fn main() {
if let Err(ref err) = run() {
write!(io::stderr(), "Error: {}", err).unwrap();
process::exit(1);
}
}