mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-28 18:43:01 +00:00
feat: Show what cargo metadata is doing in status
This commit is contained in:
parent
e2c3647c6a
commit
9dfbd56bb8
6 changed files with 56 additions and 25 deletions
|
|
@ -42,7 +42,7 @@ pub fn load_workspace_at(
|
||||||
root: &Path,
|
root: &Path,
|
||||||
cargo_config: &CargoConfig,
|
cargo_config: &CargoConfig,
|
||||||
load_config: &LoadCargoConfig,
|
load_config: &LoadCargoConfig,
|
||||||
progress: &dyn Fn(String),
|
progress: &(dyn Fn(String) + Sync),
|
||||||
) -> anyhow::Result<(RootDatabase, vfs::Vfs, Option<ProcMacroClient>)> {
|
) -> anyhow::Result<(RootDatabase, vfs::Vfs, Option<ProcMacroClient>)> {
|
||||||
let root = AbsPathBuf::assert_utf8(std::env::current_dir()?.join(root));
|
let root = AbsPathBuf::assert_utf8(std::env::current_dir()?.join(root));
|
||||||
let root = ProjectManifest::discover_single(&root)?;
|
let root = ProjectManifest::discover_single(&root)?;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use serde_json::from_value;
|
use serde_json::from_value;
|
||||||
use span::Edition;
|
use span::Edition;
|
||||||
|
use stdx::process::spawn_with_streaming_output;
|
||||||
use toolchain::Tool;
|
use toolchain::Tool;
|
||||||
|
|
||||||
use crate::{CfgOverrides, InvocationStrategy};
|
use crate::{CfgOverrides, InvocationStrategy};
|
||||||
|
|
@ -399,11 +400,21 @@ impl CargoWorkspace {
|
||||||
// FIXME: Fetching metadata is a slow process, as it might require
|
// FIXME: Fetching metadata is a slow process, as it might require
|
||||||
// calling crates.io. We should be reporting progress here, but it's
|
// calling crates.io. We should be reporting progress here, but it's
|
||||||
// unclear whether cargo itself supports it.
|
// unclear whether cargo itself supports it.
|
||||||
progress("metadata".to_owned());
|
progress("cargo metadata: started".to_owned());
|
||||||
|
|
||||||
(|| -> anyhow::Result<(_, _)> {
|
let res = (|| -> anyhow::Result<(_, _)> {
|
||||||
let output = meta.cargo_command().output()?;
|
let mut errored = false;
|
||||||
|
let output =
|
||||||
|
spawn_with_streaming_output(meta.cargo_command(), &mut |_| (), &mut |line| {
|
||||||
|
errored = errored || line.starts_with("error") || line.starts_with("warning");
|
||||||
|
if errored {
|
||||||
|
progress("cargo metadata: ?".to_owned());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
progress(format!("cargo metadata: {line}"));
|
||||||
|
})?;
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
|
progress(format!("cargo metadata: failed {}", output.status));
|
||||||
let error = cargo_metadata::Error::CargoMetadata {
|
let error = cargo_metadata::Error::CargoMetadata {
|
||||||
stderr: String::from_utf8(output.stderr)?,
|
stderr: String::from_utf8(output.stderr)?,
|
||||||
}
|
}
|
||||||
|
|
@ -431,7 +442,9 @@ impl CargoWorkspace {
|
||||||
.ok_or(cargo_metadata::Error::NoJson)?;
|
.ok_or(cargo_metadata::Error::NoJson)?;
|
||||||
Ok((cargo_metadata::MetadataCommand::parse(stdout)?, None))
|
Ok((cargo_metadata::MetadataCommand::parse(stdout)?, None))
|
||||||
})()
|
})()
|
||||||
.with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))
|
.with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()));
|
||||||
|
progress("cargo metadata: finished".to_owned());
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,7 @@ impl Sysroot {
|
||||||
pub fn load_workspace(
|
pub fn load_workspace(
|
||||||
&self,
|
&self,
|
||||||
sysroot_source_config: &RustSourceWorkspaceConfig,
|
sysroot_source_config: &RustSourceWorkspaceConfig,
|
||||||
|
progress: &dyn Fn(String),
|
||||||
) -> Option<RustLibSrcWorkspace> {
|
) -> Option<RustLibSrcWorkspace> {
|
||||||
assert!(matches!(self.workspace, RustLibSrcWorkspace::Empty), "workspace already loaded");
|
assert!(matches!(self.workspace, RustLibSrcWorkspace::Empty), "workspace already loaded");
|
||||||
let Self { root: _, rust_lib_src_root: Some(src_root), workspace: _, error: _ } = self
|
let Self { root: _, rust_lib_src_root: Some(src_root), workspace: _, error: _ } = self
|
||||||
|
|
@ -205,7 +206,7 @@ impl Sysroot {
|
||||||
let library_manifest = ManifestPath::try_from(src_root.join("Cargo.toml")).unwrap();
|
let library_manifest = ManifestPath::try_from(src_root.join("Cargo.toml")).unwrap();
|
||||||
if fs::metadata(&library_manifest).is_ok() {
|
if fs::metadata(&library_manifest).is_ok() {
|
||||||
if let Some(loaded) =
|
if let Some(loaded) =
|
||||||
self.load_library_via_cargo(library_manifest, src_root, cargo_config)
|
self.load_library_via_cargo(library_manifest, src_root, cargo_config, progress)
|
||||||
{
|
{
|
||||||
return Some(loaded);
|
return Some(loaded);
|
||||||
}
|
}
|
||||||
|
|
@ -296,6 +297,7 @@ impl Sysroot {
|
||||||
library_manifest: ManifestPath,
|
library_manifest: ManifestPath,
|
||||||
rust_lib_src_dir: &AbsPathBuf,
|
rust_lib_src_dir: &AbsPathBuf,
|
||||||
cargo_config: &CargoMetadataConfig,
|
cargo_config: &CargoMetadataConfig,
|
||||||
|
progress: &dyn Fn(String),
|
||||||
) -> Option<RustLibSrcWorkspace> {
|
) -> Option<RustLibSrcWorkspace> {
|
||||||
tracing::debug!("Loading library metadata: {library_manifest}");
|
tracing::debug!("Loading library metadata: {library_manifest}");
|
||||||
let mut cargo_config = cargo_config.clone();
|
let mut cargo_config = cargo_config.clone();
|
||||||
|
|
@ -313,7 +315,7 @@ impl Sysroot {
|
||||||
false,
|
false,
|
||||||
// Make sure we never attempt to write to the sysroot
|
// Make sure we never attempt to write to the sysroot
|
||||||
true,
|
true,
|
||||||
&|_| (),
|
progress,
|
||||||
) {
|
) {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,8 @@ fn smoke_test_real_sysroot_cargo() {
|
||||||
AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))),
|
AbsPath::assert(Utf8Path::new(env!("CARGO_MANIFEST_DIR"))),
|
||||||
&Default::default(),
|
&Default::default(),
|
||||||
);
|
);
|
||||||
let loaded_sysroot = sysroot.load_workspace(&RustSourceWorkspaceConfig::default_cargo());
|
let loaded_sysroot =
|
||||||
|
sysroot.load_workspace(&RustSourceWorkspaceConfig::default_cargo(), &|_| ());
|
||||||
if let Some(loaded_sysroot) = loaded_sysroot {
|
if let Some(loaded_sysroot) = loaded_sysroot {
|
||||||
sysroot.set_workspace(loaded_sysroot);
|
sysroot.set_workspace(loaded_sysroot);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ impl ProjectWorkspace {
|
||||||
pub fn load(
|
pub fn load(
|
||||||
manifest: ProjectManifest,
|
manifest: ProjectManifest,
|
||||||
config: &CargoConfig,
|
config: &CargoConfig,
|
||||||
progress: &dyn Fn(String),
|
progress: &(dyn Fn(String) + Sync),
|
||||||
) -> anyhow::Result<ProjectWorkspace> {
|
) -> anyhow::Result<ProjectWorkspace> {
|
||||||
ProjectWorkspace::load_inner(&manifest, config, progress)
|
ProjectWorkspace::load_inner(&manifest, config, progress)
|
||||||
.with_context(|| format!("Failed to load the project at {manifest}"))
|
.with_context(|| format!("Failed to load the project at {manifest}"))
|
||||||
|
|
@ -179,7 +179,7 @@ impl ProjectWorkspace {
|
||||||
fn load_inner(
|
fn load_inner(
|
||||||
manifest: &ProjectManifest,
|
manifest: &ProjectManifest,
|
||||||
config: &CargoConfig,
|
config: &CargoConfig,
|
||||||
progress: &dyn Fn(String),
|
progress: &(dyn Fn(String) + Sync),
|
||||||
) -> anyhow::Result<ProjectWorkspace> {
|
) -> anyhow::Result<ProjectWorkspace> {
|
||||||
let res = match manifest {
|
let res = match manifest {
|
||||||
ProjectManifest::ProjectJson(project_json) => {
|
ProjectManifest::ProjectJson(project_json) => {
|
||||||
|
|
@ -206,7 +206,7 @@ impl ProjectWorkspace {
|
||||||
fn load_cargo(
|
fn load_cargo(
|
||||||
cargo_toml: &ManifestPath,
|
cargo_toml: &ManifestPath,
|
||||||
config: &CargoConfig,
|
config: &CargoConfig,
|
||||||
progress: &dyn Fn(String),
|
progress: &(dyn Fn(String) + Sync),
|
||||||
) -> Result<ProjectWorkspace, anyhow::Error> {
|
) -> Result<ProjectWorkspace, anyhow::Error> {
|
||||||
progress("Discovering sysroot".to_owned());
|
progress("Discovering sysroot".to_owned());
|
||||||
let CargoConfig {
|
let CargoConfig {
|
||||||
|
|
@ -304,7 +304,7 @@ impl ProjectWorkspace {
|
||||||
&sysroot,
|
&sysroot,
|
||||||
*no_deps,
|
*no_deps,
|
||||||
false,
|
false,
|
||||||
&|_| (),
|
progress,
|
||||||
) {
|
) {
|
||||||
Ok((meta, _error)) => {
|
Ok((meta, _error)) => {
|
||||||
let workspace = CargoWorkspace::new(
|
let workspace = CargoWorkspace::new(
|
||||||
|
|
@ -347,13 +347,16 @@ impl ProjectWorkspace {
|
||||||
&sysroot,
|
&sysroot,
|
||||||
*no_deps,
|
*no_deps,
|
||||||
false,
|
false,
|
||||||
&|_| (),
|
progress,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let loaded_sysroot = s.spawn(|| {
|
let loaded_sysroot = s.spawn(|| {
|
||||||
sysroot.load_workspace(&RustSourceWorkspaceConfig::CargoMetadata(
|
sysroot.load_workspace(
|
||||||
sysroot_metadata_config(extra_env, &targets),
|
&RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config(
|
||||||
))
|
extra_env, &targets,
|
||||||
|
)),
|
||||||
|
progress,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
let cargo_config_extra_env =
|
let cargo_config_extra_env =
|
||||||
s.spawn(|| cargo_config_env(cargo_toml, extra_env, &sysroot));
|
s.spawn(|| cargo_config_env(cargo_toml, extra_env, &sysroot));
|
||||||
|
|
@ -411,7 +414,7 @@ impl ProjectWorkspace {
|
||||||
pub fn load_inline(
|
pub fn load_inline(
|
||||||
mut project_json: ProjectJson,
|
mut project_json: ProjectJson,
|
||||||
config: &CargoConfig,
|
config: &CargoConfig,
|
||||||
progress: &dyn Fn(String),
|
progress: &(dyn Fn(String) + Sync),
|
||||||
) -> ProjectWorkspace {
|
) -> ProjectWorkspace {
|
||||||
progress("Discovering sysroot".to_owned());
|
progress("Discovering sysroot".to_owned());
|
||||||
let mut sysroot =
|
let mut sysroot =
|
||||||
|
|
@ -443,11 +446,18 @@ impl ProjectWorkspace {
|
||||||
});
|
});
|
||||||
let loaded_sysroot = s.spawn(|| {
|
let loaded_sysroot = s.spawn(|| {
|
||||||
if let Some(sysroot_project) = sysroot_project {
|
if let Some(sysroot_project) = sysroot_project {
|
||||||
sysroot.load_workspace(&RustSourceWorkspaceConfig::Json(*sysroot_project))
|
sysroot.load_workspace(
|
||||||
|
&RustSourceWorkspaceConfig::Json(*sysroot_project),
|
||||||
|
progress,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
sysroot.load_workspace(&RustSourceWorkspaceConfig::CargoMetadata(
|
sysroot.load_workspace(
|
||||||
sysroot_metadata_config(&config.extra_env, &targets),
|
&RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config(
|
||||||
))
|
&config.extra_env,
|
||||||
|
&targets,
|
||||||
|
)),
|
||||||
|
progress,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -497,9 +507,13 @@ impl ProjectWorkspace {
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env);
|
let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env);
|
||||||
let data_layout = target_data_layout::get(query_config, None, &config.extra_env);
|
let data_layout = target_data_layout::get(query_config, None, &config.extra_env);
|
||||||
let loaded_sysroot = sysroot.load_workspace(&RustSourceWorkspaceConfig::CargoMetadata(
|
let loaded_sysroot = sysroot.load_workspace(
|
||||||
sysroot_metadata_config(&config.extra_env, &targets),
|
&RustSourceWorkspaceConfig::CargoMetadata(sysroot_metadata_config(
|
||||||
));
|
&config.extra_env,
|
||||||
|
&targets,
|
||||||
|
)),
|
||||||
|
&|_| (),
|
||||||
|
);
|
||||||
if let Some(loaded_sysroot) = loaded_sysroot {
|
if let Some(loaded_sysroot) = loaded_sysroot {
|
||||||
sysroot.set_workspace(loaded_sysroot);
|
sysroot.set_workspace(loaded_sysroot);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,8 @@ impl Tester {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env);
|
let mut sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env);
|
||||||
let loaded_sysroot = sysroot.load_workspace(&RustSourceWorkspaceConfig::default_cargo());
|
let loaded_sysroot =
|
||||||
|
sysroot.load_workspace(&RustSourceWorkspaceConfig::default_cargo(), &|_| ());
|
||||||
if let Some(loaded_sysroot) = loaded_sysroot {
|
if let Some(loaded_sysroot) = loaded_sysroot {
|
||||||
sysroot.set_workspace(loaded_sysroot);
|
sysroot.set_workspace(loaded_sysroot);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue