diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_cli/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_cli/src/help.rs | 72 | ||||
-rw-r--r-- | crates/ra_cli/src/main.rs | 143 | ||||
-rw-r--r-- | crates/ra_tools/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_tools/src/help.rs | 45 | ||||
-rw-r--r-- | crates/ra_tools/src/main.rs | 117 |
6 files changed, 289 insertions, 92 deletions
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml index 205dd223b..d42ac3ad4 100644 --- a/crates/ra_cli/Cargo.toml +++ b/crates/ra_cli/Cargo.toml | |||
@@ -6,7 +6,7 @@ authors = ["rust-analyzer developers"] | |||
6 | publish = false | 6 | publish = false |
7 | 7 | ||
8 | [dependencies] | 8 | [dependencies] |
9 | clap = { version = "2.32.0", default-features = false } | 9 | pico-args = "0.2.0" |
10 | flexi_logger = "0.14.0" | 10 | flexi_logger = "0.14.0" |
11 | indicatif = "0.11.0" | 11 | indicatif = "0.11.0" |
12 | 12 | ||
diff --git a/crates/ra_cli/src/help.rs b/crates/ra_cli/src/help.rs new file mode 100644 index 000000000..5171578f0 --- /dev/null +++ b/crates/ra_cli/src/help.rs | |||
@@ -0,0 +1,72 @@ | |||
1 | pub const GLOBAL_HELP: &str = "ra-cli | ||
2 | |||
3 | USAGE: | ||
4 | ra_cli <SUBCOMMAND> | ||
5 | |||
6 | FLAGS: | ||
7 | -h, --help Prints help information | ||
8 | |||
9 | SUBCOMMANDS: | ||
10 | analysis-bench | ||
11 | analysis-stats | ||
12 | highlight | ||
13 | parse | ||
14 | symbols"; | ||
15 | |||
16 | pub const ANALYSIS_BENCH_HELP: &str = "ra_cli-analysis-bench | ||
17 | |||
18 | USAGE: | ||
19 | ra_cli analysis-bench [FLAGS] [OPTIONS] [PATH] | ||
20 | |||
21 | FLAGS: | ||
22 | -h, --help Prints help information | ||
23 | -v, --verbose | ||
24 | |||
25 | OPTIONS: | ||
26 | --complete <PATH:LINE:COLUMN> Compute completions at this location | ||
27 | --highlight <PATH> Hightlight this file | ||
28 | |||
29 | ARGS: | ||
30 | <PATH> Project to analyse"; | ||
31 | |||
32 | pub const ANALYSIS_STATS_HELP: &str = "ra-cli-analysis-stats | ||
33 | |||
34 | USAGE: | ||
35 | ra_cli analysis-stats [FLAGS] [OPTIONS] [PATH] | ||
36 | |||
37 | FLAGS: | ||
38 | -h, --help Prints help information | ||
39 | --memory-usage | ||
40 | -v, --verbose | ||
41 | |||
42 | OPTIONS: | ||
43 | -o <ONLY> | ||
44 | |||
45 | ARGS: | ||
46 | <PATH>"; | ||
47 | |||
48 | pub const HIGHLIGHT_HELP: &str = "ra-cli-highlight | ||
49 | |||
50 | USAGE: | ||
51 | ra_cli highlight [FLAGS] | ||
52 | |||
53 | FLAGS: | ||
54 | -h, --help Prints help information | ||
55 | -r, --rainbow"; | ||
56 | |||
57 | pub const SYMBOLS_HELP: &str = "ra-cli-symbols | ||
58 | |||
59 | USAGE: | ||
60 | ra_cli highlight [FLAGS] | ||
61 | |||
62 | FLAGS: | ||
63 | -h, --help Prints help inforamtion"; | ||
64 | |||
65 | pub const PARSE_HELP: &str = "ra-cli-parse | ||
66 | |||
67 | USAGE: | ||
68 | ra_cli parse [FLAGS] | ||
69 | |||
70 | FLAGS: | ||
71 | -h, --help Prints help inforamtion | ||
72 | --no-dump"; | ||
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index de8191ca3..e6334cf56 100644 --- a/crates/ra_cli/src/main.rs +++ b/crates/ra_cli/src/main.rs | |||
@@ -1,10 +1,11 @@ | |||
1 | mod analysis_stats; | 1 | mod analysis_stats; |
2 | mod analysis_bench; | 2 | mod analysis_bench; |
3 | mod help; | ||
3 | 4 | ||
4 | use std::{error::Error, io::Read}; | 5 | use std::{error::Error, fmt::Write, io::Read}; |
5 | 6 | ||
6 | use clap::{App, Arg, SubCommand}; | ||
7 | use flexi_logger::Logger; | 7 | use flexi_logger::Logger; |
8 | use pico_args::Arguments; | ||
8 | use ra_ide_api::{file_structure, Analysis}; | 9 | use ra_ide_api::{file_structure, Analysis}; |
9 | use ra_prof::profile; | 10 | use ra_prof::profile; |
10 | use ra_syntax::{AstNode, SourceFile}; | 11 | use ra_syntax::{AstNode, SourceFile}; |
@@ -13,77 +14,89 @@ type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>; | |||
13 | 14 | ||
14 | fn main() -> Result<()> { | 15 | fn main() -> Result<()> { |
15 | Logger::with_env().start()?; | 16 | Logger::with_env().start()?; |
16 | let matches = App::new("ra-cli") | 17 | |
17 | .setting(clap::AppSettings::SubcommandRequiredElseHelp) | 18 | let subcommand = match std::env::args_os().nth(1) { |
18 | .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump"))) | 19 | None => { |
19 | .subcommand(SubCommand::with_name("symbols")) | 20 | eprintln!("{}", help::GLOBAL_HELP); |
20 | .subcommand( | 21 | return Ok(()); |
21 | SubCommand::with_name("highlight") | 22 | } |
22 | .arg(Arg::with_name("rainbow").short("r").long("rainbow")), | 23 | Some(s) => s, |
23 | ) | 24 | }; |
24 | .subcommand( | 25 | let mut matches = Arguments::from_vec(std::env::args_os().skip(2).collect()); |
25 | SubCommand::with_name("analysis-stats") | 26 | |
26 | .arg(Arg::with_name("verbose").short("v").long("verbose")) | 27 | match &*subcommand.to_string_lossy() { |
27 | .arg(Arg::with_name("memory-usage").long("memory-usage")) | 28 | "parse" => { |
28 | .arg(Arg::with_name("only").short("o").takes_value(true)) | 29 | if matches.contains(["-h", "--help"]) { |
29 | .arg(Arg::with_name("path")), | 30 | eprintln!("{}", help::PARSE_HELP); |
30 | ) | 31 | return Ok(()); |
31 | .subcommand( | 32 | } |
32 | SubCommand::with_name("analysis-bench") | 33 | let no_dump = matches.contains("--no-dump"); |
33 | .arg(Arg::with_name("verbose").short("v").long("verbose")) | 34 | matches.finish().or_else(handle_extra_flags)?; |
34 | .arg( | 35 | |
35 | Arg::with_name("highlight") | ||
36 | .long("highlight") | ||
37 | .takes_value(true) | ||
38 | .conflicts_with("complete") | ||
39 | .value_name("PATH") | ||
40 | .help("highlight this file"), | ||
41 | ) | ||
42 | .arg( | ||
43 | Arg::with_name("complete") | ||
44 | .long("complete") | ||
45 | .takes_value(true) | ||
46 | .conflicts_with("highlight") | ||
47 | .value_name("PATH:LINE:COLUMN") | ||
48 | .help("compute completions at this location"), | ||
49 | ) | ||
50 | .arg(Arg::with_name("path").value_name("PATH").help("project to analyze")), | ||
51 | ) | ||
52 | .get_matches(); | ||
53 | match matches.subcommand() { | ||
54 | ("parse", Some(matches)) => { | ||
55 | let _p = profile("parsing"); | 36 | let _p = profile("parsing"); |
56 | let file = file()?; | 37 | let file = file()?; |
57 | if !matches.is_present("no-dump") { | 38 | if !no_dump { |
58 | println!("{:#?}", file.syntax()); | 39 | println!("{:#?}", file.syntax()); |
59 | } | 40 | } |
60 | std::mem::forget(file); | 41 | std::mem::forget(file); |
61 | } | 42 | } |
62 | ("symbols", _) => { | 43 | "symbols" => { |
44 | if matches.contains(["-h", "--help"]) { | ||
45 | eprintln!("{}", help::SYMBOLS_HELP); | ||
46 | return Ok(()); | ||
47 | } | ||
48 | matches.finish().or_else(handle_extra_flags)?; | ||
63 | let file = file()?; | 49 | let file = file()?; |
64 | for s in file_structure(&file) { | 50 | for s in file_structure(&file) { |
65 | println!("{:?}", s); | 51 | println!("{:?}", s); |
66 | } | 52 | } |
67 | } | 53 | } |
68 | ("highlight", Some(matches)) => { | 54 | "highlight" => { |
55 | if matches.contains(["-h", "--help"]) { | ||
56 | eprintln!("{}", help::HIGHLIGHT_HELP); | ||
57 | return Ok(()); | ||
58 | } | ||
59 | let rainbow_opt = matches.contains(["-r", "--rainbow"]); | ||
60 | matches.finish().or_else(handle_extra_flags)?; | ||
69 | let (analysis, file_id) = Analysis::from_single_file(read_stdin()?); | 61 | let (analysis, file_id) = Analysis::from_single_file(read_stdin()?); |
70 | let html = analysis.highlight_as_html(file_id, matches.is_present("rainbow")).unwrap(); | 62 | let html = analysis.highlight_as_html(file_id, rainbow_opt).unwrap(); |
71 | println!("{}", html); | 63 | println!("{}", html); |
72 | } | 64 | } |
73 | ("analysis-stats", Some(matches)) => { | 65 | "analysis-stats" => { |
74 | let verbose = matches.is_present("verbose"); | 66 | if matches.contains(["-h", "--help"]) { |
75 | let memory_usage = matches.is_present("memory-usage"); | 67 | eprintln!("{}", help::ANALYSIS_STATS_HELP); |
76 | let path = matches.value_of("path").unwrap_or(""); | 68 | return Ok(()); |
77 | let only = matches.value_of("only"); | 69 | } |
78 | analysis_stats::run(verbose, memory_usage, path.as_ref(), only)?; | 70 | let verbose = matches.contains(["-v", "--verbose"]); |
71 | let memory_usage = matches.contains("--memory-usage"); | ||
72 | let path: String = matches.value_from_str("--path")?.unwrap_or_default(); | ||
73 | let only = matches.value_from_str(["-o", "--only"])?.map(|v: String| v.to_owned()); | ||
74 | matches.finish().or_else(handle_extra_flags)?; | ||
75 | analysis_stats::run( | ||
76 | verbose, | ||
77 | memory_usage, | ||
78 | path.as_ref(), | ||
79 | only.as_ref().map(String::as_ref), | ||
80 | )?; | ||
79 | } | 81 | } |
80 | ("analysis-bench", Some(matches)) => { | 82 | "analysis-bench" => { |
81 | let verbose = matches.is_present("verbose"); | 83 | if matches.contains(["-h", "--help"]) { |
82 | let path = matches.value_of("path").unwrap_or(""); | 84 | eprintln!("{}", help::ANALYSIS_BENCH_HELP); |
83 | let op = if let Some(path) = matches.value_of("highlight") { | 85 | return Ok(()); |
86 | } | ||
87 | let verbose = matches.contains(["-v", "--verbose"]); | ||
88 | let path: String = matches.value_from_str("--path")?.unwrap_or_default(); | ||
89 | let highlight_path = matches.value_from_str("--highlight")?; | ||
90 | let complete_path = matches.value_from_str("--complete")?; | ||
91 | if highlight_path.is_some() && complete_path.is_some() { | ||
92 | panic!("either --highlight or --complete must be set, not both") | ||
93 | } | ||
94 | let op = if let Some(path) = highlight_path { | ||
95 | let path: String = path; | ||
84 | analysis_bench::Op::Highlight { path: path.into() } | 96 | analysis_bench::Op::Highlight { path: path.into() } |
85 | } else if let Some(path_line_col) = matches.value_of("complete") { | 97 | } else if let Some(path_line_col) = complete_path { |
86 | let (path_line, column) = rsplit_at_char(path_line_col, ':')?; | 98 | let path_line_col: String = path_line_col; |
99 | let (path_line, column) = rsplit_at_char(path_line_col.as_str(), ':')?; | ||
87 | let (path, line) = rsplit_at_char(path_line, ':')?; | 100 | let (path, line) = rsplit_at_char(path_line, ':')?; |
88 | analysis_bench::Op::Complete { | 101 | analysis_bench::Op::Complete { |
89 | path: path.into(), | 102 | path: path.into(), |
@@ -93,13 +106,27 @@ fn main() -> Result<()> { | |||
93 | } else { | 106 | } else { |
94 | panic!("either --highlight or --complete must be set") | 107 | panic!("either --highlight or --complete must be set") |
95 | }; | 108 | }; |
109 | matches.finish().or_else(handle_extra_flags)?; | ||
96 | analysis_bench::run(verbose, path.as_ref(), op)?; | 110 | analysis_bench::run(verbose, path.as_ref(), op)?; |
97 | } | 111 | } |
98 | _ => unreachable!(), | 112 | _ => eprintln!("{}", help::GLOBAL_HELP), |
99 | } | 113 | } |
100 | Ok(()) | 114 | Ok(()) |
101 | } | 115 | } |
102 | 116 | ||
117 | fn handle_extra_flags(e: pico_args::Error) -> Result<()> { | ||
118 | if let pico_args::Error::UnusedArgsLeft(flags) = e { | ||
119 | let mut invalid_flags = String::new(); | ||
120 | for flag in flags { | ||
121 | write!(&mut invalid_flags, "{}, ", flag)?; | ||
122 | } | ||
123 | let (invalid_flags, _) = invalid_flags.split_at(invalid_flags.len() - 2); | ||
124 | Err(format!("Invalid flags: {}", invalid_flags).into()) | ||
125 | } else { | ||
126 | Err(e.to_string().into()) | ||
127 | } | ||
128 | } | ||
129 | |||
103 | fn file() -> Result<SourceFile> { | 130 | fn file() -> Result<SourceFile> { |
104 | let text = read_stdin()?; | 131 | let text = read_stdin()?; |
105 | Ok(SourceFile::parse(&text).tree()) | 132 | Ok(SourceFile::parse(&text).tree()) |
diff --git a/crates/ra_tools/Cargo.toml b/crates/ra_tools/Cargo.toml index b94a0b18d..848ca408d 100644 --- a/crates/ra_tools/Cargo.toml +++ b/crates/ra_tools/Cargo.toml | |||
@@ -8,7 +8,7 @@ publish = false | |||
8 | [dependencies] | 8 | [dependencies] |
9 | walkdir = "2.1.3" | 9 | walkdir = "2.1.3" |
10 | itertools = "0.8.0" | 10 | itertools = "0.8.0" |
11 | clap = { version = "2.32.0", default-features = false } | 11 | pico-args = "0.2.0" |
12 | quote = "1.0.2" | 12 | quote = "1.0.2" |
13 | proc-macro2 = "1.0.1" | 13 | proc-macro2 = "1.0.1" |
14 | ron = "0.5.1" | 14 | ron = "0.5.1" |
diff --git a/crates/ra_tools/src/help.rs b/crates/ra_tools/src/help.rs new file mode 100644 index 000000000..6dde6c2d2 --- /dev/null +++ b/crates/ra_tools/src/help.rs | |||
@@ -0,0 +1,45 @@ | |||
1 | pub const GLOBAL_HELP: &str = "tasks | ||
2 | |||
3 | USAGE: | ||
4 | ra_tools <SUBCOMMAND> | ||
5 | |||
6 | FLAGS: | ||
7 | -h, --help Prints help information | ||
8 | |||
9 | SUBCOMMANDS: | ||
10 | format | ||
11 | format-hook | ||
12 | fuzz-tests | ||
13 | gen-syntax | ||
14 | gen-tests | ||
15 | install-ra | ||
16 | lint"; | ||
17 | |||
18 | pub const INSTALL_RA_HELP: &str = "ra_tools-install-ra | ||
19 | |||
20 | USAGE: | ||
21 | ra_tools.exe install-ra [FLAGS] | ||
22 | |||
23 | FLAGS: | ||
24 | --client-code | ||
25 | -h, --help Prints help information | ||
26 | --jemalloc | ||
27 | --server"; | ||
28 | |||
29 | pub fn print_no_param_subcommand_help(subcommand: &str) { | ||
30 | eprintln!( | ||
31 | "ra_tools-{} | ||
32 | |||
33 | USAGE: | ||
34 | ra_tools {} | ||
35 | |||
36 | FLAGS: | ||
37 | -h, --help Prints help information", | ||
38 | subcommand, subcommand | ||
39 | ); | ||
40 | } | ||
41 | |||
42 | pub const INSTALL_RA_CONFLICT: &str = | ||
43 | "error: The argument `--server` cannot be used with `--client-code` | ||
44 | |||
45 | For more information try --help"; | ||
diff --git a/crates/ra_tools/src/main.rs b/crates/ra_tools/src/main.rs index 33badf290..f96f1875f 100644 --- a/crates/ra_tools/src/main.rs +++ b/crates/ra_tools/src/main.rs | |||
@@ -1,5 +1,8 @@ | |||
1 | use clap::{App, Arg, SubCommand}; | 1 | mod help; |
2 | |||
3 | use core::fmt::Write; | ||
2 | use core::str; | 4 | use core::str; |
5 | use pico_args::Arguments; | ||
3 | use ra_tools::{ | 6 | use ra_tools::{ |
4 | gen_tests, generate_boilerplate, install_format_hook, run, run_clippy, run_fuzzer, run_rustfmt, | 7 | gen_tests, generate_boilerplate, install_format_hook, run, run_clippy, run_fuzzer, run_rustfmt, |
5 | Cmd, Overwrite, Result, | 8 | Cmd, Overwrite, Result, |
@@ -20,45 +23,95 @@ struct ServerOpt { | |||
20 | } | 23 | } |
21 | 24 | ||
22 | fn main() -> Result<()> { | 25 | fn main() -> Result<()> { |
23 | let matches = App::new("tasks") | 26 | let subcommand = match std::env::args_os().nth(1) { |
24 | .setting(clap::AppSettings::SubcommandRequiredElseHelp) | 27 | None => { |
25 | .subcommand(SubCommand::with_name("gen-syntax")) | 28 | eprintln!("{}", help::GLOBAL_HELP); |
26 | .subcommand(SubCommand::with_name("gen-tests")) | 29 | return Ok(()); |
27 | .subcommand( | 30 | } |
28 | SubCommand::with_name("install-ra") | 31 | Some(s) => s, |
29 | .arg(Arg::with_name("server").long("--server")) | 32 | }; |
30 | .arg(Arg::with_name("jemalloc").long("jemalloc")) | 33 | let mut matches = Arguments::from_vec(std::env::args_os().skip(2).collect()); |
31 | .arg(Arg::with_name("client-code").long("client-code").conflicts_with("server")), | 34 | let subcommand = &*subcommand.to_string_lossy(); |
32 | ) | 35 | match subcommand { |
33 | .alias("install-code") | 36 | "install-ra" | "install-code" => { |
34 | .subcommand(SubCommand::with_name("format")) | 37 | if matches.contains(["-h", "--help"]) { |
35 | .subcommand(SubCommand::with_name("format-hook")) | 38 | eprintln!("{}", help::INSTALL_RA_HELP); |
36 | .subcommand(SubCommand::with_name("fuzz-tests")) | 39 | return Ok(()); |
37 | .subcommand(SubCommand::with_name("lint")) | 40 | } |
38 | .get_matches(); | 41 | let server = matches.contains("--server"); |
39 | match matches.subcommand() { | 42 | let client_code = matches.contains("--client-code"); |
40 | ("install-ra", Some(matches)) => { | 43 | if server && client_code { |
44 | eprintln!("{}", help::INSTALL_RA_CONFLICT); | ||
45 | return Ok(()); | ||
46 | } | ||
47 | let jemalloc = matches.contains("--jemalloc"); | ||
48 | matches.finish().or_else(handle_extra_flags)?; | ||
41 | let opts = InstallOpt { | 49 | let opts = InstallOpt { |
42 | client: if matches.is_present("server") { None } else { Some(ClientOpt::VsCode) }, | 50 | client: if server { None } else { Some(ClientOpt::VsCode) }, |
43 | server: if matches.is_present("client-code") { | 51 | server: if client_code { None } else { Some(ServerOpt { jemalloc: jemalloc }) }, |
44 | None | ||
45 | } else { | ||
46 | Some(ServerOpt { jemalloc: matches.is_present("jemalloc") }) | ||
47 | }, | ||
48 | }; | 52 | }; |
49 | install(opts)? | 53 | install(opts)? |
50 | } | 54 | } |
51 | ("gen-tests", _) => gen_tests(Overwrite)?, | 55 | "gen-tests" => { |
52 | ("gen-syntax", _) => generate_boilerplate(Overwrite)?, | 56 | if matches.contains(["-h", "--help"]) { |
53 | ("format", _) => run_rustfmt(Overwrite)?, | 57 | help::print_no_param_subcommand_help(&subcommand); |
54 | ("format-hook", _) => install_format_hook()?, | 58 | return Ok(()); |
55 | ("lint", _) => run_clippy()?, | 59 | } |
56 | ("fuzz-tests", _) => run_fuzzer()?, | 60 | gen_tests(Overwrite)? |
57 | _ => unreachable!(), | 61 | } |
62 | "gen-syntax" => { | ||
63 | if matches.contains(["-h", "--help"]) { | ||
64 | help::print_no_param_subcommand_help(&subcommand); | ||
65 | return Ok(()); | ||
66 | } | ||
67 | generate_boilerplate(Overwrite)? | ||
68 | } | ||
69 | "format" => { | ||
70 | if matches.contains(["-h", "--help"]) { | ||
71 | help::print_no_param_subcommand_help(&subcommand); | ||
72 | return Ok(()); | ||
73 | } | ||
74 | run_rustfmt(Overwrite)? | ||
75 | } | ||
76 | "format-hook" => { | ||
77 | if matches.contains(["-h", "--help"]) { | ||
78 | help::print_no_param_subcommand_help(&subcommand); | ||
79 | return Ok(()); | ||
80 | } | ||
81 | install_format_hook()? | ||
82 | } | ||
83 | "lint" => { | ||
84 | if matches.contains(["-h", "--help"]) { | ||
85 | help::print_no_param_subcommand_help(&subcommand); | ||
86 | return Ok(()); | ||
87 | } | ||
88 | run_clippy()? | ||
89 | } | ||
90 | "fuzz-tests" => { | ||
91 | if matches.contains(["-h", "--help"]) { | ||
92 | help::print_no_param_subcommand_help(&subcommand); | ||
93 | return Ok(()); | ||
94 | } | ||
95 | run_fuzzer()? | ||
96 | } | ||
97 | _ => eprintln!("{}", help::GLOBAL_HELP), | ||
58 | } | 98 | } |
59 | Ok(()) | 99 | Ok(()) |
60 | } | 100 | } |
61 | 101 | ||
102 | fn handle_extra_flags(e: pico_args::Error) -> Result<()> { | ||
103 | if let pico_args::Error::UnusedArgsLeft(flags) = e { | ||
104 | let mut invalid_flags = String::new(); | ||
105 | for flag in flags { | ||
106 | write!(&mut invalid_flags, "{}, ", flag)?; | ||
107 | } | ||
108 | let (invalid_flags, _) = invalid_flags.split_at(invalid_flags.len() - 2); | ||
109 | Err(format!("Invalid flags: {}", invalid_flags).into()) | ||
110 | } else { | ||
111 | Err(e.to_string().into()) | ||
112 | } | ||
113 | } | ||
114 | |||
62 | fn install(opts: InstallOpt) -> Result<()> { | 115 | fn install(opts: InstallOpt) -> Result<()> { |
63 | if cfg!(target_os = "macos") { | 116 | if cfg!(target_os = "macos") { |
64 | fix_path_for_mac()? | 117 | fix_path_for_mac()? |