comtrya_lib/manifests/
mod.rs

1mod load;
2pub use load::load;
3mod providers;
4use crate::actions::Actions;
5use petgraph::prelude::*;
6pub use providers::register_providers;
7pub use providers::ManifestProvider;
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use std::path::{Path, PathBuf};
11use tracing::error;
12
13#[derive(JsonSchema, Clone, Debug, Default, Serialize, Deserialize)]
14#[serde(deny_unknown_fields)]
15pub struct Manifest {
16    #[serde(default)]
17    pub r#where: Option<String>,
18
19    #[serde(default)]
20    pub name: Option<String>,
21
22    #[serde(default)]
23    pub labels: Vec<String>,
24
25    #[serde(default)]
26    pub depends: Vec<String>,
27
28    #[serde(default)]
29    pub actions: Vec<Actions>,
30
31    #[serde(skip)]
32    pub root_dir: Option<PathBuf>,
33
34    #[serde(skip)]
35    pub dag_index: Option<NodeIndex<u32>>,
36}
37
38pub fn resolve(uri: &String) -> Option<PathBuf> {
39    let manifest_directory = register_providers()
40        .into_iter()
41        .filter(|provider| std::ops::Deref::deref(&provider).looks_familiar(uri))
42        .fold(None, |path, provider| {
43            if path.is_some() {
44                return path;
45            }
46
47            match provider.resolve(uri.as_str()) {
48                Ok(path) => Some(path),
49                Err(_) => None,
50            }
51        });
52
53    let manifest_directory = match manifest_directory {
54        Some(dir) => dir.canonicalize().expect("Failed to canonicalize path"),
55        None => {
56            error!("Failed to find manifests at {}", &uri);
57            panic!();
58        }
59    };
60
61    Some(manifest_directory)
62}
63
64pub fn get_manifest_name(manifest_directory: &Path, location: &Path) -> anyhow::Result<String> {
65    let local_name = location.strip_prefix(manifest_directory)?;
66    let manifest_name = local_name
67        .components()
68        .fold(String::from(""), |mut s, next| {
69            if !s.is_empty() {
70                s.push('.');
71            }
72
73            if let Some(next) = next.as_os_str().to_str() {
74                s.push_str(next);
75            } else {
76                error!("Failed to convert path component to string");
77            }
78
79            s
80        });
81
82    let manifest_name = manifest_name.trim_end_matches(".yaml");
83    let manifest_name = manifest_name.trim_end_matches(".yml");
84
85    Ok(String::from(manifest_name.trim_end_matches(".main")))
86}
87
88#[cfg(test)]
89#[cfg(unix)]
90mod test {
91    use super::*;
92
93    #[test]
94    fn test_top_level_main_yaml() {
95        let manifest_directory = PathBuf::from("/tmp");
96        let location = PathBuf::from("/tmp/main.yaml");
97
98        assert_eq!(
99            "main",
100            get_manifest_name(&manifest_directory, &location).unwrap()
101        );
102    }
103
104    #[test]
105    fn test_main_yaml() {
106        let manifest_directory = PathBuf::from("/tmp");
107        let location = PathBuf::from("/tmp/test/main.yaml");
108
109        assert_eq!(
110            "test",
111            get_manifest_name(&manifest_directory, &location).unwrap()
112        );
113    }
114
115    #[test]
116    fn test_main_yml() {
117        let manifest_directory = PathBuf::from("/tmp");
118        let location = PathBuf::from("/tmp/test/main.yml");
119
120        assert_eq!(
121            "test",
122            get_manifest_name(&manifest_directory, &location).unwrap()
123        );
124    }
125
126    #[test]
127    fn test_non_main_yaml() {
128        let manifest_directory = PathBuf::from("/tmp");
129        let location = PathBuf::from("/tmp/test/hello.yaml");
130
131        assert_eq!(
132            "test.hello",
133            get_manifest_name(&manifest_directory, &location).unwrap()
134        );
135    }
136
137    #[test]
138    fn test_main_nested_yaml() {
139        let manifest_directory = PathBuf::from("/tmp");
140        let location = PathBuf::from("/tmp/test/nested/main.yaml");
141
142        assert_eq!(
143            "test.nested",
144            get_manifest_name(&manifest_directory, &location).unwrap()
145        );
146    }
147
148    #[test]
149    fn test_non_main_nested_yaml() {
150        let manifest_directory = PathBuf::from("/tmp");
151        let location = PathBuf::from("/tmp/test/nested/hello.yaml");
152
153        assert_eq!(
154            "test.nested.hello",
155            get_manifest_name(&manifest_directory, &location).unwrap()
156        );
157    }
158}
159
160#[cfg(test)]
161#[cfg(windows)]
162mod test {
163    use super::*;
164
165    #[test]
166    fn test_main_yaml() {
167        let manifest_directory = PathBuf::from("C:\\");
168        let location = PathBuf::from("C:\\test\\main.yaml");
169
170        assert_eq!(
171            "test",
172            get_manifest_name(&manifest_directory, &location).unwrap()
173        );
174    }
175
176    #[test]
177    fn test_main_yml() {
178        let manifest_directory = PathBuf::from("C:\\");
179        let location = PathBuf::from("C:\\test\\main.yml");
180
181        assert_eq!(
182            "test",
183            get_manifest_name(&manifest_directory, &location).unwrap()
184        );
185    }
186
187    #[test]
188    fn test_non_main_yaml() {
189        let manifest_directory = PathBuf::from("C:\\");
190        let location = PathBuf::from("C:\\test\\hello.yaml");
191
192        assert_eq!(
193            "test.hello",
194            get_manifest_name(&manifest_directory, &location).unwrap()
195        );
196    }
197
198    #[test]
199    fn test_main_nested_yaml() {
200        let manifest_directory = PathBuf::from("C:\\");
201        let location = PathBuf::from("C:\\test\\nested\\main.yaml");
202
203        assert_eq!(
204            "test.nested",
205            get_manifest_name(&manifest_directory, &location).unwrap()
206        );
207    }
208
209    #[test]
210    fn test_non_main_nested_yaml() {
211        let manifest_directory = PathBuf::from("C:\\");
212        let location = PathBuf::from("C:\\test\\nested\\hello.yaml");
213
214        assert_eq!(
215            "test.nested.hello",
216            get_manifest_name(&manifest_directory, &location).unwrap()
217        );
218    }
219}