1use clap::{CommandFactory, Parser};
2use std::path::PathBuf;
3
4use ggen_utils::app_config::AppConfig;
5use ggen_utils::error::Result;
6use ggen_utils::types::LogLevel;
7
8pub mod cmds;
9
10#[derive(Parser, Debug)]
11#[command(name = "ggen", author, about = "Graph-aware code generator", version)]
12pub struct Cli {
13 #[arg(short, long, value_name = "FILE")]
14 pub config: Option<PathBuf>,
15
16 #[arg(long, value_name = "PATH", help = "Path to ggen.toml manifest file")]
17 pub manifest_path: Option<PathBuf>,
18
19 #[arg(name = "debug", short, long = "debug", value_name = "DEBUG")]
20 pub debug: Option<bool>,
21
22 #[arg(
23 name = "log_level",
24 short,
25 long = "log-level",
26 value_name = "LOG_LEVEL"
27 )]
28 pub log_level: Option<LogLevel>,
29
30 #[arg(long, value_name = "ENDPOINT")]
33 pub otel_endpoint: Option<String>,
34
35 #[arg(long, value_name = "EXPORTER", default_value = "otlp")]
37 pub otel_exporter: String,
38
39 #[arg(long, value_name = "RATIO", default_value = "1.0")]
41 pub otel_sample_ratio: f64,
42
43 #[arg(long)]
45 pub enable_otel: bool,
46
47 #[clap(subcommand)]
48 pub command: cmds::Commands,
49}
50
51pub fn build_cli() -> clap::Command {
52 Cli::command()
53}
54
55pub async fn cli_match() -> Result<()> {
56 let cli = Cli::parse();
57
58 if cli.enable_otel {
60 use ggen_core::telemetry::{init_telemetry, shutdown_telemetry, TelemetryConfig};
61
62 let otel_config = TelemetryConfig {
63 endpoint: cli
64 .otel_endpoint
65 .clone()
66 .or_else(|| std::env::var("OTEL_EXPORTER_OTLP_ENDPOINT").ok())
67 .unwrap_or_else(|| "http://localhost:4317".to_string()),
68 service_name: "ggen-cli".to_string(),
69 sample_ratio: cli.otel_sample_ratio,
70 console_output: true,
71 };
72
73 init_telemetry(otel_config)?;
74
75 let result = async {
77 AppConfig::merge_config(cli.config.as_deref())?;
78 let app = Cli::command();
79 let matches = app.get_matches();
80 AppConfig::merge_args(&matches)?;
81
82 cli.command.run().await
84 }
85 .await;
86
87 shutdown_telemetry();
88 result
89 } else {
90 AppConfig::merge_config(cli.config.as_deref())?;
91 let app = Cli::command();
92 let matches = app.get_matches();
93 AppConfig::merge_args(&matches)?;
94
95 cli.command.run().await
97 }
98}