Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/project-model/src/cargo_workspace.rs')
-rw-r--r--crates/project-model/src/cargo_workspace.rs66
1 files changed, 49 insertions, 17 deletions
diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs
index 014028a0b6..6e730b1aea 100644
--- a/crates/project-model/src/cargo_workspace.rs
+++ b/crates/project-model/src/cargo_workspace.rs
@@ -35,6 +35,8 @@ pub struct CargoWorkspace {
target_directory: AbsPathBuf,
manifest_path: ManifestPath,
is_virtual_workspace: bool,
+ /// Whether this workspace represents the sysroot workspace.
+ is_sysroot: bool,
/// Environment variables set in the `.cargo/config` file.
config_env: Env,
}
@@ -102,11 +104,14 @@ pub struct CargoConfig {
/// Extra args to pass to the cargo command.
pub extra_args: Vec<String>,
/// Extra env vars to set when invoking the cargo command
- pub extra_env: FxHashMap<String, String>,
+ pub extra_env: FxHashMap<String, Option<String>>,
pub invocation_strategy: InvocationStrategy,
/// Optional path to use instead of `target` when building
pub target_dir: Option<Utf8PathBuf>,
+ /// Gate `#[test]` behind `#[cfg(test)]`
pub set_test: bool,
+ /// Load the project without any dependencies
+ pub no_deps: bool,
}
pub type Package = Idx<PackageData>;
@@ -224,21 +229,26 @@ pub enum TargetKind {
Example,
Test,
Bench,
+ /// Cargo calls this kind `custom-build`
BuildScript,
Other,
}
impl TargetKind {
- fn new(kinds: &[String]) -> TargetKind {
+ fn new(kinds: &[cargo_metadata::TargetKind]) -> TargetKind {
for kind in kinds {
- return match kind.as_str() {
- "bin" => TargetKind::Bin,
- "test" => TargetKind::Test,
- "bench" => TargetKind::Bench,
- "example" => TargetKind::Example,
- "custom-build" => TargetKind::BuildScript,
- "proc-macro" => TargetKind::Lib { is_proc_macro: true },
- _ if kind.contains("lib") => TargetKind::Lib { is_proc_macro: false },
+ return match kind {
+ cargo_metadata::TargetKind::Bin => TargetKind::Bin,
+ cargo_metadata::TargetKind::Test => TargetKind::Test,
+ cargo_metadata::TargetKind::Bench => TargetKind::Bench,
+ cargo_metadata::TargetKind::Example => TargetKind::Example,
+ cargo_metadata::TargetKind::CustomBuild => TargetKind::BuildScript,
+ cargo_metadata::TargetKind::ProcMacro => TargetKind::Lib { is_proc_macro: true },
+ cargo_metadata::TargetKind::Lib
+ | cargo_metadata::TargetKind::DyLib
+ | cargo_metadata::TargetKind::CDyLib
+ | cargo_metadata::TargetKind::StaticLib
+ | cargo_metadata::TargetKind::RLib => TargetKind::Lib { is_proc_macro: false },
_ => continue,
};
}
@@ -252,6 +262,22 @@ impl TargetKind {
pub fn is_proc_macro(self) -> bool {
matches!(self, TargetKind::Lib { is_proc_macro: true })
}
+
+ /// If this is a valid cargo target, returns the name cargo uses in command line arguments
+ /// and output, otherwise None.
+ /// https://docs.rs/cargo_metadata/latest/cargo_metadata/enum.TargetKind.html
+ pub fn as_cargo_target(self) -> Option<&'static str> {
+ match self {
+ TargetKind::Bin => Some("bin"),
+ TargetKind::Lib { is_proc_macro: true } => Some("proc-macro"),
+ TargetKind::Lib { is_proc_macro: false } => Some("lib"),
+ TargetKind::Example => Some("example"),
+ TargetKind::Test => Some("test"),
+ TargetKind::Bench => Some("bench"),
+ TargetKind::BuildScript => Some("custom-build"),
+ TargetKind::Other => None,
+ }
+ }
}
#[derive(Default, Clone, Debug, PartialEq, Eq)]
@@ -263,7 +289,7 @@ pub struct CargoMetadataConfig {
/// Extra args to pass to the cargo command.
pub extra_args: Vec<String>,
/// Extra env vars to set when invoking the cargo command
- pub extra_env: FxHashMap<String, String>,
+ pub extra_env: FxHashMap<String, Option<String>>,
}
// Deserialize helper for the cargo metadata
@@ -285,6 +311,7 @@ impl CargoWorkspace {
current_dir: &AbsPath,
config: &CargoMetadataConfig,
sysroot: &Sysroot,
+ no_deps: bool,
locked: bool,
progress: &dyn Fn(String),
) -> anyhow::Result<(cargo_metadata::Metadata, Option<anyhow::Error>)> {
@@ -293,8 +320,8 @@ impl CargoWorkspace {
current_dir,
config,
sysroot,
+ no_deps,
locked,
- false,
progress,
);
if let Ok((_, Some(ref e))) = res {
@@ -312,15 +339,14 @@ impl CargoWorkspace {
current_dir: &AbsPath,
config: &CargoMetadataConfig,
sysroot: &Sysroot,
- locked: bool,
no_deps: bool,
+ locked: bool,
progress: &dyn Fn(String),
) -> anyhow::Result<(cargo_metadata::Metadata, Option<anyhow::Error>)> {
- let cargo = sysroot.tool(Tool::Cargo, current_dir);
+ let cargo = sysroot.tool(Tool::Cargo, current_dir, &config.extra_env);
let mut meta = MetadataCommand::new();
meta.cargo_path(cargo.get_program());
cargo.get_envs().for_each(|(var, val)| _ = meta.env(var, val.unwrap_or_default()));
- config.extra_env.iter().for_each(|(var, val)| _ = meta.env(var, val));
meta.manifest_path(cargo_toml.to_path_buf());
match &config.features {
CargoFeatures::All => {
@@ -418,6 +444,7 @@ impl CargoWorkspace {
mut meta: cargo_metadata::Metadata,
ws_manifest_path: ManifestPath,
cargo_config_env: Env,
+ is_sysroot: bool,
) -> CargoWorkspace {
let mut pkg_by_id = FxHashMap::default();
let mut packages = Arena::default();
@@ -456,7 +483,7 @@ impl CargoWorkspace {
cargo_metadata::Edition::E2015 => Edition::Edition2015,
cargo_metadata::Edition::E2018 => Edition::Edition2018,
cargo_metadata::Edition::E2021 => Edition::Edition2021,
- cargo_metadata::Edition::_E2024 => Edition::Edition2024,
+ cargo_metadata::Edition::E2024 => Edition::Edition2024,
_ => {
tracing::error!("Unsupported edition `{:?}`", edition);
Edition::CURRENT
@@ -539,6 +566,7 @@ impl CargoWorkspace {
target_directory,
manifest_path: ws_manifest_path,
is_virtual_workspace,
+ is_sysroot,
config_env: cargo_config_env,
}
}
@@ -596,7 +624,7 @@ impl CargoWorkspace {
// this pkg is inside this cargo workspace, fallback to workspace root
if found {
return Some(vec![
- ManifestPath::try_from(self.workspace_root().join("Cargo.toml")).ok()?
+ ManifestPath::try_from(self.workspace_root().join("Cargo.toml")).ok()?,
]);
}
@@ -632,4 +660,8 @@ impl CargoWorkspace {
pub fn env(&self) -> &Env {
&self.config_env
}
+
+ pub fn is_sysroot(&self) -> bool {
+ self.is_sysroot
+ }
}