Skip to content

Commit

Permalink
add feature toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Jul 11, 2024
1 parent 2eeb597 commit 5c2b66e
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 55 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ once_cell = "1.19.0" # Use `std::sync::OnceLock::get_or_try_init` when it is sta
thiserror = "1.0.61"
json-strip-comments = "1.0.2"
indexmap = { version = "2.2.6", features = ["serde"] }
pnp = "0.8.0"
cfg-if = "1.0"

pnp = { version = "0.8.0", optional = true }

document-features = { version = "0.2.8", optional = true }

Expand All @@ -100,6 +102,8 @@ default = []
## Enables the [PackageJson::raw_json] API,
## which returns the `package.json` with `serde_json::Value`.
package_json_raw_json_api = []
## [Yarn Plug'n'Play](https://yarnpkg.com/features/pnp)
yarn_pnp = ["pnp"]
# For codspeed benchmark
codspeed = ["criterion2/codspeed"]

Expand Down
7 changes: 5 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ alias r := ready
# or install via `cargo install cargo-binstall`
# Initialize the project by installing all the necessary tools.
init:
pnpm install
cargo binstall cargo-watch typos-cli taplo-cli cargo-llvm-cov -y

install:
pnpm install
cd fixtures/pnp && yarn

# When ready, run the same CI commands
ready:
git diff --exit-code --quiet
Expand Down Expand Up @@ -44,7 +47,7 @@ check:

# Run all the tests
test:
cargo test
cargo test --all-features

# Lint the whole project
lint:
Expand Down
128 changes: 78 additions & 50 deletions src/file_system.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use cfg_if::cfg_if;
use std::{
fs, io,
path::{Component, Path, PathBuf},
};

#[cfg(feature = "yarn_pnp")]
use pnp::fs::{LruZipCache, VPath, VPathInfo, ZipCache};

/// File System abstraction used for `ResolverGeneric`
Expand Down Expand Up @@ -69,6 +71,7 @@ impl FileMetadata {
}
}

#[cfg(feature = "yarn_pnp")]
impl From<pnp::fs::FileType> for FileMetadata {
fn from(value: pnp::fs::FileType) -> Self {
Self::new(value == pnp::fs::FileType::File, value == pnp::fs::FileType::Directory, false)
Expand All @@ -82,35 +85,59 @@ impl From<fs::Metadata> for FileMetadata {
}

/// Operating System
#[cfg(feature = "yarn_pnp")]
pub struct FileSystemOs {
pub pnp_lru: LruZipCache<Vec<u8>>,
pnp_lru: LruZipCache<Vec<u8>>,
}

#[cfg(not(feature = "yarn_pnp"))]
pub struct FileSystemOs;

impl Default for FileSystemOs {
fn default() -> Self {
Self { pnp_lru: LruZipCache::new(50, pnp::fs::open_zip_via_read_p) }
cfg_if! {
if #[cfg(feature = "yarn_pnp")] {
Self { pnp_lru: LruZipCache::new(50, pnp::fs::open_zip_via_read_p) }
} else {
Self
}
}
}
}

impl FileSystem for FileSystemOs {
fn read_to_string(&self, path: &Path) -> io::Result<String> {
match VPath::from(path)? {
VPath::Zip(info) => {
self.pnp_lru.read_to_string(info.physical_base_path(), info.zip_path)
cfg_if! {
if #[cfg(feature = "yarn_pnp")] {
match VPath::from(path)? {
VPath::Zip(info) => {
self.pnp_lru.read_to_string(info.physical_base_path(), info.zip_path)
}
VPath::Virtual(info) => fs::read_to_string(info.physical_base_path()),
VPath::Native(path) => fs::read_to_string(path),
}
} else {
fs::read_to_string(path)
}
VPath::Virtual(info) => fs::read_to_string(info.physical_base_path()),
VPath::Native(path) => fs::read_to_string(path),
}
}

fn metadata(&self, path: &Path) -> io::Result<FileMetadata> {
match VPath::from(path)? {
VPath::Zip(info) => self
.pnp_lru
.file_type(info.physical_base_path(), info.zip_path)
.map(FileMetadata::from),
VPath::Virtual(info) => fs::metadata(info.physical_base_path()).map(FileMetadata::from),
VPath::Native(path) => fs::metadata(path).map(FileMetadata::from),
cfg_if! {
if #[cfg(feature = "yarn_pnp")] {
match VPath::from(path)? {
VPath::Zip(info) => self
.pnp_lru
.file_type(info.physical_base_path(), info.zip_path)
.map(FileMetadata::from),
VPath::Virtual(info) => {
fs::metadata(info.physical_base_path()).map(FileMetadata::from)
}
VPath::Native(path) => fs::metadata(path).map(FileMetadata::from),
}
} else {
fs::metadata(path).map(FileMetadata::from)
}
}
}

Expand All @@ -119,49 +146,50 @@ impl FileSystem for FileSystemOs {
}

fn canonicalize(&self, path: &Path) -> io::Result<PathBuf> {
#[cfg(target_os = "windows")]
{
match VPath::from(path)? {
VPath::Zip(info) => {
dunce::canonicalize(info.physical_base_path().join(info.zip_path))
cfg_if! {
if #[cfg(feature = "yarn_pnp")] {
match VPath::from(path)? {
VPath::Zip(info) => {
dunce::canonicalize(info.physical_base_path().join(info.zip_path))
}
VPath::Virtual(info) => dunce::canonicalize(info.physical_base_path()),
VPath::Native(path) => dunce::canonicalize(path),
}
VPath::Virtual(info) => dunce::canonicalize(info.physical_base_path()),
VPath::Native(path) => dunce::canonicalize(path),
}
}
#[cfg(not(target_os = "windows"))]
{
let mut path_buf = path.to_path_buf();
loop {
let link = fs::read_link(&path_buf)?;
path_buf.pop();
for component in link.components() {
match component {
Component::ParentDir => {
path_buf.pop();
}
Component::Normal(seg) => {
#[cfg(target_family = "wasm")]
// Need to trim the extra \0 introduces by https://github.com/nodejs/uvwasi/issues/262
{
path_buf.push(seg.to_string_lossy().trim_end_matches('\0'));
} else if #[cfg(windows)] {
dunce::canonicalize(path)
} else {
let mut path_buf = path.to_path_buf();
loop {
let link = fs::read_link(&path_buf)?;
path_buf.pop();
for component in link.components() {
match component {
Component::ParentDir => {
path_buf.pop();
}
#[cfg(not(target_family = "wasm"))]
{
path_buf.push(seg);
Component::Normal(seg) => {
#[cfg(target_family = "wasm")]
// Need to trim the extra \0 introduces by https://github.com/nodejs/uvwasi/issues/262
{
path_buf.push(seg.to_string_lossy().trim_end_matches('\0'));
}
#[cfg(not(target_family = "wasm"))]
{
path_buf.push(seg);
}
}
Component::RootDir => {
path_buf = PathBuf::from("/");
}
Component::CurDir | Component::Prefix(_) => {}
}
Component::RootDir => {
path_buf = PathBuf::from("/");
}
Component::CurDir | Component::Prefix(_) => {}
}
if !fs::symlink_metadata(&path_buf)?.is_symlink() {
break;
}
}
if !fs::symlink_metadata(&path_buf)?.is_symlink() {
break;
}
Ok(path_buf)
}
Ok(path_buf)
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,11 @@ impl<Fs: FileSystem> ResolverGeneric<Fs> {
specifier: &str,
ctx: &mut Ctx,
) -> ResolveResult {
if let Some(resolved_path) = self.load_pnp(cached_path, specifier, ctx)? {
return Ok(Some(resolved_path));
#[cfg(feature = "yarn_pnp")]
{
if let Some(resolved_path) = self.load_pnp(cached_path, specifier, ctx)? {
return Ok(Some(resolved_path));
}
}

let (package_name, subpath) = Self::parse_package_specifier(specifier);
Expand Down Expand Up @@ -740,6 +743,7 @@ impl<Fs: FileSystem> ResolverGeneric<Fs> {
Ok(None)
}

#[cfg(feature = "yarn_pnp")]
fn load_pnp(
&self,
cached_path: &CachedPath,
Expand Down
3 changes: 3 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ pub struct ResolveOptions {
/// A manifest loaded from pnp::load_pnp_manifest.
///
/// Default `None`
#[cfg(feature = "yarn_pnp")]
pub pnp_manifest: Option<pnp::Manifest>,

/// Resolve to a context instead of a file.
Expand Down Expand Up @@ -466,6 +467,7 @@ impl Default for ResolveOptions {
main_fields: vec!["main".into()],
main_files: vec!["index".into()],
modules: vec!["node_modules".into()],
#[cfg(feature = "yarn_pnp")]
pnp_manifest: None,
resolve_to_context: false,
prefer_relative: false,
Expand Down Expand Up @@ -615,6 +617,7 @@ mod test {
main_fields: vec![],
main_files: vec![],
modules: vec![],
#[cfg(feature = "yarn_pnp")]
pnp_manifest: None,
prefer_absolute: false,
prefer_relative: false,
Expand Down
1 change: 1 addition & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod incorrect_description_file;
mod main_field;
mod memory_fs;
mod missing;
#[cfg(feature = "yarn_pnp")]
mod pnp;
mod resolve;
mod restrictions;
Expand Down

0 comments on commit 5c2b66e

Please sign in to comment.