Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/project-model/src/cargo_config_file.rs')
| -rw-r--r-- | crates/project-model/src/cargo_config_file.rs | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/crates/project-model/src/cargo_config_file.rs b/crates/project-model/src/cargo_config_file.rs index 5d6e5fd648..ae36deb71f 100644 --- a/crates/project-model/src/cargo_config_file.rs +++ b/crates/project-model/src/cargo_config_file.rs @@ -132,25 +132,65 @@ impl<'a> CargoConfigFileReader<'a> { } } +pub(crate) struct LockfileCopy { + pub(crate) path: Utf8PathBuf, + pub(crate) usage: LockfileUsage, + _temp_dir: temp_dir::TempDir, +} + +pub(crate) enum LockfileUsage { + /// Rust [1.82.0, 1.95.0). `cargo <subcmd> --lockfile-path <lockfile path>` + WithFlag, + /// Rust >= 1.95.0. `CARGO_RESOLVER_LOCKFILE_PATH=<lockfile path> cargo <subcmd>` + WithEnvVar, +} + pub(crate) fn make_lockfile_copy( + toolchain_version: &semver::Version, lockfile_path: &Utf8Path, -) -> Option<(temp_dir::TempDir, Utf8PathBuf)> { +) -> Option<LockfileCopy> { + const MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH_FLAG: semver::Version = + semver::Version { + major: 1, + minor: 82, + patch: 0, + pre: semver::Prerelease::EMPTY, + build: semver::BuildMetadata::EMPTY, + }; + + const MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH_ENV: semver::Version = + semver::Version { + major: 1, + minor: 95, + patch: 0, + pre: semver::Prerelease::EMPTY, + build: semver::BuildMetadata::EMPTY, + }; + + let usage = if *toolchain_version >= MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH_ENV { + LockfileUsage::WithEnvVar + } else if *toolchain_version >= MINIMUM_TOOLCHAIN_VERSION_SUPPORTING_LOCKFILE_PATH_FLAG { + LockfileUsage::WithFlag + } else { + return None; + }; + let temp_dir = temp_dir::TempDir::with_prefix("rust-analyzer").ok()?; - let target_lockfile = temp_dir.path().join("Cargo.lock").try_into().ok()?; - match std::fs::copy(lockfile_path, &target_lockfile) { + let path: Utf8PathBuf = temp_dir.path().join("Cargo.lock").try_into().ok()?; + let path = match std::fs::copy(lockfile_path, &path) { Ok(_) => { - tracing::debug!("Copied lock file from `{}` to `{}`", lockfile_path, target_lockfile); - Some((temp_dir, target_lockfile)) + tracing::debug!("Copied lock file from `{}` to `{}`", lockfile_path, path); + path } // lockfile does not yet exist, so we can just create a new one in the temp dir - Err(e) if e.kind() == std::io::ErrorKind::NotFound => Some((temp_dir, target_lockfile)), + Err(e) if e.kind() == std::io::ErrorKind::NotFound => path, Err(e) => { - tracing::warn!( - "Failed to copy lock file from `{lockfile_path}` to `{target_lockfile}`: {e}", - ); - None + tracing::warn!("Failed to copy lock file from `{lockfile_path}` to `{path}`: {e}",); + return None; } - } + }; + + Some(LockfileCopy { path, usage, _temp_dir: temp_dir }) } #[test] |