aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-03-01 18:12:44 +0000
committerAleksey Kladov <[email protected]>2021-03-01 19:12:43 +0000
commit4ce20b80c5ca5e0523980aa8dd95b1cc76d78d59 (patch)
treecdd4c3c2b0406548415315ccafb6312860ffa402
parent9860a396035f61a5cc9265c1104a640547bded51 (diff)
Use cli parser with auto-generated help
-rw-r--r--Cargo.lock20
-rw-r--r--xtask/Cargo.toml2
-rw-r--r--xtask/src/codegen.rs8
-rw-r--r--xtask/src/flags.rs139
-rw-r--r--xtask/src/main.rs134
-rw-r--r--xtask/src/metrics.rs8
-rw-r--r--xtask/src/pre_cache.rs4
-rw-r--r--xtask/src/release.rs14
8 files changed, 195 insertions, 134 deletions
diff --git a/Cargo.lock b/Cargo.lock
index dbd7a746e..e4468ae01 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1922,6 +1922,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1922checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3" 1922checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3"
1923 1923
1924[[package]] 1924[[package]]
1925name = "xflags"
1926version = "0.1.2"
1927source = "registry+https://github.com/rust-lang/crates.io-index"
1928checksum = "1a6292b9528efc06cb25a41b8a0814dd3a9590c0fe2cd95341fe41bbe034fafb"
1929dependencies = [
1930 "xflags-macros",
1931]
1932
1933[[package]]
1934name = "xflags-macros"
1935version = "0.1.2"
1936source = "registry+https://github.com/rust-lang/crates.io-index"
1937checksum = "ba2108d40e49a0653f2ee4eda59f51447e0cab5cc2cc197a5abd96525c6bd89e"
1938dependencies = [
1939 "proc-macro2",
1940]
1941
1942[[package]]
1925name = "xshell" 1943name = "xshell"
1926version = "0.1.8" 1944version = "0.1.8"
1927source = "registry+https://github.com/rust-lang/crates.io-index" 1945source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1942,11 +1960,11 @@ version = "0.1.0"
1942dependencies = [ 1960dependencies = [
1943 "anyhow", 1961 "anyhow",
1944 "flate2", 1962 "flate2",
1945 "pico-args",
1946 "proc-macro2", 1963 "proc-macro2",
1947 "quote", 1964 "quote",
1948 "ungrammar", 1965 "ungrammar",
1949 "walkdir", 1966 "walkdir",
1950 "write-json", 1967 "write-json",
1968 "xflags",
1951 "xshell", 1969 "xshell",
1952] 1970]
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 0455dd2eb..b17dde598 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -9,11 +9,11 @@ license = "MIT OR Apache-2.0"
9[dependencies] 9[dependencies]
10anyhow = "1.0.26" 10anyhow = "1.0.26"
11flate2 = "1.0" 11flate2 = "1.0"
12pico-args = "0.4.0"
13proc-macro2 = "1.0.8" 12proc-macro2 = "1.0.8"
14quote = "1.0.2" 13quote = "1.0.2"
15ungrammar = "=1.11" 14ungrammar = "=1.11"
16walkdir = "2.3.1" 15walkdir = "2.3.1"
17write-json = "0.1.0" 16write-json = "0.1.0"
18xshell = "0.1" 17xshell = "0.1"
18xflags = "0.1.2"
19# Avoid adding more dependencies to this crate 19# Avoid adding more dependencies to this crate
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index 743e83e76..2f56c5ad0 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -18,7 +18,7 @@ use std::{
18}; 18};
19use xshell::{cmd, pushenv, read_file, write_file}; 19use xshell::{cmd, pushenv, read_file, write_file};
20 20
21use crate::{ensure_rustfmt, project_root, Result}; 21use crate::{ensure_rustfmt, flags, project_root, Result};
22 22
23pub(crate) use self::{ 23pub(crate) use self::{
24 gen_assists_docs::{generate_assists_docs, generate_assists_tests}, 24 gen_assists_docs::{generate_assists_docs, generate_assists_tests},
@@ -35,11 +35,7 @@ pub(crate) enum Mode {
35 Verify, 35 Verify,
36} 36}
37 37
38pub(crate) struct CodegenCmd { 38impl flags::Codegen {
39 pub(crate) features: bool,
40}
41
42impl CodegenCmd {
43 pub(crate) fn run(self) -> Result<()> { 39 pub(crate) fn run(self) -> Result<()> {
44 if self.features { 40 if self.features {
45 generate_lint_completions(Mode::Overwrite)?; 41 generate_lint_completions(Mode::Overwrite)?;
diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs
new file mode 100644
index 000000000..ce72879a1
--- /dev/null
+++ b/xtask/src/flags.rs
@@ -0,0 +1,139 @@
1#![allow(unreachable_pub)]
2
3xflags::args_parser! {
4 /// Run custom build command.
5 cmd xtask {
6 default cmd help {
7 /// Print help information.
8 optional -h, --help
9 }
10
11 /// Install rust-analyzer server or editor plugin.
12 cmd install {
13 /// Install only VS Code plugin.
14 optional --client
15 /// One of 'code', 'code-exploration', 'code-insiders', 'codium', or 'code-oss'.
16 optional --code-bin name: String
17
18 /// Install only the language server.
19 optional --server
20 /// Use mimalloc allocator for server
21 optional --mimalloc
22 /// Use jemalloc allocator for server
23 optional --jemalloc
24 }
25
26 cmd codegen {
27 optional --features
28 }
29
30 cmd lint {}
31 cmd fuzz-tests {}
32 cmd pre-cache {}
33
34 cmd release {
35 optional --dry-run
36 }
37 cmd promote {
38 optional --dry-run
39 }
40 cmd dist {
41 optional --nightly
42 optional --client version: String
43 }
44 cmd metrics {
45 optional --dry-run
46 }
47 /// Builds a benchmark version of rust-analyzer and puts it into `./target`.
48 cmd bb
49 required suffix : String
50 {}
51 }
52}
53
54// generated start
55// The following code is generated by `xflags` macro.
56// Run `env XFLAGS_DUMP= cargo build` to regenerate.
57#[derive(Debug)]
58pub struct Xtask {
59 pub subcommand: XtaskCmd,
60}
61
62#[derive(Debug)]
63pub enum XtaskCmd {
64 Help(Help),
65 Install(Install),
66 Codegen(Codegen),
67 Lint(Lint),
68 FuzzTests(FuzzTests),
69 PreCache(PreCache),
70 Release(Release),
71 Promote(Promote),
72 Dist(Dist),
73 Metrics(Metrics),
74 Bb(Bb),
75}
76
77#[derive(Debug)]
78pub struct Help {
79 pub help: bool,
80}
81
82#[derive(Debug)]
83pub struct Install {
84 pub client: bool,
85 pub code_bin: Option<String>,
86 pub server: bool,
87 pub mimalloc: bool,
88 pub jemalloc: bool,
89}
90
91#[derive(Debug)]
92pub struct Codegen {
93 pub features: bool,
94}
95
96#[derive(Debug)]
97pub struct Lint {}
98
99#[derive(Debug)]
100pub struct FuzzTests {}
101
102#[derive(Debug)]
103pub struct PreCache {}
104
105#[derive(Debug)]
106pub struct Release {
107 pub dry_run: bool,
108}
109
110#[derive(Debug)]
111pub struct Promote {
112 pub dry_run: bool,
113}
114
115#[derive(Debug)]
116pub struct Dist {
117 pub nightly: bool,
118 pub client: Option<String>,
119}
120
121#[derive(Debug)]
122pub struct Metrics {
123 pub dry_run: bool,
124}
125
126#[derive(Debug)]
127pub struct Bb {
128 pub suffix: String,
129}
130
131impl Xtask {
132 pub const HELP: &'static str = Self::_HELP;
133
134 pub fn from_env() -> xflags::Result<Self> {
135 let mut p = xflags::rt::Parser::new_from_env();
136 Self::_parse(&mut p)
137 }
138}
139// generated end
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 84b17ce23..e419db7a7 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -7,6 +7,8 @@
7//! 7//!
8//! This binary is integrated into the `cargo` command line by using an alias in 8//! This binary is integrated into the `cargo` command line by using an alias in
9//! `.cargo/config`. 9//! `.cargo/config`.
10mod flags;
11
10mod codegen; 12mod codegen;
11mod ast_src; 13mod ast_src;
12#[cfg(test)] 14#[cfg(test)]
@@ -19,8 +21,6 @@ mod metrics;
19mod pre_cache; 21mod pre_cache;
20 22
21use anyhow::{bail, Result}; 23use anyhow::{bail, Result};
22use codegen::CodegenCmd;
23use pico_args::Arguments;
24use std::{ 24use std::{
25 env, 25 env,
26 path::{Path, PathBuf}, 26 path::{Path, PathBuf},
@@ -32,42 +32,19 @@ use crate::{
32 codegen::Mode, 32 codegen::Mode,
33 dist::DistCmd, 33 dist::DistCmd,
34 install::{InstallCmd, Malloc, ServerOpt}, 34 install::{InstallCmd, Malloc, ServerOpt},
35 metrics::MetricsCmd,
36 pre_cache::PreCacheCmd,
37 release::{PromoteCmd, ReleaseCmd},
38}; 35};
39 36
40fn main() -> Result<()> { 37fn main() -> Result<()> {
41 let _d = pushd(project_root())?; 38 let _d = pushd(project_root())?;
42 39
43 let mut args = Arguments::from_env(); 40 let flags = flags::Xtask::from_env()?;
44 let subcommand = args.subcommand()?.unwrap_or_default(); 41 match flags.subcommand {
45 42 flags::XtaskCmd::Help(_) => {
46 match subcommand.as_str() { 43 println!("{}", flags::Xtask::HELP);
47 "install" => { 44 return Ok(());
48 if args.contains(["-h", "--help"]) { 45 }
49 eprintln!( 46 flags::XtaskCmd::Install(flags) => {
50 "\ 47 if flags.server && flags.client {
51cargo xtask install
52Install rust-analyzer server or editor plugin.
53
54USAGE:
55 cargo xtask install [FLAGS]
56
57FLAGS:
58 --client[=CLIENT] Install only VS Code plugin.
59 CLIENT is one of 'code', 'code-exploration', 'code-insiders', 'codium', or 'code-oss'
60 --server Install only the language server
61 --mimalloc Use mimalloc allocator for server
62 --jemalloc Use jemalloc allocator for server
63 -h, --help Prints help information
64 "
65 );
66 return Ok(());
67 }
68 let server = args.contains("--server");
69 let client_code = args.contains("--client");
70 if server && client_code {
71 eprintln!( 48 eprintln!(
72 "error: The argument `--server` cannot be used with `--client`\n\n\ 49 "error: The argument `--server` cannot be used with `--client`\n\n\
73 For more information try --help" 50 For more information try --help"
@@ -75,102 +52,43 @@ FLAGS:
75 return Ok(()); 52 return Ok(());
76 } 53 }
77 54
78 let malloc = if args.contains("--mimalloc") { 55 let malloc = if flags.mimalloc {
79 Malloc::Mimalloc 56 Malloc::Mimalloc
80 } else if args.contains("--jemalloc") { 57 } else if flags.jemalloc {
81 Malloc::Jemalloc 58 Malloc::Jemalloc
82 } else { 59 } else {
83 Malloc::System 60 Malloc::System
84 }; 61 };
85 62
86 let client_opt = args.opt_value_from_str("--client")?; 63 let client_bin = flags.code_bin.map(|it| it.parse()).transpose()?;
87
88 finish_args(args)?;
89 64
90 InstallCmd { 65 InstallCmd {
91 client: if server { None } else { Some(client_opt.unwrap_or_default()) }, 66 client: if flags.server { None } else { client_bin },
92 server: if client_code { None } else { Some(ServerOpt { malloc }) }, 67 server: if flags.client { None } else { Some(ServerOpt { malloc }) },
93 } 68 }
94 .run() 69 .run()
95 } 70 }
96 "codegen" => { 71 flags::XtaskCmd::Codegen(cmd) => cmd.run(),
97 let features = args.contains("--features"); 72 flags::XtaskCmd::Lint(_) => run_clippy(),
98 finish_args(args)?; 73 flags::XtaskCmd::FuzzTests(_) => run_fuzzer(),
99 CodegenCmd { features }.run() 74 flags::XtaskCmd::PreCache(cmd) => cmd.run(),
100 } 75 flags::XtaskCmd::Release(cmd) => cmd.run(),
101 "lint" => { 76 flags::XtaskCmd::Promote(cmd) => cmd.run(),
102 finish_args(args)?; 77 flags::XtaskCmd::Dist(flags) => {
103 run_clippy() 78 DistCmd { nightly: flags.nightly, client_version: flags.client }.run()
104 }
105 "fuzz-tests" => {
106 finish_args(args)?;
107 run_fuzzer()
108 }
109 "pre-cache" => {
110 finish_args(args)?;
111 PreCacheCmd.run()
112 } 79 }
113 "release" => { 80 flags::XtaskCmd::Metrics(cmd) => cmd.run(),
114 let dry_run = args.contains("--dry-run"); 81 flags::XtaskCmd::Bb(cmd) => {
115 finish_args(args)?;
116 ReleaseCmd { dry_run }.run()
117 }
118 "promote" => {
119 let dry_run = args.contains("--dry-run");
120 finish_args(args)?;
121 PromoteCmd { dry_run }.run()
122 }
123 "dist" => {
124 let nightly = args.contains("--nightly");
125 let client_version: Option<String> = args.opt_value_from_str("--client")?;
126 finish_args(args)?;
127 DistCmd { nightly, client_version }.run()
128 }
129 "metrics" => {
130 let dry_run = args.contains("--dry-run");
131 finish_args(args)?;
132 MetricsCmd { dry_run }.run()
133 }
134 "bb" => {
135 let suffix: String = args.free_from_str()?;
136 finish_args(args)?;
137 { 82 {
138 let _d = pushd("./crates/rust-analyzer")?; 83 let _d = pushd("./crates/rust-analyzer")?;
139 cmd!("cargo build --release --features jemalloc").run()?; 84 cmd!("cargo build --release --features jemalloc").run()?;
140 } 85 }
141 cp("./target/release/rust-analyzer", format!("./target/rust-analyzer-{}", suffix))?; 86 cp("./target/release/rust-analyzer", format!("./target/rust-analyzer-{}", cmd.suffix))?;
142 Ok(())
143 }
144 _ => {
145 eprintln!(
146 "\
147cargo xtask
148Run custom build command.
149
150USAGE:
151 cargo xtask <SUBCOMMAND>
152
153SUBCOMMANDS:
154 fuzz-tests
155 codegen
156 install
157 lint
158 dist
159 promote
160 bb"
161 );
162 Ok(()) 87 Ok(())
163 } 88 }
164 } 89 }
165} 90}
166 91
167fn finish_args(args: Arguments) -> Result<()> {
168 if !args.finish().is_empty() {
169 bail!("Unused arguments.");
170 }
171 Ok(())
172}
173
174fn project_root() -> PathBuf { 92fn project_root() -> PathBuf {
175 Path::new( 93 Path::new(
176 &env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| env!("CARGO_MANIFEST_DIR").to_owned()), 94 &env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| env!("CARGO_MANIFEST_DIR").to_owned()),
diff --git a/xtask/src/metrics.rs b/xtask/src/metrics.rs
index babc2a6d4..eb58b3274 100644
--- a/xtask/src/metrics.rs
+++ b/xtask/src/metrics.rs
@@ -9,13 +9,11 @@ use std::{
9use anyhow::{bail, format_err, Result}; 9use anyhow::{bail, format_err, Result};
10use xshell::{cmd, mkdir_p, pushd, pushenv, read_file, rm_rf}; 10use xshell::{cmd, mkdir_p, pushd, pushenv, read_file, rm_rf};
11 11
12type Unit = String; 12use crate::flags;
13 13
14pub(crate) struct MetricsCmd { 14type Unit = String;
15 pub(crate) dry_run: bool,
16}
17 15
18impl MetricsCmd { 16impl flags::Metrics {
19 pub(crate) fn run(self) -> Result<()> { 17 pub(crate) fn run(self) -> Result<()> {
20 let mut metrics = Metrics::new()?; 18 let mut metrics = Metrics::new()?;
21 if !self.dry_run { 19 if !self.dry_run {
diff --git a/xtask/src/pre_cache.rs b/xtask/src/pre_cache.rs
index 54f4a95a9..b456224fd 100644
--- a/xtask/src/pre_cache.rs
+++ b/xtask/src/pre_cache.rs
@@ -6,9 +6,9 @@ use std::{
6use anyhow::Result; 6use anyhow::Result;
7use xshell::rm_rf; 7use xshell::rm_rf;
8 8
9pub(crate) struct PreCacheCmd; 9use crate::flags;
10 10
11impl PreCacheCmd { 11impl flags::PreCache {
12 /// Cleans the `./target` dir after the build such that only 12 /// Cleans the `./target` dir after the build such that only
13 /// dependencies are cached on CI. 13 /// dependencies are cached on CI.
14 pub(crate) fn run(self) -> Result<()> { 14 pub(crate) fn run(self) -> Result<()> {
diff --git a/xtask/src/release.rs b/xtask/src/release.rs
index 5008881e4..d8d86fd63 100644
--- a/xtask/src/release.rs
+++ b/xtask/src/release.rs
@@ -2,13 +2,9 @@ use std::fmt::Write;
2 2
3use xshell::{cmd, cp, pushd, read_dir, write_file}; 3use xshell::{cmd, cp, pushd, read_dir, write_file};
4 4
5use crate::{codegen, date_iso, is_release_tag, project_root, Mode, Result}; 5use crate::{codegen, date_iso, flags, is_release_tag, project_root, Mode, Result};
6 6
7pub(crate) struct ReleaseCmd { 7impl flags::Release {
8 pub(crate) dry_run: bool,
9}
10
11impl ReleaseCmd {
12 pub(crate) fn run(self) -> Result<()> { 8 pub(crate) fn run(self) -> Result<()> {
13 if !self.dry_run { 9 if !self.dry_run {
14 cmd!("git switch release").run()?; 10 cmd!("git switch release").run()?;
@@ -86,11 +82,7 @@ https://github.com/sponsors/rust-analyzer[GitHub Sponsors].
86 } 82 }
87} 83}
88 84
89pub(crate) struct PromoteCmd { 85impl flags::Promote {
90 pub(crate) dry_run: bool,
91}
92
93impl PromoteCmd {
94 pub(crate) fn run(self) -> Result<()> { 86 pub(crate) fn run(self) -> Result<()> {
95 let _dir = pushd("../rust-rust-analyzer")?; 87 let _dir = pushd("../rust-rust-analyzer")?;
96 cmd!("git switch master").run()?; 88 cmd!("git switch master").run()?;