#[cfg(test)]
use std::env;
#[cfg(test)]
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use crate::errors::*;
use crate::project::Project;
use crate::template::Template;
use crate::version;
const DEFAULT_TARGETS: &[&str] = &["development", "test"];
pub trait CommandGenerate {
fn generate_new(parent_dir: &Path, name: &str) -> Result<PathBuf>;
fn generate_list(&self) -> Result<()>;
fn generate(&self, name: &str) -> Result<()>;
}
impl CommandGenerate for Project {
fn generate_new(parent_dir: &Path, name: &str) -> Result<PathBuf> {
let proj_dir = parent_dir.join(name);
let mut proj_tmpl = Template::new("new")?;
let proj_info = ProjectInfo {
name,
cage_version: &version().to_string(),
};
proj_tmpl.generate(&proj_dir, &proj_info, &mut io::stdout())?;
let mut secrets_tmpl = Template::new("secrets")?;
secrets_tmpl.generate(&proj_dir, &proj_info, &mut io::stdout())?;
let mut target_tmpl = Template::new("new/pods/targets/_default")?;
let targets_dir = proj_dir.join("pods").join("targets");
for target in DEFAULT_TARGETS {
let target_info = TargetInfo {
project: &proj_info,
name: target,
};
let dir = targets_dir.join(target);
target_tmpl.generate(&dir, &target_info, &mut io::stdout())?;
}
Ok(proj_dir)
}
fn generate_list(&self) -> Result<()> {
for generator in self.plugins().generators() {
println!(
"{:19} {}",
generator.name(),
generator.generator_description()
);
}
Ok(())
}
fn generate(&self, name: &str) -> Result<()> {
self.plugins().generate(self, name, &mut io::stdout())
}
}
#[test]
fn generate_new_creates_a_project() {
let cwd = env::current_dir().unwrap();
Project::generate_new(&cwd, "test_project").unwrap();
let proj_dir = env::current_dir().unwrap().join("test_project");
assert!(proj_dir.exists());
assert!(proj_dir.join("config").join("secrets.yml").exists());
assert!(proj_dir.join("pods").join("common.env").exists());
assert!(proj_dir.join("pods").join("frontend.yml").exists());
assert!(proj_dir.join("pods").join("db.yml").exists());
let targets = proj_dir.join("pods").join("targets");
assert!(targets.join("development").join("common.env").exists());
assert!(targets.join("production").join("common.env").exists());
assert!(targets.join("test").join("common.env").exists());
fs::remove_dir_all(&proj_dir.as_path()).unwrap();
}
#[derive(Debug, Serialize)]
struct ProjectInfo<'a> {
cage_version: &'a str,
name: &'a str,
}
#[derive(Debug, Serialize)]
struct TargetInfo<'a> {
project: &'a ProjectInfo<'a>,
name: &'a str,
}