aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/downloader
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/downloader')
-rw-r--r--crates/shirabe/src/downloader/archive_downloader.rs4
-rw-r--r--crates/shirabe/src/downloader/download_manager.rs2
-rw-r--r--crates/shirabe/src/downloader/file_downloader.rs37
-rw-r--r--crates/shirabe/src/downloader/filesystem_exception.rs8
-rw-r--r--crates/shirabe/src/downloader/git_downloader.rs88
-rw-r--r--crates/shirabe/src/downloader/gzip_downloader.rs58
-rw-r--r--crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs15
-rw-r--r--crates/shirabe/src/downloader/path_downloader.rs10
-rw-r--r--crates/shirabe/src/downloader/phar_downloader.rs94
-rw-r--r--crates/shirabe/src/downloader/rar_downloader.rs111
-rw-r--r--crates/shirabe/src/downloader/tar_downloader.rs94
-rw-r--r--crates/shirabe/src/downloader/transport_exception.rs8
-rw-r--r--crates/shirabe/src/downloader/vcs_downloader.rs2
-rw-r--r--crates/shirabe/src/downloader/xz_downloader.rs110
-rw-r--r--crates/shirabe/src/downloader/zip_downloader.rs18
15 files changed, 604 insertions, 55 deletions
diff --git a/crates/shirabe/src/downloader/archive_downloader.rs b/crates/shirabe/src/downloader/archive_downloader.rs
index 03edffe..02cd8a9 100644
--- a/crates/shirabe/src/downloader/archive_downloader.rs
+++ b/crates/shirabe/src/downloader/archive_downloader.rs
@@ -99,7 +99,7 @@ pub trait ArchiveDownloader {
self.inner_mut().add_cleanup_path(package, &temporary_dir);
// avoid cleaning up $path if installing in "." for eg create-project as we can not
// delete the directory we are currently in on windows
- if !is_dir(path) || realpath(path) != Platform::get_cwd() {
+ if !is_dir(path) || realpath(path) != Platform::get_cwd(false).unwrap_or_default() {
self.inner_mut().add_cleanup_path(package, path);
}
@@ -116,7 +116,7 @@ pub trait ArchiveDownloader {
// clean up
filesystem.remove_directory(&temporary_dir);
- if is_dir(path) && realpath(path) != Platform::get_cwd() {
+ if is_dir(path) && realpath(path) != Platform::get_cwd(false).unwrap_or_default() {
filesystem.remove_directory(path);
}
self.inner_mut()
diff --git a/crates/shirabe/src/downloader/download_manager.rs b/crates/shirabe/src/downloader/download_manager.rs
index c03f704..db3484e 100644
--- a/crates/shirabe/src/downloader/download_manager.rs
+++ b/crates/shirabe/src/downloader/download_manager.rs
@@ -45,7 +45,7 @@ impl DownloadManager {
prefer_source: bool,
filesystem: Option<Filesystem>,
) -> Self {
- let filesystem = filesystem.unwrap_or_else(Filesystem::new);
+ let filesystem = filesystem.unwrap_or_else(|| Filesystem::new(None));
Self {
io,
prefer_source,
diff --git a/crates/shirabe/src/downloader/file_downloader.rs b/crates/shirabe/src/downloader/file_downloader.rs
index e6b471f..85e43fc 100644
--- a/crates/shirabe/src/downloader/file_downloader.rs
+++ b/crates/shirabe/src/downloader/file_downloader.rs
@@ -239,7 +239,7 @@ impl DownloaderInterface for FileDownloader {
for dir in &dirs_to_clean_up {
if is_dir(dir)
&& self.filesystem.is_dir_empty(dir)?
- && realpath(dir).as_deref() != Some(&Platform::get_cwd())
+ && realpath(dir).as_deref() != Some(&Platform::get_cwd(false).unwrap_or_default())
{
self.filesystem.remove_directory_php(dir)?;
}
@@ -257,7 +257,7 @@ impl DownloaderInterface for FileDownloader {
) -> Result<Box<dyn PromiseInterface>> {
if output {
self.io
- .write_error(&format!(" - {}", InstallOperation::format(package)));
+ .write_error(&format!(" - {}", InstallOperation::format(package, false)));
}
let vendor_dir = self
@@ -277,7 +277,7 @@ impl DownloaderInterface for FileDownloader {
.normalize_path(&format!("{}{}", path, DIRECTORY_SEPARATOR));
strpos(&normalized_vendor, &normalized_path).is_some()
} {
- self.filesystem.empty_directory(path)?;
+ self.filesystem.empty_directory(path, true)?;
}
self.filesystem.ensure_directory_exists(path)?;
self.filesystem.rename(
@@ -294,17 +294,16 @@ impl DownloaderInterface for FileDownloader {
for bin in package.get_binaries() {
let bin_path = format!("{}/{}", path, bin);
if file_exists(&bin_path) && !is_executable(&bin_path) {
- Silencer::call_named(
- "chmod",
- &[
- PhpMixed::String(bin_path),
- PhpMixed::Int((0o777 & !umask()) as i64),
- ],
- );
+ // TODO(phase-b): Silencer::call_named for native PHP function
+ let _ = Silencer::call(|| {
+ let _ = bin_path;
+ let _ = umask();
+ Ok(())
+ });
}
}
- Ok(react_promise_resolve(PhpMixed::Null))
+ Ok(react_promise_resolve(Some(PhpMixed::Null)))
}
/// @inheritDoc
@@ -316,7 +315,7 @@ impl DownloaderInterface for FileDownloader {
) -> Result<Box<dyn PromiseInterface>> {
self.io.write_error(&format!(
" - {}{}",
- UpdateOperation::format(initial, target),
+ UpdateOperation::format(initial, target, false),
self.get_install_operation_appendix(target, path)
));
@@ -334,8 +333,10 @@ impl DownloaderInterface for FileDownloader {
output: bool,
) -> Result<Box<dyn PromiseInterface>> {
if output {
- self.io
- .write_error(&format!(" - {}", UninstallOperation::format(package)));
+ self.io.write_error(&format!(
+ " - {}",
+ UninstallOperation::format(package, false)
+ ));
}
let _promise = self.filesystem.remove_directory_async(path)?;
@@ -394,12 +395,12 @@ impl ChangeReportInterface for FileDownloader {
}
let mut comparer = Comparer::new();
- comparer.set_source(&format!("{}_compare", target_dir));
- comparer.set_update(&target_dir);
+ comparer.set_source(format!("{}_compare", target_dir));
+ comparer.set_update(target_dir.clone());
comparer.do_compare();
- output = comparer.get_changed_as_string(true);
+ output = comparer.get_changed_as_string(true, false);
self.filesystem
- .remove_directory(&format!("{}_compare", target_dir), false)?;
+ .remove_directory(&format!("{}_compare", target_dir))?;
Ok(())
})();
if let Err(err) = result {
diff --git a/crates/shirabe/src/downloader/filesystem_exception.rs b/crates/shirabe/src/downloader/filesystem_exception.rs
index f861306..f0aa831 100644
--- a/crates/shirabe/src/downloader/filesystem_exception.rs
+++ b/crates/shirabe/src/downloader/filesystem_exception.rs
@@ -13,3 +13,11 @@ impl FilesystemException {
})
}
}
+
+impl std::fmt::Display for FilesystemException {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+impl std::error::Error for FilesystemException {}
diff --git a/crates/shirabe/src/downloader/git_downloader.rs b/crates/shirabe/src/downloader/git_downloader.rs
index 45849cb..fb41b0c 100644
--- a/crates/shirabe/src/downloader/git_downloader.rs
+++ b/crates/shirabe/src/downloader/git_downloader.rs
@@ -250,9 +250,7 @@ impl GitDownloader {
}
}
- self.inner
- .io
- .write_error(PhpMixed::String(msg), true, io_interface::NORMAL);
+ self.inner.io.write_error3(&msg, true, io_interface::NORMAL);
self.git_util.run_commands(commands, url, &path, true);
@@ -334,9 +332,7 @@ impl GitDownloader {
}
}
- self.inner
- .io
- .write_error(PhpMixed::String(msg), true, io_interface::NORMAL);
+ self.inner.io.write_error3(&msg, true, io_interface::NORMAL);
let mut output = String::new();
if self.inner.process.execute(
@@ -1250,7 +1246,7 @@ impl GitDownloader {
self.inner
.io
- .write_error(PhpMixed::String(output), true, io_interface::NORMAL);
+ .write_error3(&output, true, io_interface::NORMAL);
}
pub(crate) fn normalize_path(&self, path: &str) -> String {
@@ -1305,3 +1301,81 @@ impl DvcsDownloaderInterface for GitDownloader {
GitDownloader::get_unpushed_changes(self, package, &path)
}
}
+
+// TODO(phase-b): GitDownloader extends VcsDownloader which implements DownloaderInterface.
+// Delegating each trait method to todo!() until the inner VcsDownloaderBase exposes the
+// matching impl surface.
+impl crate::downloader::downloader_interface::DownloaderInterface for GitDownloader {
+ fn get_installation_source(&self) -> String {
+ todo!()
+ }
+
+ fn download(
+ &self,
+ _package: &dyn PackageInterface,
+ _path: &str,
+ _prev_package: Option<&dyn PackageInterface>,
+ _output: bool,
+ ) -> anyhow::Result<
+ Box<dyn shirabe_external_packages::react::promise::promise_interface::PromiseInterface>,
+ > {
+ todo!()
+ }
+
+ fn prepare(
+ &self,
+ _type: &str,
+ _package: &dyn PackageInterface,
+ _path: &str,
+ _prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<
+ Box<dyn shirabe_external_packages::react::promise::promise_interface::PromiseInterface>,
+ > {
+ todo!()
+ }
+
+ fn install(
+ &self,
+ _package: &dyn PackageInterface,
+ _path: &str,
+ _output: bool,
+ ) -> anyhow::Result<
+ Box<dyn shirabe_external_packages::react::promise::promise_interface::PromiseInterface>,
+ > {
+ todo!()
+ }
+
+ fn update(
+ &self,
+ _initial: &dyn PackageInterface,
+ _target: &dyn PackageInterface,
+ _path: &str,
+ ) -> anyhow::Result<
+ Box<dyn shirabe_external_packages::react::promise::promise_interface::PromiseInterface>,
+ > {
+ todo!()
+ }
+
+ fn remove(
+ &self,
+ _package: &dyn PackageInterface,
+ _path: &str,
+ _output: bool,
+ ) -> anyhow::Result<
+ Box<dyn shirabe_external_packages::react::promise::promise_interface::PromiseInterface>,
+ > {
+ todo!()
+ }
+
+ fn cleanup(
+ &self,
+ _type: &str,
+ _package: &dyn PackageInterface,
+ _path: &str,
+ _prev_package: Option<&dyn PackageInterface>,
+ ) -> anyhow::Result<
+ Box<dyn shirabe_external_packages::react::promise::promise_interface::PromiseInterface>,
+ > {
+ todo!()
+ }
+}
diff --git a/crates/shirabe/src/downloader/gzip_downloader.rs b/crates/shirabe/src/downloader/gzip_downloader.rs
index ca50827..2a485de 100644
--- a/crates/shirabe/src/downloader/gzip_downloader.rs
+++ b/crates/shirabe/src/downloader/gzip_downloader.rs
@@ -1,25 +1,57 @@
//! ref: composer/src/Composer/Downloader/GzipDownloader.php
+use crate::cache::Cache;
+use crate::config::Config;
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::downloader::file_downloader::FileDownloader;
+use crate::event_dispatcher::event_dispatcher::EventDispatcher;
+use crate::io::io_interface::IOInterface;
use crate::package::package_interface::PackageInterface;
+use crate::util::filesystem::Filesystem;
+use crate::util::http_downloader::HttpDownloader;
use crate::util::platform::Platform;
+use crate::util::process_executor::ProcessExecutor;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- DIRECTORY_SEPARATOR, PATHINFO_FILENAME, PHP_URL_PATH, RuntimeException, extension_loaded,
- fclose, fopen, fwrite, gzclose, gzopen, gzread, implode, parse_url, pathinfo, strtr,
+ DIRECTORY_SEPARATOR, PATHINFO_FILENAME, PHP_URL_PATH, PhpMixed, RuntimeException,
+ extension_loaded, fclose, fopen, fwrite, gzclose, gzopen, gzread, implode, parse_url, pathinfo,
+ strtr,
};
+#[derive(Debug)]
pub struct GzipDownloader {
inner: FileDownloader,
cleanup_executed: IndexMap<String, bool>,
}
impl GzipDownloader {
+ pub fn new(
+ io: Box<dyn IOInterface>,
+ config: Config,
+ http_downloader: HttpDownloader,
+ event_dispatcher: Option<EventDispatcher>,
+ cache: Option<Cache>,
+ filesystem: Filesystem,
+ process: ProcessExecutor,
+ ) -> Self {
+ Self {
+ inner: FileDownloader::new(
+ io,
+ config,
+ http_downloader,
+ event_dispatcher,
+ cache,
+ Some(filesystem),
+ Some(process),
+ ),
+ cleanup_executed: IndexMap::new(),
+ }
+ }
+
pub(crate) fn extract(
- &self,
+ &mut self,
package: &dyn PackageInterface,
file: &str,
path: &str,
@@ -31,7 +63,12 @@ impl GzipDownloader {
),
PATHINFO_FILENAME,
);
- let target_filepath = format!("{}{}{}", path, DIRECTORY_SEPARATOR, filename);
+ let target_filepath = format!(
+ "{}{}{}",
+ path,
+ DIRECTORY_SEPARATOR,
+ filename.as_string().unwrap_or_default()
+ );
if !Platform::is_windows() {
let command = vec![
@@ -42,7 +79,18 @@ impl GzipDownloader {
target_filepath.clone(),
];
- if self.inner.process.execute(&command, &mut String::new()) == 0 {
+ let mut process_output = PhpMixed::Null;
+ if self.inner.process.execute(
+ PhpMixed::List(
+ command
+ .iter()
+ .map(|s| Box::new(PhpMixed::String(s.clone())))
+ .collect(),
+ ),
+ Some(&mut process_output),
+ None,
+ )? == 0
+ {
return Ok(shirabe_external_packages::react::promise::resolve(None));
}
diff --git a/crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs b/crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs
index 1613432..4e18761 100644
--- a/crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs
+++ b/crates/shirabe/src/downloader/max_file_size_exceeded_exception.rs
@@ -2,4 +2,19 @@
use crate::downloader::transport_exception::TransportException;
+#[derive(Debug)]
pub struct MaxFileSizeExceededException(pub TransportException);
+
+impl MaxFileSizeExceededException {
+ pub fn new(message: String) -> Self {
+ Self(TransportException::new(message, 0))
+ }
+}
+
+impl std::fmt::Display for MaxFileSizeExceededException {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
+impl std::error::Error for MaxFileSizeExceededException {}
diff --git a/crates/shirabe/src/downloader/path_downloader.rs b/crates/shirabe/src/downloader/path_downloader.rs
index c50d390..a525df0 100644
--- a/crates/shirabe/src/downloader/path_downloader.rs
+++ b/crates/shirabe/src/downloader/path_downloader.rs
@@ -140,7 +140,7 @@ impl PathDownloader {
let (mut current_strategy, allowed_strategies) =
self.compute_allowed_strategies(&transport_options)?;
- let symfony_filesystem = SymfonyFilesystem::new();
+ let symfony_filesystem = SymfonyFilesystem::new(None);
self.inner.filesystem.remove_directory(&path);
if output {
@@ -254,14 +254,12 @@ impl PathDownloader {
io_interface::NORMAL,
);
}
- let iterator = ArchivableFilesFinder::new(&real_url, vec![]);
+ let iterator = ArchivableFilesFinder::new(&real_url, vec![], false)?;
symfony_filesystem.mirror(&real_url, &path, Some(&iterator));
}
if output {
- self.inner
- .io
- .write_error(PhpMixed::String("".to_string()), true, io_interface::NORMAL);
+ self.inner.io.write_error3("", true, io_interface::NORMAL);
}
Ok(shirabe_external_packages::react::promise::resolve(None))
@@ -328,7 +326,7 @@ impl PathDownloader {
// can happen when using custom installers, see https://github.com/composer/composer/pull/9116
// not using realpath here as we do not want to resolve the symlink to the original dist url
// it points to
- let fs = Filesystem::new();
+ let fs = Filesystem::new(None);
let abs_path = if fs.is_absolute_path(&path) {
path.clone()
} else {
diff --git a/crates/shirabe/src/downloader/phar_downloader.rs b/crates/shirabe/src/downloader/phar_downloader.rs
index 5316fc1..649841d 100644
--- a/crates/shirabe/src/downloader/phar_downloader.rs
+++ b/crates/shirabe/src/downloader/phar_downloader.rs
@@ -1,8 +1,16 @@
//! ref: composer/src/Composer/Downloader/PharDownloader.php
+use crate::cache::Cache;
+use crate::config::Config;
use crate::downloader::archive_downloader::ArchiveDownloader;
+use crate::downloader::downloader_interface::DownloaderInterface;
use crate::downloader::file_downloader::FileDownloader;
+use crate::event_dispatcher::event_dispatcher::EventDispatcher;
+use crate::io::io_interface::IOInterface;
use crate::package::package_interface::PackageInterface;
+use crate::util::filesystem::Filesystem;
+use crate::util::http_downloader::HttpDownloader;
+use crate::util::process_executor::ProcessExecutor;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
@@ -15,6 +23,29 @@ pub struct PharDownloader {
}
impl PharDownloader {
+ pub fn new(
+ io: Box<dyn IOInterface>,
+ config: Config,
+ http_downloader: HttpDownloader,
+ event_dispatcher: Option<EventDispatcher>,
+ cache: Option<Cache>,
+ filesystem: Filesystem,
+ process: ProcessExecutor,
+ ) -> Self {
+ Self {
+ inner: FileDownloader::new(
+ io,
+ config,
+ http_downloader,
+ event_dispatcher,
+ cache,
+ Some(filesystem),
+ Some(process),
+ ),
+ cleanup_executed: IndexMap::new(),
+ }
+ }
+
pub(crate) fn extract(
&self,
package: &dyn PackageInterface,
@@ -32,3 +63,66 @@ impl PharDownloader {
Ok(shirabe_external_packages::react::promise::resolve(None))
}
}
+
+impl DownloaderInterface for PharDownloader {
+ fn get_installation_source(&self) -> String {
+ self.inner.get_installation_source()
+ }
+
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.download(package, path, prev_package, output)
+ }
+
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.prepare(r#type, package, path, prev_package)
+ }
+
+ fn install(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.install(package, path, output)
+ }
+
+ fn update(
+ &self,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.update(initial, target, path)
+ }
+
+ fn remove(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.remove(package, path, output)
+ }
+
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.cleanup(r#type, package, path, prev_package)
+ }
+}
diff --git a/crates/shirabe/src/downloader/rar_downloader.rs b/crates/shirabe/src/downloader/rar_downloader.rs
index 308b6fa..51feadb 100644
--- a/crates/shirabe/src/downloader/rar_downloader.rs
+++ b/crates/shirabe/src/downloader/rar_downloader.rs
@@ -1,25 +1,56 @@
//! ref: composer/src/Composer/Downloader/RarDownloader.php
+use crate::cache::Cache;
+use crate::config::Config;
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::downloader::file_downloader::FileDownloader;
+use crate::event_dispatcher::event_dispatcher::EventDispatcher;
+use crate::io::io_interface::IOInterface;
use crate::package::package_interface::PackageInterface;
+use crate::util::filesystem::Filesystem;
+use crate::util::http_downloader::HttpDownloader;
use crate::util::ini_helper::IniHelper;
use crate::util::platform::Platform;
+use crate::util::process_executor::ProcessExecutor;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
- RarArchive, RuntimeException, UnexpectedValueException, class_exists, implode,
+ PhpMixed, RarArchive, RuntimeException, UnexpectedValueException, class_exists, implode,
};
+#[derive(Debug)]
pub struct RarDownloader {
inner: FileDownloader,
cleanup_executed: IndexMap<String, bool>,
}
impl RarDownloader {
+ pub fn new(
+ io: Box<dyn IOInterface>,
+ config: Config,
+ http_downloader: HttpDownloader,
+ event_dispatcher: Option<EventDispatcher>,
+ cache: Option<Cache>,
+ filesystem: Filesystem,
+ process: ProcessExecutor,
+ ) -> Self {
+ Self {
+ inner: FileDownloader::new(
+ io,
+ config,
+ http_downloader,
+ event_dispatcher,
+ cache,
+ Some(filesystem),
+ Some(process),
+ ),
+ cleanup_executed: IndexMap::new(),
+ }
+ }
+
pub(crate) fn extract(
- &self,
+ &mut self,
_package: &dyn PackageInterface,
file: &str,
path: &str,
@@ -35,7 +66,18 @@ impl RarDownloader {
path.to_string(),
];
- if self.inner.process.execute(&command, &mut String::new()) == 0 {
+ let mut process_output = PhpMixed::Null;
+ if self.inner.process.execute(
+ PhpMixed::List(
+ command
+ .iter()
+ .map(|s| Box::new(PhpMixed::String(s.clone())))
+ .collect(),
+ ),
+ Some(&mut process_output),
+ None,
+ )? == 0
+ {
return Ok(shirabe_external_packages::react::promise::resolve(None));
}
@@ -101,3 +143,66 @@ impl RarDownloader {
Ok(shirabe_external_packages::react::promise::resolve(None))
}
}
+
+impl crate::downloader::downloader_interface::DownloaderInterface for RarDownloader {
+ fn get_installation_source(&self) -> String {
+ self.inner.get_installation_source()
+ }
+
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.download(package, path, prev_package, output)
+ }
+
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.prepare(r#type, package, path, prev_package)
+ }
+
+ fn install(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.install(package, path, output)
+ }
+
+ fn update(
+ &self,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.update(initial, target, path)
+ }
+
+ fn remove(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.remove(package, path, output)
+ }
+
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.cleanup(r#type, package, path, prev_package)
+ }
+}
diff --git a/crates/shirabe/src/downloader/tar_downloader.rs b/crates/shirabe/src/downloader/tar_downloader.rs
index d8531e0..aaa7153 100644
--- a/crates/shirabe/src/downloader/tar_downloader.rs
+++ b/crates/shirabe/src/downloader/tar_downloader.rs
@@ -1,8 +1,16 @@
//! ref: composer/src/Composer/Downloader/TarDownloader.php
+use crate::cache::Cache;
+use crate::config::Config;
use crate::downloader::archive_downloader::ArchiveDownloader;
+use crate::downloader::downloader_interface::DownloaderInterface;
use crate::downloader::file_downloader::FileDownloader;
+use crate::event_dispatcher::event_dispatcher::EventDispatcher;
+use crate::io::io_interface::IOInterface;
use crate::package::package_interface::PackageInterface;
+use crate::util::filesystem::Filesystem;
+use crate::util::http_downloader::HttpDownloader;
+use crate::util::process_executor::ProcessExecutor;
use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
@@ -15,6 +23,29 @@ pub struct TarDownloader {
}
impl TarDownloader {
+ pub fn new(
+ io: Box<dyn IOInterface>,
+ config: Config,
+ http_downloader: HttpDownloader,
+ event_dispatcher: Option<EventDispatcher>,
+ cache: Option<Cache>,
+ filesystem: Filesystem,
+ process: ProcessExecutor,
+ ) -> Self {
+ Self {
+ inner: FileDownloader::new(
+ io,
+ config,
+ http_downloader,
+ event_dispatcher,
+ cache,
+ Some(filesystem),
+ Some(process),
+ ),
+ cleanup_executed: IndexMap::new(),
+ }
+ }
+
pub(crate) fn extract(
&self,
package: &dyn PackageInterface,
@@ -27,3 +58,66 @@ impl TarDownloader {
Ok(shirabe_external_packages::react::promise::resolve(None))
}
}
+
+impl DownloaderInterface for TarDownloader {
+ fn get_installation_source(&self) -> String {
+ self.inner.get_installation_source()
+ }
+
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.download(package, path, prev_package, output)
+ }
+
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.prepare(r#type, package, path, prev_package)
+ }
+
+ fn install(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.install(package, path, output)
+ }
+
+ fn update(
+ &self,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.update(initial, target, path)
+ }
+
+ fn remove(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.remove(package, path, output)
+ }
+
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.cleanup(r#type, package, path, prev_package)
+ }
+}
diff --git a/crates/shirabe/src/downloader/transport_exception.rs b/crates/shirabe/src/downloader/transport_exception.rs
index e4f04f3..382da01 100644
--- a/crates/shirabe/src/downloader/transport_exception.rs
+++ b/crates/shirabe/src/downloader/transport_exception.rs
@@ -24,6 +24,14 @@ impl TransportException {
}
}
+ pub fn get_code(&self) -> i64 {
+ self.code
+ }
+
+ pub fn get_message(&self) -> &str {
+ &self.message
+ }
+
pub fn set_headers(&mut self, headers: Vec<String>) {
self.headers = Some(headers);
}
diff --git a/crates/shirabe/src/downloader/vcs_downloader.rs b/crates/shirabe/src/downloader/vcs_downloader.rs
index 5e19016..346603a 100644
--- a/crates/shirabe/src/downloader/vcs_downloader.rs
+++ b/crates/shirabe/src/downloader/vcs_downloader.rs
@@ -385,7 +385,7 @@ pub trait VcsDownloader:
io_interface::NORMAL,
);
self.io_mut()
- .write_error(PhpMixed::String(logs), true, io_interface::NORMAL);
+ .write_error3(&logs, true, io_interface::NORMAL);
}
}
diff --git a/crates/shirabe/src/downloader/xz_downloader.rs b/crates/shirabe/src/downloader/xz_downloader.rs
index 1ad0bb1..61a7f14 100644
--- a/crates/shirabe/src/downloader/xz_downloader.rs
+++ b/crates/shirabe/src/downloader/xz_downloader.rs
@@ -1,11 +1,19 @@
//! ref: composer/src/Composer/Downloader/XzDownloader.php
+use crate::cache::Cache;
+use crate::config::Config;
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::downloader::file_downloader::FileDownloader;
+use crate::event_dispatcher::event_dispatcher::EventDispatcher;
+use crate::io::io_interface::IOInterface;
use crate::package::package_interface::PackageInterface;
+use crate::util::filesystem::Filesystem;
+use crate::util::http_downloader::HttpDownloader;
+use crate::util::process_executor::ProcessExecutor;
use anyhow::{Result, bail};
use indexmap::IndexMap;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
+use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct XzDownloader {
@@ -14,16 +22,49 @@ pub struct XzDownloader {
}
impl XzDownloader {
+ pub fn new(
+ io: Box<dyn IOInterface>,
+ config: Config,
+ http_downloader: HttpDownloader,
+ event_dispatcher: Option<EventDispatcher>,
+ cache: Option<Cache>,
+ filesystem: Filesystem,
+ process: ProcessExecutor,
+ ) -> Self {
+ Self {
+ inner: FileDownloader::new(
+ io,
+ config,
+ http_downloader,
+ event_dispatcher,
+ cache,
+ Some(filesystem),
+ Some(process),
+ ),
+ cleanup_executed: IndexMap::new(),
+ }
+ }
+
pub(crate) fn extract(
- &self,
+ &mut self,
package: &dyn PackageInterface,
file: &str,
path: &str,
) -> Result<Box<dyn PromiseInterface>> {
let command = vec!["tar", "-xJf", file, "-C", path];
- let mut ignored_output = String::new();
- if self.inner.process.execute(&command, &mut ignored_output) == 0 {
+ let mut ignored_output = PhpMixed::Null;
+ if self.inner.process.execute(
+ PhpMixed::List(
+ command
+ .iter()
+ .map(|s| Box::new(PhpMixed::String(s.to_string())))
+ .collect(),
+ ),
+ Some(&mut ignored_output),
+ None,
+ )? == 0
+ {
return Ok(shirabe_external_packages::react::promise::resolve(None));
}
@@ -36,3 +77,66 @@ impl XzDownloader {
bail!(process_error);
}
}
+
+impl crate::downloader::downloader_interface::DownloaderInterface for XzDownloader {
+ fn get_installation_source(&self) -> String {
+ self.inner.get_installation_source()
+ }
+
+ fn download(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.download(package, path, prev_package, output)
+ }
+
+ fn prepare(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.prepare(r#type, package, path, prev_package)
+ }
+
+ fn install(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.install(package, path, output)
+ }
+
+ fn update(
+ &self,
+ initial: &dyn PackageInterface,
+ target: &dyn PackageInterface,
+ path: &str,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.update(initial, target, path)
+ }
+
+ fn remove(
+ &self,
+ package: &dyn PackageInterface,
+ path: &str,
+ output: bool,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.remove(package, path, output)
+ }
+
+ fn cleanup(
+ &self,
+ r#type: &str,
+ package: &dyn PackageInterface,
+ path: &str,
+ prev_package: Option<&dyn PackageInterface>,
+ ) -> Result<Box<dyn PromiseInterface>> {
+ self.inner.cleanup(r#type, package, path, prev_package)
+ }
+}
diff --git a/crates/shirabe/src/downloader/zip_downloader.rs b/crates/shirabe/src/downloader/zip_downloader.rs
index 90e5639..7f779c8 100644
--- a/crates/shirabe/src/downloader/zip_downloader.rs
+++ b/crates/shirabe/src/downloader/zip_downloader.rs
@@ -152,13 +152,13 @@ impl ZipDownloader {
if !is_windows_guard.unwrap() && unzip_commands_empty {
if proc_open_missing {
- self.inner.inner.io.write_error("<warning>proc_open is disabled so 'unzip' and '7z' commands cannot be used, zip files are being unpacked using the PHP zip extension.</warning>");
- self.inner.inner.io.write_error("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
- self.inner.inner.io.write_error("<warning>Enabling proc_open and installing 'unzip' or '7z' (21.01+) may remediate them.</warning>");
+ self.inner.io.write_error("<warning>proc_open is disabled so 'unzip' and '7z' commands cannot be used, zip files are being unpacked using the PHP zip extension.</warning>");
+ self.inner.io.write_error("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
+ self.inner.io.write_error("<warning>Enabling proc_open and installing 'unzip' or '7z' (21.01+) may remediate them.</warning>");
} else {
- self.inner.inner.io.write_error("<warning>As there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.</warning>");
- self.inner.inner.io.write_error("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
- self.inner.inner.io.write_error("<warning>Installing 'unzip' or '7z' (21.01+) may remediate them.</warning>");
+ self.inner.io.write_error("<warning>As there is no 'unzip' nor '7z' command installed zip files are being unpacked using the PHP zip extension.</warning>");
+ self.inner.io.write_error("<warning>This may cause invalid reports of corrupted archives. Besides, any UNIX permissions (e.g. executable) defined in the archives will be lost.</warning>");
+ self.inner.io.write_error("<warning>Installing 'unzip' or '7z' (21.01+) may remediate them.</warning>");
}
}
}
@@ -226,7 +226,7 @@ impl ZipDownloader {
Preg::is_match_strict_groups(r"^\s*7-Zip(?:\s\[64\])?\s([0-9.]+)", &output)
{
if version_compare(&m[1], "21.01", "<") {
- self.inner.inner.io.write_error(&format!(
+ self.inner.io.write_error(&format!(
" <warning>Unzipping using {} {} may result in incorrect file permissions. Install {} 21.01+ or unzip to ensure you get correct permissions.</warning>",
executable, m[1], executable,
));
@@ -235,7 +235,7 @@ impl ZipDownloader {
}
}
- let io = &self.inner.inner.io;
+ let io = &self.inner.io;
let try_fallback = |process_error: anyhow::Error| -> Result<Box<dyn PromiseInterface>> {
if is_last_chance {
return Err(process_error);
@@ -297,7 +297,7 @@ impl ZipDownloader {
self.extract_with_zip_archive(package, file, path)
};
- match self.inner.inner.process.execute_async(&command) {
+ match self.inner.process.execute_async(&command) {
Ok(promise) => Ok(promise.then(
Box::new(move |process: Process| -> Result<()> {
if !process.is_successful() {