aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock30
-rw-r--r--crates/ra_cli/Cargo.toml2
-rw-r--r--crates/ra_cli/src/help.rs72
-rw-r--r--crates/ra_cli/src/main.rs143
-rw-r--r--crates/ra_tools/Cargo.toml2
-rw-r--r--crates/ra_tools/src/help.rs45
-rw-r--r--crates/ra_tools/src/main.rs117
7 files changed, 297 insertions, 114 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6f1e4128b..4e08a0bd1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -185,16 +185,6 @@ dependencies = [
185] 185]
186 186
187[[package]] 187[[package]]
188name = "clap"
189version = "2.33.0"
190source = "registry+https://github.com/rust-lang/crates.io-index"
191dependencies = [
192 "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
193 "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
194 "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
195]
196
197[[package]]
198name = "clicolors-control" 188name = "clicolors-control"
199version = "1.0.1" 189version = "1.0.1"
200source = "registry+https://github.com/rust-lang/crates.io-index" 190source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -838,6 +828,11 @@ dependencies = [
838] 828]
839 829
840[[package]] 830[[package]]
831name = "pico-args"
832version = "0.2.0"
833source = "registry+https://github.com/rust-lang/crates.io-index"
834
835[[package]]
841name = "ppv-lite86" 836name = "ppv-lite86"
842version = "0.2.5" 837version = "0.2.5"
843source = "registry+https://github.com/rust-lang/crates.io-index" 838source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -930,9 +925,9 @@ dependencies = [
930name = "ra_cli" 925name = "ra_cli"
931version = "0.1.0" 926version = "0.1.0"
932dependencies = [ 927dependencies = [
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)", 928 "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)", 929 "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
930 "pico-args 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
936 "ra_batch 0.1.0", 931 "ra_batch 0.1.0",
937 "ra_db 0.1.0", 932 "ra_db 0.1.0",
938 "ra_hir 0.1.0", 933 "ra_hir 0.1.0",
@@ -1112,8 +1107,8 @@ dependencies = [
1112name = "ra_tools" 1107name = "ra_tools"
1113version = "0.1.0" 1108version = "0.1.0"
1114dependencies = [ 1109dependencies = [
1115 "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
1116 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1110 "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1111 "pico-args 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1117 "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1112 "proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1118 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1113 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1119 "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1114 "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1595,14 +1590,6 @@ version = "0.1.9"
1595source = "registry+https://github.com/rust-lang/crates.io-index" 1590source = "registry+https://github.com/rust-lang/crates.io-index"
1596 1591
1597[[package]] 1592[[package]]
1598name = "textwrap"
1599version = "0.11.0"
1600source = "registry+https://github.com/rust-lang/crates.io-index"
1601dependencies = [
1602 "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
1603]
1604
1605[[package]]
1606name = "thread_local" 1593name = "thread_local"
1607version = "0.3.6" 1594version = "0.3.6"
1608source = "registry+https://github.com/rust-lang/crates.io-index" 1595source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1796,7 +1783,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1796"checksum chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git)" = "<none>" 1783"checksum chalk-rust-ir 0.1.0 (git+https://github.com/rust-lang/chalk.git)" = "<none>"
1797"checksum chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git)" = "<none>" 1784"checksum chalk-solve 0.1.0 (git+https://github.com/rust-lang/chalk.git)" = "<none>"
1798"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" 1785"checksum chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68"
1799"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
1800"checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" 1786"checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e"
1801"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1787"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
1802"checksum console 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b147390a412132d75d10dd3b7b175a69cf5fd95032f7503c7091b8831ba10242" 1788"checksum console 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b147390a412132d75d10dd3b7b175a69cf5fd95032f7503c7091b8831ba10242"
@@ -1874,6 +1860,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1874"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" 1860"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5"
1875"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1861"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
1876"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" 1862"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
1863"checksum pico-args 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2fce25154205cf4360b456fd7d48994afe20663b77e3bd3d0a353a2fccf7f22c"
1877"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" 1864"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
1878"checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8" 1865"checksum proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e688f31d92ffd7c1ddc57a1b4e6d773c0f2a14ee437a4b0a4f5a69c80eb221c8"
1879"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95" 1866"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95"
@@ -1931,7 +1918,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1931"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 1918"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
1932"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" 1919"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
1933"checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579" 1920"checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579"
1934"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
1935"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" 1921"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
1936"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" 1922"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865"
1937"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" 1923"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
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"]
6publish = false 6publish = false
7 7
8[dependencies] 8[dependencies]
9clap = { version = "2.32.0", default-features = false } 9pico-args = "0.2.0"
10flexi_logger = "0.14.0" 10flexi_logger = "0.14.0"
11indicatif = "0.11.0" 11indicatif = "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 @@
1pub const GLOBAL_HELP: &str = "ra-cli
2
3USAGE:
4 ra_cli <SUBCOMMAND>
5
6FLAGS:
7 -h, --help Prints help information
8
9SUBCOMMANDS:
10 analysis-bench
11 analysis-stats
12 highlight
13 parse
14 symbols";
15
16pub const ANALYSIS_BENCH_HELP: &str = "ra_cli-analysis-bench
17
18USAGE:
19 ra_cli analysis-bench [FLAGS] [OPTIONS] [PATH]
20
21FLAGS:
22 -h, --help Prints help information
23 -v, --verbose
24
25OPTIONS:
26 --complete <PATH:LINE:COLUMN> Compute completions at this location
27 --highlight <PATH> Hightlight this file
28
29ARGS:
30 <PATH> Project to analyse";
31
32pub const ANALYSIS_STATS_HELP: &str = "ra-cli-analysis-stats
33
34USAGE:
35 ra_cli analysis-stats [FLAGS] [OPTIONS] [PATH]
36
37FLAGS:
38 -h, --help Prints help information
39 --memory-usage
40 -v, --verbose
41
42OPTIONS:
43 -o <ONLY>
44
45ARGS:
46 <PATH>";
47
48pub const HIGHLIGHT_HELP: &str = "ra-cli-highlight
49
50USAGE:
51 ra_cli highlight [FLAGS]
52
53FLAGS:
54 -h, --help Prints help information
55 -r, --rainbow";
56
57pub const SYMBOLS_HELP: &str = "ra-cli-symbols
58
59USAGE:
60 ra_cli highlight [FLAGS]
61
62FLAGS:
63 -h, --help Prints help inforamtion";
64
65pub const PARSE_HELP: &str = "ra-cli-parse
66
67USAGE:
68 ra_cli parse [FLAGS]
69
70FLAGS:
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 @@
1mod analysis_stats; 1mod analysis_stats;
2mod analysis_bench; 2mod analysis_bench;
3mod help;
3 4
4use std::{error::Error, io::Read}; 5use std::{error::Error, fmt::Write, io::Read};
5 6
6use clap::{App, Arg, SubCommand};
7use flexi_logger::Logger; 7use flexi_logger::Logger;
8use pico_args::Arguments;
8use ra_ide_api::{file_structure, Analysis}; 9use ra_ide_api::{file_structure, Analysis};
9use ra_prof::profile; 10use ra_prof::profile;
10use ra_syntax::{AstNode, SourceFile}; 11use ra_syntax::{AstNode, SourceFile};
@@ -13,77 +14,89 @@ type Result<T> = std::result::Result<T, Box<dyn Error + Send + Sync>>;
13 14
14fn main() -> Result<()> { 15fn 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
117fn 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
103fn file() -> Result<SourceFile> { 130fn 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]
9walkdir = "2.1.3" 9walkdir = "2.1.3"
10itertools = "0.8.0" 10itertools = "0.8.0"
11clap = { version = "2.32.0", default-features = false } 11pico-args = "0.2.0"
12quote = "1.0.2" 12quote = "1.0.2"
13proc-macro2 = "1.0.1" 13proc-macro2 = "1.0.1"
14ron = "0.5.1" 14ron = "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 @@
1pub const GLOBAL_HELP: &str = "tasks
2
3USAGE:
4 ra_tools <SUBCOMMAND>
5
6FLAGS:
7 -h, --help Prints help information
8
9SUBCOMMANDS:
10 format
11 format-hook
12 fuzz-tests
13 gen-syntax
14 gen-tests
15 install-ra
16 lint";
17
18pub const INSTALL_RA_HELP: &str = "ra_tools-install-ra
19
20USAGE:
21 ra_tools.exe install-ra [FLAGS]
22
23FLAGS:
24 --client-code
25 -h, --help Prints help information
26 --jemalloc
27 --server";
28
29pub fn print_no_param_subcommand_help(subcommand: &str) {
30 eprintln!(
31 "ra_tools-{}
32
33USAGE:
34 ra_tools {}
35
36FLAGS:
37 -h, --help Prints help information",
38 subcommand, subcommand
39 );
40}
41
42pub const INSTALL_RA_CONFLICT: &str =
43 "error: The argument `--server` cannot be used with `--client-code`
44
45For 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 @@
1use clap::{App, Arg, SubCommand}; 1mod help;
2
3use core::fmt::Write;
2use core::str; 4use core::str;
5use pico_args::Arguments;
3use ra_tools::{ 6use 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
22fn main() -> Result<()> { 25fn 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
102fn 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
62fn install(opts: InstallOpt) -> Result<()> { 115fn 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()?