diff options
author | Aleksey Kladov <[email protected]> | 2020-02-17 17:02:10 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-02-17 17:02:10 +0000 |
commit | 017f0e4e53dfb1fb1b8a1844cf99b253dd9dbd25 (patch) | |
tree | 8800cc2503cd4a0c71537f008780e014ff11c248 /crates/ra_cli/src | |
parent | 90e61ac75dcf4cdae41de4df41557f6ae5186a9a (diff) |
Refactor arg parsing
Diffstat (limited to 'crates/ra_cli/src')
-rw-r--r-- | crates/ra_cli/src/main.rs | 284 |
1 files changed, 169 insertions, 115 deletions
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index 4a428faff..7479fbd80 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs | |||
@@ -14,6 +14,15 @@ use ra_syntax::{AstNode, SourceFile}; | |||
14 | 14 | ||
15 | type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>; | 15 | type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>; |
16 | 16 | ||
17 | fn main() -> Result<()> { | ||
18 | env_logger::try_init()?; | ||
19 | |||
20 | let command = Command::from_args()?; | ||
21 | command.run()?; | ||
22 | |||
23 | Ok(()) | ||
24 | } | ||
25 | |||
17 | #[derive(Clone, Copy)] | 26 | #[derive(Clone, Copy)] |
18 | pub enum Verbosity { | 27 | pub enum Verbosity { |
19 | Spammy, | 28 | Spammy, |
@@ -37,17 +46,40 @@ impl Verbosity { | |||
37 | } | 46 | } |
38 | } | 47 | } |
39 | 48 | ||
40 | fn main() -> Result<()> { | 49 | enum Command { |
41 | env_logger::try_init()?; | 50 | Parse { |
51 | no_dump: bool, | ||
52 | }, | ||
53 | Symbols, | ||
54 | Highlight { | ||
55 | rainbow: bool, | ||
56 | }, | ||
57 | Stats { | ||
58 | verbosity: Verbosity, | ||
59 | randomize: bool, | ||
60 | memory_usage: bool, | ||
61 | only: Option<String>, | ||
62 | with_deps: bool, | ||
63 | path: String, | ||
64 | }, | ||
65 | Bench { | ||
66 | verbose: bool, | ||
67 | path: String, | ||
68 | op: analysis_bench::Op, | ||
69 | }, | ||
70 | HelpPrinted, | ||
71 | } | ||
42 | 72 | ||
43 | let mut matches = Arguments::from_env(); | 73 | impl Command { |
44 | let subcommand = matches.subcommand()?.unwrap_or_default(); | 74 | fn from_args() -> Result<Command> { |
75 | let mut matches = Arguments::from_env(); | ||
76 | let subcommand = matches.subcommand()?.unwrap_or_default(); | ||
45 | 77 | ||
46 | match subcommand.as_str() { | 78 | let command = match subcommand.as_str() { |
47 | "parse" => { | 79 | "parse" => { |
48 | if matches.contains(["-h", "--help"]) { | 80 | if matches.contains(["-h", "--help"]) { |
49 | eprintln!( | 81 | eprintln!( |
50 | "\ | 82 | "\ |
51 | ra-cli-parse | 83 | ra-cli-parse |
52 | 84 | ||
53 | USAGE: | 85 | USAGE: |
@@ -56,24 +88,18 @@ USAGE: | |||
56 | FLAGS: | 88 | FLAGS: |
57 | -h, --help Prints help inforamtion | 89 | -h, --help Prints help inforamtion |
58 | --no-dump" | 90 | --no-dump" |
59 | ); | 91 | ); |
60 | return Ok(()); | 92 | return Ok(Command::HelpPrinted); |
61 | } | 93 | } |
62 | |||
63 | let no_dump = matches.contains("--no-dump"); | ||
64 | matches.finish().or_else(handle_extra_flags)?; | ||
65 | 94 | ||
66 | let _p = profile("parsing"); | 95 | let no_dump = matches.contains("--no-dump"); |
67 | let file = file()?; | 96 | matches.finish().or_else(handle_extra_flags)?; |
68 | if !no_dump { | 97 | Command::Parse { no_dump } |
69 | println!("{:#?}", file.syntax()); | ||
70 | } | 98 | } |
71 | std::mem::forget(file); | 99 | "symbols" => { |
72 | } | 100 | if matches.contains(["-h", "--help"]) { |
73 | "symbols" => { | 101 | eprintln!( |
74 | if matches.contains(["-h", "--help"]) { | 102 | "\ |
75 | eprintln!( | ||
76 | "\ | ||
77 | ra-cli-symbols | 103 | ra-cli-symbols |
78 | 104 | ||
79 | USAGE: | 105 | USAGE: |
@@ -81,21 +107,18 @@ USAGE: | |||
81 | 107 | ||
82 | FLAGS: | 108 | FLAGS: |
83 | -h, --help Prints help inforamtion" | 109 | -h, --help Prints help inforamtion" |
84 | ); | 110 | ); |
85 | return Ok(()); | 111 | return Ok(Command::HelpPrinted); |
86 | } | 112 | } |
87 | 113 | ||
88 | matches.finish().or_else(handle_extra_flags)?; | 114 | matches.finish().or_else(handle_extra_flags)?; |
89 | 115 | ||
90 | let file = file()?; | 116 | Command::Symbols |
91 | for s in file_structure(&file) { | ||
92 | println!("{:?}", s); | ||
93 | } | 117 | } |
94 | } | 118 | "highlight" => { |
95 | "highlight" => { | 119 | if matches.contains(["-h", "--help"]) { |
96 | if matches.contains(["-h", "--help"]) { | 120 | eprintln!( |
97 | eprintln!( | 121 | "\ |
98 | "\ | ||
99 | ra-cli-highlight | 122 | ra-cli-highlight |
100 | 123 | ||
101 | USAGE: | 124 | USAGE: |
@@ -104,21 +127,18 @@ USAGE: | |||
104 | FLAGS: | 127 | FLAGS: |
105 | -h, --help Prints help information | 128 | -h, --help Prints help information |
106 | -r, --rainbow" | 129 | -r, --rainbow" |
107 | ); | 130 | ); |
108 | return Ok(()); | 131 | return Ok(Command::HelpPrinted); |
109 | } | 132 | } |
110 | |||
111 | let rainbow_opt = matches.contains(["-r", "--rainbow"]); | ||
112 | matches.finish().or_else(handle_extra_flags)?; | ||
113 | 133 | ||
114 | let (analysis, file_id) = Analysis::from_single_file(read_stdin()?); | 134 | let rainbow = matches.contains(["-r", "--rainbow"]); |
115 | let html = analysis.highlight_as_html(file_id, rainbow_opt).unwrap(); | 135 | matches.finish().or_else(handle_extra_flags)?; |
116 | println!("{}", html); | 136 | Command::Highlight { rainbow } |
117 | } | 137 | } |
118 | "analysis-stats" => { | 138 | "analysis-stats" => { |
119 | if matches.contains(["-h", "--help"]) { | 139 | if matches.contains(["-h", "--help"]) { |
120 | eprintln!( | 140 | eprintln!( |
121 | "\ | 141 | "\ |
122 | ra-cli-analysis-stats | 142 | ra-cli-analysis-stats |
123 | 143 | ||
124 | USAGE: | 144 | USAGE: |
@@ -135,47 +155,40 @@ OPTIONS: | |||
135 | 155 | ||
136 | ARGS: | 156 | ARGS: |
137 | <PATH>" | 157 | <PATH>" |
138 | ); | 158 | ); |
139 | return Ok(()); | 159 | return Ok(Command::HelpPrinted); |
140 | } | ||
141 | |||
142 | let verbosity = match ( | ||
143 | matches.contains(["-vv", "--spammy"]), | ||
144 | matches.contains(["-v", "--verbose"]), | ||
145 | matches.contains(["-q", "--quiet"]), | ||
146 | ) { | ||
147 | (true, _, true) => Err("Invalid flags: -q conflicts with -vv")?, | ||
148 | (true, _, false) => Verbosity::Spammy, | ||
149 | (false, false, false) => Verbosity::Normal, | ||
150 | (false, false, true) => Verbosity::Quiet, | ||
151 | (false, true, false) => Verbosity::Verbose, | ||
152 | (false, true, true) => Err("Invalid flags: -q conflicts with -v")?, | ||
153 | }; | ||
154 | let randomize = matches.contains("--randomize"); | ||
155 | let memory_usage = matches.contains("--memory-usage"); | ||
156 | let only: Option<String> = matches.opt_value_from_str(["-o", "--only"])?; | ||
157 | let with_deps: bool = matches.contains("--with-deps"); | ||
158 | let path = { | ||
159 | let mut trailing = matches.free()?; | ||
160 | if trailing.len() != 1 { | ||
161 | Err("Invalid flags")?; | ||
162 | } | 160 | } |
163 | trailing.pop().unwrap() | 161 | |
164 | }; | 162 | let verbosity = match ( |
165 | 163 | matches.contains(["-vv", "--spammy"]), | |
166 | analysis_stats::run( | 164 | matches.contains(["-v", "--verbose"]), |
167 | verbosity, | 165 | matches.contains(["-q", "--quiet"]), |
168 | memory_usage, | 166 | ) { |
169 | path.as_ref(), | 167 | (true, _, true) => Err("Invalid flags: -q conflicts with -vv")?, |
170 | only.as_ref().map(String::as_ref), | 168 | (true, _, false) => Verbosity::Spammy, |
171 | with_deps, | 169 | (false, false, false) => Verbosity::Normal, |
172 | randomize, | 170 | (false, false, true) => Verbosity::Quiet, |
173 | )?; | 171 | (false, true, false) => Verbosity::Verbose, |
174 | } | 172 | (false, true, true) => Err("Invalid flags: -q conflicts with -v")?, |
175 | "analysis-bench" => { | 173 | }; |
176 | if matches.contains(["-h", "--help"]) { | 174 | let randomize = matches.contains("--randomize"); |
177 | eprintln!( | 175 | let memory_usage = matches.contains("--memory-usage"); |
178 | "\ | 176 | let only: Option<String> = matches.opt_value_from_str(["-o", "--only"])?; |
177 | let with_deps: bool = matches.contains("--with-deps"); | ||
178 | let path = { | ||
179 | let mut trailing = matches.free()?; | ||
180 | if trailing.len() != 1 { | ||
181 | Err("Invalid flags")?; | ||
182 | } | ||
183 | trailing.pop().unwrap() | ||
184 | }; | ||
185 | |||
186 | Command::Stats { verbosity, randomize, memory_usage, only, with_deps, path } | ||
187 | } | ||
188 | "analysis-bench" => { | ||
189 | if matches.contains(["-h", "--help"]) { | ||
190 | eprintln!( | ||
191 | "\ | ||
179 | ra_cli-analysis-bench | 192 | ra_cli-analysis-bench |
180 | 193 | ||
181 | USAGE: | 194 | USAGE: |
@@ -191,29 +204,28 @@ OPTIONS: | |||
191 | 204 | ||
192 | ARGS: | 205 | ARGS: |
193 | <PATH> Project to analyse" | 206 | <PATH> Project to analyse" |
194 | ); | 207 | ); |
195 | return Ok(()); | 208 | return Ok(Command::HelpPrinted); |
196 | } | 209 | } |
197 | 210 | ||
198 | let verbose = matches.contains(["-v", "--verbose"]); | 211 | let verbose = matches.contains(["-v", "--verbose"]); |
199 | let path: String = matches.opt_value_from_str("--path")?.unwrap_or_default(); | 212 | let path: String = matches.opt_value_from_str("--path")?.unwrap_or_default(); |
200 | let highlight_path: Option<String> = matches.opt_value_from_str("--highlight")?; | 213 | let highlight_path: Option<String> = matches.opt_value_from_str("--highlight")?; |
201 | let complete_path: Option<String> = matches.opt_value_from_str("--complete")?; | 214 | let complete_path: Option<String> = matches.opt_value_from_str("--complete")?; |
202 | let goto_def_path: Option<String> = matches.opt_value_from_str("--goto-def")?; | 215 | let goto_def_path: Option<String> = matches.opt_value_from_str("--goto-def")?; |
203 | let op = match (highlight_path, complete_path, goto_def_path) { | 216 | let op = match (highlight_path, complete_path, goto_def_path) { |
204 | (Some(path), None, None) => analysis_bench::Op::Highlight { path: path.into() }, | 217 | (Some(path), None, None) => analysis_bench::Op::Highlight { path: path.into() }, |
205 | (None, Some(position), None) => analysis_bench::Op::Complete(position.parse()?), | 218 | (None, Some(position), None) => analysis_bench::Op::Complete(position.parse()?), |
206 | (None, None, Some(position)) => analysis_bench::Op::GotoDef(position.parse()?), | 219 | (None, None, Some(position)) => analysis_bench::Op::GotoDef(position.parse()?), |
207 | _ => panic!( | 220 | _ => panic!( |
208 | "exactly one of `--highlight`, `--complete` or `--goto-def` must be set" | 221 | "exactly one of `--highlight`, `--complete` or `--goto-def` must be set" |
209 | ), | 222 | ), |
210 | }; | 223 | }; |
211 | matches.finish().or_else(handle_extra_flags)?; | 224 | Command::Bench { verbose, path, op } |
212 | 225 | } | |
213 | analysis_bench::run(verbose, path.as_ref(), op)?; | 226 | _ => { |
214 | } | 227 | eprintln!( |
215 | _ => eprintln!( | 228 | "\ |
216 | "\ | ||
217 | ra-cli | 229 | ra-cli |
218 | 230 | ||
219 | USAGE: | 231 | USAGE: |
@@ -228,9 +240,51 @@ SUBCOMMANDS: | |||
228 | highlight | 240 | highlight |
229 | parse | 241 | parse |
230 | symbols" | 242 | symbols" |
231 | ), | 243 | ); |
244 | return Ok(Command::HelpPrinted); | ||
245 | } | ||
246 | }; | ||
247 | Ok(command) | ||
248 | } | ||
249 | |||
250 | fn run(self) -> Result<()> { | ||
251 | match self { | ||
252 | Command::Parse { no_dump } => { | ||
253 | let _p = profile("parsing"); | ||
254 | let file = file()?; | ||
255 | if !no_dump { | ||
256 | println!("{:#?}", file.syntax()); | ||
257 | } | ||
258 | std::mem::forget(file); | ||
259 | } | ||
260 | Command::Symbols => { | ||
261 | let file = file()?; | ||
262 | for s in file_structure(&file) { | ||
263 | println!("{:?}", s); | ||
264 | } | ||
265 | } | ||
266 | Command::Highlight { rainbow } => { | ||
267 | let (analysis, file_id) = Analysis::from_single_file(read_stdin()?); | ||
268 | let html = analysis.highlight_as_html(file_id, rainbow).unwrap(); | ||
269 | println!("{}", html); | ||
270 | } | ||
271 | Command::Stats { verbosity, randomize, memory_usage, only, with_deps, path } => { | ||
272 | analysis_stats::run( | ||
273 | verbosity, | ||
274 | memory_usage, | ||
275 | path.as_ref(), | ||
276 | only.as_ref().map(String::as_ref), | ||
277 | with_deps, | ||
278 | randomize, | ||
279 | )?; | ||
280 | } | ||
281 | Command::Bench { verbose, path, op } => { | ||
282 | analysis_bench::run(verbose, path.as_ref(), op)?; | ||
283 | } | ||
284 | Command::HelpPrinted => (), | ||
285 | } | ||
286 | Ok(()) | ||
232 | } | 287 | } |
233 | Ok(()) | ||
234 | } | 288 | } |
235 | 289 | ||
236 | fn handle_extra_flags(e: pico_args::Error) -> Result<()> { | 290 | fn handle_extra_flags(e: pico_args::Error) -> Result<()> { |