greentic_component/
cli.rs1use anyhow::{Error, Result, bail};
2use clap::{Parser, Subcommand};
3
4use crate::cmd::{
5 self, build::BuildArgs, doctor::DoctorArgs, flow::FlowCommand, hash::HashArgs,
6 inspect::InspectArgs, new::NewArgs, store::StoreCommand, templates::TemplatesArgs,
7 test::TestArgs,
8};
9use crate::scaffold::engine::ScaffoldEngine;
10
11#[derive(Parser, Debug)]
12#[command(
13 name = "greentic-component",
14 about = "Toolkit for Greentic component developers",
15 version,
16 propagate_version = true,
17 arg_required_else_help = true,
18 disable_version_flag = true
19)]
20pub struct Cli {
21 #[command(subcommand)]
22 command: Commands,
23}
24
25#[derive(Subcommand, Debug)]
26enum Commands {
27 New(NewArgs),
29 Templates(TemplatesArgs),
31 Doctor(DoctorArgs),
33 Inspect(InspectArgs),
35 Hash(HashArgs),
37 Build(BuildArgs),
39 #[command(
41 long_about = "Invoke a component locally with in-memory state/secrets. \
42See docs/component-developer-guide.md for a walkthrough."
43 )]
44 Test(Box<TestArgs>),
45 #[command(subcommand)]
47 Flow(FlowCommand),
48 #[command(subcommand)]
50 Store(StoreCommand),
51}
52
53pub fn main() -> Result<()> {
54 let cli = Cli::parse();
55 let engine = ScaffoldEngine::new();
56 match cli.command {
57 Commands::New(args) => cmd::new::run(args, &engine),
58 Commands::Templates(args) => cmd::templates::run(args, &engine),
59 Commands::Doctor(args) => cmd::doctor::run(args).map_err(Error::new),
60 Commands::Inspect(args) => {
61 let result = cmd::inspect::run(&args)?;
62 cmd::inspect::emit_warnings(&result.warnings);
63 if args.strict && !result.warnings.is_empty() {
64 bail!(
65 "component-inspect: {} warning(s) treated as errors (--strict)",
66 result.warnings.len()
67 );
68 }
69 Ok(())
70 }
71 Commands::Hash(args) => cmd::hash::run(args),
72 Commands::Build(args) => cmd::build::run(args),
73 Commands::Test(args) => cmd::test::run(*args),
74 Commands::Flow(flow_cmd) => cmd::flow::run(flow_cmd),
75 Commands::Store(store_cmd) => cmd::store::run(store_cmd),
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn parses_new_subcommand() {
85 let cli = Cli::try_parse_from(["greentic-component", "new", "--name", "demo", "--json"])
86 .expect("expected CLI to parse");
87 match cli.command {
88 Commands::New(args) => {
89 assert_eq!(args.name, "demo");
90 assert!(args.json);
91 assert!(!args.no_check);
92 assert!(!args.no_git);
93 }
94 _ => panic!("expected new args"),
95 }
96 }
97}