11//! CLI argument parsing and configuration
22
3- use clap:: { Parser , Subcommand } ;
3+ use clap:: { Parser , Subcommand , ValueEnum } ;
44use std:: path:: PathBuf ;
55
66#[ derive( Parser ) ]
77#[ command( name = "smart-diff" ) ]
8- #[ command( about = "A smart code diffing tool that understands code structure" ) ]
8+ #[ command( about = "A smart code diffing tool that understands code structure and semantics " ) ]
99#[ command( version) ]
10+ #[ command( long_about = "Smart Code Diff is a next-generation code comparison tool that performs \
11+ structural and semantic analysis of source code files. Unlike traditional line-based diff tools, \
12+ it understands code structure, detects refactoring patterns, and provides intelligent matching \
13+ of functions and classes across different versions of your codebase.") ]
1014pub struct Cli {
1115 #[ command( subcommand) ]
1216 pub command : Commands ,
1317
14- /// Enable verbose output
15- #[ arg( short, long) ]
18+ /// Enable verbose output with detailed logging
19+ #[ arg( short, long, global = true ) ]
1620 pub verbose : bool ,
1721
22+ /// Enable debug output with extensive logging
23+ #[ arg( short, long, global = true ) ]
24+ pub debug : bool ,
25+
1826 /// Configuration file path
19- #[ arg( short, long) ]
27+ #[ arg( short, long, global = true ) ]
2028 pub config : Option < PathBuf > ,
29+
30+ /// Disable colored output
31+ #[ arg( long, global = true ) ]
32+ pub no_color : bool ,
33+
34+ /// Enable quiet mode (minimal output)
35+ #[ arg( short, long, global = true ) ]
36+ pub quiet : bool ,
2137}
2238
2339#[ derive( Subcommand ) ]
2440pub enum Commands {
25- /// Compare files or directories
41+ /// Compare files or directories with structural analysis
2642 Compare {
2743 /// First file or directory to compare
28- #[ arg( value_name = "FILE1 " ) ]
29- file1 : PathBuf ,
44+ #[ arg( value_name = "SOURCE " ) ]
45+ source : PathBuf ,
3046
3147 /// Second file or directory to compare
32- #[ arg( value_name = "FILE2 " ) ]
33- file2 : PathBuf ,
48+ #[ arg( value_name = "TARGET " ) ]
49+ target : PathBuf ,
3450
35- /// Output format
51+ /// Output format for comparison results
3652 #[ arg( short, long, default_value = "text" ) ]
3753 format : OutputFormat ,
3854
3955 /// Compare directories recursively
4056 #[ arg( short, long) ]
4157 recursive : bool ,
4258
43- /// Ignore whitespace changes
59+ /// Ignore whitespace changes in comparison
4460 #[ arg( long) ]
4561 ignore_whitespace : bool ,
4662
47- /// Minimum similarity threshold (0.0-1.0)
63+ /// Ignore case differences in comparison
64+ #[ arg( long) ]
65+ ignore_case : bool ,
66+
67+ /// Minimum similarity threshold for function matching (0.0-1.0)
4868 #[ arg( long, default_value = "0.7" ) ]
4969 threshold : f64 ,
5070
71+ /// Output file path (stdout if not specified)
72+ #[ arg( short, long) ]
73+ output : Option < PathBuf > ,
74+
75+ /// Force language detection (override auto-detection)
76+ #[ arg( short, long) ]
77+ language : Option < Language > ,
78+
79+ /// Enable refactoring pattern detection
80+ #[ arg( long) ]
81+ detect_refactoring : bool ,
82+
83+ /// Enable cross-file function tracking
84+ #[ arg( long) ]
85+ track_moves : bool ,
86+
87+ /// Show function-level similarity scores
88+ #[ arg( long) ]
89+ show_similarity : bool ,
90+
91+ /// Include AST structure in output
92+ #[ arg( long) ]
93+ include_ast : bool ,
94+
95+ /// Maximum depth for AST comparison
96+ #[ arg( long, default_value = "10" ) ]
97+ max_depth : usize ,
98+
99+ /// Show performance statistics
100+ #[ arg( long) ]
101+ show_stats : bool ,
102+
103+ /// File patterns to include (glob patterns)
104+ #[ arg( long, value_delimiter = ',' ) ]
105+ include : Vec < String > ,
106+
107+ /// File patterns to exclude (glob patterns)
108+ #[ arg( long, value_delimiter = ',' ) ]
109+ exclude : Vec < String > ,
110+ } ,
111+
112+ /// Analyze a single file or directory for code metrics
113+ Analyze {
114+ /// File or directory to analyze
115+ #[ arg( value_name = "PATH" ) ]
116+ path : PathBuf ,
117+
118+ /// Output format for analysis results
119+ #[ arg( short, long, default_value = "text" ) ]
120+ format : OutputFormat ,
121+
122+ /// Analyze directories recursively
123+ #[ arg( short, long) ]
124+ recursive : bool ,
125+
126+ /// Force language detection
127+ #[ arg( short, long) ]
128+ language : Option < Language > ,
129+
130+ /// Include complexity metrics
131+ #[ arg( long) ]
132+ complexity : bool ,
133+
134+ /// Include dependency analysis
135+ #[ arg( long) ]
136+ dependencies : bool ,
137+
138+ /// Include function signatures
139+ #[ arg( long) ]
140+ signatures : bool ,
141+
51142 /// Output file path
52143 #[ arg( short, long) ]
53144 output : Option < PathBuf > ,
@@ -58,29 +149,143 @@ pub enum Commands {
58149 #[ command( subcommand) ]
59150 action : ConfigAction ,
60151 } ,
152+
153+ /// Validate configuration and test setup
154+ Doctor {
155+ /// Check specific component
156+ #[ arg( long) ]
157+ component : Option < String > ,
158+
159+ /// Fix issues automatically where possible
160+ #[ arg( long) ]
161+ fix : bool ,
162+ } ,
61163}
62164
63- #[ derive( clap :: ValueEnum , Clone , Debug ) ]
165+ #[ derive( ValueEnum , Clone , Debug ) ]
64166pub enum OutputFormat {
167+ /// Human-readable text output with colors
65168 Text ,
169+ /// JSON format for programmatic consumption
66170 Json ,
171+ /// HTML format with syntax highlighting
67172 Html ,
173+ /// XML format for structured data
68174 Xml ,
175+ /// Compact JSON format (single line)
176+ JsonCompact ,
177+ /// CSV format for tabular data
178+ Csv ,
179+ /// Markdown format for documentation
180+ Markdown ,
181+ }
182+
183+ #[ derive( ValueEnum , Clone , Debug ) ]
184+ pub enum Language {
185+ /// Java programming language
186+ Java ,
187+ /// Python programming language
188+ Python ,
189+ /// JavaScript programming language
190+ JavaScript ,
191+ /// C++ programming language
192+ Cpp ,
193+ /// C programming language
194+ C ,
195+ /// Auto-detect language from file extension and content
196+ Auto ,
69197}
70198
71199#[ derive( Subcommand ) ]
72200pub enum ConfigAction {
73201 /// Show current configuration
74- Show ,
202+ Show {
203+ /// Show specific configuration section
204+ #[ arg( long) ]
205+ section : Option < String > ,
206+ } ,
75207
76208 /// Set configuration value
77209 Set {
78- /// Configuration key
210+ /// Configuration key (dot-separated path)
79211 key : String ,
80212 /// Configuration value
81213 value : String ,
82214 } ,
83215
216+ /// Get configuration value
217+ Get {
218+ /// Configuration key (dot-separated path)
219+ key : String ,
220+ } ,
221+
84222 /// Reset configuration to defaults
85- Reset ,
223+ Reset {
224+ /// Reset specific section only
225+ #[ arg( long) ]
226+ section : Option < String > ,
227+ } ,
228+
229+ /// List all available configuration keys
230+ List ,
231+
232+ /// Validate current configuration
233+ Validate ,
234+ }
235+
236+ impl OutputFormat {
237+ /// Check if format supports colored output
238+ pub fn supports_color ( & self ) -> bool {
239+ matches ! ( self , OutputFormat :: Text | OutputFormat :: Html | OutputFormat :: Markdown )
240+ }
241+
242+ /// Get file extension for format
243+ pub fn file_extension ( & self ) -> & ' static str {
244+ match self {
245+ OutputFormat :: Text => "txt" ,
246+ OutputFormat :: Json | OutputFormat :: JsonCompact => "json" ,
247+ OutputFormat :: Html => "html" ,
248+ OutputFormat :: Xml => "xml" ,
249+ OutputFormat :: Csv => "csv" ,
250+ OutputFormat :: Markdown => "md" ,
251+ }
252+ }
253+
254+ /// Get MIME type for format
255+ pub fn mime_type ( & self ) -> & ' static str {
256+ match self {
257+ OutputFormat :: Text => "text/plain" ,
258+ OutputFormat :: Json | OutputFormat :: JsonCompact => "application/json" ,
259+ OutputFormat :: Html => "text/html" ,
260+ OutputFormat :: Xml => "application/xml" ,
261+ OutputFormat :: Csv => "text/csv" ,
262+ OutputFormat :: Markdown => "text/markdown" ,
263+ }
264+ }
265+ }
266+
267+ impl Language {
268+ /// Convert to parser language enum
269+ pub fn to_parser_language ( & self ) -> Option < smart_diff_parser:: Language > {
270+ match self {
271+ Language :: Java => Some ( smart_diff_parser:: Language :: Java ) ,
272+ Language :: Python => Some ( smart_diff_parser:: Language :: Python ) ,
273+ Language :: JavaScript => Some ( smart_diff_parser:: Language :: JavaScript ) ,
274+ Language :: Cpp => Some ( smart_diff_parser:: Language :: Cpp ) ,
275+ Language :: C => Some ( smart_diff_parser:: Language :: C ) ,
276+ Language :: Auto => None ,
277+ }
278+ }
279+
280+ /// Get file extensions for language
281+ pub fn file_extensions ( & self ) -> Vec < & ' static str > {
282+ match self {
283+ Language :: Java => vec ! [ "java" ] ,
284+ Language :: Python => vec ! [ "py" , "pyx" , "pyi" ] ,
285+ Language :: JavaScript => vec ! [ "js" , "jsx" , "mjs" , "cjs" ] ,
286+ Language :: Cpp => vec ! [ "cpp" , "cxx" , "cc" , "hpp" , "hxx" , "h" ] ,
287+ Language :: C => vec ! [ "c" , "h" ] ,
288+ Language :: Auto => vec ! [ ] ,
289+ }
290+ }
86291}
0 commit comments