Skip to main content

bytes_radar/cli/
args.rs

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    // Version
54    #[arg(short = 'v', long = "version", action = clap::ArgAction::Version, help = "Current version information")]
55    version: (),
56
57    // Output Options
58    #[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    // Authentication
84    #[arg(long = "token", help = "Authentication token for private repositories")]
85    pub token: Option<String>,
86
87    // Network Options
88    #[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    // Filtering Options
115    #[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    // Language Options
164    #[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    // Analysis Options
179    #[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    // Debug and Logging
197    #[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    // Advanced Options
207    #[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    // Experimental Features
234    #[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}