|
1 | 1 | use anyhow::Result; |
2 | | -use clap::Parser; |
| 2 | +use clap::{Parser, error::ErrorKind}; |
3 | 3 | use log::LevelFilter; |
4 | 4 | use std::{env, io::Write, path::Path}; |
5 | 5 |
|
6 | 6 | use rescript::{build, cli, cmd, format, lock, watcher}; |
7 | 7 |
|
8 | 8 | fn main() -> Result<()> { |
9 | | - let mut args: Vec<String> = env::args().collect(); |
10 | | - handle_default_arg(&mut args); |
11 | | - |
12 | | - let cli = cli::Cli::parse_from(args); |
| 9 | + let raw_args: Vec<String> = env::args().collect(); |
| 10 | + let cli = parse_cli(raw_args); |
13 | 11 |
|
14 | 12 | let log_level_filter = cli.verbose.log_level_filter(); |
15 | 13 |
|
@@ -115,16 +113,63 @@ fn get_lock(folder: &str) -> lock::Lock { |
115 | 113 | } |
116 | 114 | } |
117 | 115 |
|
118 | | -fn handle_default_arg(args: &mut Vec<String>) { |
119 | | - let first_arg = args.get(1); |
120 | | - let global_flags = ["-h", "--help", "-V", "--version"]; |
| 116 | +fn parse_cli(raw_args: Vec<String>) -> cli::Cli { |
| 117 | + match cli::Cli::try_parse_from(&raw_args) { |
| 118 | + Ok(cli) => cli, |
| 119 | + Err(err) => { |
| 120 | + if should_default_to_build(&err, &raw_args) { |
| 121 | + let mut fallback_args = raw_args.clone(); |
| 122 | + let insert_at = index_after_global_flags(&fallback_args); |
| 123 | + fallback_args.insert(insert_at, "build".into()); |
| 124 | + |
| 125 | + match cli::Cli::try_parse_from(&fallback_args) { |
| 126 | + Ok(cli) => cli, |
| 127 | + Err(fallback_err) => fallback_err.exit(), |
| 128 | + } |
| 129 | + } else { |
| 130 | + err.exit() |
| 131 | + } |
| 132 | + } |
| 133 | + } |
| 134 | +} |
121 | 135 |
|
122 | | - let needs_default_arg = match first_arg { |
123 | | - Some(arg) => arg.starts_with("-") && !global_flags.contains(&arg.as_str()), |
124 | | - None => true, |
125 | | - }; |
| 136 | +fn should_default_to_build(err: &clap::Error, args: &[String]) -> bool { |
| 137 | + match err.kind() { |
| 138 | + ErrorKind::MissingSubcommand | ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand => true, |
| 139 | + ErrorKind::UnknownArgument | ErrorKind::InvalidSubcommand => { |
| 140 | + args.iter().skip(1).any(|arg| !is_global_flag(arg)) |
| 141 | + } |
| 142 | + _ => false, |
| 143 | + } |
| 144 | +} |
126 | 145 |
|
127 | | - if needs_default_arg { |
128 | | - args.insert(1, "build".to_string()); |
| 146 | +fn index_after_global_flags(args: &[String]) -> usize { |
| 147 | + let mut idx = 1; |
| 148 | + while let Some(arg) = args.get(idx) { |
| 149 | + if is_global_flag(arg) { |
| 150 | + idx += 1; |
| 151 | + } else { |
| 152 | + break; |
| 153 | + } |
129 | 154 | } |
| 155 | + idx.min(args.len()) |
| 156 | +} |
| 157 | + |
| 158 | +fn is_global_flag(arg: &str) -> bool { |
| 159 | + matches!( |
| 160 | + arg, |
| 161 | + "-v" | "-vv" |
| 162 | + | "-vvv" |
| 163 | + | "-vvvv" |
| 164 | + | "-q" |
| 165 | + | "-qq" |
| 166 | + | "-qqq" |
| 167 | + | "-qqqq" |
| 168 | + | "--verbose" |
| 169 | + | "--quiet" |
| 170 | + | "-h" |
| 171 | + | "--help" |
| 172 | + | "-V" |
| 173 | + | "--version" |
| 174 | + ) |
130 | 175 | } |
0 commit comments