From 01675eda6a7f6f8102de4921f504187467434179 Mon Sep 17 00:00:00 2001 From: ityuany <519495771@qq.com> Date: Tue, 2 Jul 2024 17:44:30 +0800 Subject: [PATCH] yarn bugfix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit . ├── 1.22.0 │ └── yarn-v1.22.0 ├── 1.22.1 │ └── package ├── 1.22.10 │ └── yarn-v1.22.10 ├── 1.22.21 │ └── package ├── 1.22.22 │ └── package ├── 2.4.1 │ └── package ├── 2.4.2 │ └── package ├── 4.0.0 │ └── package --- crates/snm_tarball/src/lib.rs | 42 +++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/crates/snm_tarball/src/lib.rs b/crates/snm_tarball/src/lib.rs index 09428deb..1d08f81c 100644 --- a/crates/snm_tarball/src/lib.rs +++ b/crates/snm_tarball/src/lib.rs @@ -1,6 +1,9 @@ use flate2::read::GzDecoder; use snm_utils::snm_error::SnmError; -use std::{fs::File, path::PathBuf}; +use std::{ + fs::File, + path::{Path, PathBuf}, +}; use tar::Archive; use xz2::read::XzDecoder; @@ -20,9 +23,44 @@ pub fn decompress( match tarball_type { TarballType::Tgz => { + let new_dir_name = "package"; let decoder = GzDecoder::new(input_file); let mut archive = Archive::new(decoder); - archive.unpack(output_path)?; + + // yarn decompress dir different versions are different. + // . + // ├── 1.22.0 + // │ └── yarn-v1.22.0 👈 + // ├── 1.22.1 + // │ └── package + // ├── 1.22.10 + // │ └── yarn-v1.22.10 👈 + // ├── 1.22.21 + // │ └── package + // ├── 1.22.22 + // │ └── package + // ├── 2.4.1 + // │ └── package + // ├── 2.4.2 + // │ └── package + // ├── 4.0.0 + // │ └── package + + for entry in archive.entries()? { + let mut entry = entry?; + let path = entry.path()?.to_owned(); + let new_path = if let Some(first_component) = path.components().next() { + let stripped = path.strip_prefix(first_component.as_os_str()).unwrap(); + Path::new(new_dir_name).join(stripped) + } else { + path.to_path_buf() + }; + let final_path = Path::new(&output_path).join(new_path); + if let Some(parent) = final_path.parent() { + std::fs::create_dir_all(parent)?; + } + entry.unpack(final_path)?; + } } TarballType::Xz => { let decoder = XzDecoder::new(input_file);