diff --git a/packages/zpm-switch/src/cache.rs b/packages/zpm-switch/src/cache.rs index e36ca2c5..324041d2 100644 --- a/packages/zpm-switch/src/cache.rs +++ b/packages/zpm-switch/src/cache.rs @@ -2,13 +2,12 @@ use std::{future::Future, io::Write}; use serde::{Deserialize, Serialize}; use zpm_parsers::JsonDocument; -use zpm_semver::{Version, VersionRc}; -use zpm_utils::{DataType, Hash64, Path, ToFileString, ToHumanString, Unit, is_terminal}; -use zpm_utils::eco_vec; +use zpm_semver::{Range, VersionRc}; +use zpm_utils::{DataType, FromFileString, Hash64, Path, ToFileString, ToHumanString, Unit, is_terminal}; use crate::errors::Error; -pub const CACHE_VERSION: usize = 1; +pub const CACHE_VERSION: usize = 2; #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -26,18 +25,17 @@ fn get_npm_registry_server() -> String { impl CacheKey { pub fn to_npm_url(&self) -> Option { if self.version.rc.as_ref().map_or(true, |rc| !rc.starts_with(&[VersionRc::String("git".into())])) { - // Older RC versions (<6.0.0-rc.9) are not available in npm - let first_npm_release = Version::new_from_components( - 6, - 0, - 0, - Some(eco_vec![VersionRc::String("rc".into()), VersionRc::Number(9)]), - ); - - if self.version >= first_npm_release { + // zpm is available on npm since 6.0.0-rc.9 + if Range::from_file_string(">=6.0.0-rc.9").unwrap().check_ignore_rc(&self.version) { let registry = get_npm_registry_server(); return Some(format!("{}/@yarnpkg/yarn-{}/-/yarn-{}-{}.tgz", registry, self.platform, self.platform, self.version.to_file_string())); } + + // berry has been published to npm since 2.4.1 + if Range::from_file_string(">=2.4.1 <6.0.0-0").unwrap().check_ignore_rc(&self.version) { + let registry = get_npm_registry_server(); + return Some(format!("{}/@yarnpkg/cli-dist/-/cli-dist-{}.tgz", registry, self.version.to_file_string())); + } } None diff --git a/packages/zpm-switch/src/install.rs b/packages/zpm-switch/src/install.rs index 1fd6f908..6386756e 100644 --- a/packages/zpm-switch/src/install.rs +++ b/packages/zpm-switch/src/install.rs @@ -119,10 +119,10 @@ async fn install_node_js_from_url(source: &cache::CacheKey) -> Result Result { +async fn install_node_js_from_package(source: &cache::CacheKey, url: &str, main_file: &Path) -> Result { let cache_path = cache::ensure(source, |p| async move { let compressed_data - = fetch(&source.to_url()).await?; + = fetch(url).await?; tokio::task::spawn_blocking(move || -> Result<(), Error> { let data @@ -153,6 +153,18 @@ async fn install_node_js_from_package(source: &cache::CacheKey, main_file: &Path Ok(command) } +async fn install_berry(source: &cache:: CacheKey) -> Result { + if let Some(npm_url) = source.to_npm_url() { + install_node_js_from_package(source, &npm_url, &Path::from_str("bin/yarn.js").unwrap()).await + } else { + install_node_js_from_url(source).await + } +} + +async fn install_yarnpkg_legacy(source: &cache:: CacheKey) -> Result { + install_node_js_from_package(source, &source.to_url(), &Path::from_str("bin/yarn.js").unwrap()).await +} + pub async fn install_package_manager(package_manager: &VersionPackageManagerReference) -> Result { let version_platform = cache::CacheKey { cache_version: cache::CACHE_VERSION, @@ -165,11 +177,11 @@ pub async fn install_package_manager(package_manager: &VersionPackageManagerRefe } if zpm_semver::Range::from_file_string(">=2.0.0-0").unwrap().check_ignore_rc(&package_manager.version) { - return install_node_js_from_url(&version_platform).await; + return install_berry(&version_platform).await; } if zpm_semver::Range::from_file_string(">=0.0.0-0").unwrap().check_ignore_rc(&package_manager.version) { - return install_node_js_from_package(&version_platform, &Path::from_str("bin/yarn.js").unwrap()).await; + return install_yarnpkg_legacy(&version_platform).await; } unreachable!() diff --git a/packages/zpm-switch/tests/postinstall.rs b/packages/zpm-switch/tests/postinstall.rs index 82018efc..b247aa38 100644 --- a/packages/zpm-switch/tests/postinstall.rs +++ b/packages/zpm-switch/tests/postinstall.rs @@ -35,12 +35,12 @@ fn empty_profile_file() -> Result<(), Box> { cmd.assert() .success(); - let profile_content = tmp_dir - .with_join_str(".profile") + let bashrc_content = tmp_dir + .with_join_str(".bashrc") .fs_read_text_prealloc() - .expect("Failed to read .profile"); + .expect("Failed to read .bashrc"); - assert_eq!(profile_content, format!(". \"{}/.yarn/switch/env\"\n", tmp_dir.to_file_string())); + assert_eq!(bashrc_content, format!("# Added by Yarn Switch\nsource \"{}/.yarn/switch/env\"\n", tmp_dir.to_file_string())); Ok(()) } @@ -53,9 +53,9 @@ fn profile_file_with_existing_path() -> Result<(), Box> { } = init_test_env(); tmp_dir - .with_join_str(".profile") + .with_join_str(".bashrc") .fs_write_text("# Hello world!\n") - .expect("Failed to write .profile"); + .expect("Failed to write .bashrc"); cmd.args(vec!["switch", "postinstall", "--home-dir", tmp_dir.as_str()]); cmd.env("SHELL", "/bin/bash"); @@ -63,12 +63,12 @@ fn profile_file_with_existing_path() -> Result<(), Box> { cmd.assert() .success(); - let profile_content = tmp_dir - .with_join_str(".profile") + let bashrc_content = tmp_dir + .with_join_str(".bashrc") .fs_read_text_prealloc() - .expect("Failed to read .profile"); + .expect("Failed to read .bashrc"); - assert_eq!(profile_content, format!("# Hello world!\n. \"{}/.yarn/switch/env\"\n", tmp_dir.to_file_string())); + assert_eq!(bashrc_content, format!("# Hello world!\n\n# Added by Yarn Switch\nsource \"{}/.yarn/switch/env\"\n", tmp_dir.to_file_string())); Ok(()) }