diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 881842b..6b9f61e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,24 @@ jobs: with: save-cache: ${{ github.ref_name == 'main' }} - - run: cargo check + - uses: actions/setup-node@v4 + with: + node-version: lts/* + + - name: Prepare fixtures + run: | + corepack enable + cd fixtures/global-cache + yarn install + + - name: Build + run: cargo build + + - name: Check + run: cargo check - - run: cargo test + - name: Run tests + run: cargo test clippy: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index 71bc4d3..0a71646 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -93,6 +93,27 @@ dependencies = [ "once_cell", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.60.2", +] + [[package]] name = "endian-type" version = "0.1.2" @@ -171,6 +192,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "glob" version = "0.3.2" @@ -211,6 +243,16 @@ version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +[[package]] +name = "libredox" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" +dependencies = [ + "bitflags 2.9.1", + "libc", +] + [[package]] name = "mach2" version = "0.4.3" @@ -289,6 +331,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "path-slash" version = "0.2.1" @@ -320,6 +368,7 @@ dependencies = [ "byteorder", "clean-path", "concurrent_lru", + "dirs", "fancy-regex", "miniz_oxide", "mmap-rs", @@ -370,6 +419,17 @@ dependencies = [ "nibble_vec", ] +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom", + "libredox", + "thiserror 2.0.12", +] + [[package]] name = "regex" version = "1.11.1" @@ -613,6 +673,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + [[package]] name = "widestring" version = "1.2.0" @@ -625,7 +691,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] [[package]] @@ -646,6 +712,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -670,13 +745,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -689,6 +780,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -701,6 +798,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -713,12 +816,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -731,6 +846,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -743,6 +864,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -755,6 +882,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -767,6 +900,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.7.11" diff --git a/Cargo.toml b/Cargo.toml index 1510fa7..1597715 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ thiserror = "2" rustc-hash = "2" [dev-dependencies] +dirs = "6.0.0" rstest = "0.25.0" [features] diff --git a/fixtures/global-cache/.gitignore b/fixtures/global-cache/.gitignore new file mode 100644 index 0000000..5f58b7e --- /dev/null +++ b/fixtures/global-cache/.gitignore @@ -0,0 +1,2 @@ +.yarn/* +.pnp.* diff --git a/fixtures/global-cache/.yarnrc.yml b/fixtures/global-cache/.yarnrc.yml new file mode 100644 index 0000000..956fdce --- /dev/null +++ b/fixtures/global-cache/.yarnrc.yml @@ -0,0 +1,3 @@ +enableGlobalCache: true + +nodeLinker: pnp diff --git a/fixtures/global-cache/package.json b/fixtures/global-cache/package.json new file mode 100644 index 0000000..1be2eac --- /dev/null +++ b/fixtures/global-cache/package.json @@ -0,0 +1,7 @@ +{ + "name": "global-cache", + "dependencies": { + "source-map-support": "^0.5.21" + }, + "packageManager": "yarn@4.9.2" +} diff --git a/fixtures/global-cache/test.js b/fixtures/global-cache/test.js new file mode 100644 index 0000000..1e73bc0 --- /dev/null +++ b/fixtures/global-cache/test.js @@ -0,0 +1 @@ +console.log(require.resolve('source-map-support')); diff --git a/fixtures/global-cache/yarn.lock b/fixtures/global-cache/yarn.lock new file mode 100644 index 0000000..dd14adb --- /dev/null +++ b/fixtures/global-cache/yarn.lock @@ -0,0 +1,38 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"buffer-from@npm:^1.0.0": + version: 1.1.2 + resolution: "buffer-from@npm:1.1.2" + checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 + languageName: node + linkType: hard + +"global-cache@workspace:.": + version: 0.0.0-use.local + resolution: "global-cache@workspace:." + dependencies: + source-map-support: "npm:^0.5.21" + languageName: unknown + linkType: soft + +"source-map-support@npm:^0.5.21": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10c0/9ee09942f415e0f721d6daad3917ec1516af746a8120bba7bb56278707a37f1eb8642bde456e98454b8a885023af81a16e646869975f06afc1a711fb90484e7d + languageName: node + linkType: hard + +"source-map@npm:^0.6.0": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 + languageName: node + linkType: hard diff --git a/src/lib.rs b/src/lib.rs index c48fef8..98ad91f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -157,12 +157,18 @@ pub fn init_pnp_manifest>(manifest: &mut Manifest, p: P) { for (name, ranges) in manifest.package_registry_data.iter_mut() { for (reference, info) in ranges.iter_mut() { + println!("manifest.manifest_dir, {}", manifest.manifest_dir.to_string_lossy()); + let package_location = manifest.manifest_dir.join(info.package_location.clone()); let normalized_location = util::normalize_path(package_location.to_string_lossy()); + println!("normalized_location: {normalized_location}"); + info.package_location = PathBuf::from(normalized_location); + println!("info.package_location: {}", info.package_location.to_string_lossy()); + if !info.discard_from_lookup { manifest.location_trie.insert( &info.package_location, @@ -207,6 +213,12 @@ pub fn find_locator<'a, P: AsRef>( } } + println!("path {}", path.as_ref().to_string_lossy()); + + let path = util::normalize_path(path.as_ref().to_string_lossy()); + + println!("path {path}"); + manifest.location_trie.get_ancestor_value(&path) } diff --git a/src/lib_tests.rs b/src/lib_tests.rs index 44ad700..483d0d5 100644 --- a/src/lib_tests.rs +++ b/src/lib_tests.rs @@ -18,12 +18,12 @@ struct TestSuite { #[cfg(test)] mod tests { - use std::{fs, path::PathBuf}; + use std::{env, fs, path::PathBuf}; use super::*; use crate::{ ResolutionConfig, ResolutionHost, init_pnp_manifest, load_pnp_manifest, - parse_bare_identifier, resolve_to_unqualified, resolve_to_unqualified_via_manifest, + parse_bare_identifier, resolve_to_unqualified, resolve_to_unqualified_via_manifest, util, }; #[test] @@ -163,4 +163,49 @@ mod tests { let parsed = parse_bare_identifier("@scope/pkg/a/b/c/index.js"); assert_eq!(parsed, Ok(("@scope/pkg".to_string(), Some("a/b/c/index.js".to_string())))); } + + #[test] + fn test_global_cache() { + let manifest = load_pnp_manifest( + env::current_dir().unwrap().join("fixtures").join("global-cache").join(".pnp.cjs"), + ) + .unwrap(); + + let home_dir = dirs::home_dir().unwrap(); + + #[cfg(windows)] + let global_cache = home_dir.join("AppData\\Local\\Yarn\\Berry\\cache"); + #[cfg(not(windows))] + let global_cache = home_dir.join(".yarn/berry/cache"); + + let result = resolve_to_unqualified_via_manifest( + &manifest, + "source-map", + global_cache + .join("source-map-support-npm-0.5.21-09ca99e250-10c0.zip") + .join("node_modules") + .join("source-map-support") + .join(""), + ); + + match result { + Ok(Resolution::Resolved(path, subpath)) => { + assert_eq!( + path.to_string_lossy(), + util::normalize_path( + global_cache + .join("source-map-npm-0.6.1-1a3621db16-10c0.zip") + .join("node_modules") + .join("source-map") + .join("") + .to_string_lossy() + ) + ); + assert_eq!(subpath, None); + } + _ => { + panic!("Unexpected resolve failed"); + } + } + } } diff --git a/src/util.rs b/src/util.rs index ec9a7b9..cc5f3a5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Deserializer, de::Error}; use std::borrow::Cow; use path_slash::PathBufExt; -use std::path::{Path, PathBuf}; +use std::path::{MAIN_SEPARATOR_STR, Path, PathBuf}; #[derive(Debug, Default, Clone)] pub struct Trie { @@ -39,7 +39,9 @@ pub fn normalize_path>(original: P) -> String { let p = PathBuf::from(original_str); let mut str = clean_path::clean(p).to_slash_lossy().to_string(); - if original_str.ends_with('/') && !str.ends_with('/') { + if (original_str.ends_with('/') || original_str.ends_with(MAIN_SEPARATOR_STR)) + && !str.ends_with('/') + { str.push('/'); }