1use clap::{ArgGroup, Parser, ValueEnum};
2
3#[derive(Parser)]
4#[command(name = "bradar")]
5#[command(about = "A professional tool for analyzing code statistics from remote repositories")]
6#[command(version)]
7#[command(long_about = "
8bradar - Bytes Radar: A hyper-fast code analysis tool for remote repositories.
9
10SUPPORTED PLATFORMS:
11 • GitHub (github.com, GitHub Enterprise)
12 • GitLab (gitlab.com, self-hosted instances)
13 • Bitbucket (bitbucket.org)
14 • Codeberg (codeberg.org)
15 • SourceForge (sourceforge.net)
16 • Gitea instances
17 • Azure DevOps
18 • Direct archive URLs (tar.gz, tgz, zip)
19
20URL FORMATS:
21 user/repo # GitHub repo (default branch)
22 user/repo@branch # Specific branch
23 user/repo@commit-hash # Specific commit
24 https://github.com/user/repo # Full GitHub URL
25 https://gitlab.com/user/repo # GitLab URL
26 https://example.com/archive.tar.gz # Direct archive URL
27
28EXAMPLES:
29 bradar microsoft/vscode
30 bradar torvalds/linux@master
31 bradar https://github.com/rust-lang/rust
32 bradar --format json --detailed user/repo
33 bradar --token ghp_xxx --include-tests private/repo
34 bradar --aggressive-filter --max-file-size 2048 large/repo
35")]
36#[command(arg_required_else_help = true)]
37#[command(disable_version_flag = true)]
38#[command(group(
39 ArgGroup::new("auth")
40 .args(&["token"])
41 .multiple(false)
42))]
43#[command(group(
44 ArgGroup::new("output_control")
45 .args(&["quiet", "debug"])
46 .multiple(false)
47))]
48#[non_exhaustive]
49pub struct Cli {
50 #[arg(help = "Repository URL to analyze (user/repo, user/repo@branch, or full URL)")]
51 pub url: Option<String>,
52
53 #[arg(short = 'v', long = "version", action = clap::ArgAction::Version, help = "Current version information")]
55 version: (),
56
57 #[arg(
59 short = 'f',
60 long = "format",
61 help = "Output format",
62 value_enum,
63 default_value = "table"
64 )]
65 pub format: OutputFormat,
66
67 #[arg(long = "detailed", help = "Show detailed file-by-file statistics")]
68 pub detailed: bool,
69
70 #[arg(
71 short = 'q',
72 long = "quiet",
73 help = "Quiet mode - suppress progress and minimize output"
74 )]
75 pub quiet: bool,
76
77 #[arg(long = "no-progress", help = "Disable progress bar")]
78 pub no_progress: bool,
79
80 #[arg(long = "no-color", help = "Disable colored output")]
81 pub no_color: bool,
82
83 #[arg(long = "token", help = "Authentication token for private repositories")]
85 pub token: Option<String>,
86
87 #[arg(
89 long = "timeout",
90 help = "Request timeout in seconds",
91 default_value = "300",
92 value_name = "SECONDS"
93 )]
94 pub timeout: u64,
95
96 #[arg(long = "allow-insecure", help = "Allow insecure HTTPS connections")]
97 pub allow_insecure: bool,
98
99 #[arg(
100 long = "user-agent",
101 help = "Custom User-Agent string",
102 value_name = "STRING"
103 )]
104 pub user_agent: Option<String>,
105
106 #[arg(
107 long = "retry-count",
108 help = "Number of retry attempts for failed requests",
109 default_value = "3",
110 value_name = "COUNT"
111 )]
112 pub retry_count: u32,
113
114 #[arg(
116 long = "aggressive-filter",
117 help = "Enable aggressive filtering for maximum performance"
118 )]
119 pub aggressive_filter: bool,
120
121 #[arg(
122 long = "max-file-size",
123 help = "Maximum file size to process in KB",
124 default_value = "1024",
125 value_name = "KB"
126 )]
127 pub max_file_size: u64,
128
129 #[arg(long = "include-tests", help = "Include test directories in analysis")]
130 pub include_tests: bool,
131
132 #[arg(
133 long = "include-docs",
134 help = "Include documentation directories in analysis"
135 )]
136 pub include_docs: bool,
137
138 #[arg(long = "include-hidden", help = "Include hidden files and directories")]
139 pub include_hidden: bool,
140
141 #[arg(
142 long = "exclude-pattern",
143 help = "Exclude files matching this pattern (glob)",
144 value_name = "PATTERN"
145 )]
146 pub exclude_pattern: Option<String>,
147
148 #[arg(
149 long = "include-pattern",
150 help = "Only include files matching this pattern (glob)",
151 value_name = "PATTERN"
152 )]
153 pub include_pattern: Option<String>,
154
155 #[arg(
156 long = "min-file-size",
157 help = "Minimum file size to process in bytes",
158 default_value = "1",
159 value_name = "BYTES"
160 )]
161 pub min_file_size: u64,
162
163 #[arg(
165 long = "language",
166 help = "Only analyze files of specific language",
167 value_name = "LANG"
168 )]
169 pub language: Option<String>,
170
171 #[arg(
172 long = "exclude-language",
173 help = "Exclude specific language from analysis",
174 value_name = "LANG"
175 )]
176 pub exclude_language: Vec<String>,
177
178 #[arg(
180 long = "ignore-whitespace",
181 help = "Ignore whitespace-only lines in code analysis"
182 )]
183 pub ignore_whitespace: bool,
184
185 #[arg(long = "count-generated", help = "Include generated files in analysis")]
186 pub count_generated: bool,
187
188 #[arg(
189 long = "max-line-length",
190 help = "Maximum line length to consider (0 = unlimited)",
191 default_value = "0",
192 value_name = "LENGTH"
193 )]
194 pub max_line_length: usize,
195
196 #[arg(short = 'd', long = "debug", help = "Enable debug output")]
198 pub debug: bool,
199
200 #[arg(long = "trace", help = "Enable trace-level logging")]
201 pub trace: bool,
202
203 #[arg(long = "log-file", help = "Write logs to file", value_name = "FILE")]
204 pub log_file: Option<String>,
205
206 #[arg(
208 long = "threads",
209 help = "Number of worker threads (0 = auto)",
210 default_value = "0",
211 value_name = "COUNT"
212 )]
213 pub threads: usize,
214
215 #[arg(
216 long = "memory-limit",
217 help = "Memory limit in MB (0 = unlimited)",
218 default_value = "0",
219 value_name = "MB"
220 )]
221 pub memory_limit: usize,
222
223 #[arg(
224 long = "cache-dir",
225 help = "Directory for caching downloaded files",
226 value_name = "DIR"
227 )]
228 pub cache_dir: Option<String>,
229
230 #[arg(long = "no-cache", help = "Disable caching of downloaded files")]
231 pub no_cache: bool,
232
233 #[arg(
235 long = "experimental-parallel",
236 help = "Enable experimental parallel processing"
237 )]
238 pub experimental_parallel: bool,
239
240 #[arg(
241 long = "experimental-streaming",
242 help = "Enable experimental streaming analysis"
243 )]
244 pub experimental_streaming: bool,
245}
246
247#[derive(Clone, ValueEnum)]
248pub enum OutputFormat {
249 #[value(name = "table", help = "Human-readable table format")]
250 Table,
251 #[value(name = "json", help = "JSON format")]
252 Json,
253 #[value(name = "csv", help = "CSV format")]
254 Csv,
255 #[value(name = "xml", help = "XML format")]
256 Xml,
257 #[value(name = "yaml", help = "YAML format")]
258 Yaml,
259 #[value(name = "toml", help = "TOML format")]
260 Toml,
261}
262
263impl Default for OutputFormat {
264 fn default() -> Self {
265 Self::Table
266 }
267}