comtrya_lib/manifests/
mod.rs1mod 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}