Repository: rust-analyzer/rust-analyzer
Pull request #3200 (2020-02-17 18:07:53)

Merge ra_vfs_glob and ra_lsp_server


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 82f910c1b7..c22cbca3a3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -941,30 +941,6 @@ dependencies = [
  "rustc-hash",
 ]
 
-[[package]]
-name = "ra_cli"
-version = "0.1.0"
-dependencies = [
- "anyhow",
- "crossbeam-channel",
- "env_logger",
- "itertools",
- "log",
- "pico-args",
- "ra_db",
- "ra_hir",
- "ra_hir_def",
- "ra_hir_ty",
- "ra_ide",
- "ra_prof",
- "ra_project_model",
- "ra_syntax",
- "ra_vfs",
- "ra_vfs_glob",
- "rand",
- "rustc-hash",
-]
-
 [[package]]
 name = "ra_db"
 version = "0.1.0"
@@ -1122,22 +1098,30 @@ dependencies = [
 name = "ra_lsp_server"
 version = "0.1.0"
 dependencies = [
+ "anyhow",
  "crossbeam-channel",
  "either",
  "env_logger",
+ "globset",
+ "itertools",
  "jod-thread",
  "log",
  "lsp-server",
  "lsp-types",
  "parking_lot",
+ "pico-args",
  "ra_cargo_watch",
+ "ra_db",
+ "ra_hir",
+ "ra_hir_def",
+ "ra_hir_ty",
  "ra_ide",
  "ra_prof",
  "ra_project_model",
  "ra_syntax",
  "ra_text_edit",
  "ra_vfs",
- "ra_vfs_glob",
+ "rand",
  "relative-path",
  "rustc-hash",
  "serde",
@@ -1243,14 +1227,6 @@ dependencies = [
  "walkdir",
 ]
 
-[[package]]
-name = "ra_vfs_glob"
-version = "0.1.0"
-dependencies = [
- "globset",
- "ra_vfs",
-]
-
 [[package]]
 name = "rand"
 version = "0.7.3"
diff --git a/crates/ra_cli/Cargo.toml b/crates/ra_cli/Cargo.toml
deleted file mode 100644
index ce88a76b1d..0000000000
--- a/crates/ra_cli/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-[package]
-edition = "2018"
-name = "ra_cli"
-version = "0.1.0"
-authors = ["rust-analyzer developers"]
-publish = false
-
-[dependencies]
-crossbeam-channel = "0.4.0"
-env_logger = { version = "0.7.1", default-features = false }
-itertools = "0.8.0"
-log = "0.4.5"
-pico-args = "0.3.0"
-rand = { version = "0.7.0", features = ["small_rng"] }
-rustc-hash = "1.0"
-anyhow = "1.0"
-
-hir = { path = "../ra_hir", package = "ra_hir" }
-hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
-hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
-ra_db = { path = "../ra_db" }
-ra_ide = { path = "../ra_ide" }
-ra_project_model = { path = "../ra_project_model" }
-ra_syntax = { path = "../ra_syntax" }
-ra_vfs = "0.5.0"
-ra_vfs_glob = { path = "../ra_vfs_glob" }
-
-[dependencies.ra_prof]
-path = "../ra_prof"
-# features = [ "cpu_profiler" ]
-# features = [ "jemalloc" ]
diff --git a/crates/ra_lsp_server/Cargo.toml b/crates/ra_lsp_server/Cargo.toml
index 0066929c0c..da523ba8a2 100644
--- a/crates/ra_lsp_server/Cargo.toml
+++ b/crates/ra_lsp_server/Cargo.toml
@@ -8,13 +8,18 @@ authors = ["rust-analyzer developers"]
 doctest = false
 
 [dependencies]
+anyhow = "1.0"
 crossbeam-channel = "0.4"
 either = "1.5"
 env_logger = { version = "0.7.1", default-features = false }
+globset = "0.4.4"
+itertools = "0.8.0"
 jod-thread = "0.1.0"
 log = "0.4.3"
 lsp-types = { version = "0.70.0", features = ["proposed"] }
 parking_lot = "0.10.0"
+pico-args = "0.3.0"
+rand = { version = "0.7.0", features = ["small_rng"] }
 relative-path = "1.0.0"
 rustc-hash = "1.0"
 serde = { version = "1.0.83", features = ["derive"] }
@@ -29,7 +34,13 @@ ra_project_model = { path = "../ra_project_model" }
 ra_syntax = { path = "../ra_syntax" }
 ra_text_edit = { path = "../ra_text_edit" }
 ra_vfs = "0.5.0"
-ra_vfs_glob = { path = "../ra_vfs_glob" }
+
+# This should only be used in CLI
+ra_db = { path = "../ra_db" }
+hir = { path = "../ra_hir", package = "ra_hir" }
+hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
+hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
+
 
 [target.'cfg(windows)'.dependencies]
 winapi = "0.3"
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_lsp_server/src/args.rs
similarity index 63%
rename from crates/ra_cli/src/main.rs
rename to crates/ra_lsp_server/src/args.rs
index 4cf062f472..89e2139cec 100644
--- a/crates/ra_cli/src/main.rs
+++ b/crates/ra_lsp_server/src/args.rs
@@ -1,65 +1,20 @@
-//! FIXME: write short doc here
-
-mod load_cargo;
-mod analysis_stats;
-mod analysis_bench;
-mod progress_report;
-
-use std::{fmt::Write, io::Read, path::PathBuf, str::FromStr};
+//! Command like parsing for rust-analyzer.
+//!
+//! If run started args, we run the LSP server loop. With a subcommand, we do a
+//! one-time batch processing.
 
+use anyhow::{bail, Result};
 use pico_args::Arguments;
-use ra_ide::{file_structure, Analysis};
-use ra_prof::profile;
-use ra_syntax::{AstNode, SourceFile};
-
-use anyhow::{bail, format_err, Result};
-
-fn main() -> Result<()> {
-    env_logger::try_init()?;
-
-    let command = match Command::from_env_args()? {
-        Ok(it) => it,
-        Err(HelpPrinted) => return Ok(()),
-    };
-    match command {
-        Command::Parse { no_dump } => {
-            let _p = profile("parsing");
-            let file = file()?;
-            if !no_dump {
-                println!("{:#?}", file.syntax());
-            }
-            std::mem::forget(file);
-        }
-        Command::Symbols => {
-            let file = file()?;
-            for s in file_structure(&file) {
-                println!("{:?}", s);
-            }
-        }
-        Command::Highlight { rainbow } => {
-            let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
-            let html = analysis.highlight_as_html(file_id, rainbow).unwrap();
-            println!("{}", html);
-        }
-        Command::Stats { verbosity, randomize, memory_usage, only, with_deps, path } => {
-            analysis_stats::run(
-                verbosity,
-                memory_usage,
-                path.as_ref(),
-                only.as_ref().map(String::as_ref),
-                with_deps,
-                randomize,
-            )?;
-        }
-        Command::Bench { verbosity, path, what } => {
-            analysis_bench::run(verbosity, path.as_ref(), what)?;
-        }
-    }
+use ra_lsp_server::cli::{BenchWhat, Position, Verbosity};
 
-    Ok(())
+use std::{fmt::Write, path::PathBuf};
+
+pub(crate) struct Args {
+    pub(crate) verbosity: Verbosity,
+    pub(crate) command: Command,
 }
 
-enum Command {
+pub(crate) enum Command {
     Parse {
         no_dump: bool,
     },
@@ -68,7 +23,6 @@ enum Command {
         rainbow: bool,
     },
     Stats {
-        verbosity: Verbosity,
         randomize: bool,
         memory_usage: bool,
         only: Option<String>,
@@ -76,67 +30,21 @@ enum Command {
         path: PathBuf,
     },
     Bench {
-        verbosity: Verbosity,
         path: PathBuf,
         what: BenchWhat,
     },
+    RunServer,
+    Version,
 }
 
-#[derive(Clone, Copy)]
-pub enum Verbosity {
-    Spammy,
-    Verbose,
-    Normal,
-    Quiet,
-}
+impl Args {
+    pub(crate) fn parse() -> Result<Result<Args, HelpPrinted>> {
+        let mut matches = Arguments::from_env();
 
-impl Verbosity {
-    fn is_verbose(self) -> bool {
-        match self {
-            Verbosity::Verbose | Verbosity::Spammy => true,
-            _ => false,
-        }
-    }
-    fn is_spammy(self) -> bool {
-        match self {
-            Verbosity::Spammy => true,
-            _ => false,
+        if matches.contains("--version") {
+            matches.finish().or_else(handle_extra_flags)?;
+            return Ok(Ok(Args { verbosity: Verbosity::Normal, command: Command::Version }));
         }
-    }
-}
-
-enum BenchWhat {
-    Highlight { path: PathBuf },
-    Complete(Position),
-    GotoDef(Position),
-}
-
-pub(crate) struct Position {
-    path: PathBuf,
-    line: u32,
-    column: u32,
-}
-
-impl FromStr for Position {
-    type Err = anyhow::Error;
-    fn from_str(s: &str) -> Result<Self> {
-        let (path_line, column) = rsplit_at_char(s, ':')?;
-        let (path, line) = rsplit_at_char(path_line, ':')?;
-        Ok(Position { path: path.into(), line: line.parse()?, column: column.parse()? })
-    }
-}
-
-fn rsplit_at_char(s: &str, c: char) -> Result<(&str, &str)> {
-    let idx = s.rfind(c).ok_or_else(|| format_err!("no `{}` in {}", c, s))?;
-    Ok((&s[..idx], &s[idx + 1..]))
-}
-
-struct HelpPrinted;
-
-impl Command {
-    fn from_env_args() -> Result<Result<Command, HelpPrinted>> {
-        let mut matches = Arguments::from_env();
-        let subcommand = matches.subcommand()?.unwrap_or_default();
 
         let verbosity = match (
             matches.contains(["-vv", "--spammy"]),
@@ -151,6 +59,13 @@ impl Command {
             (false, true, true) => bail!("Invalid flags: -q conflicts with -v"),
         };
 
+        let subcommand = match matches.subcommand()? {
+            Some(it) => it,
+            None => {
+                matches.finish().or_else(handle_extra_flags)?;
+                return Ok(Ok(Args { verbosity, command: Command::RunServer }));
+            }
+        };
         let command = match subcommand.as_str() {
             "parse" => {
                 if matches.contains(["-h", "--help"]) {
@@ -247,7 +162,7 @@ ARGS:
                     trailing.pop().unwrap().into()
                 };
 
-                Command::Stats { verbosity, randomize, memory_usage, only, with_deps, path }
+                Command::Stats { randomize, memory_usage, only, with_deps, path }
             }
             "analysis-bench" => {
                 if matches.contains(["-h", "--help"]) {
@@ -284,7 +199,7 @@ ARGS:
                         "exactly one of  `--highlight`, `--complete` or `--goto-def` must be set"
                     ),
                 };
-                Command::Bench { verbosity, path, what }
+                Command::Bench { path, what }
             }
             _ => {
                 eprintln!(
@@ -307,10 +222,12 @@ SUBCOMMANDS:
                 return Ok(Err(HelpPrinted));
             }
         };
-        Ok(Ok(command))
+        Ok(Ok(Args { verbosity, command }))
     }
 }
 
+pub(crate) struct HelpPrinted;
+
 fn handle_extra_flags(e: pico_args::Error) -> Result<()> {
     if let pico_args::Error::UnusedArgsLeft(flags) = e {
         let mut invalid_flags = String::new();
@@ -323,14 +240,3 @@ fn handle_extra_flags(e: pico_args::Error) -> Result<()> {
         bail!(e);
     }
 }
-
-fn file() -> Result<SourceFile> {
-    let text = read_stdin()?;
-    Ok(SourceFile::parse(&text).tree())
-}
-
-fn read_stdin() -> Result<String> {
-    let mut buff = String::new();
-    std::io::stdin().read_to_string(&mut buff)?;
-    Ok(buff)
-}
diff --git a/crates/ra_lsp_server/src/cli.rs b/crates/ra_lsp_server/src/cli.rs
new file mode 100644
index 0000000000..3c7b8e2509
--- /dev/null
+++ b/crates/ra_lsp_server/src/cli.rs
@@ -0,0 +1,75 @@
+//! FIXME: write short doc here
+
+mod load_cargo;
+mod analysis_stats;
+mod analysis_bench;
+mod progress_report;
+
+use std::io::Read;
+
+use anyhow::Result;
+use ra_ide::{file_structure, Analysis};
+use ra_prof::profile;
+use ra_syntax::{AstNode, SourceFile};
+
+#[derive(Clone, Copy)]
+pub enum Verbosity {
+    Spammy,
+    Verbose,
+    Normal,
+    Quiet,
+}
+
+impl Verbosity {
+    pub fn is_verbose(self) -> bool {
+        match self {
+            Verbosity::Verbose | Verbosity::Spammy => true,
+            _ => false,
+        }
+    }
+    pub fn is_spammy(self) -> bool {
+        match self {
+            Verbosity::Spammy => true,
+            _ => false,
+        }
+    }
+}
+
+pub fn parse(no_dump: bool) -> Result<()> {
+    let _p = profile("parsing");
+    let file = file()?;
+    if !no_dump {
+        println!("{:#?}", file.syntax());
+    }
+    std::mem::forget(file);
+    Ok(())
+}
+
+pub fn symbols() -> Result<()> {
+    let file = file()?;
+    for s in file_structure(&file) {
+        println!("{:?}", s);
+    }
+    Ok(())
+}
+
+pub fn highlight(rainbow: bool) -> Result<()> {
+    let (analysis, file_id) = Analysis::from_single_file(read_stdin()?);
+    let html = analysis.highlight_as_html(file_id, rainbow).unwrap();
+    println!("{}", html);
+    Ok(())
+}
+
+pub use analysis_bench::{analysis_bench, BenchWhat, Position};
+pub use analysis_stats::analysis_stats;
+
+fn file() -> Result<SourceFile> {
+    let text = read_stdin()?;
+    Ok(SourceFile::parse(&text).tree())
+}
+
+fn read_stdin() -> Result<String> {
+    let mut buff = String::new();
+    std::io::stdin().read_to_string(&mut buff)?;
+    Ok(buff)
+}
diff --git a/crates/ra_cli/src/analysis_bench.rs b/crates/ra_lsp_server/src/cli/analysis_bench.rs
similarity index 81%
rename from crates/ra_cli/src/analysis_bench.rs
rename to crates/ra_lsp_server/src/cli/analysis_bench.rs
index 91fc55fe20..e00f810734 100644
--- a/crates/ra_cli/src/analysis_bench.rs
+++ b/crates/ra_lsp_server/src/cli/analysis_bench.rs
@@ -1,17 +1,48 @@
 //! FIXME: write short doc here
 
-use std::{path::Path, sync::Arc, time::Instant};
+use std::{
+    path::{Path, PathBuf},
+    str::FromStr,
+    sync::Arc,
+    time::Instant,
+};
 
-use anyhow::format_err;
+use anyhow::{format_err, Result};
 use ra_db::{
     salsa::{Database, Durability},
     FileId, SourceDatabaseExt,
 };
 use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol};
 
-use crate::{load_cargo::load_cargo, BenchWhat, Result, Verbosity};
+use crate::cli::{load_cargo::load_cargo, Verbosity};
+
+pub enum BenchWhat {
+    Highlight { path: PathBuf },
+    Complete(Position),
+    GotoDef(Position),
+}
+
+pub struct Position {
+    pub path: PathBuf,
+    pub line: u32,
+    pub column: u32,
+}
+
+impl FromStr for Position {
+    type Err = anyhow::Error;
+    fn from_str(s: &str) -> Result<Self> {
+        let (path_line, column) = rsplit_at_char(s, ':')?;
+        let (path, line) = rsplit_at_char(path_line, ':')?;
+        Ok(Position { path: path.into(), line: line.parse()?, column: column.parse()? })
+    }
+}
+
+fn rsplit_at_char(s: &str, c: char) -> Result<(&str, &str)> {
+    let idx = s.rfind(c).ok_or_else(|| format_err!("no `{}` in {}", c, s))?;
+    Ok((&s[..idx], &s[idx + 1..]))
+}
 
-pub(crate) fn run(verbosity: Verbosity, path: &Path, what: BenchWhat) -> Result<()> {
+pub fn analysis_bench(verbosity: Verbosity, path: &Path, what: BenchWhat) -> Result<()> {
     ra_prof::init();
 
     let start = Instant::now();
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_lsp_server/src/cli/analysis_stats.rs
similarity index 98%
rename from crates/ra_cli/src/analysis_stats.rs
rename to crates/ra_lsp_server/src/cli/analysis_stats.rs
index d40f043919..c27fabe3c4 100644
--- a/crates/ra_cli/src/analysis_stats.rs
+++ b/crates/ra_lsp_server/src/cli/analysis_stats.rs
@@ -13,9 +13,9 @@ use ra_db::SourceDatabaseExt;
 use ra_syntax::AstNode;
 use rand::{seq::SliceRandom, thread_rng};
 
-use crate::{load_cargo::load_cargo, progress_report::ProgressReport, Result, Verbosity};
+use crate::cli::{load_cargo::load_cargo, progress_report::ProgressReport, Result, Verbosity};
 
-pub fn run(
+pub fn analysis_stats(
     verbosity: Verbosity,
     memory_usage: bool,
     path: &Path,
diff --git a/crates/ra_cli/src/load_cargo.rs b/crates/ra_lsp_server/src/cli/load_cargo.rs
similarity index 99%
rename from crates/ra_cli/src/load_cargo.rs
rename to crates/ra_lsp_server/src/cli/load_cargo.rs
index b9a4e6abad..bb3e1513b8 100644
--- a/crates/ra_cli/src/load_cargo.rs
+++ b/crates/ra_lsp_server/src/cli/load_cargo.rs
@@ -7,9 +7,10 @@ use ra_db::{CrateGraph, FileId, SourceRootId};
 use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags};
 use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace};
 use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
-use ra_vfs_glob::RustPackageFilterBuilder;
 use rustc_hash::FxHashMap;
 
+use crate::vfs_glob::RustPackageFilterBuilder;
+
 use anyhow::Result;
 
 fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId {
diff --git a/crates/ra_cli/src/progress_report.rs b/crates/ra_lsp_server/src/cli/progress_report.rs
similarity index 100%
rename from crates/ra_cli/src/progress_report.rs
rename to crates/ra_lsp_server/src/cli/progress_report.rs
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs
index a3464a5a3c..958c70fe5f 100644
--- a/crates/ra_lsp_server/src/lib.rs
+++ b/crates/ra_lsp_server/src/lib.rs
@@ -7,6 +7,8 @@
 //! state, and `main_loop` module defines the rules for modifying it.
 #![recursion_limit = "512"]
 
+pub mod cli;
+
 #[allow(unused)]
 macro_rules! println {
     ($($tt:tt)*) => {
@@ -21,6 +23,7 @@ macro_rules! print {
     };
 }
 
+mod vfs_glob;
 mod caps;
 mod cargo_target_spec;
 mod conv;
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs
index ed2eaabd4c..a549e5ff12 100644
--- a/crates/ra_lsp_server/src/main.rs
+++ b/crates/ra_lsp_server/src/main.rs
@@ -1,14 +1,39 @@
 //! `ra_lsp_server` binary
+mod args;
 
 use lsp_server::Connection;
-use ra_lsp_server::{from_json, show_message, Result, ServerConfig};
+use ra_lsp_server::{cli, from_json, show_message, Result, ServerConfig};
 use ra_prof;
 
+use crate::args::HelpPrinted;
+
 fn main() -> Result<()> {
     setup_logging()?;
-    match Args::parse()? {
-        Args::Version => println!("rust-analyzer {}", env!("REV")),
-        Args::Run => run_server()?,
+    let args = match args::Args::parse()? {
+        Ok(it) => it,
+        Err(HelpPrinted) => return Ok(()),
+    };
+    match args.command {
+        args::Command::Parse { no_dump } => cli::parse(no_dump)?,
+        args::Command::Symbols => cli::symbols()?,
+        args::Command::Highlight { rainbow } => cli::highlight(rainbow)?,
+        args::Command::Stats { randomize, memory_usage, only, with_deps, path } => {
+            cli::analysis_stats(
+                args.verbosity,
+                memory_usage,
+                path.as_ref(),
+                only.as_ref().map(String::as_ref),
+                with_deps,
+                randomize,
+            )?
+        }
+
+        args::Command::Bench { path, what } => {
+            cli::analysis_bench(args.verbosity, path.as_ref(), what)?
+        }
+
+        args::Command::RunServer => run_server()?,
+        args::Command::Version => println!("rust-analyzer {}", env!("REV")),
     }
     Ok(())
 }
@@ -20,19 +45,6 @@ fn setup_logging() -> Result<()> {
     Ok(())
 }
 
-enum Args {
-    Version,
-    Run,
-}
-
-impl Args {
-    fn parse() -> Result<Args> {
-        let res =
-            if std::env::args().any(|it| it == "--version") { Args::Version } else { Args::Run };
-        Ok(res)
-    }
-}
-
 fn run_server() -> Result<()> {
     log::info!("lifecycle: server started");
 
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 7ae2e1e6fd..944074118d 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -135,7 +135,7 @@ pub fn main_loop(
         let globs = config
             .exclude_globs
             .iter()
-            .map(|glob| ra_vfs_glob::Glob::new(glob))
+            .map(|glob| crate::vfs_glob::Glob::new(glob))
             .collect::<std::result::Result<Vec<_>, _>>()?;
 
         if config.use_client_watching {
diff --git a/crates/ra_vfs_glob/src/lib.rs b/crates/ra_lsp_server/src/vfs_glob.rs
similarity index 100%
rename from crates/ra_vfs_glob/src/lib.rs
rename to crates/ra_lsp_server/src/vfs_glob.rs
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs
index d993c5fc46..71c95d4af0 100644
--- a/crates/ra_lsp_server/src/world.rs
+++ b/crates/ra_lsp_server/src/world.rs
@@ -19,12 +19,12 @@ use ra_ide::{
 };
 use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace};
 use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch};
-use ra_vfs_glob::{Glob, RustPackageFilterBuilder};
 use relative_path::RelativePathBuf;
 
 use crate::{
     diagnostics::{CheckFixes, DiagnosticCollection},
     main_loop::pending_requests::{CompletedRequest, LatestRequests},
+    vfs_glob::{Glob, RustPackageFilterBuilder},
     LspError, Result,
 };
 
diff --git a/crates/ra_vfs_glob/Cargo.toml b/crates/ra_vfs_glob/Cargo.toml
deleted file mode 100644
index 094d6d6f44..0000000000
--- a/crates/ra_vfs_glob/Cargo.toml
+++ /dev/null
@@ -1,12 +0,0 @@
-[package]
-edition = "2018"
-name = "ra_vfs_glob"
-version = "0.1.0"
-authors = ["rust-analyzer developers"]
-
-[lib]
-doctest = false
-
-[dependencies]
-ra_vfs = "0.5.0"
-globset = "0.4.4"


Test patch:
diff --git a/xtask/tests/tidy-tests/docs.rs b/xtask/tests/tidy-tests/docs.rs
index a8ed9793f2..b2571df258 100644
--- a/xtask/tests/tidy-tests/docs.rs
+++ b/xtask/tests/tidy-tests/docs.rs
@@ -73,7 +73,6 @@ fn no_docs_comments() {
     }
 
     let whitelist = [
-        "ra_cli",
         "ra_db",
         "ra_hir",
         "ra_hir_expand",