diff options
-rw-r--r-- | Cargo.lock | 8 | ||||
-rw-r--r-- | crates/ra_cli/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/ra_cli/src/help.rs | 96 | ||||
-rw-r--r-- | crates/ra_cli/src/main.rs | 186 |
4 files changed, 213 insertions, 79 deletions
diff --git a/Cargo.lock b/Cargo.lock index 9092a87d3..f4b5d12a3 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -838,6 +838,11 @@ dependencies = [ | |||
838 | ] | 838 | ] |
839 | 839 | ||
840 | [[package]] | 840 | [[package]] |
841 | name = "pico-args" | ||
842 | version = "0.2.0" | ||
843 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
844 | |||
845 | [[package]] | ||
841 | name = "ppv-lite86" | 846 | name = "ppv-lite86" |
842 | version = "0.2.5" | 847 | version = "0.2.5" |
843 | source = "registry+https://github.com/rust-lang/crates.io-index" | 848 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -930,9 +935,9 @@ dependencies = [ | |||
930 | name = "ra_cli" | 935 | name = "ra_cli" |
931 | version = "0.1.0" | 936 | version = "0.1.0" |
932 | dependencies = [ | 937 | dependencies = [ |
933 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
934 | "flexi_logger 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", | 938 | "flexi_logger 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", |
935 | "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", | 939 | "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |
940 | "pico-args 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
936 | "ra_batch 0.1.0", | 941 | "ra_batch 0.1.0", |
937 | "ra_db 0.1.0", | 942 | "ra_db 0.1.0", |
938 | "ra_hir 0.1.0", | 943 | "ra_hir 0.1.0", |
@@ -1873,6 +1878,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1873 | "checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" | 1878 | "checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" |
1874 | "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" | 1879 | "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" |
1875 | "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" | 1880 | "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" |
1881 | "checksum pico-args 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fce25154205cf4360b456fd7d48994afe20663b77e3bd3d0a353a2fccf7f22c" | ||
1876 | "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" | 1882 | "checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" |
1877 | "checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8" | 1883 | "checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8" |
1878 | "checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" | 1884 | "checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" |
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..bf31472ac --- /dev/null +++ b/crates/ra_cli/src/help.rs | |||
@@ -0,0 +1,96 @@ | |||
1 | pub fn print_global_help() { | ||
2 | println!( | ||
3 | "ra-cli | ||
4 | |||
5 | USAGE: | ||
6 | ra_cli <SUBCOMMAND> | ||
7 | |||
8 | FLAGS: | ||
9 | -h, --help Prints help information | ||
10 | |||
11 | SUBCOMMANDS: | ||
12 | analysis-bench | ||
13 | analysis-stats | ||
14 | highlight | ||
15 | parse | ||
16 | symbols" | ||
17 | ) | ||
18 | } | ||
19 | |||
20 | pub fn print_analysis_bench_help() { | ||
21 | println!( | ||
22 | "ra_cli-analysis-bench | ||
23 | |||
24 | USAGE: | ||
25 | ra_cli analysis-bench [FLAGS] [OPTIONS] [PATH] | ||
26 | |||
27 | FLAGS: | ||
28 | -h, --help Prints help information | ||
29 | -v, --verbose | ||
30 | |||
31 | OPTIONS: | ||
32 | --complete <PATH:LINE:COLUMN> Compute completions at this location | ||
33 | --highlight <PATH> Hightlight this file | ||
34 | |||
35 | ARGS: | ||
36 | <PATH> Project to analyse" | ||
37 | ) | ||
38 | } | ||
39 | |||
40 | pub fn print_analysis_stats_help() { | ||
41 | println!( | ||
42 | "ra-cli-analysis-stats | ||
43 | |||
44 | USAGE: | ||
45 | ra_cli analysis-stats [FLAGS] [OPTIONS] [PATH] | ||
46 | |||
47 | FLAGS: | ||
48 | -h, --help Prints help information | ||
49 | --memory-usage | ||
50 | -v, --verbose | ||
51 | |||
52 | OPTIONS: | ||
53 | -o <ONLY> | ||
54 | |||
55 | ARGS: | ||
56 | <PATH>" | ||
57 | ) | ||
58 | } | ||
59 | |||
60 | pub fn print_highlight_help() { | ||
61 | println!( | ||
62 | "ra-cli-highlight | ||
63 | |||
64 | USAGE: | ||
65 | ra_cli highlight [FLAGS] | ||
66 | |||
67 | FLAGS: | ||
68 | -h, --help Prints help information | ||
69 | -r, --rainbow" | ||
70 | ) | ||
71 | } | ||
72 | |||
73 | pub fn print_symbols_help() { | ||
74 | println!( | ||
75 | "ra-cli-symbols | ||
76 | |||
77 | USAGE: | ||
78 | ra_cli highlight [FLAGS] | ||
79 | |||
80 | FLAGS: | ||
81 | -h, --help Prints help inforamtion" | ||
82 | ) | ||
83 | } | ||
84 | |||
85 | pub fn print_parse_help() { | ||
86 | println!( | ||
87 | "ra-cli-parse | ||
88 | |||
89 | USAGE: | ||
90 | ra_cli parse [FLAGS] | ||
91 | |||
92 | FLAGS: | ||
93 | -h, --help Prints help inforamtion | ||
94 | --no-dump" | ||
95 | ) | ||
96 | } | ||
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs index de8191ca3..9e6f869c1 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,93 +14,124 @@ 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 = std::env::args_os().nth(1); |
18 | .subcommand(SubCommand::with_name("parse").arg(Arg::with_name("no-dump").long("--no-dump"))) | 19 | if subcommand.is_none() { |
19 | .subcommand(SubCommand::with_name("symbols")) | 20 | help::print_global_help(); |
20 | .subcommand( | 21 | return Ok(()); |
21 | SubCommand::with_name("highlight") | 22 | } |
22 | .arg(Arg::with_name("rainbow").short("r").long("rainbow")), | 23 | let subcommand = subcommand.unwrap(); |
23 | ) | 24 | let mut args: Vec<_> = std::env::args_os().collect(); |
24 | .subcommand( | 25 | let mut matches = Arguments::from_vec(args.drain(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 | help::print_parse_help(); |
30 | ) | 31 | return Ok(()); |
31 | .subcommand( | 32 | } else { |
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 | let _p = profile("parsing"); |
36 | .long("highlight") | 37 | let file = file()?; |
37 | .takes_value(true) | 38 | if !no_dump { |
38 | .conflicts_with("complete") | 39 | println!("{:#?}", file.syntax()); |
39 | .value_name("PATH") | 40 | } |
40 | .help("highlight this file"), | 41 | std::mem::forget(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"); | ||
56 | let file = file()?; | ||
57 | if !matches.is_present("no-dump") { | ||
58 | println!("{:#?}", file.syntax()); | ||
59 | } | 42 | } |
60 | std::mem::forget(file); | ||
61 | } | 43 | } |
62 | ("symbols", _) => { | 44 | "symbols" => { |
63 | let file = file()?; | 45 | if matches.contains(["-h", "--help"]) { |
64 | for s in file_structure(&file) { | 46 | help::print_symbols_help(); |
65 | println!("{:?}", s); | 47 | return Ok(()); |
48 | } else { | ||
49 | matches.finish().or_else(handle_extra_flags)?; | ||
50 | let file = file()?; | ||
51 | for s in file_structure(&file) { | ||
52 | println!("{:?}", s); | ||
53 | } | ||
66 | } | 54 | } |
67 | } | 55 | } |
68 | ("highlight", Some(matches)) => { | 56 | "highlight" => { |
69 | let (analysis, file_id) = Analysis::from_single_file(read_stdin()?); | 57 | if matches.contains(["-h", "--help"]) { |
70 | let html = analysis.highlight_as_html(file_id, matches.is_present("rainbow")).unwrap(); | 58 | help::print_highlight_help(); |
71 | println!("{}", html); | 59 | return Ok(()); |
60 | } else { | ||
61 | let rainbow_opt = matches.contains(["-r", "--rainbow"]); | ||
62 | matches.finish().or_else(handle_extra_flags)?; | ||
63 | let (analysis, file_id) = Analysis::from_single_file(read_stdin()?); | ||
64 | let html = analysis.highlight_as_html(file_id, rainbow_opt).unwrap(); | ||
65 | println!("{}", html); | ||
66 | } | ||
72 | } | 67 | } |
73 | ("analysis-stats", Some(matches)) => { | 68 | "analysis-stats" => { |
74 | let verbose = matches.is_present("verbose"); | 69 | if matches.contains(["-h", "--help"]) { |
75 | let memory_usage = matches.is_present("memory-usage"); | 70 | help::print_analysis_stats_help(); |
76 | let path = matches.value_of("path").unwrap_or(""); | 71 | return Ok(()); |
77 | let only = matches.value_of("only"); | 72 | } else { |
78 | analysis_stats::run(verbose, memory_usage, path.as_ref(), only)?; | 73 | let verbose = matches.contains(["-v", "--verbose"]); |
74 | let memory_usage = matches.contains("--memory-usage"); | ||
75 | let path = matches.value_from_str("--path")?.unwrap_or("".to_string()); | ||
76 | let only = matches.value_from_str(["-o", "--only"])?.map(|v: String| v.to_owned()); | ||
77 | matches.finish().or_else(handle_extra_flags)?; | ||
78 | analysis_stats::run( | ||
79 | verbose, | ||
80 | memory_usage, | ||
81 | path.as_ref(), | ||
82 | only.as_ref().map(String::as_ref), | ||
83 | )?; | ||
84 | } | ||
79 | } | 85 | } |
80 | ("analysis-bench", Some(matches)) => { | 86 | "analysis-bench" => { |
81 | let verbose = matches.is_present("verbose"); | 87 | if matches.contains(["-h", "--help"]) { |
82 | let path = matches.value_of("path").unwrap_or(""); | 88 | help::print_analysis_bench_help(); |
83 | let op = if let Some(path) = matches.value_of("highlight") { | 89 | return Ok(()); |
84 | analysis_bench::Op::Highlight { path: path.into() } | ||
85 | } else if let Some(path_line_col) = matches.value_of("complete") { | ||
86 | let (path_line, column) = rsplit_at_char(path_line_col, ':')?; | ||
87 | let (path, line) = rsplit_at_char(path_line, ':')?; | ||
88 | analysis_bench::Op::Complete { | ||
89 | path: path.into(), | ||
90 | line: line.parse()?, | ||
91 | column: column.parse()?, | ||
92 | } | ||
93 | } else { | 90 | } else { |
94 | panic!("either --highlight or --complete must be set") | 91 | let verbose = matches.contains(["-v", "--verbose"]); |
95 | }; | 92 | let path = matches.value_from_str("--path")?.unwrap_or("".to_string()); |
96 | analysis_bench::run(verbose, path.as_ref(), op)?; | 93 | let highlight_path = matches.value_from_str("--highlight")?; |
94 | let complete_path = matches.value_from_str("--complete")?; | ||
95 | if highlight_path.is_some() && complete_path.is_some() { | ||
96 | panic!("either --highlight or --complete must be set, not both") | ||
97 | } | ||
98 | let op = if let Some(path) = highlight_path { | ||
99 | let path: String = path; | ||
100 | analysis_bench::Op::Highlight { path: path.into() } | ||
101 | } else if let Some(path_line_col) = complete_path { | ||
102 | let path_line_col: String = path_line_col; | ||
103 | let (path_line, column) = rsplit_at_char(path_line_col.as_str(), ':')?; | ||
104 | let (path, line) = rsplit_at_char(path_line, ':')?; | ||
105 | analysis_bench::Op::Complete { | ||
106 | path: path.into(), | ||
107 | line: line.parse()?, | ||
108 | column: column.parse()?, | ||
109 | } | ||
110 | } else { | ||
111 | panic!("either --highlight or --complete must be set") | ||
112 | }; | ||
113 | matches.finish().or_else(handle_extra_flags)?; | ||
114 | analysis_bench::run(verbose, path.as_ref(), op)?; | ||
115 | } | ||
97 | } | 116 | } |
98 | _ => unreachable!(), | 117 | _ => help::print_global_help(), |
99 | } | 118 | } |
100 | Ok(()) | 119 | Ok(()) |
101 | } | 120 | } |
102 | 121 | ||
122 | fn handle_extra_flags(e: pico_args::Error) -> Result<()> { | ||
123 | if let pico_args::Error::UnusedArgsLeft(flags) = e { | ||
124 | let mut invalid_flags = String::new(); | ||
125 | for flag in flags { | ||
126 | write!(&mut invalid_flags, "{}, ", flag).expect("Error on write"); | ||
127 | } | ||
128 | let (invalid_flags, _) = invalid_flags.split_at(invalid_flags.len() - 2); | ||
129 | Err(format!("Invalid flags: {}", invalid_flags).into()) | ||
130 | } else { | ||
131 | Err(e.to_string().into()) | ||
132 | } | ||
133 | } | ||
134 | |||
103 | fn file() -> Result<SourceFile> { | 135 | fn file() -> Result<SourceFile> { |
104 | let text = read_stdin()?; | 136 | let text = read_stdin()?; |
105 | Ok(SourceFile::parse(&text).tree()) | 137 | Ok(SourceFile::parse(&text).tree()) |