diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-17 02:53:53 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-17 02:53:53 +0900 |
| commit | a1c7e6908a26e10f6e1f23a51721664b5e2d838d (patch) | |
| tree | c575c76f1b43359ed74913da4c6a2636643f1ba0 /crates/shirabe/src/downloader | |
| parent | 7f606f36fef0c0467c3c0db3d0da33af486dae8a (diff) | |
| download | php-shirabe-a1c7e6908a26e10f6e1f23a51721664b5e2d838d.tar.gz php-shirabe-a1c7e6908a26e10f6e1f23a51721664b5e2d838d.tar.zst php-shirabe-a1c7e6908a26e10f6e1f23a51721664b5e2d838d.zip | |
chore(style): cargo fmt
Diffstat (limited to 'crates/shirabe/src/downloader')
18 files changed, 665 insertions, 341 deletions
diff --git a/crates/shirabe/src/downloader/archive_downloader.rs b/crates/shirabe/src/downloader/archive_downloader.rs index 9220410..59704e3 100644 --- a/crates/shirabe/src/downloader/archive_downloader.rs +++ b/crates/shirabe/src/downloader/archive_downloader.rs @@ -1,14 +1,16 @@ //! ref: composer/src/Composer/Downloader/ArchiveDownloader.php -use anyhow::Result; -use indexmap::IndexMap; -use shirabe_php_shim::{bin2hex, file_exists, is_dir, random_bytes, realpath, RuntimeException, DIRECTORY_SEPARATOR}; -use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; -use shirabe_external_packages::symfony::component::finder::finder::Finder; use crate::dependency_resolver::operation::install_operation::InstallOperation; use crate::downloader::file_downloader::FileDownloader; use crate::package::package_interface::PackageInterface; use crate::util::platform::Platform; +use anyhow::Result; +use indexmap::IndexMap; +use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; +use shirabe_external_packages::symfony::component::finder::finder::Finder; +use shirabe_php_shim::{ + DIRECTORY_SEPARATOR, RuntimeException, bin2hex, file_exists, is_dir, random_bytes, realpath, +}; #[derive(Debug)] pub struct ArchiveDownloader { @@ -17,21 +19,43 @@ pub struct ArchiveDownloader { } impl ArchiveDownloader { - pub fn prepare(&mut self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Result<Box<dyn PromiseInterface>> { + pub fn prepare( + &mut self, + r#type: &str, + package: &dyn PackageInterface, + path: &str, + prev_package: Option<&dyn PackageInterface>, + ) -> Result<Box<dyn PromiseInterface>> { self.cleanup_executed.remove(package.get_name()); self.inner.prepare(r#type, package, path, prev_package) } - pub fn cleanup(&mut self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> Result<Box<dyn PromiseInterface>> { - self.cleanup_executed.insert(package.get_name().to_string(), true); + pub fn cleanup( + &mut self, + r#type: &str, + package: &dyn PackageInterface, + path: &str, + prev_package: Option<&dyn PackageInterface>, + ) -> Result<Box<dyn PromiseInterface>> { + self.cleanup_executed + .insert(package.get_name().to_string(), true); self.inner.cleanup(r#type, package, path, prev_package) } - pub fn install(&mut self, package: &dyn PackageInterface, path: &str, output: bool) -> Result<Box<dyn PromiseInterface>> { + pub fn install( + &mut self, + package: &dyn PackageInterface, + path: &str, + output: bool, + ) -> Result<Box<dyn PromiseInterface>> { if output { - self.inner.io.write_error(&format!(" - {}{}", InstallOperation::format(package, false), self.get_install_operation_appendix(package, path))); + self.inner.io.write_error(&format!( + " - {}{}", + InstallOperation::format(package, false), + self.get_install_operation_appendix(package, path) + )); } let vendor_dir = self.inner.config.get("vendor-dir"); @@ -39,7 +63,12 @@ impl ArchiveDownloader { // clean up the target directory, unless it contains the vendor dir, as the vendor dir contains // the archive to be extracted. This is the case when installing with create-project in the current directory // but in that case we ensure the directory is empty already in ProjectInstaller so no need to empty it here. - if !self.inner.filesystem.normalize_path(&vendor_dir).contains(&self.inner.filesystem.normalize_path(&format!("{}{}", path, DIRECTORY_SEPARATOR))) { + if !self.inner.filesystem.normalize_path(&vendor_dir).contains( + &self + .inner + .filesystem + .normalize_path(&format!("{}{}", path, DIRECTORY_SEPARATOR)), + ) { self.inner.filesystem.empty_directory(path); } @@ -58,7 +87,9 @@ impl ArchiveDownloader { self.inner.add_cleanup_path(package, path); } - self.inner.filesystem.ensure_directory_exists(&temporary_dir); + self.inner + .filesystem + .ensure_directory_exists(&temporary_dir); let file_name = self.inner.get_file_name(package, path); let filesystem = &self.inner.filesystem; @@ -187,11 +218,20 @@ impl ArchiveDownloader { )) } - pub fn get_install_operation_appendix(&self, _package: &dyn PackageInterface, _path: &str) -> &str { + pub fn get_install_operation_appendix( + &self, + _package: &dyn PackageInterface, + _path: &str, + ) -> &str { ": Extracting archive" } - pub(crate) fn extract(&self, _package: &dyn PackageInterface, _file: &str, _path: &str) -> Result<Box<dyn PromiseInterface>> { + pub(crate) fn extract( + &self, + _package: &dyn PackageInterface, + _file: &str, + _path: &str, + ) -> Result<Box<dyn PromiseInterface>> { todo!() } } diff --git a/crates/shirabe/src/downloader/download_manager.rs b/crates/shirabe/src/downloader/download_manager.rs index e787689..ff453f3 100644 --- a/crates/shirabe/src/downloader/download_manager.rs +++ b/crates/shirabe/src/downloader/download_manager.rs @@ -5,9 +5,9 @@ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use shirabe_php_shim::{ - array_keys, array_reverse, array_shift, dirname, get_class, implode, in_array, preg_quote, - rtrim, sprintf, str_replace, strtolower, usort, InvalidArgumentException, LogicException, - PhpMixed, RuntimeException, + InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_keys, + array_reverse, array_shift, dirname, get_class, implode, in_array, preg_quote, rtrim, sprintf, + str_replace, strtolower, usort, }; use crate::downloader::downloader_interface::DownloaderInterface; @@ -200,7 +200,8 @@ impl DownloadManager { prev_package: Option<&dyn PackageInterface>, ) -> Result<Box<dyn PromiseInterface>> { let target_dir = self.normalize_target_dir(target_dir); - self.filesystem.ensure_directory_exists(&dirname(&target_dir)); + self.filesystem + .ensure_directory_exists(&dirname(&target_dir)); let mut sources = self.get_available_sources(package, prev_package)?; @@ -241,7 +242,8 @@ impl DownloadManager { // PHP closure handleError: rethrow if not RuntimeException or if IrrecoverableDownloadException // TODO(phase-b): downcast for instanceof checks let is_runtime: bool = todo!("e instanceof RuntimeException"); - let is_irrecoverable: bool = todo!("e instanceof IrrecoverableDownloadException"); + let is_irrecoverable: bool = + todo!("e instanceof IrrecoverableDownloadException"); if is_runtime && !is_irrecoverable { if sources.is_empty() { return Err(e); @@ -268,7 +270,9 @@ impl DownloadManager { // PHP: $result->then(static fn ($res) => $res, $handleError); // TODO(phase-b): chain $handleError as the rejection handler on the promise - let res = result.then(Box::new(move |res: PhpMixed| -> Result<PhpMixed> { Ok(res) })); + let res = result.then(Box::new(move |res: PhpMixed| -> Result<PhpMixed> { + Ok(res) + })); return Ok(res); } @@ -358,10 +362,7 @@ impl DownloadManager { return Err(e); } self.io.write_error( - PhpMixed::String(format!( - "<error> Update failed ({})</error>", - e, - )), + PhpMixed::String(format!("<error> Update failed ({})</error>", e,)), true, IOInterface::NORMAL, ); @@ -503,11 +504,7 @@ impl DownloadManager { { let prev_source_owned = prev_source.unwrap_or("").to_string(); usort(&mut sources, move |a: &String, b: &String| -> i64 { - if *a == prev_source_owned { - -1 - } else { - 1 - } + if *a == prev_source_owned { -1 } else { 1 } }); return Ok(sources); diff --git a/crates/shirabe/src/downloader/downloader_interface.rs b/crates/shirabe/src/downloader/downloader_interface.rs index c78a094..423df69 100644 --- a/crates/shirabe/src/downloader/downloader_interface.rs +++ b/crates/shirabe/src/downloader/downloader_interface.rs @@ -7,15 +7,45 @@ use crate::package::package_interface::PackageInterface; pub trait DownloaderInterface { fn get_installation_source(&self) -> String; - fn download(&self, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Box<dyn PromiseInterface>>; + fn download( + &self, + package: &dyn PackageInterface, + path: &str, + prev_package: Option<&dyn PackageInterface>, + ) -> anyhow::Result<Box<dyn PromiseInterface>>; - fn prepare(&self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Box<dyn PromiseInterface>>; + fn prepare( + &self, + r#type: &str, + package: &dyn PackageInterface, + path: &str, + prev_package: Option<&dyn PackageInterface>, + ) -> anyhow::Result<Box<dyn PromiseInterface>>; - fn install(&self, package: &dyn PackageInterface, path: &str) -> anyhow::Result<Box<dyn PromiseInterface>>; + fn install( + &self, + package: &dyn PackageInterface, + path: &str, + ) -> anyhow::Result<Box<dyn PromiseInterface>>; - fn update(&self, initial: &dyn PackageInterface, target: &dyn PackageInterface, path: &str) -> anyhow::Result<Box<dyn PromiseInterface>>; + fn update( + &self, + initial: &dyn PackageInterface, + target: &dyn PackageInterface, + path: &str, + ) -> anyhow::Result<Box<dyn PromiseInterface>>; - fn remove(&self, package: &dyn PackageInterface, path: &str) -> anyhow::Result<Box<dyn PromiseInterface>>; + fn remove( + &self, + package: &dyn PackageInterface, + path: &str, + ) -> anyhow::Result<Box<dyn PromiseInterface>>; - fn cleanup(&self, r#type: &str, package: &dyn PackageInterface, path: &str, prev_package: Option<&dyn PackageInterface>) -> anyhow::Result<Box<dyn PromiseInterface>>; + fn cleanup( + &self, + r#type: &str, + package: &dyn PackageInterface, + path: &str, + prev_package: Option<&dyn PackageInterface>, + ) -> anyhow::Result<Box<dyn PromiseInterface>>; } diff --git a/crates/shirabe/src/downloader/file_downloader.rs b/crates/shirabe/src/downloader/file_downloader.rs index 7ddc60a..5b002ff 100644 --- a/crates/shirabe/src/downloader/file_downloader.rs +++ b/crates/shirabe/src/downloader/file_downloader.rs @@ -7,11 +7,11 @@ use std::sync::{LazyLock, Mutex}; use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use shirabe_external_packages::react::promise::resolve as react_promise_resolve; use shirabe_php_shim::{ - array_search, array_shift, file_exists, filesize, get_class, hash, hash_file, in_array, - is_dir, is_executable, parse_url, pathinfo, realpath, rtrim, spl_object_hash, strlen, strpos, - strtr, trim, umask, usleep, InvalidArgumentException, PhpMixed, RuntimeException, Silencer, - UnexpectedValueException, DIRECTORY_SEPARATOR, PATHINFO_BASENAME, PATHINFO_EXTENSION, - PHP_URL_PATH, + DIRECTORY_SEPARATOR, InvalidArgumentException, PATHINFO_BASENAME, PATHINFO_EXTENSION, + PHP_URL_PATH, PhpMixed, RuntimeException, Silencer, UnexpectedValueException, array_search, + array_shift, file_exists, filesize, get_class, hash, hash_file, in_array, is_dir, + is_executable, parse_url, pathinfo, realpath, rtrim, spl_object_hash, strlen, strpos, strtr, + trim, umask, usleep, }; use crate::cache::Cache; @@ -106,10 +106,7 @@ impl FileDownloader { this.io.write_error("Running cache garbage collection"); this.cache.as_mut().unwrap().gc( this.config.get("cache-files-ttl").as_int().unwrap_or(0), - this.config - .get("cache-files-maxsize") - .as_int() - .unwrap_or(0), + this.config.get("cache-files-maxsize").as_int().unwrap_or(0), ); } @@ -180,13 +177,15 @@ impl DownloaderInterface for FileDownloader { let _ = PluginEvents::PRE_FILE_DOWNLOAD; let _ = PluginEvents::POST_FILE_DOWNLOAD; - todo!("phase-b: orchestrate download/accept/reject closures and call download() returning a PromiseInterface") + todo!( + "phase-b: orchestrate download/accept/reject closures and call download() returning a PromiseInterface" + ) } /// @inheritDoc fn prepare( &mut self, - _r#type: &str, + _type: &str, _package: &dyn PackageInterface, _path: &str, _prev_package: Option<&dyn PackageInterface>, @@ -197,7 +196,7 @@ impl DownloaderInterface for FileDownloader { /// @inheritDoc fn cleanup( &mut self, - _r#type: &str, + _type: &str, package: &dyn PackageInterface, path: &str, _prev_package: Option<&dyn PackageInterface>, @@ -226,7 +225,11 @@ impl DownloaderInterface for FileDownloader { vendor_dir.clone(), ]; - if let Some(paths) = self.additional_cleanup_paths.get(package.get_name()).cloned() { + if let Some(paths) = self + .additional_cleanup_paths + .get(package.get_name()) + .cloned() + { for path_to_clean in &paths { self.filesystem.remove(path_to_clean)?; } @@ -337,9 +340,7 @@ impl DownloaderInterface for FileDownloader { // TODO(phase-b): chain `.then(|result| if !result { throw RuntimeException })` let _ = path; - todo!( - "phase-b: chain promise.then(|result| {{ if !result {{ throw RuntimeException }} }})" - ) + todo!("phase-b: chain promise.then(|result| {{ if !result {{ throw RuntimeException }} }})") } } @@ -365,7 +366,8 @@ impl ChangeReportInterface for FileDownloader { .remove_directory(&format!("{}_compare", target_dir), false)?; } - let promise = self.download(package, &format!("{}_compare", target_dir), None, false)?; + let promise = + self.download(package, &format!("{}_compare", target_dir), None, false)?; promise.then_with( None, Some(Box::new(|ex: PhpMixed| { @@ -419,7 +421,11 @@ impl ChangeReportInterface for FileDownloader { let output = trim(&output, None); - Ok(if strlen(&output) > 0 { Some(output) } else { None }) + Ok(if strlen(&output) > 0 { + Some(output) + } else { + None + }) } } diff --git a/crates/shirabe/src/downloader/fossil_downloader.rs b/crates/shirabe/src/downloader/fossil_downloader.rs index 47ad973..a686177 100644 --- a/crates/shirabe/src/downloader/fossil_downloader.rs +++ b/crates/shirabe/src/downloader/fossil_downloader.rs @@ -1,11 +1,11 @@ //! ref: composer/src/Composer/Downloader/FossilDownloader.php +use crate::downloader::vcs_downloader::VcsDownloader; +use crate::package::package_interface::PackageInterface; use anyhow::Result; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use shirabe_php_shim::RuntimeException; -use crate::downloader::vcs_downloader::VcsDownloader; -use crate::package::package_interface::PackageInterface; #[derive(Debug)] pub struct FossilDownloader { @@ -29,26 +29,48 @@ impl FossilDownloader { path: String, url: String, ) -> Result<Box<dyn PromiseInterface>> { - self.inner.config.prohibit_url_by_config(&url, &self.inner.io)?; + self.inner + .config + .prohibit_url_by_config(&url, &self.inner.io)?; let repo_file = format!("{}.fossil", path); let real_path = shirabe_php_shim::realpath(&path); - self.inner.io.write_error(&format!("Cloning {}", package.get_source_reference().unwrap_or_default())); + self.inner.io.write_error(&format!( + "Cloning {}", + package.get_source_reference().unwrap_or_default() + )); let mut output = String::new(); self.execute( - vec!["fossil".to_string(), "clone".to_string(), "--".to_string(), url, repo_file.clone()], + vec![ + "fossil".to_string(), + "clone".to_string(), + "--".to_string(), + url, + repo_file.clone(), + ], None, &mut output, )?; self.execute( - vec!["fossil".to_string(), "open".to_string(), "--nested".to_string(), "--".to_string(), repo_file], + vec![ + "fossil".to_string(), + "open".to_string(), + "--nested".to_string(), + "--".to_string(), + repo_file, + ], real_path.clone(), &mut output, )?; self.execute( - vec!["fossil".to_string(), "update".to_string(), "--".to_string(), package.get_source_reference().unwrap_or_default()], + vec![ + "fossil".to_string(), + "update".to_string(), + "--".to_string(), + package.get_source_reference().unwrap_or_default(), + ], real_path, &mut output, )?; @@ -63,9 +85,14 @@ impl FossilDownloader { path: String, url: String, ) -> Result<Box<dyn PromiseInterface>> { - self.inner.config.prohibit_url_by_config(&url, &self.inner.io)?; + self.inner + .config + .prohibit_url_by_config(&url, &self.inner.io)?; - self.inner.io.write_error(&format!(" Updating to {}", target.get_source_reference().unwrap_or_default())); + self.inner.io.write_error(&format!( + " Updating to {}", + target.get_source_reference().unwrap_or_default() + )); if !self.has_metadata_repository(&path) { return Err(RuntimeException { @@ -85,7 +112,12 @@ impl FossilDownloader { &mut output, )?; self.execute( - vec!["fossil".to_string(), "up".to_string(), "--".to_string(), target.get_source_reference().unwrap_or_default()], + vec![ + "fossil".to_string(), + "up".to_string(), + "--".to_string(), + target.get_source_reference().unwrap_or_default(), + ], real_path, &mut output, )?; @@ -93,7 +125,11 @@ impl FossilDownloader { Ok(shirabe_external_packages::react::promise::resolve(None)) } - pub fn get_local_changes(&self, _package: &dyn PackageInterface, path: String) -> Option<String> { + pub fn get_local_changes( + &self, + _package: &dyn PackageInterface, + path: String, + ) -> Option<String> { if !self.has_metadata_repository(&path) { return None; } @@ -119,11 +155,16 @@ impl FossilDownloader { let mut output = String::new(); self.execute( vec![ - "fossil".to_string(), "timeline".to_string(), - "-t".to_string(), "ci".to_string(), - "-W".to_string(), "0".to_string(), - "-n".to_string(), "0".to_string(), - "before".to_string(), to_reference.clone(), + "fossil".to_string(), + "timeline".to_string(), + "-t".to_string(), + "ci".to_string(), + "-W".to_string(), + "0".to_string(), + "-n".to_string(), + "0".to_string(), + "before".to_string(), + to_reference.clone(), ], shirabe_php_shim::realpath(&path), &mut output, @@ -149,7 +190,12 @@ impl FossilDownloader { Ok(log) } - fn execute(&self, command: Vec<String>, cwd: Option<String>, output: &mut String) -> Result<()> { + fn execute( + &self, + command: Vec<String>, + cwd: Option<String>, + output: &mut String, + ) -> Result<()> { if self.inner.process.execute(&command, output, cwd) != 0 { return Err(RuntimeException { message: format!( @@ -158,7 +204,8 @@ impl FossilDownloader { self.inner.process.get_error_output() ), code: 0, - }.into()); + } + .into()); } Ok(()) } diff --git a/crates/shirabe/src/downloader/git_downloader.rs b/crates/shirabe/src/downloader/git_downloader.rs index 6957ba1..97d0ee9 100644 --- a/crates/shirabe/src/downloader/git_downloader.rs +++ b/crates/shirabe/src/downloader/git_downloader.rs @@ -6,8 +6,8 @@ use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_external_packages::react::promise; use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use shirabe_php_shim::{ - array_map, basename, dirname, implode, in_array, is_dir, preg_quote, realpath, rtrim, sprintf, - strlen, strpos, substr, trim, version_compare, PhpMixed, RuntimeException, + PhpMixed, RuntimeException, array_map, basename, dirname, implode, in_array, is_dir, + preg_quote, realpath, rtrim, sprintf, strlen, strpos, substr, trim, version_compare, }; use crate::cache::Cache; @@ -42,12 +42,7 @@ impl GitDownloader { fs: Option<Filesystem>, ) -> Self { let inner = VcsDownloader::new(io, config, process, fs); - let git_util = GitUtil::new( - &*inner.io, - &inner.config, - &inner.process, - &inner.filesystem, - ); + let git_util = GitUtil::new(&*inner.io, &inner.config, &inner.process, &inner.filesystem); Self { inner, has_stashed_changes: IndexMap::new(), @@ -73,7 +68,11 @@ impl GitDownloader { let cache_path = format!( "{}/{}/", - self.inner.config.get("cache-vcs-dir").as_string().unwrap_or(""), + self.inner + .config + .get("cache-vcs-dir") + .as_string() + .unwrap_or(""), Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(url.to_string())), ); let git_version = GitUtil::get_version(&self.inner.process); @@ -134,7 +133,11 @@ impl GitDownloader { let path = self.normalize_path(path); let cache_path = format!( "{}/{}/", - self.inner.config.get("cache-vcs-dir").as_string().unwrap_or(""), + self.inner + .config + .get("cache-vcs-dir") + .as_string() + .unwrap_or(""), Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(url.to_string())), ); let r#ref = package.get_source_reference().unwrap_or("").to_string(); @@ -157,10 +160,7 @@ impl GitDownloader { ]; let transport_options = package.get_transport_options(); if let Some(git_opts) = transport_options.get("git").and_then(|v| v.as_array()) { - if let Some(single) = git_opts - .get("single_use_clone") - .and_then(|v| v.as_bool()) - { + if let Some(single) = git_opts.get("single_use_clone").and_then(|v| v.as_bool()) { if single { clone_flags = vec![]; } @@ -298,7 +298,11 @@ impl GitDownloader { let cache_path = format!( "{}/{}/", - self.inner.config.get("cache-vcs-dir").as_string().unwrap_or(""), + self.inner + .config + .get("cache-vcs-dir") + .as_string() + .unwrap_or(""), Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(url.to_string())), ); let r#ref = target.get_source_reference().unwrap_or("").to_string(); @@ -401,7 +405,8 @@ impl GitDownloader { ) == 0 { let origin_match = Preg::is_match_strict_groups(r"{^origin\s+(?P<url>\S+)}m", &output); - let composer_match = Preg::is_match_strict_groups(r"{^composer\s+(?P<url>\S+)}m", &output); + let composer_match = + Preg::is_match_strict_groups(r"{^composer\s+(?P<url>\S+)}m", &output); if let (Some(origin_match), Some(composer_match)) = (origin_match, composer_match) { let origin_url = origin_match.get("url").cloned().unwrap_or_default(); let composer_url = composer_match.get("url").cloned().unwrap_or_default(); @@ -560,11 +565,11 @@ impl GitDownloader { "--".to_string(), ]; let mut output = String::new(); - if self.inner.process.execute( - &command, - &mut output, - Some(path.clone()), - ) != 0 + if self + .inner + .process + .execute(&command, &mut output, Some(path.clone())) + != 0 { // TODO(phase-b): bubble error via Result later panic!( @@ -580,8 +585,7 @@ impl GitDownloader { let output = trim(&output, None); // keep the shortest diff from all remote branches we compare against if unpushed_changes.is_none() - || strlen(&output) - < strlen(unpushed_changes.as_deref().unwrap_or("")) + || strlen(&output) < strlen(unpushed_changes.as_deref().unwrap_or("")) { unpushed_changes = Some(output); } @@ -593,11 +597,7 @@ impl GitDownloader { if unpushed_changes.is_some() && i == 0 { let mut output = String::new(); self.inner.process.execute( - &vec![ - "git".to_string(), - "fetch".to_string(), - "--all".to_string(), - ], + &vec!["git".to_string(), "fetch".to_string(), "--all".to_string()], &mut output, Some(path.clone()), ); @@ -786,9 +786,7 @@ impl GitDownloader { " n - abort the {} and let you manually clean things up", if update { "update" } else { "uninstall" } ))), - Box::new(PhpMixed::String( - " v - view modified files".to_string(), - )), + Box::new(PhpMixed::String(" v - view modified files".to_string())), Box::new(PhpMixed::String( " d - view local modifications (diff)".to_string(), )), @@ -833,11 +831,7 @@ impl GitDownloader { ); let mut output = String::new(); if self.inner.process.execute( - &vec![ - "git".to_string(), - "stash".to_string(), - "pop".to_string(), - ], + &vec!["git".to_string(), "stash".to_string(), "pop".to_string()], &mut output, Some(path.clone()), ) != 0 @@ -886,8 +880,11 @@ impl GitDownloader { // If the non-existent branch is actually the name of a file, the file // is checked out. - let mut branch = - Preg::replace(r"{(?:^dev-|(?:\.x)?-dev$)}i", "", pretty_version.to_string()); + let mut branch = Preg::replace( + r"{(?:^dev-|(?:\.x)?-dev$)}i", + "", + pretty_version.to_string(), + ); // Closure equivalent: $execute = function(array $command) use (&$output, $path) { ... }; // Inlined below at each call site. @@ -910,10 +907,7 @@ impl GitDownloader { if !Preg::is_match(r"{^[a-f0-9]{40}$}", reference).unwrap_or(false) && branches.is_some() && Preg::is_match( - &format!( - "{{^\\s+composer/{}$}}m", - preg_quote(reference, None) - ), + &format!("{{^\\s+composer/{}$}}m", preg_quote(reference, None)), branches.as_deref().unwrap_or(""), ) .unwrap_or(false) @@ -935,18 +929,17 @@ impl GitDownloader { ]; let mut output = String::new(); - let ok1 = self.inner.process.execute( - &command1, - &mut output, - Some(path.to_string()), - ) == 0; + let ok1 = self + .inner + .process + .execute(&command1, &mut output, Some(path.to_string())) + == 0; let ok2 = if ok1 { let mut output = String::new(); - self.inner.process.execute( - &command2, - &mut output, - Some(path.to_string()), - ) == 0 + self.inner + .process + .execute(&command2, &mut output, Some(path.to_string())) + == 0 } else { false }; @@ -960,18 +953,12 @@ impl GitDownloader { // add 'v' in front of the branch if it was stripped when generating the pretty name if branches.is_some() && !Preg::is_match( - &format!( - "{{^\\s+composer/{}$}}m", - preg_quote(&branch, None) - ), + &format!("{{^\\s+composer/{}$}}m", preg_quote(&branch, None)), branches.as_deref().unwrap_or(""), ) .unwrap_or(false) && Preg::is_match( - &format!( - "{{^\\s+composer/v{}$}}m", - preg_quote(&branch, None) - ), + &format!("{{^\\s+composer/v{}$}}m", preg_quote(&branch, None)), branches.as_deref().unwrap_or(""), ) .unwrap_or(false) @@ -985,8 +972,7 @@ impl GitDownloader { branch.clone(), "--".to_string(), ]; - let mut fallback_command: Vec<String> = - vec!["git".to_string(), "checkout".to_string()]; + let mut fallback_command: Vec<String> = vec!["git".to_string(), "checkout".to_string()]; fallback_command.extend(force.clone()); fallback_command.extend(vec![ "-B".to_string(), @@ -1003,28 +989,26 @@ impl GitDownloader { ]; let mut output = String::new(); - let ok_command = self.inner.process.execute( - &command, - &mut output, - Some(path.to_string()), - ) == 0; + let ok_command = + self.inner + .process + .execute(&command, &mut output, Some(path.to_string())) + == 0; let ok_fallback = if !ok_command { let mut output = String::new(); - self.inner.process.execute( - &fallback_command, - &mut output, - Some(path.to_string()), - ) == 0 + self.inner + .process + .execute(&fallback_command, &mut output, Some(path.to_string())) + == 0 } else { false }; let ok_reset = if ok_command || ok_fallback { let mut output = String::new(); - self.inner.process.execute( - &reset_command, - &mut output, - Some(path.to_string()), - ) == 0 + self.inner + .process + .execute(&reset_command, &mut output, Some(path.to_string())) + == 0 } else { false }; @@ -1045,18 +1029,17 @@ impl GitDownloader { ]; { let mut output = String::new(); - let ok1 = self.inner.process.execute( - &command1, - &mut output, - Some(path.to_string()), - ) == 0; + let ok1 = self + .inner + .process + .execute(&command1, &mut output, Some(path.to_string())) + == 0; let ok2 = if ok1 { let mut output = String::new(); - self.inner.process.execute( - &command2, - &mut output, - Some(path.to_string()), - ) == 0 + self.inner + .process + .execute(&command2, &mut output, Some(path.to_string())) + == 0 } else { false }; @@ -1193,11 +1176,7 @@ impl GitDownloader { let path = self.normalize_path(path); let mut output = String::new(); if self.inner.process.execute( - &vec![ - "git".to_string(), - "clean".to_string(), - "-df".to_string(), - ], + &vec!["git".to_string(), "clean".to_string(), "-df".to_string()], &mut output, Some(path.clone()), ) != 0 @@ -1210,11 +1189,7 @@ impl GitDownloader { } let mut output = String::new(); if self.inner.process.execute( - &vec![ - "git".to_string(), - "reset".to_string(), - "--hard".to_string(), - ], + &vec!["git".to_string(), "reset".to_string(), "--hard".to_string()], &mut output, Some(path.clone()), ) != 0 @@ -1263,11 +1238,7 @@ impl GitDownloader { let path = self.normalize_path(path); let mut output = String::new(); if self.inner.process.execute( - &vec![ - "git".to_string(), - "diff".to_string(), - "HEAD".to_string(), - ], + &vec!["git".to_string(), "diff".to_string(), "HEAD".to_string()], &mut output, Some(path.clone()), ) != 0 @@ -1333,4 +1304,3 @@ impl DvcsDownloaderInterface for GitDownloader { GitDownloader::get_unpushed_changes(self, package, &path) } } - diff --git a/crates/shirabe/src/downloader/gzip_downloader.rs b/crates/shirabe/src/downloader/gzip_downloader.rs index 2158126..81fdbed 100644 --- a/crates/shirabe/src/downloader/gzip_downloader.rs +++ b/crates/shirabe/src/downloader/gzip_downloader.rs @@ -1,25 +1,31 @@ //! ref: composer/src/Composer/Downloader/GzipDownloader.php +use crate::downloader::archive_downloader::ArchiveDownloader; +use crate::package::package_interface::PackageInterface; +use crate::util::platform::Platform; 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, + DIRECTORY_SEPARATOR, PATHINFO_FILENAME, PHP_URL_PATH, RuntimeException, extension_loaded, + fclose, fopen, fwrite, gzclose, gzopen, gzread, implode, parse_url, pathinfo, strtr, }; -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>> { + 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), + parse_url( + &strtr(&package.get_dist_url().unwrap_or_default(), "\\", "/"), + PHP_URL_PATH, + ), PATHINFO_FILENAME, ); let target_filepath = format!("{}{}{}", path, DIRECTORY_SEPARATOR, filename); @@ -47,7 +53,10 @@ impl GzipDownloader { implode(" ", &command), self.inner.process.get_error_output(), ); - return Err(anyhow::anyhow!(RuntimeException { message: process_error, code: 0 })); + return Err(anyhow::anyhow!(RuntimeException { + message: process_error, + code: 0 + })); } self.extract_using_ext(file, &target_filepath); diff --git a/crates/shirabe/src/downloader/hg_downloader.rs b/crates/shirabe/src/downloader/hg_downloader.rs index 7501fb6..ff06806 100644 --- a/crates/shirabe/src/downloader/hg_downloader.rs +++ b/crates/shirabe/src/downloader/hg_downloader.rs @@ -1,11 +1,11 @@ //! ref: composer/src/Composer/Downloader/HgDownloader.php -use anyhow::Result; -use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; -use shirabe_php_shim::RuntimeException; use crate::downloader::vcs_downloader::VcsDownloader; use crate::package::package_interface::PackageInterface; use crate::util::hg::Hg as HgUtils; +use anyhow::Result; +use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; +use shirabe_php_shim::RuntimeException; #[derive(Debug)] pub struct HgDownloader { @@ -24,7 +24,8 @@ impl HgDownloader { return Err(RuntimeException { message: "hg was not found in your PATH, skipping source download".to_string(), code: 0, - }.into()); + } + .into()); } Ok(shirabe_external_packages::react::promise::resolve(None)) @@ -40,7 +41,13 @@ impl HgDownloader { let path_clone = path.clone(); let clone_command = move |url: String| -> Vec<String> { - vec!["hg".to_string(), "clone".to_string(), "--".to_string(), url, path_clone.clone()] + vec![ + "hg".to_string(), + "clone".to_string(), + "--".to_string(), + url, + path_clone.clone(), + ] }; hg_utils.run_command(clone_command, url, Some(path.clone())); @@ -51,7 +58,12 @@ impl HgDownloader { package.get_source_reference().unwrap_or_default(), ]; let mut ignored_output = String::new(); - if self.inner.process.execute(&command, &mut ignored_output, shirabe_php_shim::realpath(&path)) != 0 { + if self.inner.process.execute( + &command, + &mut ignored_output, + shirabe_php_shim::realpath(&path), + ) != 0 + { return Err(RuntimeException { message: format!( "Failed to execute {}\n\n{}", @@ -59,7 +71,8 @@ impl HgDownloader { self.inner.process.get_error_output() ), code: 0, - }.into()); + } + .into()); } Ok(shirabe_external_packages::react::promise::resolve(None)) @@ -75,7 +88,10 @@ impl HgDownloader { let hg_utils = HgUtils::new(&self.inner.io, &self.inner.config, &self.inner.process); let ref_ = target.get_source_reference().unwrap_or_default(); - self.inner.io.write_error(&format!(" Updating to {}", target.get_source_reference().unwrap_or_default())); + self.inner.io.write_error(&format!( + " Updating to {}", + target.get_source_reference().unwrap_or_default() + )); if !self.has_metadata_repository(path.clone()) { return Err(RuntimeException { @@ -94,14 +110,23 @@ impl HgDownloader { let ref_clone = ref_.clone(); let up_command = move |_url: String| -> Vec<String> { - vec!["hg".to_string(), "up".to_string(), "--".to_string(), ref_clone.clone()] + vec![ + "hg".to_string(), + "up".to_string(), + "--".to_string(), + ref_clone.clone(), + ] }; hg_utils.run_command(up_command, url, Some(path)); Ok(shirabe_external_packages::react::promise::resolve(None)) } - pub fn get_local_changes(&self, package: &dyn PackageInterface, path: String) -> Option<String> { + pub fn get_local_changes( + &self, + package: &dyn PackageInterface, + path: String, + ) -> Option<String> { if !std::path::Path::new(&format!("{}/.hg", path)).is_dir() { return None; } @@ -115,7 +140,11 @@ impl HgDownloader { let output = output.trim().to_string(); - if !output.is_empty() { Some(output) } else { None } + if !output.is_empty() { + Some(output) + } else { + None + } } pub(crate) fn get_commit_logs( @@ -134,7 +163,12 @@ impl HgDownloader { ]; let mut output = String::new(); - if self.inner.process.execute(&command, &mut output, shirabe_php_shim::realpath(&path)) != 0 { + if self + .inner + .process + .execute(&command, &mut output, shirabe_php_shim::realpath(&path)) + != 0 + { return Err(RuntimeException { message: format!( "Failed to execute {}\n\n{}", @@ -142,7 +176,8 @@ impl HgDownloader { self.inner.process.get_error_output() ), code: 0, - }.into()); + } + .into()); } Ok(output) diff --git a/crates/shirabe/src/downloader/mod.rs b/crates/shirabe/src/downloader/mod.rs new file mode 100644 index 0000000..391ae23 --- /dev/null +++ b/crates/shirabe/src/downloader/mod.rs @@ -0,0 +1,23 @@ +pub mod archive_downloader; +pub mod change_report_interface; +pub mod download_manager; +pub mod downloader_interface; +pub mod dvcs_downloader_interface; +pub mod file_downloader; +pub mod filesystem_exception; +pub mod fossil_downloader; +pub mod git_downloader; +pub mod gzip_downloader; +pub mod hg_downloader; +pub mod max_file_size_exceeded_exception; +pub mod path_downloader; +pub mod perforce_downloader; +pub mod phar_downloader; +pub mod rar_downloader; +pub mod svn_downloader; +pub mod tar_downloader; +pub mod transport_exception; +pub mod vcs_capable_downloader_interface; +pub mod vcs_downloader; +pub mod xz_downloader; +pub mod zip_downloader; diff --git a/crates/shirabe/src/downloader/path_downloader.rs b/crates/shirabe/src/downloader/path_downloader.rs index 2ad3312..33e3b45 100644 --- a/crates/shirabe/src/downloader/path_downloader.rs +++ b/crates/shirabe/src/downloader/path_downloader.rs @@ -6,8 +6,8 @@ use shirabe_external_packages::react::promise::promise_interface::PromiseInterfa use shirabe_external_packages::symfony::component::filesystem::exception::io_exception::IOException; use shirabe_external_packages::symfony::component::filesystem::filesystem::Filesystem as SymfonyFilesystem; use shirabe_php_shim::{ - file_exists, function_exists, is_dir, realpath, PhpMixed, RuntimeException, - DIRECTORY_SEPARATOR, PHP_WINDOWS_VERSION_MAJOR, PHP_WINDOWS_VERSION_MINOR, + DIRECTORY_SEPARATOR, PHP_WINDOWS_VERSION_MAJOR, PHP_WINDOWS_VERSION_MINOR, PhpMixed, + RuntimeException, file_exists, function_exists, is_dir, realpath, }; use crate::dependency_resolver::operation::install_operation::InstallOperation; @@ -68,8 +68,12 @@ impl PathDownloader { return Ok(shirabe_external_packages::react::promise::resolve(None)); } - if format!("{}{}", realpath(&path).unwrap_or_default(), DIRECTORY_SEPARATOR) - .starts_with(&format!("{}{}", real_url, DIRECTORY_SEPARATOR)) + if format!( + "{}{}", + realpath(&path).unwrap_or_default(), + DIRECTORY_SEPARATOR + ) + .starts_with(&format!("{}{}", real_url, DIRECTORY_SEPARATOR)) { // IMPORTANT NOTICE: If you wish to change this, don't. You are wasting your time and ours. // @@ -140,7 +144,10 @@ impl PathDownloader { if output { self.inner.io.write_error( - PhpMixed::String(format!(" - {}: ", InstallOperation::format(package, false))), + PhpMixed::String(format!( + " - {}: ", + InstallOperation::format(package, false) + )), false, IOInterface::NORMAL, ); @@ -251,11 +258,9 @@ impl PathDownloader { } if output { - self.inner.io.write_error( - PhpMixed::String("".to_string()), - true, - IOInterface::NORMAL, - ); + self.inner + .io + .write_error(PhpMixed::String("".to_string()), true, IOInterface::NORMAL); } Ok(shirabe_external_packages::react::promise::resolve(None)) @@ -352,11 +357,7 @@ impl PathDownloader { self.inner.remove(package, &path, output) } - pub fn get_vcs_reference( - &self, - package: &dyn PackageInterface, - path: &str, - ) -> Option<String> { + pub fn get_vcs_reference(&self, package: &dyn PackageInterface, path: &str) -> Option<String> { let path = Filesystem::trim_trailing_slash(path); let parser = VersionParser::new(); let guesser = VersionGuesser::new( diff --git a/crates/shirabe/src/downloader/perforce_downloader.rs b/crates/shirabe/src/downloader/perforce_downloader.rs index 27316e7..8674b3d 100644 --- a/crates/shirabe/src/downloader/perforce_downloader.rs +++ b/crates/shirabe/src/downloader/perforce_downloader.rs @@ -1,14 +1,14 @@ //! ref: composer/src/Composer/Downloader/PerforceDownloader.php -use std::any::Any; -use anyhow::Result; -use indexmap::IndexMap; -use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; -use shirabe_php_shim::PhpMixed; use crate::downloader::vcs_downloader::VcsDownloader; use crate::package::package_interface::PackageInterface; use crate::repository::vcs_repository::VcsRepository; use crate::util::perforce::Perforce; +use anyhow::Result; +use indexmap::IndexMap; +use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; +use shirabe_php_shim::PhpMixed; +use std::any::Any; #[derive(Debug)] pub struct PerforceDownloader { @@ -36,13 +36,22 @@ impl PerforceDownloader { let source_ref = package.get_source_reference(); let label = self.get_label_from_source_reference(source_ref.clone().unwrap_or_default()); - self.inner.io.write_error(&format!("Cloning {}", source_ref.clone().unwrap_or_default())); + self.inner.io.write_error(&format!( + "Cloning {}", + source_ref.clone().unwrap_or_default() + )); self.init_perforce(package, path.clone(), url); - self.perforce.as_mut().unwrap().set_stream(source_ref.clone().unwrap_or_default()); + self.perforce + .as_mut() + .unwrap() + .set_stream(source_ref.clone().unwrap_or_default()); self.perforce.as_mut().unwrap().p4_login(); self.perforce.as_mut().unwrap().write_p4_client_spec(); self.perforce.as_mut().unwrap().connect_client(); - self.perforce.as_mut().unwrap().sync_code_base(label.as_deref()); + self.perforce + .as_mut() + .unwrap() + .sync_code_base(label.as_deref()); self.perforce.as_mut().unwrap().cleanup_client_spec(); Ok(shirabe_external_packages::react::promise::resolve(None)) @@ -73,7 +82,13 @@ impl PerforceDownloader { } else { None }; - self.perforce = Some(Perforce::create(repo_config, url, path, &self.inner.process, &self.inner.io)); + self.perforce = Some(Perforce::create( + repo_config, + url, + path, + &self.inner.process, + &self.inner.io, + )); } fn get_repo_config(&self, repository: &VcsRepository) -> IndexMap<String, PhpMixed> { @@ -90,8 +105,14 @@ impl PerforceDownloader { self.do_install(target, path, url) } - pub fn get_local_changes(&self, _package: &dyn PackageInterface, _path: String) -> Option<String> { - self.inner.io.write_error("Perforce driver does not check for local changes before overriding"); + pub fn get_local_changes( + &self, + _package: &dyn PackageInterface, + _path: String, + ) -> Option<String> { + self.inner + .io + .write_error("Perforce driver does not check for local changes before overriding"); None } @@ -102,7 +123,11 @@ impl PerforceDownloader { to_reference: String, _path: String, ) -> Result<String> { - Ok(self.perforce.as_ref().unwrap().get_commit_logs(from_reference, to_reference)) + Ok(self + .perforce + .as_ref() + .unwrap() + .get_commit_logs(from_reference, to_reference)) } pub fn set_perforce(&mut self, perforce: Perforce) { diff --git a/crates/shirabe/src/downloader/phar_downloader.rs b/crates/shirabe/src/downloader/phar_downloader.rs index 57610f1..8fea679 100644 --- a/crates/shirabe/src/downloader/phar_downloader.rs +++ b/crates/shirabe/src/downloader/phar_downloader.rs @@ -1,10 +1,10 @@ //! ref: composer/src/Composer/Downloader/PharDownloader.php -use anyhow::Result; -use shirabe_php_shim::Phar; -use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use crate::downloader::archive_downloader::ArchiveDownloader; use crate::package::package_interface::PackageInterface; +use anyhow::Result; +use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; +use shirabe_php_shim::Phar; #[derive(Debug)] pub struct PharDownloader { @@ -12,7 +12,12 @@ pub struct PharDownloader { } impl PharDownloader { - pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> { + pub(crate) fn extract( + &self, + package: &dyn PackageInterface, + file: &str, + path: &str, + ) -> Result<Box<dyn PromiseInterface>> { // Can throw an UnexpectedValueException let archive = Phar::new(file.to_string()); archive.extract_to(path, None, true); diff --git a/crates/shirabe/src/downloader/rar_downloader.rs b/crates/shirabe/src/downloader/rar_downloader.rs index 1aaa71c..1b4767f 100644 --- a/crates/shirabe/src/downloader/rar_downloader.rs +++ b/crates/shirabe/src/downloader/rar_downloader.rs @@ -1,19 +1,26 @@ //! ref: composer/src/Composer/Downloader/RarDownloader.php -use anyhow::Result; -use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; -use shirabe_php_shim::{class_exists, implode, RarArchive, RuntimeException, UnexpectedValueException}; use crate::downloader::archive_downloader::ArchiveDownloader; use crate::package::package_interface::PackageInterface; use crate::util::ini_helper::IniHelper; use crate::util::platform::Platform; +use anyhow::Result; +use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; +use shirabe_php_shim::{ + RarArchive, RuntimeException, UnexpectedValueException, class_exists, implode, +}; pub struct RarDownloader { inner: ArchiveDownloader, } impl RarDownloader { - pub(crate) fn extract(&self, _package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> { + pub(crate) fn extract( + &self, + _package: &dyn PackageInterface, + file: &str, + path: &str, + ) -> Result<Box<dyn PromiseInterface>> { let mut process_error: Option<String> = None; if !Platform::is_windows() { @@ -39,7 +46,10 @@ impl RarDownloader { if !class_exists("RarArchive") { let ini_message = IniHelper::get_message(); let error = if !Platform::is_windows() { - format!("Could not decompress the archive, enable the PHP rar extension.\n{}", ini_message) + format!( + "Could not decompress the archive, enable the PHP rar extension.\n{}", + ini_message + ) } else { format!( "Could not decompress the archive, enable the PHP rar extension or install unrar.\n{}\n{}", @@ -47,7 +57,11 @@ impl RarDownloader { process_error.as_deref().unwrap_or(""), ) }; - return Err(RuntimeException { message: error, code: 0 }.into()); + return Err(RuntimeException { + message: error, + code: 0, + } + .into()); } let rar_archive = RarArchive::open(file); @@ -55,7 +69,8 @@ impl RarDownloader { return Err(UnexpectedValueException { message: format!("Could not open RAR archive: {}", file), code: 0, - }.into()); + } + .into()); } let rar_archive = rar_archive.unwrap(); @@ -64,7 +79,8 @@ impl RarDownloader { return Err(RuntimeException { message: "Could not retrieve RAR archive entries".to_string(), code: 0, - }.into()); + } + .into()); } for entry in entries.unwrap() { @@ -72,7 +88,8 @@ impl RarDownloader { return Err(RuntimeException { message: "Could not extract entry".to_string(), code: 0, - }.into()); + } + .into()); } } diff --git a/crates/shirabe/src/downloader/svn_downloader.rs b/crates/shirabe/src/downloader/svn_downloader.rs index 75e5c02..30a64f2 100644 --- a/crates/shirabe/src/downloader/svn_downloader.rs +++ b/crates/shirabe/src/downloader/svn_downloader.rs @@ -3,7 +3,7 @@ use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_external_packages::react::promise; use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; -use shirabe_php_shim::{is_dir, version_compare, PhpMixed, RuntimeException}; +use shirabe_php_shim::{PhpMixed, RuntimeException, is_dir, version_compare}; use crate::downloader::vcs_downloader::VcsDownloader; use crate::io::io_interface::IOInterface; @@ -26,7 +26,12 @@ impl SvnDownloader { prev_package: Option<&dyn PackageInterface>, ) -> anyhow::Result<Box<dyn PromiseInterface>> { SvnUtil::clean_env(); - let util = SvnUtil::new(url, &*self.inner.io, &self.inner.config, &self.inner.process); + let util = SvnUtil::new( + url, + &*self.inner.io, + &self.inner.config, + &self.inner.process, + ); if util.binary_version().is_none() { return Err(RuntimeException { message: "svn was not found in your PATH, skipping source download".to_string(), @@ -52,7 +57,10 @@ impl SvnDownloader { if let Some(vcs_repo) = repo.as_any().downcast_ref::<VcsRepository>() { let repo_config = vcs_repo.get_repo_config(); if repo_config.contains_key("svn-cache-credentials") { - if let Some(val) = repo_config.get("svn-cache-credentials").and_then(|v| v.as_bool()) { + if let Some(val) = repo_config + .get("svn-cache-credentials") + .and_then(|v| v.as_bool()) + { self.cache_credentials = val; } } @@ -97,7 +105,12 @@ impl SvnDownloader { .into()); } - let util = SvnUtil::new(url, &*self.inner.io, &self.inner.config, &self.inner.process); + let util = SvnUtil::new( + url, + &*self.inner.io, + &self.inner.config, + &self.inner.process, + ); let mut flags: Vec<String> = vec![]; if version_compare(&util.binary_version().unwrap_or_default(), "1.7.0", ">=") { flags.push("--ignore-ancestry".to_string()); @@ -271,9 +284,7 @@ impl SvnDownloader { " n - abort the {} and let you manually clean things up", if update { "update" } else { "uninstall" } ))), - Box::new(PhpMixed::String( - " v - view modified files".to_string(), - )), + Box::new(PhpMixed::String(" v - view modified files".to_string())), Box::new(PhpMixed::String(" ? - print help".to_string())), ]), true, @@ -355,11 +366,7 @@ impl SvnDownloader { util.execute_local(command.clone(), path, None, self.inner.io.is_verbose()) .map_err(|e| { RuntimeException { - message: format!( - "Failed to execute {}\n\n{}", - command.join(" "), - e - ), + message: format!("Failed to execute {}\n\n{}", command.join(" "), e), code: 0, } .into() @@ -375,9 +382,7 @@ impl SvnDownloader { pub(crate) fn discard_changes(&self, path: &str) -> anyhow::Result<Box<dyn PromiseInterface>> { let mut output = String::new(); if self.inner.process.execute( - &["svn", "revert", "-R", "."] - .map(|s| s.to_string()) - .to_vec(), + &["svn", "revert", "-R", "."].map(|s| s.to_string()).to_vec(), &mut output, Some(path.to_string()), ) != 0 diff --git a/crates/shirabe/src/downloader/tar_downloader.rs b/crates/shirabe/src/downloader/tar_downloader.rs index 4b13f3b..c327ca0 100644 --- a/crates/shirabe/src/downloader/tar_downloader.rs +++ b/crates/shirabe/src/downloader/tar_downloader.rs @@ -1,10 +1,10 @@ //! ref: composer/src/Composer/Downloader/TarDownloader.php -use anyhow::Result; -use shirabe_php_shim::PharData; -use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use crate::downloader::archive_downloader::ArchiveDownloader; use crate::package::package_interface::PackageInterface; +use anyhow::Result; +use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; +use shirabe_php_shim::PharData; #[derive(Debug)] pub struct TarDownloader { @@ -12,7 +12,12 @@ pub struct TarDownloader { } impl TarDownloader { - pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> { + pub(crate) fn extract( + &self, + package: &dyn PackageInterface, + file: &str, + path: &str, + ) -> Result<Box<dyn PromiseInterface>> { let archive = PharData::new(file.to_string()); archive.extract_to(path, None, true); diff --git a/crates/shirabe/src/downloader/vcs_downloader.rs b/crates/shirabe/src/downloader/vcs_downloader.rs index 3fb305f..37954d2 100644 --- a/crates/shirabe/src/downloader/vcs_downloader.rs +++ b/crates/shirabe/src/downloader/vcs_downloader.rs @@ -4,9 +4,8 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use shirabe_php_shim::{ - array_map, array_shift, count, explode, get_class, implode, rawurldecode, realpath, - str_replace, strlen, strpos, substr, trim, InvalidArgumentException, PhpMixed, - RuntimeException, + InvalidArgumentException, PhpMixed, RuntimeException, array_map, array_shift, count, explode, + get_class, implode, rawurldecode, realpath, str_replace, strlen, strpos, substr, trim, }; use crate::config::Config; @@ -91,11 +90,7 @@ impl VcsDownloader { } if self.io.is_debug() { self.io.write_error( - PhpMixed::String(format!( - "Failed: [{}] {}", - get_class(&e), - e, - )), + PhpMixed::String(format!("Failed: [{}] {}", get_class(&e), e,)), true, IOInterface::NORMAL, ); @@ -183,7 +178,10 @@ impl VcsDownloader { } self.io.write_error( - PhpMixed::String(format!(" - {}: ", InstallOperation::format(package, false))), + PhpMixed::String(format!( + " - {}: ", + InstallOperation::format(package, false) + )), false, IOInterface::NORMAL, ); @@ -203,11 +201,7 @@ impl VcsDownloader { } if self.io.is_debug() { self.io.write_error( - PhpMixed::String(format!( - "Failed: [{}] {}", - get_class(&e), - e, - )), + PhpMixed::String(format!("Failed: [{}] {}", get_class(&e), e,)), true, IOInterface::NORMAL, ); @@ -285,11 +279,7 @@ impl VcsDownloader { } if self.io.is_debug() { self.io.write_error( - PhpMixed::String(format!( - "Failed: [{}] {}", - get_class(&e), - e, - )), + PhpMixed::String(format!("Failed: [{}] {}", get_class(&e), e,)), true, IOInterface::NORMAL, ); @@ -364,7 +354,10 @@ impl VcsDownloader { path: &str, ) -> Result<Box<dyn PromiseInterface>> { self.io.write_error( - PhpMixed::String(format!(" - {}", UninstallOperation::format(package, false))), + PhpMixed::String(format!( + " - {}", + UninstallOperation::format(package, false) + )), true, IOInterface::NORMAL, ); @@ -372,24 +365,22 @@ impl VcsDownloader { let promise = self.filesystem.remove_directory_async(path); let path = path.to_string(); - Ok(promise.then(Box::new(move |result: PhpMixed| -> Result<()> { - let result_bool = result.as_bool().unwrap_or(false); - if !result_bool { - return Err(RuntimeException { - message: format!("Could not completely delete {}, aborting.", path), - code: 0, + Ok( + promise.then(Box::new(move |result: PhpMixed| -> Result<()> { + let result_bool = result.as_bool().unwrap_or(false); + if !result_bool { + return Err(RuntimeException { + message: format!("Could not completely delete {}, aborting.", path), + code: 0, + } + .into()); } - .into()); - } - Ok(()) - }))) + Ok(()) + })), + ) } - pub fn get_vcs_reference( - &self, - package: &dyn PackageInterface, - path: &str, - ) -> Option<String> { + pub fn get_vcs_reference(&self, package: &dyn PackageInterface, path: &str) -> Option<String> { let parser = VersionParser::new(); let guesser = VersionGuesser::new(&self.config, &self.process, &parser, &*self.io); let dumper = ArrayDumper::new(); diff --git a/crates/shirabe/src/downloader/xz_downloader.rs b/crates/shirabe/src/downloader/xz_downloader.rs index a53c9c6..0c5d876 100644 --- a/crates/shirabe/src/downloader/xz_downloader.rs +++ b/crates/shirabe/src/downloader/xz_downloader.rs @@ -1,9 +1,9 @@ //! ref: composer/src/Composer/Downloader/XzDownloader.php -use anyhow::{bail, Result}; -use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use crate::downloader::archive_downloader::ArchiveDownloader; use crate::package::package_interface::PackageInterface; +use anyhow::{Result, bail}; +use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; #[derive(Debug)] pub struct XzDownloader { @@ -11,7 +11,12 @@ pub struct XzDownloader { } impl XzDownloader { - pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> { + pub(crate) fn extract( + &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(); @@ -19,7 +24,11 @@ impl XzDownloader { return Ok(shirabe_external_packages::react::promise::resolve(None)); } - let process_error = format!("Failed to execute {}\n\n{}", command.join(" "), self.inner.process.get_error_output()); + let process_error = format!( + "Failed to execute {}\n\n{}", + command.join(" "), + self.inner.process.get_error_output() + ); bail!(process_error); } diff --git a/crates/shirabe/src/downloader/zip_downloader.rs b/crates/shirabe/src/downloader/zip_downloader.rs index 71a23b8..ecb7821 100644 --- a/crates/shirabe/src/downloader/zip_downloader.rs +++ b/crates/shirabe/src/downloader/zip_downloader.rs @@ -1,23 +1,22 @@ //! ref: composer/src/Composer/Downloader/ZipDownloader.php -use std::sync::Mutex; +use crate::downloader::archive_downloader::ArchiveDownloader; +use crate::downloader::file_downloader::FileDownloader; +use crate::package::package_interface::PackageInterface; +use crate::util::ini_helper::IniHelper; +use crate::util::platform::Platform; use anyhow::Result; use indexmap::IndexMap; +use shirabe_external_packages::composer::pcre::preg::Preg; +use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; +use shirabe_external_packages::symfony::component::process::executable_finder::ExecutableFinder; +use shirabe_external_packages::symfony::component::process::process::Process; use shirabe_php_shim::{ + DIRECTORY_SEPARATOR, ErrorException, RuntimeException, UnexpectedValueException, ZipArchive, bin2hex, class_exists, file_exists, file_get_contents, filesize, function_exists, hash_file, is_file, json_encode, random_int, version_compare, - ErrorException, RuntimeException, UnexpectedValueException, ZipArchive, - DIRECTORY_SEPARATOR, }; -use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; -use shirabe_external_packages::symfony::component::process::executable_finder::ExecutableFinder; -use shirabe_external_packages::symfony::component::process::process::Process; -use shirabe_external_packages::composer::pcre::preg::Preg; -use crate::downloader::archive_downloader::ArchiveDownloader; -use crate::downloader::file_downloader::FileDownloader; -use crate::package::package_interface::PackageInterface; -use crate::util::ini_helper::IniHelper; -use crate::util::platform::Platform; +use std::sync::Mutex; static UNZIP_COMMANDS: Mutex<Option<Vec<Vec<String>>>> = Mutex::new(None); static HAS_ZIP_ARCHIVE: Mutex<Option<bool>> = Mutex::new(None); @@ -46,22 +45,61 @@ impl ZipDownloader { let commands = unzip_commands.as_mut().unwrap(); if Platform::is_windows() { if let Some(cmd) = finder.find("7z", None, &[r"C:\Program Files\7-Zip"]) { - commands.push(vec!["7z".to_string(), cmd, "x".to_string(), "-bb0".to_string(), "-y".to_string(), "%file%".to_string(), "-o%path%".to_string()]); + commands.push(vec![ + "7z".to_string(), + cmd, + "x".to_string(), + "-bb0".to_string(), + "-y".to_string(), + "%file%".to_string(), + "-o%path%".to_string(), + ]); } } if let Some(cmd) = finder.find("unzip", None, &[]) { - commands.push(vec!["unzip".to_string(), cmd, "-qq".to_string(), "%file%".to_string(), "-d".to_string(), "%path%".to_string()]); + commands.push(vec![ + "unzip".to_string(), + cmd, + "-qq".to_string(), + "%file%".to_string(), + "-d".to_string(), + "%path%".to_string(), + ]); } if !Platform::is_windows() { if let Some(cmd) = finder.find("7z", None, &[]) { // 7z linux/macOS support is only used if unzip is not present - commands.push(vec!["7z".to_string(), cmd, "x".to_string(), "-bb0".to_string(), "-y".to_string(), "%file%".to_string(), "-o%path%".to_string()]); + commands.push(vec![ + "7z".to_string(), + cmd, + "x".to_string(), + "-bb0".to_string(), + "-y".to_string(), + "%file%".to_string(), + "-o%path%".to_string(), + ]); } else if let Some(cmd) = finder.find("7zz", None, &[]) { // 7zz linux/macOS support is only used if unzip is not present - commands.push(vec!["7zz".to_string(), cmd, "x".to_string(), "-bb0".to_string(), "-y".to_string(), "%file%".to_string(), "-o%path%".to_string()]); + commands.push(vec![ + "7zz".to_string(), + cmd, + "x".to_string(), + "-bb0".to_string(), + "-y".to_string(), + "%file%".to_string(), + "-o%path%".to_string(), + ]); } else if let Some(cmd) = finder.find("7za", None, &[]) { // 7za linux/macOS support is only used if unzip is not present - commands.push(vec!["7za".to_string(), cmd, "x".to_string(), "-bb0".to_string(), "-y".to_string(), "%file%".to_string(), "-o%path%".to_string()]); + commands.push(vec![ + "7za".to_string(), + cmd, + "x".to_string(), + "-bb0".to_string(), + "-y".to_string(), + "%file%".to_string(), + "-o%path%".to_string(), + ]); } } } @@ -80,16 +118,30 @@ impl ZipDownloader { } let has_zip_archive = HAS_ZIP_ARCHIVE.lock().unwrap().unwrap_or(false); - let unzip_commands_empty = UNZIP_COMMANDS.lock().unwrap().as_ref().map_or(true, |v| v.is_empty()); + let unzip_commands_empty = UNZIP_COMMANDS + .lock() + .unwrap() + .as_ref() + .map_or(true, |v| v.is_empty()); if !has_zip_archive && unzip_commands_empty { let ini_message = IniHelper::get_message(); let error = if proc_open_missing { - format!("The zip extension is missing and unzip/7z commands cannot be called as proc_open is disabled, skipping.\n{}", ini_message) + format!( + "The zip extension is missing and unzip/7z commands cannot be called as proc_open is disabled, skipping.\n{}", + ini_message + ) } else { - format!("The zip extension and unzip/7z commands are both missing, skipping.\n{}", ini_message) + format!( + "The zip extension and unzip/7z commands are both missing, skipping.\n{}", + ini_message + ) }; - return Err(RuntimeException { message: error, code: 0 }.into()); + return Err(RuntimeException { + message: error, + code: 0, + } + .into()); } { @@ -111,7 +163,9 @@ impl ZipDownloader { } } - self.inner.inner.download(package, path, prev_package, output) + self.inner + .inner + .download(package, path, prev_package, output) } fn extract_with_system_unzip( @@ -124,7 +178,11 @@ impl ZipDownloader { let is_last_chance = !HAS_ZIP_ARCHIVE.lock().unwrap().unwrap_or(false); - let unzip_commands_empty = UNZIP_COMMANDS.lock().unwrap().as_ref().map_or(true, |v| v.is_empty()); + let unzip_commands_empty = UNZIP_COMMANDS + .lock() + .unwrap() + .as_ref() + .map_or(true, |v| v.is_empty()); if unzip_commands_empty { return self.extract_with_zip_archive(package, file, path); } @@ -136,14 +194,19 @@ impl ZipDownloader { // see https://github.com/composer/composer/issues/10058 ("%file%", file.replace('/', DIRECTORY_SEPARATOR)), ("%path%", path.replace('/', DIRECTORY_SEPARATOR)), - ].into_iter().collect(); - let command: Vec<String> = command_spec[1..].iter().map(|value| { - let mut v = value.clone(); - for (from, to) in &map { - v = v.replace(from, to.as_str()); - } - v - }).collect(); + ] + .into_iter() + .collect(); + let command: Vec<String> = command_spec[1..] + .iter() + .map(|value| { + let mut v = value.clone(); + for (from, to) in &map { + v = v.replace(from, to.as_str()); + } + v + }) + .collect(); if !*WARNED_7ZIP_LINUX.lock().unwrap() && !Platform::is_windows() @@ -151,8 +214,16 @@ impl ZipDownloader { { *WARNED_7ZIP_LINUX.lock().unwrap() = true; let mut output = String::new(); - if self.inner.inner.process.execute(&[command_spec[1].as_str()], &mut output) == 0 { - if let Some(m) = Preg::is_match_strict_groups(r"^\s*7-Zip(?:\s\[64\])?\s([0-9.]+)", &output) { + if self + .inner + .inner + .process + .execute(&[command_spec[1].as_str()], &mut output) + == 0 + { + if let Some(m) = + 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!( " <warning>Unzipping using {} {} may result in incorrect file permissions. Install {} 21.01+ or unzip to ensure you get correct permissions.</warning>", @@ -180,21 +251,44 @@ impl ZipDownloader { } else { io.write_error(&format!(" <warning>{}</warning>", process_error)); io.write_error(" The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)"); - io.write_error(&format!(" Unzip with {} command failed, falling back to ZipArchive class", executable)); + io.write_error(&format!( + " Unzip with {} command failed, falling back to ZipArchive class", + executable + )); - if Platform::get_env("GITHUB_ACTIONS").is_some() && Platform::get_env("COMPOSER_TESTS_ARE_RUNNING").is_none() { + if Platform::get_env("GITHUB_ACTIONS").is_some() + && Platform::get_env("COMPOSER_TESTS_ARE_RUNNING").is_none() + { io.write_error(" <warning>Additional debug info, please report to https://github.com/composer/composer/issues/11148 if you see this:</warning>"); io.write_error(&format!("File size: {}", filesize(file).unwrap_or(0))); - io.write_error(&format!("File SHA1: {}", hash_file("sha1", file).unwrap_or_default())); + io.write_error(&format!( + "File SHA1: {}", + hash_file("sha1", file).unwrap_or_default() + )); let content = file_get_contents(file).unwrap_or_default(); let bytes = content.as_bytes(); - io.write_error(&format!("First 100 bytes (hex): {}", bin2hex(&bytes[..bytes.len().min(100)]))); + io.write_error(&format!( + "First 100 bytes (hex): {}", + bin2hex(&bytes[..bytes.len().min(100)]) + )); let len = bytes.len(); - io.write_error(&format!("Last 100 bytes (hex): {}", bin2hex(&bytes[len.saturating_sub(100)..]))); + io.write_error(&format!( + "Last 100 bytes (hex): {}", + bin2hex(&bytes[len.saturating_sub(100)..]) + )); if package.get_dist_url().map_or(false, |u| !u.is_empty()) { - io.write_error(&format!("Origin URL: {}", self.inner.inner.process_url(package, &package.get_dist_url().unwrap_or_default()))); + io.write_error(&format!( + "Origin URL: {}", + self.inner + .inner + .process_url(package, &package.get_dist_url().unwrap_or_default()) + )); let headers = FileDownloader::response_headers.lock().unwrap(); - io.write_error(&format!("Response Headers: {}", json_encode(&shirabe_php_shim::PhpMixed::Null).unwrap_or_else(|| "[]".to_string()))); + io.write_error(&format!( + "Response Headers: {}", + json_encode(&shirabe_php_shim::PhpMixed::Null) + .unwrap_or_else(|| "[]".to_string()) + )); } } } @@ -241,7 +335,10 @@ impl ZipDownloader { file: &str, path: &str, ) -> Result<Box<dyn PromiseInterface>> { - let mut zip_archive = self.zip_archive_object.take().unwrap_or_else(ZipArchive::new); + let mut zip_archive = self + .zip_archive_object + .take() + .unwrap_or_else(ZipArchive::new); let result: Result<Box<dyn PromiseInterface>> = (|| { let retval = if !file_exists(file) || filesize(file).map_or(true, |s| s == 0) { @@ -259,10 +356,15 @@ impl ZipDownloader { let mut files_to_inspect = total_files.min(5); let mut i: i64 = 0; while i < files_to_inspect { - let stat_index = if inspect_all { i } else { random_int(0, total_files - 1) }; + let stat_index = if inspect_all { + i + } else { + random_int(0, total_files - 1) + }; if let Some(stat) = zip_archive.stat_index(stat_index) { let size = stat.get("size").and_then(|v| v.as_int()).unwrap_or(0); - let comp_size = stat.get("comp_size").and_then(|v| v.as_int()).unwrap_or(0); + let comp_size = + stat.get("comp_size").and_then(|v| v.as_int()).unwrap_or(0); total_size += size; if !inspect_all && size > comp_size * 200 { total_size = 0; @@ -305,7 +407,8 @@ impl ZipDownloader { return Err(UnexpectedValueException { message: self.get_error_message(code, file).trim_end().to_string(), code, - }.into()); + } + .into()); } })(); @@ -345,8 +448,14 @@ impl ZipDownloader { ZipArchive::ER_OPEN => format!("Can't open zip file: {}", file), ZipArchive::ER_READ => format!("Zip read error ({})", file), ZipArchive::ER_SEEK => format!("Zip seek error ({})", file), - -1 => format!("'{}' is a corrupted zip archive (0 bytes), try again.", file), - _ => format!("'{}' is not a valid zip archive, got error code: {}", file, retval), + -1 => format!( + "'{}' is a corrupted zip archive (0 bytes), try again.", + file + ), + _ => format!( + "'{}' is not a valid zip archive, got error code: {}", + file, retval + ), } } } |
