aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/downloader
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-12 04:20:57 +0900
committernsfisis <nsfisis@gmail.com>2026-05-12 04:20:57 +0900
commit213c3d019a43d765638c2a0fdf26b7b322899ca1 (patch)
treeebf18e97e0e6b8c75c436490c6135916398876fb /crates/shirabe/src/downloader
parent698bccd425ccefcb4728c4035fa08ebd9dd258f6 (diff)
downloadphp-shirabe-213c3d019a43d765638c2a0fdf26b7b322899ca1.tar.gz
php-shirabe-213c3d019a43d765638c2a0fdf26b7b322899ca1.tar.zst
php-shirabe-213c3d019a43d765638c2a0fdf26b7b322899ca1.zip
feat(port): port GzipDownloader.php
Diffstat (limited to 'crates/shirabe/src/downloader')
-rw-r--r--crates/shirabe/src/downloader/gzip_downloader.rs70
1 files changed, 70 insertions, 0 deletions
diff --git a/crates/shirabe/src/downloader/gzip_downloader.rs b/crates/shirabe/src/downloader/gzip_downloader.rs
index bb976da..2158126 100644
--- a/crates/shirabe/src/downloader/gzip_downloader.rs
+++ b/crates/shirabe/src/downloader/gzip_downloader.rs
@@ -1 +1,71 @@
//! ref: composer/src/Composer/Downloader/GzipDownloader.php
+
+use anyhow::Result;
+use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::{
+ RuntimeException,
+ extension_loaded, fclose, fopen, fwrite, gzclose, gzopen, gzread,
+ implode, parse_url, pathinfo, strtr,
+ DIRECTORY_SEPARATOR, PATHINFO_FILENAME, PHP_URL_PATH,
+};
+use crate::downloader::archive_downloader::ArchiveDownloader;
+use crate::package::package_interface::PackageInterface;
+use crate::util::platform::Platform;
+
+pub struct GzipDownloader {
+ inner: ArchiveDownloader,
+}
+
+impl GzipDownloader {
+ pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> {
+ let filename = pathinfo(
+ parse_url(&strtr(&package.get_dist_url().unwrap_or_default(), "\\", "/"), PHP_URL_PATH),
+ PATHINFO_FILENAME,
+ );
+ let target_filepath = format!("{}{}{}", path, DIRECTORY_SEPARATOR, filename);
+
+ if !Platform::is_windows() {
+ let command = vec![
+ "sh".to_string(),
+ "-c".to_string(),
+ "gzip -cd -- \"$0\" > \"$1\"".to_string(),
+ file.to_string(),
+ target_filepath.clone(),
+ ];
+
+ if self.inner.process.execute(&command, &mut String::new()) == 0 {
+ return Ok(shirabe_external_packages::react::promise::resolve(None));
+ }
+
+ if extension_loaded("zlib") {
+ self.extract_using_ext(file, &target_filepath);
+ return Ok(shirabe_external_packages::react::promise::resolve(None));
+ }
+
+ let process_error = format!(
+ "Failed to execute {}\n\n{}",
+ implode(" ", &command),
+ self.inner.process.get_error_output(),
+ );
+ return Err(anyhow::anyhow!(RuntimeException { message: process_error, code: 0 }));
+ }
+
+ self.extract_using_ext(file, &target_filepath);
+
+ Ok(shirabe_external_packages::react::promise::resolve(None))
+ }
+
+ fn extract_using_ext(&self, file: &str, target_filepath: &str) {
+ let archive_file = gzopen(file, "rb");
+ let target_file = fopen(target_filepath, "wb");
+ loop {
+ let string = gzread(archive_file.clone(), 4096);
+ if string.is_empty() {
+ break;
+ }
+ fwrite(target_file.clone(), &string, Platform::strlen(&string));
+ }
+ gzclose(archive_file);
+ fclose(target_file);
+ }
+}