Skip to content
This repository was archived by the owner on Sep 3, 2025. It is now read-only.

Commit 09cd925

Browse files
authored
Merge pull request #1 from creepersaur/init-files-dir
Init files dir
2 parents 6dd9f46 + 58cc6b5 commit 09cd925

File tree

7 files changed

+221
-142
lines changed

7 files changed

+221
-142
lines changed

src/filesystem.rs

Lines changed: 82 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ use colored::Colorize;
22
use fs::File;
33
use serde_json::json;
44
use std::env;
5+
use std::ffi::OsStr;
56
use std::fs;
67
use std::io::Write;
78
use std::path::{Path, PathBuf};
89
use toml::Table;
910
use unescape::unescape;
1011

12+
use crate::CWD;
1113
use crate::{get::GLOBAL_DATA, ROOT};
1214

1315
#[derive(Debug, Clone, PartialEq)]
@@ -52,9 +54,7 @@ pub fn get_tree(root: &str) -> Vec<FileTree> {
5254
}
5355

5456
pub fn get_root_files(root: &str) -> Vec<FileTree> {
55-
let cwd = get_cwd();
56-
let cwd_path = PathBuf::from(cwd);
57-
let game = cwd_path.join(root);
57+
let game = CWD.join(root);
5858
get_tree(game.to_str().expect("Failed to get root."))
5959
}
6060

@@ -76,14 +76,8 @@ pub fn get_files(path: &str) -> Result<Vec<(PathBuf, bool)>, ()> {
7676
Ok(children)
7777
}
7878

79-
pub fn get_cwd() -> String {
80-
let cwd = env::current_dir()
81-
.expect("Failed to get current working directory.")
82-
.to_str()
83-
.expect("Failed to convert cwd to str.")
84-
.to_owned();
85-
86-
cwd
79+
pub fn get_cwd() -> PathBuf {
80+
env::current_dir().expect("Failed to get current working directory.")
8781
}
8882

8983
pub fn write_file(path: String, contents: String, file_type: String) {
@@ -139,20 +133,7 @@ pub fn write_file(path: String, contents: String, file_type: String) {
139133
));
140134
}
141135

142-
if let Ok(mut new_file) = File::create(&new_file_path) {
143-
new_file
144-
.write_all(contents.as_bytes())
145-
.expect("Failed to write to file.")
146-
} else {
147-
println!(
148-
"{}",
149-
format!(
150-
"{} {}",
151-
"Failed to create file:".red(),
152-
new_file_path.to_str().unwrap().purple()
153-
)
154-
)
155-
}
136+
create_file(&new_file_path, &contents);
156137

157138
let data = match GLOBAL_DATA.lock() {
158139
Ok(guard) => guard,
@@ -185,45 +166,89 @@ fn alter_tree(x: &mut Vec<FileTree>, new_path: String, contents: String) {
185166
}
186167
}
187168

188-
pub fn write_sourcemap(data: String, game_name: String) {
169+
pub fn write_sourcemap(data: String) {
189170
let sourcemap = format!("{}{data}{}", "{", "}");
190171

191-
if let Ok(mut new_file) = File::create("sourcemap.json") {
192-
new_file
193-
.write_all(sourcemap.as_bytes())
194-
.expect("Failed to write to file.")
195-
} else {
196-
println!(
197-
"{}",
198-
format!(
199-
"{} {}",
200-
"Failed to create file:".red(),
201-
"sourcemap.json".purple()
202-
)
203-
)
204-
}
172+
create_file(
173+
&"sourcemap.json",
174+
&sourcemap
175+
);
176+
}
205177

178+
pub fn write_project(game_name: String) {
206179
let project = format!(
207180
r#"{{
208-
"name": "{game_name}",
209-
"tree": {{
210-
"$className": "DataModel"
211-
}}
212-
}}"#
181+
"name": "{game_name}",
182+
"tree": {{
183+
"$className": "DataModel"
184+
}}
185+
}}"#
213186
);
214187

215-
if let Ok(mut new_file) = File::create("default.project.json") {
216-
new_file
217-
.write_all(project.as_bytes())
218-
.expect("Failed to write to file.")
219-
} else {
188+
create_file(
189+
&"default.project.json",
190+
&project
191+
)
192+
}
193+
194+
pub trait StrPath: AsRef<OsStr> {
195+
fn get_path(&self) -> PathBuf {
196+
PathBuf::from(&self)
197+
}
198+
199+
fn get_bytes(&self) -> &[u8] {
200+
return &[];
201+
}
202+
}
203+
204+
impl StrPath for String {
205+
fn get_bytes(&self) -> &[u8] {
206+
&self.as_bytes()
207+
}
208+
}
209+
210+
impl StrPath for &str {
211+
fn get_bytes(&self) -> &[u8] {
212+
&self.as_bytes()
213+
}
214+
}
215+
216+
impl StrPath for PathBuf {}
217+
218+
pub fn create_file(path: &impl StrPath, content: &impl StrPath) {
219+
let file_path = path.get_path();
220+
let file_name = file_path
221+
.file_name()
222+
.expect("Failed to get file_name: create_file().")
223+
.to_str()
224+
.unwrap();
225+
226+
if let Err(out) = File::create(&file_path)
227+
.expect(format!("Failed to create `{}`.", file_name).as_str())
228+
.write_all(content.get_bytes())
229+
{
220230
println!(
221-
"{}",
222-
format!(
223-
"{} {}",
224-
"Failed to create file:".red(),
225-
"default.project.json".purple()
226-
)
227-
)
231+
"{} Failed to write to: {}.",
232+
"[ERROR]".red(),
233+
format!("`{}`", file_name).purple()
234+
);
235+
236+
println!("{}", out.to_string().dimmed());
228237
}
229238
}
239+
240+
pub fn build_dir(path: impl StrPath) {
241+
let build_path = path.get_path();
242+
let mut builder = fs::DirBuilder::new();
243+
builder.recursive(true);
244+
245+
if let Err(out) = builder.create(&build_path) {
246+
println!(
247+
"{} Failed to build directory: {}.",
248+
"[ERROR]".red(),
249+
format!("`{}`", build_path.display()).purple()
250+
);
251+
252+
println!("{}", out.to_string().dimmed());
253+
}
254+
}

src/init.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use colored::Colorize;
2+
3+
use super::filesystem as fs;
4+
5+
pub fn initialize(args: Vec<String>) {
6+
let mut root = "game";
7+
if args.len() > 2 {
8+
if args[2] == "src" {
9+
root = "src";
10+
}
11+
}
12+
13+
fs::create_file(
14+
&"creeper.toml",
15+
&format!(r#"
16+
# Your root/src directory.
17+
root = "{root}"
18+
# The port to host the sever at.
19+
port = 8080
20+
# Enable two_way_sync on the following (array)
21+
two_way_sync = [
22+
"ServerStorage",
23+
"ServerScriptService"
24+
]
25+
# Should include descendants when syncing back?
26+
two_way_descendants = true
27+
"#,)
28+
);
29+
30+
fs::build_dir(format!("{root}/ServerScriptService/server"));
31+
fs::build_dir(format!("{root}/StarterPlayerScripts/client"));
32+
fs::build_dir(format!("{root}/ReplicatedStorage/shared"));
33+
34+
fs::create_file(
35+
&format!("{root}/ServerScriptService/server/hello.server.luau"),
36+
&r#"print("Hello from CreeperCLI! (server)")"#
37+
);
38+
39+
fs::create_file(
40+
&"sourcemap.json",
41+
&r#"["Will be replaced when the plugin connects."]"#
42+
);
43+
44+
fs::create_file(
45+
&"default.project.json",
46+
&r#"["Will be replaced when the plugin connects."]"#
47+
);
48+
49+
println!("{} 👍", "Successfully initialized CreeperCLI project!".green());
50+
}

src/main.rs

Lines changed: 13 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,33 @@
1-
use colored::Colorize;
21
use lazy_static::lazy_static;
3-
use std::{env, io::stdin, path::Path, sync::Mutex};
4-
use filesystem::get_cwd;
5-
use server::run_server;
6-
use std::mem::drop;
2+
use colored::Colorize;
3+
use std::{env, path::PathBuf, sync::Mutex};
74

8-
mod sourcemap;
95
mod filesystem;
106
mod get;
117
mod post;
128
mod server;
139
mod settings;
1410
mod update;
11+
mod run_server;
12+
mod init;
1513

1614
lazy_static! {
17-
// pub static ref DIRECTORIES: Mutex<Table> = Mutex::new(Table::new());
1815
pub static ref ROOT: Mutex<String> = Mutex::new("game".to_string());
16+
pub static ref CWD: PathBuf = filesystem::get_cwd();
1917
}
2018

2119
#[actix_web::main]
2220
async fn main() -> std::io::Result<()> {
23-
let cwd = get_cwd();
24-
2521
let args: Vec<String> = env::args().collect();
26-
if args.len() > 1 && args[1] == "update" {
27-
update::update_cli().expect("Failed to update CreeperCLI.");
28-
return Ok(())
29-
}
30-
31-
let mut port: u16 = 8080;
32-
33-
if let Ok(settings) = settings::get_settings(&cwd) {
34-
for (name, value) in settings.iter() {
35-
match name.to_lowercase().as_str() {
36-
"port" => port = value.as_integer().unwrap_or(8080) as u16,
37-
"root" => {
38-
let mut data = match ROOT.lock() {
39-
Ok(guard) => guard,
40-
Err(poisoned) => poisoned.into_inner(), // Recover from poisoned mutex
41-
};
42-
*data = value.as_str().unwrap_or("game").to_string();
43-
drop(data);
44-
},
45-
_ => {}
46-
}
22+
if args.len() > 1 {
23+
match args[1].as_str() {
24+
"update" => update::update_cli().expect("Failed to update CreeperCLI."),
25+
"init" => init::initialize(args),
26+
_ => println!("{} Could not find command `{}`.", "[NO_COMMAND]".red(), args[1])
4727
}
28+
} else {
29+
run_server::start().await
4830
}
49-
50-
let root = match ROOT.lock() {
51-
Ok(guard) => guard,
52-
Err(poisoned) => poisoned.into_inner()
53-
};
54-
let game_dir = format!("{}//{}", &cwd, *root);
55-
56-
let path = Path::new(game_dir.as_str());
57-
if !(path.exists() && path.is_dir()) {
58-
println!(
59-
"{} {} {}",
60-
"YOU MUST HAVE A".red(),
61-
format!("`{}`",root).purple(),
62-
"DIRECTORY IN THE WORKING DIRECTORY.".red()
63-
);
64-
stdin()
65-
.read_line(&mut String::new())
66-
.expect("Failed to read_line.");
67-
return Ok(());
68-
}
69-
70-
drop(root);
7131

72-
println!(
73-
"{} {}",
74-
"Running server at:".bold().green(),
75-
format!("http://localhost:{}", port).purple()
76-
);
77-
Ok(run_server(port).await.expect("Failed to run server!"))
32+
Ok(())
7833
}

src/post.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use serde_json::{json, Value};
44
use std::mem::drop;
55

66
use crate::{
7-
filesystem::{self, get_cwd},
7+
filesystem,
88
get::map_tree,
99
settings::get_settings,
1010
ROOT,
@@ -29,14 +29,18 @@ pub async fn post(body: String) -> impl Responder {
2929
};
3030
let files = filesystem::get_root_files(root.as_str());
3131
drop(root);
32+
33+
let game_name = data[2].to_string();
34+
filesystem::write_project(
35+
game_name[1..game_name.len() - 1].to_string()
36+
);
3237

3338
return HttpResponse::Ok()
3439
.append_header((header::CONTENT_TYPE, "application/json"))
3540
.body(map_tree(files));
3641
},
3742
"__SETTINGS__" => {
38-
let cwd = get_cwd();
39-
if let Ok(settings) = get_settings(&cwd) {
43+
if let Ok(settings) = get_settings() {
4044
let json = json!(settings).to_string();
4145

4246
return HttpResponse::Ok().body(json);
@@ -60,13 +64,9 @@ pub async fn post(body: String) -> impl Responder {
6064
return HttpResponse::Ok().body(r#"{"File added": "SUCCESS"}"#);
6165
},
6266
"__SOURCEMAP__" => {
63-
let data = [
64-
data[1].to_string(),
65-
data[2].to_string()
66-
];
67+
let data = data[1].to_string();
6768
filesystem::write_sourcemap(
68-
data[0][1..data[0].len() - 1].to_string(),
69-
data[1][1..data[1].len() - 1].to_string()
69+
data[1..data.len() - 1].to_string(),
7070
)
7171
}
7272
_ => {}

0 commit comments

Comments
 (0)