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
|
use std::env::set_current_dir;
use std::fs;
use std::io::Write as _;
use std::path::Path;
use std::process::Command;
use structopt::StructOpt;
const TOSIN_DEPENDENCY: &str = concat!(r#"tosin = { path = ""#, env!("CARGO_MANIFEST_DIR"), r#"" }"#);
const PROJECT_MAIN: &str = r#"
use tosin::Settings;
use tosin::contrib::admin;
use tosin::db::backend::Connectable;
use tosin::urls::{UrlMap, url_map};
fn urls() -> UrlMap {
url_map! {
"admin" / ..admin::site::urls(),
}
}
fn settings() -> Settings<impl Connectable> {
Settings {
..Settings::default()
}
}
tosin::main!(urls(), settings());
"#;
const APP_MOD: &str = r#"
pub mod urls;
pub mod views;
pub use urls::urls;
"#;
const APP_URLS: &str = r#"
use tosin::urls::{UrlMap, url_map};
use super::views;
pub fn urls() -> UrlMap {
todo!("fill in URL map")
}
"#;
const APP_VIEWS: &str = r#"
use tosin::http::{Reply, Response};
todo!("write some views");
"#;
#[derive(StructOpt, Debug)]
enum Opt {
/// Start a new project/site (can contain multiple apps)
StartProject {
name: Option<String>,
},
/// Start a new app
StartApp {
name: String,
}
}
fn main() {
let opts = Opt::from_args();
match opts {
Opt::StartProject { name } => {
match name {
Some(name) => {
// there's a name, so we're creating a project.
// TODO make this all more robust
let cargo_new = Command::new("cargo")
.args(&["new", "--bin", &name])
.status()
.unwrap();
if !cargo_new.success() {
panic!("cargo new failed");
}
set_current_dir(name).unwrap();
let mut cargo_toml = fs::OpenOptions::new()
.append(true)
.open("Cargo.toml")
.unwrap();
writeln!(cargo_toml, "{}", TOSIN_DEPENDENCY).unwrap();
drop(cargo_toml);
fs::write("src/main.rs", PROJECT_MAIN).unwrap();
}
None => {
todo!("absorb existing Rust project maybe??")
}
}
}
Opt::StartApp { name } => {
// TODO make this more robust
if fs::metadata("Cargo.toml").is_ok() {
let app_folder = Path::new("src").join(name);
fs::create_dir(&app_folder).unwrap();
fs::write(app_folder.join("mod.rs"), APP_MOD).unwrap();
fs::write(app_folder.join("urls.rs"), APP_URLS).unwrap();
fs::write(app_folder.join("views.rs"), APP_VIEWS).unwrap();
} else {
todo!("new standalone app crate maybe??")
}
}
}
}
|