Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 54 additions & 8 deletions crates/vite_install/src/package_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,9 +936,7 @@ fn open_lock_file(lock_path: &Path) -> io::Result<File> {
fs::OpenOptions::new().read(true).write(true).create(true).truncate(false).open(lock_path)
}

/// Get the platform-specific npm package name for bun.
/// Returns the `@oven/bun-{os}-{arch}` package name for the current platform.
fn get_bun_platform_package_name() -> Result<&'static str, Error> {
fn get_bun_platform_package_name() -> Result<String, Error> {
let name = match (env::consts::OS, env::consts::ARCH) {
("macos", "aarch64") => "@oven/bun-darwin-aarch64",
("macos", "x86_64") => "@oven/bun-darwin-x64",
Expand All @@ -958,7 +956,21 @@ fn get_bun_platform_package_name() -> Result<&'static str, Error> {
));
}
};
Ok(name)
Ok(with_bun_baseline(name, bun_requires_baseline()))
}

fn with_bun_baseline(name: &str, requires_baseline: bool) -> String {
if requires_baseline { format!("{name}-baseline") } else { name.to_string() }
}

#[cfg(target_arch = "x86_64")]
fn bun_requires_baseline() -> bool {
!std::arch::is_x86_feature_detected!("avx2")
}

#[cfg(not(target_arch = "x86_64"))]
fn bun_requires_baseline() -> bool {
false
}

/// Download bun package manager (native binary) from npm.
Expand All @@ -972,7 +984,6 @@ async fn download_bun_package_manager(
home_dir: &AbsolutePath,
) -> Result<(AbsolutePathBuf, Str, Str), Error> {
let package_name: Str = "bun".into();
let platform_package_name = get_bun_platform_package_name()?;

// $VP_HOME/package_manager/bun/{version}
let target_dir = home_dir.join("package_manager").join("bun").join(version.as_str());
Expand All @@ -984,11 +995,14 @@ async fn download_bun_package_manager(
return Ok((install_dir, package_name, version.clone()));
}

// Temporary by design: select a CPU-compatible package for new downloads without replacing existing installs.
let platform_package_name = get_bun_platform_package_name()?;

let parent_dir = target_dir.parent().unwrap();
tokio::fs::create_dir_all(parent_dir).await?;

// Download the platform-specific package directly
let platform_tgz_url = get_npm_package_tgz_url(platform_package_name, version);
let platform_tgz_url = get_npm_package_tgz_url(&platform_package_name, version);
// Keep the TempDir guard alive so a failure path cleans up the temp dir.
let tmp_dir = tempfile::tempdir_in(parent_dir)?;
let target_dir_tmp = tmp_dir.path().to_path_buf();
Expand Down Expand Up @@ -3450,10 +3464,42 @@ mod tests {
// On musl targets, the package name should contain "-musl"
#[cfg(target_env = "musl")]
assert!(
name.ends_with("-musl"),
"On musl targets, package name should end with -musl, got: {name}"
name.contains("-musl"),
"On musl targets, package name should contain -musl, got: {name}"
);
}

#[test]
fn test_get_bun_platform_package_name_uses_baseline_without_avx2() {
for (name, expected) in [
("@oven/bun-darwin-x64", "@oven/bun-darwin-x64-baseline"),
("@oven/bun-linux-x64", "@oven/bun-linux-x64-baseline"),
("@oven/bun-linux-x64-musl", "@oven/bun-linux-x64-musl-baseline"),
("@oven/bun-windows-x64", "@oven/bun-windows-x64-baseline"),
] {
assert_eq!(with_bun_baseline(name, true), expected);
}
assert_eq!(with_bun_baseline("@oven/bun-linux-x64", false), "@oven/bun-linux-x64");
}

#[tokio::test]
async fn test_download_bun_package_manager_preserves_existing_install() {
let temp_dir = create_temp_dir();
let vp_home = AbsolutePathBuf::new(temp_dir.path().to_path_buf()).unwrap();
let version: Str = "1.3.14".into();
write_pm_install(&vp_home, "bun", version.as_str(), InstallState::Complete);
let native_bin = vp_home
.join("package_manager")
.join("bun")
.join(version.as_str())
.join("bun/bin/bun.native");
fs::write(&native_bin, "existing bun").unwrap();

download_bun_package_manager(&version, &vp_home).await.unwrap();

assert_eq!(fs::read_to_string(native_bin).unwrap(), "existing bun");
}

/// Note: The true ERROR_SHARING_VIOLATION occurs when *multiple processes*
/// attempt to lock the file concurrently on Windows (e.g. during parallel MSBuild tasks).
/// Standard cargo tests run in a single process, which the Windows OS allows to bypass
Expand Down
Loading