1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use rustc_serialize::json::{Json, ToJson};
use std::collections::BTreeMap;
#[cfg(test)]
use std::env;
#[cfg(test)]
use std::fs;
use std::io;
use std::path::{PathBuf, Path};
use project::Project;
use template::Template;
use util::Error;
const OVERRIDES: &'static [&'static str] = &["development", "production", "test"];
pub trait CommandGenerate {
fn generate_new(parent_dir: &Path, name: &str) -> Result<PathBuf, Error>;
fn generate_list(&self) -> Result<(), Error>;
fn generate(&self, name: &str) -> Result<(), Error>;
}
impl CommandGenerate for Project {
fn generate_new(parent_dir: &Path, name: &str) -> Result<PathBuf, Error> {
let proj_dir = parent_dir.join(name);
let mut proj_tmpl = try!(Template::new("new"));
let proj_info = ProjectInfo { name: name };
try!(proj_tmpl.generate(&proj_dir, &proj_info, &mut io::stdout()));
let mut ovr_tmpl = try!(Template::new("new/pods/_overrides/_default"));
let overrides_dir = proj_dir.join("pods").join("overrides");
for ovr in OVERRIDES {
let ovr_info = OverrideInfo {
project: &proj_info,
name: ovr,
};
let dir = overrides_dir.join(ovr);
try!(ovr_tmpl.generate(&dir, &ovr_info, &mut io::stdout()));
}
Ok(proj_dir)
}
fn generate_list(&self) -> Result<(), Error> {
for generator in self.plugins().generators() {
println!("{:19} {}",
generator.name(),
generator.generator_description());
}
Ok(())
}
fn generate(&self, name: &str) -> Result<(), Error> {
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("pods/common.env").exists());
assert!(proj_dir.join("pods/frontend.yml").exists());
assert!(proj_dir.join("pods/db.yml").exists());
assert!(proj_dir.join("pods/overrides/development/common.env").exists());
assert!(proj_dir.join("pods/overrides/production/common.env").exists());
assert!(proj_dir.join("pods/overrides/test/common.env").exists());
fs::remove_dir_all(&proj_dir.as_path()).unwrap();
}
#[derive(Debug)]
struct ProjectInfo<'a> {
name: &'a str,
}
impl<'a> ToJson for ProjectInfo<'a> {
fn to_json(&self) -> Json {
let mut info: BTreeMap<String, Json> = BTreeMap::new();
info.insert("name".to_string(), self.name.to_json());
info.to_json()
}
}
#[derive(Debug)]
struct OverrideInfo<'a> {
project: &'a ProjectInfo<'a>,
name: &'a str,
}
impl<'a> ToJson for OverrideInfo<'a> {
fn to_json(&self) -> Json {
let mut info: BTreeMap<String, Json> = BTreeMap::new();
info.insert("project".to_string(), self.project.to_json());
info.insert("name".to_string(), self.name.to_json());
info.to_json()
}
}