ggen_cli_lib/cmds/project/mod.rs
1use clap::{Args, Subcommand};
2use ggen_utils::error::Result;
3
4// Declare verb modules
5pub mod apply;
6pub mod diff;
7pub mod freeze;
8pub mod gen;
9pub mod inject;
10pub mod plan;
11pub mod test;
12pub mod validate;
13pub mod watch;
14
15#[derive(Args, Debug)]
16pub struct ProjectCmd {
17 #[command(subcommand)]
18 pub verb: Verb,
19}
20
21#[derive(Subcommand, Debug)]
22pub enum Verb {
23 /// Generate artifacts from a template directly
24 ///
25 /// Examples:
26 /// ggen project gen "rust-cli-template" --var name=myapp
27 /// ggen project gen "web-api.tmpl" --dry-run
28 /// ggen project gen "template.tmpl" --seed 12345
29 Gen(gen::GenArgs),
30
31 /// Create a machine-readable plan of changes without applying them (dry-run)
32 ///
33 /// Examples:
34 /// ggen project plan "rust-cli-template" --var name=myapp
35 /// ggen project plan "template.tmpl" --format yaml
36 Plan(plan::PlanArgs),
37
38 /// Apply a previously generated plan to the filesystem
39 ///
40 /// Examples:
41 /// ggen project apply plan.json
42 /// ggen project apply plan.yaml --dry-run
43 Apply(apply::ApplyArgs),
44
45 /// Show a unified diff of what a generation would change
46 ///
47 /// Examples:
48 /// ggen project diff "rust-cli-template" --var name=myapp
49 /// ggen project diff "template.tmpl" --var version=1.0.0
50 Diff(diff::DiffArgs),
51
52 /// Run golden file snapshot tests for templates
53 ///
54 /// Examples:
55 /// ggen project test "template.tmpl" --golden expected/
56 /// ggen project test "rust-cli.tmpl" --golden golden/ --update
57 /// ggen project test "*.tmpl" --golden snapshots/ --json
58 Test(test::TestArgs),
59
60 /// Add freeze blocks to generated files for immutability
61 ///
62 /// Examples:
63 /// ggen project freeze "src/main.rs" --blocks "impl,business_logic"
64 /// ggen project freeze "src/" --blocks "custom" --recursive
65 /// ggen project freeze "app.ts" --blocks "config,routes" --dry-run
66 Freeze(freeze::FreezeArgs),
67
68 /// Inject code idempotently into existing files
69 ///
70 /// Examples:
71 /// ggen project inject "src/mod.rs" --anchor "// IMPORTS" --content "use foo;"
72 /// ggen project inject "main.rs" --anchor "fn main()" --content "println!(\"hello\");" --after
73 /// ggen project inject "config.toml" --anchor "[dependencies]" --content "serde = \"1.0\"" --dry-run
74 Inject(inject::InjectArgs),
75
76 /// Validate plan files or generated output
77 ///
78 /// Examples:
79 /// ggen project validate plan.json
80 /// ggen project validate generated/ --recursive
81 /// ggen project validate output.rs --schema rust-file.schema.json
82 /// ggen project validate plan.yaml --verbose --json
83 Validate(validate::ValidateArgs),
84
85 /// Watch templates and continuously regenerate on changes
86 ///
87 /// Examples:
88 /// ggen project watch "*.tmpl" --target src/
89 /// ggen project watch "templates/" --target output/ --recursive
90 /// ggen project watch "api.tmpl" --target api/ --debounce 1000 --var env=dev
91 Watch(watch::WatchArgs),
92}
93
94impl ProjectCmd {
95 pub async fn run(&self) -> Result<()> {
96 match &self.verb {
97 Verb::Gen(args) => gen::run(args).await,
98 Verb::Plan(args) => plan::run(args).await,
99 Verb::Apply(args) => apply::run(args).await,
100 Verb::Diff(args) => diff::run(args).await,
101 Verb::Test(args) => test::run(args).await,
102 Verb::Freeze(args) => freeze::run(args).await,
103 Verb::Inject(args) => inject::run(args).await,
104 Verb::Validate(args) => validate::run(args).await,
105 Verb::Watch(args) => watch::run(args).await,
106 }
107 }
108}