mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Merge #7835
7835: Use cli parser with auto-generated help r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
10a57b8109
8 changed files with 195 additions and 134 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -1912,6 +1912,24 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06069a848f95fceae3e5e03c0ddc8cb78452b56654ee0c8e68f938cf790fb9e3"
|
||||
|
||||
[[package]]
|
||||
name = "xflags"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a6292b9528efc06cb25a41b8a0814dd3a9590c0fe2cd95341fe41bbe034fafb"
|
||||
dependencies = [
|
||||
"xflags-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xflags-macros"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba2108d40e49a0653f2ee4eda59f51447e0cab5cc2cc197a5abd96525c6bd89e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xshell"
|
||||
version = "0.1.9"
|
||||
|
@ -1933,11 +1951,11 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"flate2",
|
||||
"pico-args",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"ungrammar",
|
||||
"walkdir",
|
||||
"write-json",
|
||||
"xflags",
|
||||
"xshell",
|
||||
]
|
||||
|
|
|
@ -9,11 +9,11 @@ license = "MIT OR Apache-2.0"
|
|||
[dependencies]
|
||||
anyhow = "1.0.26"
|
||||
flate2 = "1.0"
|
||||
pico-args = "0.4.0"
|
||||
proc-macro2 = "1.0.8"
|
||||
quote = "1.0.2"
|
||||
ungrammar = "=1.11"
|
||||
walkdir = "2.3.1"
|
||||
write-json = "0.1.0"
|
||||
xshell = "0.1"
|
||||
xflags = "0.1.2"
|
||||
# Avoid adding more dependencies to this crate
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::{
|
|||
};
|
||||
use xshell::{cmd, pushenv, read_file, write_file};
|
||||
|
||||
use crate::{ensure_rustfmt, project_root, Result};
|
||||
use crate::{ensure_rustfmt, flags, project_root, Result};
|
||||
|
||||
pub(crate) use self::{
|
||||
gen_assists_docs::{generate_assists_docs, generate_assists_tests},
|
||||
|
@ -35,11 +35,7 @@ pub(crate) enum Mode {
|
|||
Verify,
|
||||
}
|
||||
|
||||
pub(crate) struct CodegenCmd {
|
||||
pub(crate) features: bool,
|
||||
}
|
||||
|
||||
impl CodegenCmd {
|
||||
impl flags::Codegen {
|
||||
pub(crate) fn run(self) -> Result<()> {
|
||||
if self.features {
|
||||
generate_lint_completions(Mode::Overwrite)?;
|
||||
|
|
139
xtask/src/flags.rs
Normal file
139
xtask/src/flags.rs
Normal file
|
@ -0,0 +1,139 @@
|
|||
#![allow(unreachable_pub)]
|
||||
|
||||
xflags::args_parser! {
|
||||
/// Run custom build command.
|
||||
cmd xtask {
|
||||
default cmd help {
|
||||
/// Print help information.
|
||||
optional -h, --help
|
||||
}
|
||||
|
||||
/// Install rust-analyzer server or editor plugin.
|
||||
cmd install {
|
||||
/// Install only VS Code plugin.
|
||||
optional --client
|
||||
/// One of 'code', 'code-exploration', 'code-insiders', 'codium', or 'code-oss'.
|
||||
optional --code-bin name: String
|
||||
|
||||
/// Install only the language server.
|
||||
optional --server
|
||||
/// Use mimalloc allocator for server
|
||||
optional --mimalloc
|
||||
/// Use jemalloc allocator for server
|
||||
optional --jemalloc
|
||||
}
|
||||
|
||||
cmd codegen {
|
||||
optional --features
|
||||
}
|
||||
|
||||
cmd lint {}
|
||||
cmd fuzz-tests {}
|
||||
cmd pre-cache {}
|
||||
|
||||
cmd release {
|
||||
optional --dry-run
|
||||
}
|
||||
cmd promote {
|
||||
optional --dry-run
|
||||
}
|
||||
cmd dist {
|
||||
optional --nightly
|
||||
optional --client version: String
|
||||
}
|
||||
cmd metrics {
|
||||
optional --dry-run
|
||||
}
|
||||
/// Builds a benchmark version of rust-analyzer and puts it into `./target`.
|
||||
cmd bb
|
||||
required suffix: String
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
// generated start
|
||||
// The following code is generated by `xflags` macro.
|
||||
// Run `env XFLAGS_DUMP= cargo build` to regenerate.
|
||||
#[derive(Debug)]
|
||||
pub struct Xtask {
|
||||
pub subcommand: XtaskCmd,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum XtaskCmd {
|
||||
Help(Help),
|
||||
Install(Install),
|
||||
Codegen(Codegen),
|
||||
Lint(Lint),
|
||||
FuzzTests(FuzzTests),
|
||||
PreCache(PreCache),
|
||||
Release(Release),
|
||||
Promote(Promote),
|
||||
Dist(Dist),
|
||||
Metrics(Metrics),
|
||||
Bb(Bb),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Help {
|
||||
pub help: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Install {
|
||||
pub client: bool,
|
||||
pub code_bin: Option<String>,
|
||||
pub server: bool,
|
||||
pub mimalloc: bool,
|
||||
pub jemalloc: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Codegen {
|
||||
pub features: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Lint {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FuzzTests {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PreCache {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Release {
|
||||
pub dry_run: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Promote {
|
||||
pub dry_run: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Dist {
|
||||
pub nightly: bool,
|
||||
pub client: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Metrics {
|
||||
pub dry_run: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Bb {
|
||||
pub suffix: String,
|
||||
}
|
||||
|
||||
impl Xtask {
|
||||
pub const HELP: &'static str = Self::_HELP;
|
||||
|
||||
pub fn from_env() -> xflags::Result<Self> {
|
||||
let mut p = xflags::rt::Parser::new_from_env();
|
||||
Self::_parse(&mut p)
|
||||
}
|
||||
}
|
||||
// generated end
|
|
@ -7,6 +7,8 @@
|
|||
//!
|
||||
//! This binary is integrated into the `cargo` command line by using an alias in
|
||||
//! `.cargo/config`.
|
||||
mod flags;
|
||||
|
||||
mod codegen;
|
||||
mod ast_src;
|
||||
#[cfg(test)]
|
||||
|
@ -19,8 +21,6 @@ mod metrics;
|
|||
mod pre_cache;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use codegen::CodegenCmd;
|
||||
use pico_args::Arguments;
|
||||
use std::{
|
||||
env,
|
||||
path::{Path, PathBuf},
|
||||
|
@ -32,42 +32,19 @@ use crate::{
|
|||
codegen::Mode,
|
||||
dist::DistCmd,
|
||||
install::{InstallCmd, Malloc, ServerOpt},
|
||||
metrics::MetricsCmd,
|
||||
pre_cache::PreCacheCmd,
|
||||
release::{PromoteCmd, ReleaseCmd},
|
||||
};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let _d = pushd(project_root())?;
|
||||
|
||||
let mut args = Arguments::from_env();
|
||||
let subcommand = args.subcommand()?.unwrap_or_default();
|
||||
|
||||
match subcommand.as_str() {
|
||||
"install" => {
|
||||
if args.contains(["-h", "--help"]) {
|
||||
eprintln!(
|
||||
"\
|
||||
cargo xtask install
|
||||
Install rust-analyzer server or editor plugin.
|
||||
|
||||
USAGE:
|
||||
cargo xtask install [FLAGS]
|
||||
|
||||
FLAGS:
|
||||
--client[=CLIENT] Install only VS Code plugin.
|
||||
CLIENT is one of 'code', 'code-exploration', 'code-insiders', 'codium', or 'code-oss'
|
||||
--server Install only the language server
|
||||
--mimalloc Use mimalloc allocator for server
|
||||
--jemalloc Use jemalloc allocator for server
|
||||
-h, --help Prints help information
|
||||
"
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
let server = args.contains("--server");
|
||||
let client_code = args.contains("--client");
|
||||
if server && client_code {
|
||||
let flags = flags::Xtask::from_env()?;
|
||||
match flags.subcommand {
|
||||
flags::XtaskCmd::Help(_) => {
|
||||
println!("{}", flags::Xtask::HELP);
|
||||
return Ok(());
|
||||
}
|
||||
flags::XtaskCmd::Install(flags) => {
|
||||
if flags.server && flags.client {
|
||||
eprintln!(
|
||||
"error: The argument `--server` cannot be used with `--client`\n\n\
|
||||
For more information try --help"
|
||||
|
@ -75,102 +52,43 @@ FLAGS:
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let malloc = if args.contains("--mimalloc") {
|
||||
let malloc = if flags.mimalloc {
|
||||
Malloc::Mimalloc
|
||||
} else if args.contains("--jemalloc") {
|
||||
} else if flags.jemalloc {
|
||||
Malloc::Jemalloc
|
||||
} else {
|
||||
Malloc::System
|
||||
};
|
||||
|
||||
let client_opt = args.opt_value_from_str("--client")?;
|
||||
|
||||
finish_args(args)?;
|
||||
let client_bin = flags.code_bin.map(|it| it.parse()).transpose()?;
|
||||
|
||||
InstallCmd {
|
||||
client: if server { None } else { Some(client_opt.unwrap_or_default()) },
|
||||
server: if client_code { None } else { Some(ServerOpt { malloc }) },
|
||||
client: if flags.server { None } else { client_bin },
|
||||
server: if flags.client { None } else { Some(ServerOpt { malloc }) },
|
||||
}
|
||||
.run()
|
||||
}
|
||||
"codegen" => {
|
||||
let features = args.contains("--features");
|
||||
finish_args(args)?;
|
||||
CodegenCmd { features }.run()
|
||||
flags::XtaskCmd::Codegen(cmd) => cmd.run(),
|
||||
flags::XtaskCmd::Lint(_) => run_clippy(),
|
||||
flags::XtaskCmd::FuzzTests(_) => run_fuzzer(),
|
||||
flags::XtaskCmd::PreCache(cmd) => cmd.run(),
|
||||
flags::XtaskCmd::Release(cmd) => cmd.run(),
|
||||
flags::XtaskCmd::Promote(cmd) => cmd.run(),
|
||||
flags::XtaskCmd::Dist(flags) => {
|
||||
DistCmd { nightly: flags.nightly, client_version: flags.client }.run()
|
||||
}
|
||||
"lint" => {
|
||||
finish_args(args)?;
|
||||
run_clippy()
|
||||
}
|
||||
"fuzz-tests" => {
|
||||
finish_args(args)?;
|
||||
run_fuzzer()
|
||||
}
|
||||
"pre-cache" => {
|
||||
finish_args(args)?;
|
||||
PreCacheCmd.run()
|
||||
}
|
||||
"release" => {
|
||||
let dry_run = args.contains("--dry-run");
|
||||
finish_args(args)?;
|
||||
ReleaseCmd { dry_run }.run()
|
||||
}
|
||||
"promote" => {
|
||||
let dry_run = args.contains("--dry-run");
|
||||
finish_args(args)?;
|
||||
PromoteCmd { dry_run }.run()
|
||||
}
|
||||
"dist" => {
|
||||
let nightly = args.contains("--nightly");
|
||||
let client_version: Option<String> = args.opt_value_from_str("--client")?;
|
||||
finish_args(args)?;
|
||||
DistCmd { nightly, client_version }.run()
|
||||
}
|
||||
"metrics" => {
|
||||
let dry_run = args.contains("--dry-run");
|
||||
finish_args(args)?;
|
||||
MetricsCmd { dry_run }.run()
|
||||
}
|
||||
"bb" => {
|
||||
let suffix: String = args.free_from_str()?;
|
||||
finish_args(args)?;
|
||||
flags::XtaskCmd::Metrics(cmd) => cmd.run(),
|
||||
flags::XtaskCmd::Bb(cmd) => {
|
||||
{
|
||||
let _d = pushd("./crates/rust-analyzer")?;
|
||||
cmd!("cargo build --release --features jemalloc").run()?;
|
||||
}
|
||||
cp("./target/release/rust-analyzer", format!("./target/rust-analyzer-{}", suffix))?;
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
eprintln!(
|
||||
"\
|
||||
cargo xtask
|
||||
Run custom build command.
|
||||
|
||||
USAGE:
|
||||
cargo xtask <SUBCOMMAND>
|
||||
|
||||
SUBCOMMANDS:
|
||||
fuzz-tests
|
||||
codegen
|
||||
install
|
||||
lint
|
||||
dist
|
||||
promote
|
||||
bb"
|
||||
);
|
||||
cp("./target/release/rust-analyzer", format!("./target/rust-analyzer-{}", cmd.suffix))?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn finish_args(args: Arguments) -> Result<()> {
|
||||
if !args.finish().is_empty() {
|
||||
bail!("Unused arguments.");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn project_root() -> PathBuf {
|
||||
Path::new(
|
||||
&env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| env!("CARGO_MANIFEST_DIR").to_owned()),
|
||||
|
|
|
@ -9,13 +9,11 @@ use std::{
|
|||
use anyhow::{bail, format_err, Result};
|
||||
use xshell::{cmd, mkdir_p, pushd, pushenv, read_file, rm_rf};
|
||||
|
||||
use crate::flags;
|
||||
|
||||
type Unit = String;
|
||||
|
||||
pub(crate) struct MetricsCmd {
|
||||
pub(crate) dry_run: bool,
|
||||
}
|
||||
|
||||
impl MetricsCmd {
|
||||
impl flags::Metrics {
|
||||
pub(crate) fn run(self) -> Result<()> {
|
||||
let mut metrics = Metrics::new()?;
|
||||
if !self.dry_run {
|
||||
|
|
|
@ -6,9 +6,9 @@ use std::{
|
|||
use anyhow::Result;
|
||||
use xshell::rm_rf;
|
||||
|
||||
pub(crate) struct PreCacheCmd;
|
||||
use crate::flags;
|
||||
|
||||
impl PreCacheCmd {
|
||||
impl flags::PreCache {
|
||||
/// Cleans the `./target` dir after the build such that only
|
||||
/// dependencies are cached on CI.
|
||||
pub(crate) fn run(self) -> Result<()> {
|
||||
|
|
|
@ -2,13 +2,9 @@ use std::fmt::Write;
|
|||
|
||||
use xshell::{cmd, cp, pushd, read_dir, write_file};
|
||||
|
||||
use crate::{codegen, date_iso, is_release_tag, project_root, Mode, Result};
|
||||
use crate::{codegen, date_iso, flags, is_release_tag, project_root, Mode, Result};
|
||||
|
||||
pub(crate) struct ReleaseCmd {
|
||||
pub(crate) dry_run: bool,
|
||||
}
|
||||
|
||||
impl ReleaseCmd {
|
||||
impl flags::Release {
|
||||
pub(crate) fn run(self) -> Result<()> {
|
||||
if !self.dry_run {
|
||||
cmd!("git switch release").run()?;
|
||||
|
@ -86,11 +82,7 @@ https://github.com/sponsors/rust-analyzer[GitHub Sponsors].
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PromoteCmd {
|
||||
pub(crate) dry_run: bool,
|
||||
}
|
||||
|
||||
impl PromoteCmd {
|
||||
impl flags::Promote {
|
||||
pub(crate) fn run(self) -> Result<()> {
|
||||
let _dir = pushd("../rust-rust-analyzer")?;
|
||||
cmd!("git switch master").run()?;
|
||||
|
|
Loading…
Reference in a new issue