syncable_cli/
cli.rs

1use clap::{Parser, Subcommand, ValueEnum};
2use std::path::PathBuf;
3
4#[derive(Parser)]
5#[command(name = "sync-ctl")]
6#[command(version = env!("CARGO_PKG_VERSION"))]
7#[command(about = "Generate Infrastructure as Code from your codebase")]
8#[command(
9    long_about = "A powerful CLI tool that analyzes your codebase and automatically generates optimized Infrastructure as Code configurations including Dockerfiles, Docker Compose files, and Terraform configurations"
10)]
11pub struct Cli {
12    #[command(subcommand)]
13    pub command: Commands,
14
15    /// Path to configuration file
16    #[arg(short, long, global = true, value_name = "FILE")]
17    pub config: Option<PathBuf>,
18
19    /// Enable verbose logging (-v for info, -vv for debug, -vvv for trace)
20    #[arg(short, long, global = true, action = clap::ArgAction::Count)]
21    pub verbose: u8,
22
23    /// Suppress all output except errors
24    #[arg(short, long, global = true)]
25    pub quiet: bool,
26
27    /// Output in JSON format where applicable
28    #[arg(long, global = true)]
29    pub json: bool,
30
31    /// Clear the update check cache and force a new check
32    #[arg(long, global = true)]
33    pub clear_update_cache: bool,
34
35    /// Disable telemetry data collection
36    #[arg(long, global = true)]
37    pub disable_telemetry: bool,
38}
39
40#[derive(Subcommand)]
41pub enum Commands {
42    /// Analyze a project and display detected components
43    Analyze {
44        /// Path to the project directory to analyze
45        #[arg(value_name = "PROJECT_PATH")]
46        path: PathBuf,
47
48        /// Output analysis results in JSON format
49        #[arg(short, long)]
50        json: bool,
51
52        /// Show detailed analysis information (legacy format)
53        #[arg(short, long, conflicts_with = "display")]
54        detailed: bool,
55
56        /// Display format for analysis results
57        #[arg(long, value_enum, default_value = "matrix")]
58        display: Option<DisplayFormat>,
59
60        /// Only analyze specific aspects (languages, frameworks, dependencies)
61        #[arg(long, value_delimiter = ',')]
62        only: Option<Vec<String>>,
63
64        /// Color scheme for terminal output (auto-detect, dark, light)
65        #[arg(long, value_enum, default_value = "auto")]
66        color_scheme: Option<ColorScheme>,
67    },
68
69    /// Generate IaC files for a project
70    Generate {
71        /// Path to the project directory to analyze
72        #[arg(value_name = "PROJECT_PATH")]
73        path: PathBuf,
74
75        /// Output directory for generated files
76        #[arg(short, long, value_name = "OUTPUT_DIR")]
77        output: Option<PathBuf>,
78
79        /// Generate Dockerfile
80        #[arg(long)]
81        dockerfile: bool,
82
83        /// Generate Docker Compose file
84        #[arg(long)]
85        compose: bool,
86
87        /// Generate Terraform configuration
88        #[arg(long)]
89        terraform: bool,
90
91        /// Generate all supported IaC files
92        #[arg(long, conflicts_with_all = ["dockerfile", "compose", "terraform"])]
93        all: bool,
94
95        /// Perform a dry run without creating files
96        #[arg(long)]
97        dry_run: bool,
98
99        /// Overwrite existing files
100        #[arg(long)]
101        force: bool,
102    },
103
104    /// Validate existing IaC files against best practices
105    Validate {
106        /// Path to the directory containing IaC files
107        #[arg(value_name = "PATH")]
108        path: PathBuf,
109
110        /// Types of files to validate
111        #[arg(long, value_delimiter = ',')]
112        types: Option<Vec<String>>,
113
114        /// Fix issues automatically where possible
115        #[arg(long)]
116        fix: bool,
117    },
118
119    /// Show supported languages and frameworks
120    Support {
121        /// Show only languages
122        #[arg(long)]
123        languages: bool,
124
125        /// Show only frameworks
126        #[arg(long)]
127        frameworks: bool,
128
129        /// Show detailed information
130        #[arg(short, long)]
131        detailed: bool,
132    },
133
134    /// Analyze project dependencies in detail
135    Dependencies {
136        /// Path to the project directory to analyze
137        #[arg(value_name = "PROJECT_PATH")]
138        path: PathBuf,
139
140        /// Show license information for dependencies
141        #[arg(long)]
142        licenses: bool,
143
144        /// Check for known vulnerabilities
145        #[arg(long)]
146        vulnerabilities: bool,
147
148        /// Show only production dependencies
149        #[arg(long, conflicts_with = "dev_only")]
150        prod_only: bool,
151
152        /// Show only development dependencies
153        #[arg(long, conflicts_with = "prod_only")]
154        dev_only: bool,
155
156        /// Output format
157        #[arg(long, value_enum, default_value = "table")]
158        format: OutputFormat,
159    },
160
161    /// Check dependencies for known vulnerabilities
162    Vulnerabilities {
163        /// Check vulnerabilities in a specific path
164        #[arg(default_value = ".")]
165        path: PathBuf,
166
167        /// Show only vulnerabilities with severity >= threshold
168        #[arg(long, value_enum)]
169        severity: Option<SeverityThreshold>,
170
171        /// Output format
172        #[arg(long, value_enum, default_value = "table")]
173        format: OutputFormat,
174
175        /// Export report to file
176        #[arg(long)]
177        output: Option<PathBuf>,
178    },
179
180    /// Perform comprehensive security analysis
181    Security {
182        /// Path to the project directory to analyze
183        #[arg(value_name = "PROJECT_PATH", default_value = ".")]
184        path: PathBuf,
185
186        /// Security scan mode (lightning, fast, balanced, thorough, paranoid)
187        #[arg(long, value_enum, default_value = "thorough")]
188        mode: SecurityScanMode,
189
190        /// Include low severity findings
191        #[arg(long)]
192        include_low: bool,
193
194        /// Skip secrets detection
195        #[arg(long)]
196        no_secrets: bool,
197
198        /// Skip code pattern analysis
199        #[arg(long)]
200        no_code_patterns: bool,
201
202        /// Skip infrastructure analysis (not implemented yet)
203        #[arg(long, hide = true)]
204        no_infrastructure: bool,
205
206        /// Skip compliance checks (not implemented yet)
207        #[arg(long, hide = true)]
208        no_compliance: bool,
209
210        /// Compliance frameworks to check (not implemented yet)
211        #[arg(long, value_delimiter = ',', hide = true)]
212        frameworks: Vec<String>,
213
214        /// Output format
215        #[arg(long, value_enum, default_value = "table")]
216        format: OutputFormat,
217
218        /// Export report to file
219        #[arg(long)]
220        output: Option<PathBuf>,
221
222        /// Exit with error code on security findings
223        #[arg(long)]
224        fail_on_findings: bool,
225    },
226
227    /// Manage vulnerability scanning tools
228    Tools {
229        #[command(subcommand)]
230        command: ToolsCommand,
231    },
232
233    /// Start an interactive AI chat session to analyze and understand your project
234    Chat {
235        /// Path to the project directory (default: current directory)
236        #[arg(value_name = "PROJECT_PATH", default_value = ".")]
237        path: PathBuf,
238
239        /// LLM provider to use (omit to use saved default or prompt for setup)
240        #[arg(long, value_enum)]
241        provider: Option<ChatProvider>,
242
243        /// Model to use (e.g., gpt-4o, claude-3-5-sonnet-latest, llama3.2)
244        #[arg(long)]
245        model: Option<String>,
246
247        /// Run a single query instead of interactive mode
248        #[arg(long)]
249        query: Option<String>,
250
251        /// Run the setup wizard to configure API keys
252        #[arg(long)]
253        setup: bool,
254    },
255}
256
257#[derive(Subcommand)]
258pub enum ToolsCommand {
259    /// Check which vulnerability scanning tools are installed
260    Status {
261        /// Output format
262        #[arg(long, value_enum, default_value = "table")]
263        format: OutputFormat,
264
265        /// Check tools for specific languages only
266        #[arg(long, value_delimiter = ',')]
267        languages: Option<Vec<String>>,
268    },
269
270    /// Install missing vulnerability scanning tools
271    Install {
272        /// Install tools for specific languages only
273        #[arg(long, value_delimiter = ',')]
274        languages: Option<Vec<String>>,
275
276        /// Also install OWASP Dependency Check (large download)
277        #[arg(long)]
278        include_owasp: bool,
279
280        /// Perform a dry run to show what would be installed
281        #[arg(long)]
282        dry_run: bool,
283
284        /// Skip confirmation prompts
285        #[arg(short, long)]
286        yes: bool,
287    },
288
289    /// Verify that installed tools are working correctly
290    Verify {
291        /// Test tools for specific languages only
292        #[arg(long, value_delimiter = ',')]
293        languages: Option<Vec<String>>,
294
295        /// Show detailed verification output
296        #[arg(short, long)]
297        detailed: bool,
298    },
299
300    /// Show tool installation guides for manual setup
301    Guide {
302        /// Show guide for specific languages only
303        #[arg(long, value_delimiter = ',')]
304        languages: Option<Vec<String>>,
305
306        /// Show platform-specific instructions
307        #[arg(long)]
308        platform: Option<String>,
309    },
310}
311
312#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
313pub enum OutputFormat {
314    Table,
315    Json,
316}
317
318#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
319pub enum DisplayFormat {
320    /// Compact matrix/dashboard view (modern, easy to scan)
321    Matrix,
322    /// Detailed vertical view (legacy format with all details)
323    Detailed,
324    /// Brief summary only
325    Summary,
326}
327
328#[derive(Clone, Copy, Debug, ValueEnum)]
329pub enum ColorScheme {
330    /// Auto-detect terminal background (default)
331    Auto,
332    /// Dark background terminal colors
333    Dark,
334    /// Light background terminal colors
335    Light,
336}
337
338#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
339pub enum SeverityThreshold {
340    Low,
341    Medium,
342    High,
343    Critical,
344}
345
346#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
347pub enum SecurityScanMode {
348    /// Lightning fast scan - critical files only (.env, configs)
349    Lightning,
350    /// Fast scan - smart sampling with priority patterns
351    Fast,
352    /// Balanced scan - good coverage with performance optimizations (recommended)
353    Balanced,
354    /// Thorough scan - comprehensive analysis of all files
355    Thorough,
356    /// Paranoid scan - most comprehensive including low-severity findings
357    Paranoid,
358}
359
360#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Default)]
361pub enum ChatProvider {
362    /// OpenAI (GPT-4o, GPT-4, etc.)
363    #[default]
364    Openai,
365    /// Anthropic (Claude 3)
366    Anthropic,
367    /// Ollama (local LLM, no API key needed)
368    Ollama,
369}
370
371impl Cli {
372    /// Initialize logging based on verbosity level
373    pub fn init_logging(&self) {
374        if self.quiet {
375            return;
376        }
377
378        let level = match self.verbose {
379            0 => log::LevelFilter::Warn,
380            1 => log::LevelFilter::Info,
381            2 => log::LevelFilter::Debug,
382            _ => log::LevelFilter::Trace,
383        };
384
385        env_logger::Builder::from_default_env()
386            .filter_level(level)
387            .init();
388    }
389}