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.rs | 66 |
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 + } } |