Skip to content

Commit b0736a2

Browse files
committed
geode project add
1 parent cde8594 commit b0736a2

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

src/project.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
use serde_json::json;
2+
use clap::ValueEnum;
3+
use serde::Deserialize;
4+
use crate::logging::ask_value;
15
use crate::mod_file::{PlatformName, ToGeodeString};
26
use crate::util::mod_file::DependencyImportance;
37
use crate::{done, fail, fatal, index, info, warn, NiceUnwrap};
@@ -18,6 +22,15 @@ use std::{
1822
fs,
1923
path::{Path, PathBuf},
2024
};
25+
use serde_json::Value;
26+
27+
#[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone, Copy, ValueEnum)]
28+
#[serde(rename_all = "lowercase")]
29+
pub enum ResourceType {
30+
Sprite,
31+
Font,
32+
File
33+
}
2134

2235
#[derive(Subcommand, Debug)]
2336
#[clap(rename_all = "kebab-case")]
@@ -51,6 +64,13 @@ pub enum Project {
5164
#[clap(long, num_args(0..))]
5265
externals: Vec<String>,
5366
},
67+
68+
/// Add a resource to the mod.json file
69+
Add {
70+
/// Type of resource to add
71+
resource: ResourceType,
72+
files: Vec<PathBuf>
73+
}
5474
}
5575

5676
fn find_build_directory(root: &Path) -> Option<PathBuf> {
@@ -517,6 +537,80 @@ pub fn check_dependencies(
517537
}
518538
}
519539

540+
fn add_resource(dir: &Path, resource: ResourceType, files: Vec<PathBuf>) {
541+
let mut mod_json: HashMap<String, Value> = serde_json::from_reader(fs::File::open(dir.join("mod.json")).ok().nice_unwrap("Must be inside a project with a mod.json"))
542+
.nice_unwrap("Unable to read mod.json");
543+
544+
545+
let mut do_thing = |name: &str, othername: &str| {
546+
let resource = mod_json.get("resources")
547+
.and_then(|x| x.get(name))
548+
.and_then(|x| x.as_array())
549+
.unwrap_or(&vec![])
550+
.clone();
551+
552+
let mut new_resource: Vec<Value> = resource.into_iter().chain(files.clone().into_iter().filter_map(|x| {
553+
if !x.exists() {
554+
warn!("{} {} does not exist", othername, x.display());
555+
return None
556+
} else {
557+
Some(Value::String(x.as_os_str().to_str().unwrap().to_string()))
558+
}
559+
})).collect();
560+
561+
let mut duplicates: Vec<_> = new_resource.iter().filter(|x| new_resource.iter().filter(|y| y == x).count() > 1).collect();
562+
duplicates.dedup();
563+
duplicates.into_iter().for_each(|x| warn!("Duplicate {}: {}", othername, x));
564+
565+
new_resource.dedup();
566+
567+
*mod_json.entry("resources".to_string()).or_insert(json!({}))
568+
.as_object_mut().nice_unwrap("resources is not an object")
569+
.entry(name.to_string()).or_insert(json!([]))
570+
.as_array_mut().nice_unwrap(&format!("{} is not an array", name)) = new_resource;
571+
};
572+
573+
match resource {
574+
ResourceType::Sprite => do_thing("sprites", "Sprite"),
575+
ResourceType::File => do_thing("files", "File"),
576+
577+
ResourceType::Font => {
578+
let fonts = mod_json.get("resources")
579+
.and_then(|x| x.get("fonts"))
580+
.and_then(|x| x.as_array())
581+
.unwrap_or(&vec![])
582+
.clone();
583+
584+
let mut new_fonts: Vec<Value> = fonts.into_iter().chain(files.into_iter().filter_map(|x| {
585+
if !x.exists() {
586+
warn!("Font {} does not exist", x.display());
587+
return None
588+
} else {
589+
Some(json!({
590+
"path": x.as_os_str().to_str().unwrap().to_string(),
591+
"size": ask_value("Font Size", None, true).parse::<u32>().ok().nice_unwrap("Invalid font size!")
592+
}))
593+
}
594+
})).collect();
595+
596+
let mut duplicates: Vec<_> = new_fonts.iter().filter_map(|x| x.get("path")).filter(|x| new_fonts.iter().filter(|y| y.get("path").map(|y| y == *x).unwrap_or(false)).count() > 1).collect();
597+
duplicates.dedup();
598+
duplicates.into_iter().for_each(|x| warn!("Duplicate Font: {}", x));
599+
600+
new_fonts.dedup();
601+
602+
*mod_json.entry("resources".to_string()).or_insert(json!({}))
603+
.as_object_mut().nice_unwrap("resources is not an object")
604+
.entry("fonts".to_string()).or_insert(json!([]))
605+
.as_array_mut().nice_unwrap("fonts is not an array") = new_fonts;
606+
}
607+
};
608+
609+
fs::write(dir.join("mod.json"), serde_json::to_string_pretty(&mod_json).unwrap()).nice_unwrap("Failed to save mod.json");
610+
611+
done!("Resource added to mod.json");
612+
}
613+
520614
pub fn subcommand(cmd: Project) {
521615
match cmd {
522616
Project::New { path } => template::build_template(path),
@@ -531,5 +625,10 @@ pub fn subcommand(cmd: Project) {
531625
platform,
532626
externals,
533627
),
628+
Project::Add { resource, files } => add_resource(
629+
&std::env::current_dir().unwrap(),
630+
resource,
631+
files
632+
),
534633
}
535634
}

0 commit comments

Comments
 (0)