Skip to main content

greentic_dev/
toolchain_catalogue.rs

1#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2pub struct ToolchainPackageSpec {
3    pub crate_name: &'static str,
4    pub bins: &'static [&'static str],
5}
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub struct OciPackageSpec {
9    pub package: &'static str,
10}
11
12pub const GREENTIC_TOOLCHAIN_PACKAGES: &[ToolchainPackageSpec] = &[
13    ToolchainPackageSpec {
14        crate_name: "greentic-dev",
15        bins: &["greentic-dev"],
16    },
17    ToolchainPackageSpec {
18        crate_name: "greentic-operator",
19        bins: &["greentic-operator"],
20    },
21    ToolchainPackageSpec {
22        crate_name: "greentic-bundle",
23        bins: &["greentic-bundle"],
24    },
25    ToolchainPackageSpec {
26        crate_name: "greentic-setup",
27        bins: &["greentic-setup"],
28    },
29    ToolchainPackageSpec {
30        crate_name: "greentic-start",
31        bins: &["greentic-start"],
32    },
33    ToolchainPackageSpec {
34        crate_name: "greentic-deployer",
35        bins: &["greentic-deployer"],
36    },
37    ToolchainPackageSpec {
38        crate_name: "greentic-component",
39        bins: &["greentic-component"],
40    },
41    ToolchainPackageSpec {
42        crate_name: "greentic-flow",
43        bins: &["greentic-flow"],
44    },
45    ToolchainPackageSpec {
46        crate_name: "greentic-pack",
47        bins: &["greentic-pack"],
48    },
49    ToolchainPackageSpec {
50        crate_name: "greentic-runner",
51        bins: &["greentic-runner"],
52    },
53    ToolchainPackageSpec {
54        crate_name: "greentic-gui",
55        bins: &["greentic-gui"],
56    },
57    ToolchainPackageSpec {
58        crate_name: "greentic-secrets",
59        bins: &["greentic-secrets"],
60    },
61    ToolchainPackageSpec {
62        crate_name: "greentic-mcp",
63        bins: &["greentic-mcp"],
64    },
65];
66
67pub const GREENTIC_EXTENSION_PACK_PACKAGES: &[OciPackageSpec] = &[
68    OciPackageSpec {
69        package: "packs/demos/cards-demo",
70    },
71    OciPackageSpec {
72        package: "packs/demos/cloud-deploy-demo-app",
73    },
74    OciPackageSpec {
75        package: "packs/demos/deep-research-demo",
76    },
77    OciPackageSpec {
78        package: "packs/demos/helpdesk-itsm",
79    },
80    OciPackageSpec {
81        package: "packs/demos/hr-onboarding",
82    },
83    OciPackageSpec {
84        package: "packs/demos/incident-demo",
85    },
86    OciPackageSpec {
87        package: "packs/demos/quickstart",
88    },
89    OciPackageSpec {
90        package: "packs/demos/quickstart-event",
91    },
92    OciPackageSpec {
93        package: "packs/demos/redbutton-demo",
94    },
95    OciPackageSpec {
96        package: "packs/demos/sales-crm",
97    },
98    OciPackageSpec {
99        package: "packs/demos/supply-chain",
100    },
101    OciPackageSpec {
102        package: "packs/demos/telco-x",
103    },
104    OciPackageSpec {
105        package: "packs/demos/weather-mcp-demo",
106    },
107    OciPackageSpec {
108        package: "packs/demos/weatherapi-pack",
109    },
110    OciPackageSpec {
111        package: "packs/deployer/greentic.deploy.gcp",
112    },
113    OciPackageSpec {
114        package: "packs/deployer/greentic.deploy.azure",
115    },
116    OciPackageSpec {
117        package: "packs/deployer/greentic.deploy.aws",
118    },
119    OciPackageSpec {
120        package: "packs/deployer/greentic.deploy.helm",
121    },
122    OciPackageSpec {
123        package: "packs/deployer/greentic.deploy.juju-k8s",
124    },
125    OciPackageSpec {
126        package: "packs/deployer/greentic.deploy.juju-machine",
127    },
128    OciPackageSpec {
129        package: "packs/deployer/greentic.deploy.k8s-raw",
130    },
131    OciPackageSpec {
132        package: "packs/deployer/greentic.deploy.serverless",
133    },
134    OciPackageSpec {
135        package: "packs/deployer/greentic.deploy.snap",
136    },
137    OciPackageSpec {
138        package: "packs/deployer/greentic.deploy.terraform",
139    },
140    OciPackageSpec {
141        package: "packs/dw/context/compressor-pack",
142    },
143    OciPackageSpec {
144        package: "packs/dw/context/retrieval-pack",
145    },
146    OciPackageSpec {
147        package: "packs/dw/context/static-pack",
148    },
149    OciPackageSpec {
150        package: "packs/dw/control/basic-policy-pack",
151    },
152    OciPackageSpec {
153        package: "packs/dw/control/delegation-guard-pack",
154    },
155    OciPackageSpec {
156        package: "packs/dw/delegation/capability-match-pack",
157    },
158    OciPackageSpec {
159        package: "packs/dw/delegation/static-router-pack",
160    },
161    OciPackageSpec {
162        package: "packs/dw/engine/default-pack",
163    },
164    OciPackageSpec {
165        package: "packs/dw/engine/router-lite-pack",
166    },
167    OciPackageSpec {
168        package: "packs/dw/memory/short-term-in-memory-pack",
169    },
170    OciPackageSpec {
171        package: "packs/dw/memory/short-term-redis-pack",
172    },
173    OciPackageSpec {
174        package: "packs/dw/observer/basic-audit-pack",
175    },
176    OciPackageSpec {
177        package: "packs/dw/observer/basic-metrics-pack",
178    },
179    OciPackageSpec {
180        package: "packs/dw/planning/llm-outline-pack",
181    },
182    OciPackageSpec {
183        package: "packs/dw/planning/static-pack",
184    },
185    OciPackageSpec {
186        package: "packs/dw/reflection/llm-critic-pack",
187    },
188    OciPackageSpec {
189        package: "packs/dw/reflection/rules-pack",
190    },
191    OciPackageSpec {
192        package: "packs/dw/reflection/schema-check-pack",
193    },
194    OciPackageSpec {
195        package: "packs/dw/state/task-store-in-memory-pack",
196    },
197    OciPackageSpec {
198        package: "packs/dw/state/task-store-redis-pack",
199    },
200    OciPackageSpec {
201        package: "packs/dw/tool/component-adapter-pack",
202    },
203    OciPackageSpec {
204        package: "packs/dw/tool/mcp-adapter-pack",
205    },
206    OciPackageSpec {
207        package: "packs/dw/workspace/fs-pack",
208    },
209    OciPackageSpec {
210        package: "packs/dw/workspace/in-memory-pack",
211    },
212    OciPackageSpec {
213        package: "packs/events/events-dummy",
214    },
215    OciPackageSpec {
216        package: "packs/events/events-email",
217    },
218    OciPackageSpec {
219        package: "packs/events/events-email-sendgrid",
220    },
221    OciPackageSpec {
222        package: "packs/events/events-sms",
223    },
224    OciPackageSpec {
225        package: "packs/events/events-sms-twilio",
226    },
227    OciPackageSpec {
228        package: "packs/events/events-timer",
229    },
230    OciPackageSpec {
231        package: "packs/events/events-webhook",
232    },
233    OciPackageSpec {
234        package: "packs/messaging/messaging-dummy",
235    },
236    OciPackageSpec {
237        package: "packs/messaging/messaging-email",
238    },
239    OciPackageSpec {
240        package: "packs/messaging/messaging-slack",
241    },
242    OciPackageSpec {
243        package: "packs/messaging/messaging-teams",
244    },
245    OciPackageSpec {
246        package: "packs/messaging/messaging-telegram",
247    },
248    OciPackageSpec {
249        package: "packs/messaging/messaging-webchat",
250    },
251    OciPackageSpec {
252        package: "packs/messaging/messaging-webchat-gui",
253    },
254    OciPackageSpec {
255        package: "packs/messaging/messaging-webex",
256    },
257    OciPackageSpec {
258        package: "packs/messaging/messaging-whatsapp",
259    },
260    OciPackageSpec {
261        package: "packs/oauth/oauth-github",
262    },
263    OciPackageSpec {
264        package: "packs/oauth/oauth-google",
265    },
266    OciPackageSpec {
267        package: "packs/oauth/oauth-microsoft-graph",
268    },
269    OciPackageSpec {
270        package: "packs/oauth/oauth-oidc-generic",
271    },
272    OciPackageSpec {
273        package: "packs/oauth/oauth-slack",
274    },
275    OciPackageSpec {
276        package: "packs/secret/greentic.secrets.aws-sm.gtpack",
277    },
278    OciPackageSpec {
279        package: "packs/secret/greentic.secrets.azure-kv.gtpack",
280    },
281    OciPackageSpec {
282        package: "packs/secret/greentic.secrets.gcp-sm.gtpack",
283    },
284    OciPackageSpec {
285        package: "packs/secret/greentic.secrets.k8s.gtpack",
286    },
287    OciPackageSpec {
288        package: "packs/secret/greentic.secrets.providers.gtpack",
289    },
290    OciPackageSpec {
291        package: "packs/secret/greentic.secrets.vault-kv.gtpack",
292    },
293    OciPackageSpec {
294        package: "packs/state-memory",
295    },
296    OciPackageSpec {
297        package: "packs/state-redis",
298    },
299    OciPackageSpec {
300        package: "packs/state/state-memory",
301    },
302    OciPackageSpec {
303        package: "packs/state/state-redis",
304    },
305];
306pub const GREENTIC_COMPONENT_PACKAGES: &[OciPackageSpec] = &[
307    OciPackageSpec {
308        package: "component/component-events2msg",
309    },
310    OciPackageSpec {
311        package: "component/component-http",
312    },
313    OciPackageSpec {
314        package: "component/component-llm-openai",
315    },
316    OciPackageSpec {
317        package: "component/component-msg2events",
318    },
319    OciPackageSpec {
320        package: "component/component-pack2flow",
321    },
322    OciPackageSpec {
323        package: "component/component-sorx-business",
324    },
325    OciPackageSpec {
326        package: "components/component-adaptive-card",
327    },
328    OciPackageSpec {
329        package: "components/component-qa",
330    },
331    OciPackageSpec {
332        package: "components/secrets-provider-inmemory",
333    },
334    OciPackageSpec {
335        package: "components/templates",
336    },
337];
338
339#[cfg(test)]
340mod tests {
341    use super::{
342        GREENTIC_COMPONENT_PACKAGES, GREENTIC_EXTENSION_PACK_PACKAGES, GREENTIC_TOOLCHAIN_PACKAGES,
343        OciPackageSpec,
344    };
345    use std::collections::BTreeSet;
346
347    #[test]
348    fn catalogue_contains_expected_public_toolchain() {
349        let expected = [
350            ("greentic-dev", "greentic-dev"),
351            ("greentic-operator", "greentic-operator"),
352            ("greentic-bundle", "greentic-bundle"),
353            ("greentic-setup", "greentic-setup"),
354            ("greentic-start", "greentic-start"),
355            ("greentic-deployer", "greentic-deployer"),
356            ("greentic-component", "greentic-component"),
357            ("greentic-flow", "greentic-flow"),
358            ("greentic-pack", "greentic-pack"),
359            ("greentic-runner", "greentic-runner"),
360            ("greentic-gui", "greentic-gui"),
361            ("greentic-secrets", "greentic-secrets"),
362            ("greentic-mcp", "greentic-mcp"),
363        ];
364
365        let actual = catalogue_pairs();
366        for pair in expected {
367            assert!(actual.contains(&pair), "missing {pair:?}");
368        }
369    }
370
371    #[test]
372    fn catalogue_has_no_duplicate_crate_bin_pairs() {
373        let mut seen = BTreeSet::new();
374        for package in GREENTIC_TOOLCHAIN_PACKAGES {
375            for bin in package.bins {
376                assert!(
377                    seen.insert((package.crate_name, *bin)),
378                    "duplicate crate/bin pair: {}/{}",
379                    package.crate_name,
380                    bin
381                );
382            }
383        }
384    }
385
386    #[test]
387    fn extension_pack_catalogue_tracks_github_packages() {
388        assert_eq!(GREENTIC_EXTENSION_PACK_PACKAGES.len(), 79);
389        assert_catalogue_has_no_duplicate_packages(GREENTIC_EXTENSION_PACK_PACKAGES);
390        assert!(GREENTIC_EXTENSION_PACK_PACKAGES.iter().all(|package| {
391            package.package.starts_with("packs/") || package.package.starts_with("greentic-bundle/")
392        }));
393        assert!(
394            GREENTIC_EXTENSION_PACK_PACKAGES
395                .iter()
396                .any(|package| package.package == "packs/deployer/greentic.deploy.aws")
397        );
398        assert!(
399            GREENTIC_EXTENSION_PACK_PACKAGES
400                .iter()
401                .any(|package| package.package == "packs/deployer/greentic.deploy.helm")
402        );
403        assert!(GREENTIC_EXTENSION_PACK_PACKAGES.iter().all(|package| {
404            !package
405                .package
406                .starts_with("packs/deployer/greentic.fixture.")
407        }));
408        assert!(
409            GREENTIC_EXTENSION_PACK_PACKAGES
410                .iter()
411                .any(|package| package.package == "packs/messaging/messaging-webchat-gui")
412        );
413        assert!(
414            GREENTIC_EXTENSION_PACK_PACKAGES
415                .iter()
416                .any(|package| package.package == "packs/oauth/oauth-microsoft-graph")
417        );
418    }
419
420    #[test]
421    fn component_catalogue_tracks_github_packages() {
422        assert_eq!(GREENTIC_COMPONENT_PACKAGES.len(), 10);
423        assert_catalogue_has_no_duplicate_packages(GREENTIC_COMPONENT_PACKAGES);
424        assert!(GREENTIC_COMPONENT_PACKAGES.iter().all(|package| {
425            package.package.starts_with("component/")
426                || package.package.starts_with("components/")
427                || package.package.starts_with("validators/")
428        }));
429        assert!(
430            GREENTIC_COMPONENT_PACKAGES
431                .iter()
432                .any(|package| package.package == "component/component-llm-openai")
433        );
434        assert!(
435            GREENTIC_COMPONENT_PACKAGES
436                .iter()
437                .any(|package| package.package == "component/component-sorx-business")
438        );
439        assert!(
440            GREENTIC_COMPONENT_PACKAGES
441                .iter()
442                .any(|package| package.package == "components/component-adaptive-card")
443        );
444    }
445
446    fn catalogue_pairs() -> BTreeSet<(&'static str, &'static str)> {
447        GREENTIC_TOOLCHAIN_PACKAGES
448            .iter()
449            .flat_map(|package| {
450                package
451                    .bins
452                    .iter()
453                    .map(move |bin| (package.crate_name, *bin))
454            })
455            .collect()
456    }
457
458    fn assert_catalogue_has_no_duplicate_packages(catalogue: &[OciPackageSpec]) {
459        let mut seen = BTreeSet::new();
460        for package in catalogue {
461            assert!(
462                seen.insert(package.package),
463                "duplicate package: {}",
464                package.package
465            );
466        }
467    }
468}