mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-18 04:44:53 +08:00
Fix zip extract not strip dir bug
This commit is contained in:
parent
e2fd3e18d6
commit
4e4ce282db
@ -584,7 +584,7 @@ class FileSystem
|
|||||||
'tar', 'xz', 'txz' => f_passthru("tar -xf {$filename} -C {$target} --strip-components 1"),
|
'tar', 'xz', 'txz' => f_passthru("tar -xf {$filename} -C {$target} --strip-components 1"),
|
||||||
'tgz', 'gz' => f_passthru("tar -xzf {$filename} -C {$target} --strip-components 1"),
|
'tgz', 'gz' => f_passthru("tar -xzf {$filename} -C {$target} --strip-components 1"),
|
||||||
'bz2' => f_passthru("tar -xjf {$filename} -C {$target} --strip-components 1"),
|
'bz2' => f_passthru("tar -xjf {$filename} -C {$target} --strip-components 1"),
|
||||||
'zip' => f_passthru("unzip {$filename} -d {$target}"),
|
'zip' => self::unzipWithStrip($filename, $target),
|
||||||
default => throw new FileSystemException('unknown archive format: ' . $filename),
|
default => throw new FileSystemException('unknown archive format: ' . $filename),
|
||||||
};
|
};
|
||||||
} elseif (PHP_OS_FAMILY === 'Windows') {
|
} elseif (PHP_OS_FAMILY === 'Windows') {
|
||||||
@ -599,7 +599,7 @@ class FileSystem
|
|||||||
match (self::extname($filename)) {
|
match (self::extname($filename)) {
|
||||||
'tar' => f_passthru("tar -xf {$filename} -C {$target} --strip-components 1"),
|
'tar' => f_passthru("tar -xf {$filename} -C {$target} --strip-components 1"),
|
||||||
'xz', 'txz', 'gz', 'tgz', 'bz2' => cmd()->execWithResult("\"{$_7z}\" x -so {$filename} | tar -f - -x -C \"{$target}\" --strip-components 1"),
|
'xz', 'txz', 'gz', 'tgz', 'bz2' => cmd()->execWithResult("\"{$_7z}\" x -so {$filename} | tar -f - -x -C \"{$target}\" --strip-components 1"),
|
||||||
'zip' => f_passthru("\"{$_7z}\" x {$filename} -o{$target} -y"),
|
'zip' => self::unzipWithStrip($filename, $target),
|
||||||
default => throw new FileSystemException("unknown archive format: {$filename}"),
|
default => throw new FileSystemException("unknown archive format: {$filename}"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -644,4 +644,59 @@ class FileSystem
|
|||||||
SPC_SOURCE_LOCAL => symlink(self::convertPath($filename), $extract_path),
|
SPC_SOURCE_LOCAL => symlink(self::convertPath($filename), $extract_path),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unzip file with stripping top-level directory
|
||||||
|
*/
|
||||||
|
private static function unzipWithStrip(string $zip_file, string $extract_path): void
|
||||||
|
{
|
||||||
|
$temp_dir = self::convertPath(sys_get_temp_dir() . '/spc_unzip_' . bin2hex(random_bytes(16)));
|
||||||
|
$zip_file = self::convertPath($zip_file);
|
||||||
|
$extract_path = self::convertPath($extract_path);
|
||||||
|
|
||||||
|
// extract to temp dir
|
||||||
|
self::createDir($temp_dir);
|
||||||
|
|
||||||
|
if (PHP_OS_FAMILY === 'Windows') {
|
||||||
|
$mute = defined('DEBUG_MODE') ? '' : ' > NUL';
|
||||||
|
// use php-sdk-binary-tools/bin/7za.exe
|
||||||
|
$_7z = self::convertPath(getenv('PHP_SDK_PATH') . '/bin/7za.exe');
|
||||||
|
f_passthru("\"{$_7z}\" x {$zip_file} -o{$temp_dir} -y{$mute}");
|
||||||
|
} else {
|
||||||
|
$mute = defined('DEBUG_MODE') ? '' : ' > /dev/null';
|
||||||
|
f_passthru("unzip \"{$zip_file}\" -d \"{$temp_dir}\"{$mute}");
|
||||||
|
}
|
||||||
|
// scan first level dirs (relative, not recursive, include dirs)
|
||||||
|
$contents = self::scanDirFiles($temp_dir, false, true, true);
|
||||||
|
if ($contents === false) {
|
||||||
|
throw new FileSystemException('Cannot scan unzip temp dir: ' . $temp_dir);
|
||||||
|
}
|
||||||
|
// if extract path already exists, remove it
|
||||||
|
if (is_dir($extract_path)) {
|
||||||
|
self::removeDir($extract_path);
|
||||||
|
}
|
||||||
|
// if only one dir, move its contents to extract_path using rename
|
||||||
|
$subdir = self::convertPath("{$temp_dir}/{$contents[0]}");
|
||||||
|
if (count($contents) === 1 && is_dir($subdir)) {
|
||||||
|
rename($subdir, $extract_path);
|
||||||
|
} else {
|
||||||
|
// else, move all contents to extract_path
|
||||||
|
self::createDir($extract_path);
|
||||||
|
foreach ($contents as $item) {
|
||||||
|
$subdir = self::convertPath("{$temp_dir}/{$item}");
|
||||||
|
if (is_dir($subdir)) {
|
||||||
|
// move all dir contents to extract_path (strip top-level)
|
||||||
|
$sub_contents = self::scanDirFiles($subdir, false, true, true);
|
||||||
|
if ($sub_contents === false) {
|
||||||
|
throw new FileSystemException('Cannot scan unzip temp sub-dir: ' . $subdir);
|
||||||
|
}
|
||||||
|
foreach ($sub_contents as $sub_item) {
|
||||||
|
rename(self::convertPath("{$subdir}/{$sub_item}"), self::convertPath("{$extract_path}/{$sub_item}"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rename(self::convertPath("{$temp_dir}/{$item}"), self::convertPath("{$extract_path}/{$item}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user