mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-14 04:15:35 +08:00
Enhance Windows support by updating artifact configuration and improving extraction logic
This commit is contained in:
@@ -167,11 +167,22 @@ class Artifact
|
||||
return false;
|
||||
}
|
||||
|
||||
// For standalone mode, check directory and hash
|
||||
// For standalone mode, check directory or file and hash
|
||||
$target_path = $extract_config['path'];
|
||||
|
||||
if (!is_dir($target_path)) {
|
||||
return false;
|
||||
// Check if target is a file or directory
|
||||
$is_file_target = !is_dir($target_path) && str_contains($target_path, '.');
|
||||
|
||||
if ($is_file_target) {
|
||||
// For single file extraction (e.g., vswhere.exe)
|
||||
if (!file_exists($target_path)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// For directory extraction
|
||||
if (!is_dir($target_path)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$compare_hash) {
|
||||
@@ -320,7 +331,7 @@ class Artifact
|
||||
* For merge mode, returns the base path.
|
||||
* For standalone mode, returns the specific directory.
|
||||
*/
|
||||
public function getBinaryDir(): string
|
||||
public function getBinaryDir(): ?string
|
||||
{
|
||||
$config = $this->getBinaryExtractConfig();
|
||||
return $config['path'];
|
||||
|
||||
@@ -293,7 +293,7 @@ class ArtifactExtractor
|
||||
// Process file mappings
|
||||
foreach ($file_map as $src_pattern => $dst_path) {
|
||||
$dst_path = $this->replacePathVariables($dst_path);
|
||||
$src_full = "{$temp_path}/{$src_pattern}";
|
||||
$src_full = FileSystem::convertPath("{$temp_path}/{$src_pattern}");
|
||||
|
||||
// Handle glob patterns
|
||||
if (str_contains($src_pattern, '*')) {
|
||||
@@ -460,40 +460,36 @@ class ArtifactExtractor
|
||||
$target = FileSystem::convertPath($target);
|
||||
$filename = FileSystem::convertPath($filename);
|
||||
|
||||
FileSystem::createDir($target);
|
||||
$extname = FileSystem::extname($filename);
|
||||
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
// Use 7za.exe for Windows
|
||||
$is_txz = str_ends_with($filename, '.txz') || str_ends_with($filename, '.tar.xz');
|
||||
default_shell()->execute7zExtract($filename, $target, $is_txz);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unix-like systems: determine compression type
|
||||
if (str_ends_with($filename, '.tar.gz') || str_ends_with($filename, '.tgz')) {
|
||||
default_shell()->executeTarExtract($filename, $target, 'gz');
|
||||
} elseif (str_ends_with($filename, '.tar.bz2')) {
|
||||
default_shell()->executeTarExtract($filename, $target, 'bz2');
|
||||
} elseif (str_ends_with($filename, '.tar.xz') || str_ends_with($filename, '.txz')) {
|
||||
default_shell()->executeTarExtract($filename, $target, 'xz');
|
||||
} elseif (str_ends_with($filename, '.tar')) {
|
||||
default_shell()->executeTarExtract($filename, $target, 'none');
|
||||
} elseif (str_ends_with($filename, '.zip')) {
|
||||
// Zip requires special handling for strip-components
|
||||
$this->unzipWithStrip($filename, $target);
|
||||
} elseif (str_ends_with($filename, '.exe')) {
|
||||
// exe just copy to target
|
||||
$dest_file = FileSystem::convertPath("{$target}/" . basename($filename));
|
||||
FileSystem::copy($filename, $dest_file);
|
||||
} else {
|
||||
throw new FileSystemException("Unknown archive format: {$filename}");
|
||||
if ($extname !== 'exe' && !is_dir($target)) {
|
||||
FileSystem::createDir($target);
|
||||
}
|
||||
match (SystemTarget::getTargetOS()) {
|
||||
'Windows' => match ($extname) {
|
||||
'tar' => default_shell()->executeTarExtract($filename, $target, 'none'),
|
||||
'xz', 'txz', 'gz', 'tgz', 'bz2' => default_shell()->execute7zExtract($filename, $target),
|
||||
'zip' => $this->unzipWithStrip($filename, $target),
|
||||
'exe' => $this->copyFile($filename, $target),
|
||||
default => throw new FileSystemException("Unknown archive format: {$filename}"),
|
||||
},
|
||||
'Linux', 'Darwin' => match ($extname) {
|
||||
'tar' => default_shell()->executeTarExtract($filename, $target, 'none'),
|
||||
'gz', 'tgz' => default_shell()->executeTarExtract($filename, $target, 'gz'),
|
||||
'bz2' => default_shell()->executeTarExtract($filename, $target, 'bz2'),
|
||||
'xz', 'txz' => default_shell()->executeTarExtract($filename, $target, 'xz'),
|
||||
'zip' => $this->unzipWithStrip($filename, $target),
|
||||
'exe' => $this->copyFile($filename, $target),
|
||||
default => throw new FileSystemException("Unknown archive format: {$filename}"),
|
||||
},
|
||||
default => throw new SPCInternalException('Unsupported OS for archive extraction')
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Unzip file with stripping top-level directory.
|
||||
*/
|
||||
protected function unzipWithStrip(string $zip_file, string $extract_path): void
|
||||
protected function unzipWithStrip(string $zip_file, string $extract_path): bool
|
||||
{
|
||||
$temp_dir = FileSystem::convertPath(sys_get_temp_dir() . '/spc_unzip_' . bin2hex(random_bytes(16)));
|
||||
$zip_file = FileSystem::convertPath($zip_file);
|
||||
@@ -572,6 +568,8 @@ class ArtifactExtractor
|
||||
|
||||
// Clean up temp directory
|
||||
FileSystem::removeDir($temp_dir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -585,6 +583,7 @@ class ArtifactExtractor
|
||||
'{source_path}' => SOURCE_PATH,
|
||||
'{download_path}' => DOWNLOAD_PATH,
|
||||
'{working_dir}' => WORKING_DIR,
|
||||
'{php_sdk_path}' => getenv('PHP_SDK_PATH') ?: '',
|
||||
];
|
||||
return str_replace(array_keys($replacement), array_values($replacement), $path);
|
||||
}
|
||||
@@ -627,9 +626,9 @@ class ArtifactExtractor
|
||||
}
|
||||
}
|
||||
|
||||
private function copyFile(string $source_file, string $target_path): void
|
||||
private function copyFile(string $source_file, string $target_path): bool
|
||||
{
|
||||
FileSystem::createDir(dirname($target_path));
|
||||
FileSystem::copy(FileSystem::convertPath($source_file), $target_path);
|
||||
return FileSystem::copy(FileSystem::convertPath($source_file), $target_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ class DownloadResult
|
||||
) {
|
||||
switch ($this->cache_type) {
|
||||
case 'archive':
|
||||
$this->filename !== null ?: throw new DownloaderException('Archive download result must have a filename.');
|
||||
case 'file':
|
||||
$this->filename !== null ?: throw new DownloaderException('Archive/file download result must have a filename.');
|
||||
$fn = FileSystem::isRelativePath($this->filename) ? (DOWNLOAD_PATH . DIRECTORY_SEPARATOR . $this->filename) : $this->filename;
|
||||
file_exists($fn) ?: throw new DownloaderException("Downloaded archive file does not exist: {$fn}");
|
||||
break;
|
||||
@@ -60,7 +61,20 @@ class DownloadResult
|
||||
?string $version = null,
|
||||
array $metadata = []
|
||||
): DownloadResult {
|
||||
return new self('archive', config: $config, filename: $filename, extract: $extract, verified: $verified, version: $version, metadata: $metadata);
|
||||
// judge if it is archive or just a pure file
|
||||
$cache_type = self::isArchiveFile($filename) ? 'archive' : 'file';
|
||||
return new self($cache_type, config: $config, filename: $filename, extract: $extract, verified: $verified, version: $version, metadata: $metadata);
|
||||
}
|
||||
|
||||
public static function file(
|
||||
string $filename,
|
||||
array $config,
|
||||
bool $verified = false,
|
||||
?string $version = null,
|
||||
array $metadata = []
|
||||
): DownloadResult {
|
||||
$cache_type = self::isArchiveFile($filename) ? 'archive' : 'file';
|
||||
return new self($cache_type, config: $config, filename: $filename, verified: $verified, version: $version, metadata: $metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,4 +157,16 @@ class DownloadResult
|
||||
array_merge($this->metadata, [$key => $value])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check
|
||||
*/
|
||||
private static function isArchiveFile(string $filename): bool
|
||||
{
|
||||
$archive_extensions = [
|
||||
'zip', 'tar', 'tar.gz', 'tgz', 'tar.bz2', 'tbz2', 'tar.xz', 'txz', 'rar', '7z',
|
||||
];
|
||||
$lower_filename = strtolower($filename);
|
||||
return array_any($archive_extensions, fn ($ext) => str_ends_with($lower_filename, '.' . $ext));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user