1use std::{
2 collections::{HashMap, HashSet},
3 fs::File,
4 io::BufReader,
5 path::Path,
6};
7
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10
11use crate::error::Result;
12
13#[derive(Debug, Deserialize, Serialize, JsonSchema)]
14pub struct ConfigFile {
15 pub default: Option<ConfigDefault>,
16 #[serde(default)]
17 pub stacks: HashMap<String, ConfigStack>,
18 pub processes: HashMap<String, ConfigProcess>,
19}
20
21impl ConfigFile {
22 pub fn load(target_dir: &Path) -> Result<Option<Self>> {
23 let filepath = target_dir.join("jocker.yml");
24 if !filepath.exists() {
25 return Ok(None);
26 }
27 let file = File::open(filepath)?;
28 let reader = BufReader::new(file);
29 let res = serde_yml::from_reader(reader)?;
30 Ok(res)
31 }
32}
33
34#[derive(Debug, Default, Deserialize, Serialize, JsonSchema)]
35pub struct ConfigDefault {
36 pub stack: Option<String>,
37 pub process: Option<ConfigProcessDefault>,
38}
39
40#[derive(Debug, Default, Deserialize, Serialize, JsonSchema)]
41pub struct ConfigProcessDefault {
42 #[serde(default)]
43 pub cargo_args: Vec<String>,
44}
45
46#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema)]
47pub struct ConfigStack {
48 #[serde(default)]
49 pub inherits: HashSet<String>,
50 #[serde(default)]
51 pub processes: HashSet<String>,
52}
53
54#[derive(Debug, Default, Deserialize, Serialize, JsonSchema)]
55pub struct ConfigProcess {
56 pub binary: Option<String>,
57 #[serde(default)]
58 pub args: Vec<String>,
59 #[serde(default)]
60 pub cargo_args: Vec<String>,
61 #[serde(default)]
62 pub env: HashMap<String, String>,
63}
64
65#[cfg(test)]
66mod tests {
67 use std::io::Write;
68
69 use schemars::schema_for;
70
71 use super::*;
72
73 #[test]
74 #[ignore = "Temporary thing to generate JsonSchema"]
75 fn generate_json_schema() {
76 let schema = schema_for!(ConfigFile);
77 File::create(
78 Path::new(env!("CARGO_MANIFEST_DIR"))
79 .join("..")
80 .join("..")
81 .join("schema.json"),
82 )
83 .unwrap()
84 .write_all(serde_json::to_string_pretty(&schema).unwrap().as_bytes())
85 .unwrap();
86 }
87}