From a1c7e6908a26e10f6e1f23a51721664b5e2d838d Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 17 May 2026 02:53:53 +0900 Subject: chore(style): cargo fmt --- .../src/repository/advisory_provider_interface.rs | 10 +- crates/shirabe/src/repository/array_repository.rs | 29 ++- .../shirabe/src/repository/artifact_repository.rs | 27 +- .../src/repository/canonical_packages_trait.rs | 2 +- .../shirabe/src/repository/composer_repository.rs | 271 ++++++++------------- .../shirabe/src/repository/composite_repository.rs | 26 +- .../src/repository/filesystem_repository.rs | 124 ++++++---- crates/shirabe/src/repository/filter_repository.rs | 113 +++++++-- .../shirabe/src/repository/installed_repository.rs | 16 +- crates/shirabe/src/repository/mod.rs | 31 +++ crates/shirabe/src/repository/path_repository.rs | 81 +++--- .../shirabe/src/repository/platform_repository.rs | 165 +++++++------ .../shirabe/src/repository/repository_factory.rs | 148 ++++++++--- .../shirabe/src/repository/repository_interface.rs | 18 +- .../shirabe/src/repository/repository_manager.rs | 59 ++++- crates/shirabe/src/repository/repository_set.rs | 35 ++- crates/shirabe/src/repository/repository_utils.rs | 19 +- .../shirabe/src/repository/vcs/forgejo_driver.rs | 197 ++++++++------- crates/shirabe/src/repository/vcs/fossil_driver.rs | 22 +- .../src/repository/vcs/git_bitbucket_driver.rs | 118 ++++----- crates/shirabe/src/repository/vcs/git_driver.rs | 43 +--- crates/shirabe/src/repository/vcs/github_driver.rs | 175 +++++-------- crates/shirabe/src/repository/vcs/gitlab_driver.rs | 123 ++++------ crates/shirabe/src/repository/vcs/hg_driver.rs | 117 +++++++-- crates/shirabe/src/repository/vcs/mod.rs | 11 + .../shirabe/src/repository/vcs/perforce_driver.rs | 66 ++++- crates/shirabe/src/repository/vcs/svn_driver.rs | 139 +++++------ crates/shirabe/src/repository/vcs/vcs_driver.rs | 58 ++++- .../src/repository/vcs/vcs_driver_interface.rs | 9 +- crates/shirabe/src/repository/vcs_repository.rs | 117 +++++---- .../src/repository/writable_array_repository.rs | 8 +- .../repository/writable_repository_interface.rs | 2 +- 32 files changed, 1364 insertions(+), 1015 deletions(-) create mode 100644 crates/shirabe/src/repository/mod.rs create mode 100644 crates/shirabe/src/repository/vcs/mod.rs (limited to 'crates/shirabe/src/repository') diff --git a/crates/shirabe/src/repository/advisory_provider_interface.rs b/crates/shirabe/src/repository/advisory_provider_interface.rs index d0aaceb..f9ddeb2 100644 --- a/crates/shirabe/src/repository/advisory_provider_interface.rs +++ b/crates/shirabe/src/repository/advisory_provider_interface.rs @@ -1,9 +1,9 @@ //! ref: composer/src/Composer/Repository/AdvisoryProviderInterface.php -use indexmap::IndexMap; -use shirabe_semver::constraint::constraint_interface::ConstraintInterface; use crate::advisory::partial_security_advisory::PartialSecurityAdvisory; use crate::advisory::security_advisory::SecurityAdvisory; +use indexmap::IndexMap; +use shirabe_semver::constraint::constraint_interface::ConstraintInterface; #[derive(Debug)] pub enum PartialOrSecurityAdvisory { @@ -20,5 +20,9 @@ pub struct SecurityAdvisoryResult { pub trait AdvisoryProviderInterface { fn has_security_advisories(&self) -> bool; - fn get_security_advisories(&self, package_constraint_map: IndexMap>, allow_partial_advisories: bool) -> anyhow::Result; + fn get_security_advisories( + &self, + package_constraint_map: IndexMap>, + allow_partial_advisories: bool, + ) -> anyhow::Result; } diff --git a/crates/shirabe/src/repository/array_repository.rs b/crates/shirabe/src/repository/array_repository.rs index 5be2a8b..7bb7e81 100644 --- a/crates/shirabe/src/repository/array_repository.rs +++ b/crates/shirabe/src/repository/array_repository.rs @@ -7,8 +7,8 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - implode, preg_quote, spl_object_hash, strtolower, Countable, InvalidArgumentException, - LogicException, + Countable, InvalidArgumentException, LogicException, implode, preg_quote, spl_object_hash, + strtolower, }; use shirabe_semver::constraint::constraint::Constraint; use shirabe_semver::constraint::constraint_interface::ConstraintInterface; @@ -53,7 +53,10 @@ impl ArrayRepository { /// Adds a new package to the repository pub fn add_package(&self, package: Box) -> Result<()> { // PHP: if (!$package instanceof BasePackage) throw new \InvalidArgumentException(...) - if (package.as_any() as &dyn Any).downcast_ref::().is_none() { + if (package.as_any() as &dyn Any) + .downcast_ref::() + .is_none() + { return Err(InvalidArgumentException { message: "Only subclasses of BasePackage are supported".to_string(), code: 0, @@ -61,7 +64,8 @@ impl ArrayRepository { .into()); } // TODO(phase-b): convert Box to Box - let mut package: Box = todo!("downcast Box to Box"); + let mut package: Box = + todo!("downcast Box to Box"); if self.packages.borrow().is_none() { self.initialize(); @@ -101,7 +105,10 @@ impl ArrayRepository { package = alias_pkg.get_alias_of().clone_box(); } - if (package.as_any() as &dyn Any).downcast_ref::().is_some() { + if (package.as_any() as &dyn Any) + .downcast_ref::() + .is_some() + { // TODO(phase-b): construct CompleteAliasPackage/AliasPackage and return as Box return todo!("new CompleteAliasPackage(package, alias, pretty_alias)"); } @@ -291,10 +298,7 @@ impl RepositoryInterface for ArrayRepository { ) } else { // vendor/name searches expect the caller to have preg_quoted the query - format!( - "{{(?:{})}}i", - implode("|", &Preg::split("{\\s+}", &query)) - ) + format!("{{(?:{})}}i", implode("|", &Preg::split("{\\s+}", &query))) }; let mut matches: IndexMap = IndexMap::new(); @@ -314,8 +318,7 @@ impl RepositoryInterface for ArrayRepository { } } - let complete = - (package.as_any() as &dyn Any).downcast_ref::(); + let complete = (package.as_any() as &dyn Any).downcast_ref::(); let fulltext_match = mode == Self::SEARCH_FULLTEXT && complete.is_some() @@ -397,8 +400,8 @@ impl RepositoryInterface for ArrayRepository { } for link in candidate.get_provides().values() { if package_name == link.get_target() { - let complete = (candidate.as_any() as &dyn Any) - .downcast_ref::(); + let complete = + (candidate.as_any() as &dyn Any).downcast_ref::(); let description = complete.and_then(|c| c.get_description().map(String::from)); result.insert( candidate.get_name().to_string(), diff --git a/crates/shirabe/src/repository/artifact_repository.rs b/crates/shirabe/src/repository/artifact_repository.rs index 988e456..a9832a1 100644 --- a/crates/shirabe/src/repository/artifact_repository.rs +++ b/crates/shirabe/src/repository/artifact_repository.rs @@ -3,7 +3,9 @@ use std::path::Path; use indexmap::IndexMap; -use shirabe_php_shim::{extension_loaded, hash_file, PhpMixed, RuntimeException, UnexpectedValueException}; +use shirabe_php_shim::{ + PhpMixed, RuntimeException, UnexpectedValueException, extension_loaded, hash_file, +}; use crate::io::io_interface::IOInterface; use crate::json::json_file::JsonFile; @@ -34,7 +36,10 @@ impl std::fmt::Debug for ArtifactRepository { } impl ArtifactRepository { - pub fn new(repo_config: IndexMap, io: Box) -> anyhow::Result { + pub fn new( + repo_config: IndexMap, + io: Box, + ) -> anyhow::Result { if !extension_loaded("zip") { return Err(RuntimeException { message: "The artifact repository requires PHP's zip extension".to_string(), @@ -101,7 +106,10 @@ impl ArtifactRepository { match package { None => { self.io.write_error( - &format!("File {} doesn't seem to hold a package", basename), + &format!( + "File {} doesn't seem to hold a package", + basename + ), true, IOInterface::VERBOSE, ); @@ -169,7 +177,8 @@ impl ArtifactRepository { return Ok(None); } - let mut package = JsonFile::parse_json(&json.unwrap(), &format!("{}#composer.json", pathname))?; + let mut package = + JsonFile::parse_json(&json.unwrap(), &format!("{}#composer.json", pathname))?; let url_normalized = pathname.replace('\\', '/'); let real_path = file .canonicalize() @@ -179,8 +188,14 @@ impl ArtifactRepository { let shasum = hash_file("sha1", &real_path).unwrap_or_default(); let mut dist = IndexMap::new(); - dist.insert("type".to_string(), Box::new(PhpMixed::String(file_type.to_string()))); - dist.insert("url".to_string(), Box::new(PhpMixed::String(url_normalized))); + dist.insert( + "type".to_string(), + Box::new(PhpMixed::String(file_type.to_string())), + ); + dist.insert( + "url".to_string(), + Box::new(PhpMixed::String(url_normalized)), + ); dist.insert("shasum".to_string(), Box::new(PhpMixed::String(shasum))); package.insert("dist".to_string(), Box::new(PhpMixed::Array(dist))); diff --git a/crates/shirabe/src/repository/canonical_packages_trait.rs b/crates/shirabe/src/repository/canonical_packages_trait.rs index 3fac07e..8fae936 100644 --- a/crates/shirabe/src/repository/canonical_packages_trait.rs +++ b/crates/shirabe/src/repository/canonical_packages_trait.rs @@ -1,7 +1,7 @@ //! ref: composer/src/Composer/Repository/CanonicalPackagesTrait.php -use indexmap::IndexMap; use crate::package::package_interface::PackageInterface; +use indexmap::IndexMap; /// Provides get_canonical_packages() to various repository implementations. pub trait CanonicalPackagesTrait { diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 9d74e5b..ea73090 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -5,11 +5,10 @@ use shirabe_external_packages::composer::metadata_minifier::metadata_minifier::M use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_external_packages::react::promise::promise_interface::PromiseInterface; use shirabe_php_shim::{ - PhpMixed, InvalidArgumentException, LogicException, RuntimeException, - UnexpectedValueException, PHP_EOL, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, - extension_loaded, hash, http_build_query, in_array, - json_decode, parse_url_all, realpath, strtolower, strtr, - spl_object_hash, urlencode, var_export, + InvalidArgumentException, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, LogicException, + PHP_EOL, PhpMixed, RuntimeException, UnexpectedValueException, extension_loaded, hash, + http_build_query, in_array, json_decode, parse_url_all, realpath, spl_object_hash, strtolower, + strtr, urlencode, var_export, }; use shirabe_semver::compiling_matcher::CompilingMatcher; @@ -190,7 +189,11 @@ impl ComposerRepository { } if url_after.starts_with("https?") { - let scheme = if extension_loaded("openssl") { "https" } else { "http" }; + let scheme = if extension_loaded("openssl") { + "https" + } else { + "http" + }; let rest = &url_after[6..]; repo_config.insert( "url".to_string(), @@ -211,10 +214,7 @@ impl ComposerRepository { .map_or(false, |s| !s.is_empty()); if url_bits_arr.is_none() || !scheme_present { return Err(UnexpectedValueException { - message: format!( - "Invalid url given for Composer repository: {}", - current_url - ), + message: format!("Invalid url given for Composer repository: {}", current_url), code: 0, } .into()); @@ -255,8 +255,7 @@ impl ComposerRepository { url = format!("{}://repo.packagist.org", proto); } - let base_url_trimmed = - Preg::replace(r"{(?:/[^/\\]+\.json)?(?:[?#].*)?$}", "", &url)?; + let base_url_trimmed = Preg::replace(r"{(?:/[^/\\]+\.json)?(?:[?#].*)?$}", "", &url)?; let base_url = base_url_trimmed.trim_end_matches('/').to_string(); assert!(!base_url.is_empty()); @@ -503,15 +502,14 @@ impl ComposerRepository { if self.lazy_providers_url.is_some() { if let Some(ref available_packages) = self.available_packages.clone() { if self.available_package_patterns.is_none() { - let mut package_map: IndexMap< - String, - Option>, - > = IndexMap::new(); + let mut package_map: IndexMap>> = + IndexMap::new(); for name in available_packages.values() { package_map.insert( name.clone(), - Some(Box::new(MatchAllConstraint::new()) - as Box), + Some( + Box::new(MatchAllConstraint::new()) as Box + ), ); } @@ -536,10 +534,8 @@ impl ComposerRepository { let partial = self.partial_packages_by_name.clone().unwrap(); let flat: Vec> = partial.into_values().flatten().collect(); - return self.create_packages_flat( - flat, - Some("packages.json inline packages".to_string()), - ); + return self + .create_packages_flat(flat, Some("packages.json inline packages".to_string())); } return Err(LogicException { @@ -643,10 +639,7 @@ impl ComposerRepository { Ok(vendors) } - fn load_package_list( - &mut self, - package_filter: Option<&str>, - ) -> anyhow::Result> { + fn load_package_list(&mut self, package_filter: Option<&str>) -> anyhow::Result> { if self.list_url.is_none() { return Err(LogicException { message: "Make sure to call loadRootServerFile before loadPackageList".to_string(), @@ -768,8 +761,7 @@ impl ComposerRepository { let matches_constraint = match &constraint { None => true, Some(c) => { - let pkg_c = - Constraint::new("==", candidate.get_version().to_string()); + let pkg_c = Constraint::new("==", candidate.get_version().to_string()); c.matches(&pkg_c) } }; @@ -909,10 +901,7 @@ impl ComposerRepository { for name in Preg::grep(®ex, &vendor_names)? { let mut entry = IndexMap::new(); entry.insert("name".to_string(), PhpMixed::String(name)); - entry.insert( - "description".to_string(), - PhpMixed::String(String::new()), - ); + entry.insert("description".to_string(), PhpMixed::String(String::new())); results.push(entry); } @@ -926,8 +915,7 @@ impl ComposerRepository { r"{^\^(?P(?P[a-z0-9_.-]+)/[a-z0-9_.-]*)\*?$}i", &query, &mut match_groups, - )? - && self.list_url.is_some() + )? && self.list_url.is_some() { let q = match_groups.get(1).cloned().unwrap_or_default(); let vendor = match_groups.get(2).cloned().unwrap_or_default(); @@ -951,14 +939,9 @@ impl ComposerRepository { for name_mixed in list.iter() { if let Some(name) = name_mixed.as_string() { let mut entry = IndexMap::new(); - entry.insert( - "name".to_string(), - PhpMixed::String(name.to_string()), - ); - entry.insert( - "description".to_string(), - PhpMixed::String(String::new()), - ); + entry.insert("name".to_string(), PhpMixed::String(name.to_string())); + entry + .insert("description".to_string(), PhpMixed::String(String::new())); results.push(entry); } } @@ -975,10 +958,7 @@ impl ComposerRepository { for name in Preg::grep(®ex, &package_names)? { let mut entry = IndexMap::new(); entry.insert("name".to_string(), PhpMixed::String(name)); - entry.insert( - "description".to_string(), - PhpMixed::String(String::new()), - ); + entry.insert("description".to_string(), PhpMixed::String(String::new())); results.push(entry); } @@ -991,9 +971,10 @@ impl ComposerRepository { pub fn has_security_advisories(&mut self) -> anyhow::Result { self.load_root_server_file(Some(600))?; - Ok(self.security_advisory_config.as_ref().map_or(false, |c| { - c.metadata || c.api_url.is_some() - })) + Ok(self + .security_advisory_config + .as_ref() + .map_or(false, |c| c.metadata || c.api_url.is_some())) } /// @inheritDoc @@ -1032,10 +1013,7 @@ impl ComposerRepository { let repo_name = self.get_repo_name(); let create = |data: &IndexMap, name: &str, - package_constraint_map: &IndexMap< - String, - Box, - >| + package_constraint_map: &IndexMap>| -> anyhow::Result> { let advisory = PartialSecurityAdvisory::create(name.to_string(), data.clone(), &parser)?; @@ -1095,8 +1073,7 @@ impl ComposerRepository { .then_boxed(Box::new({ let advisories_ptr = &mut advisories as *mut _; let names_found_ptr = &mut names_found as *mut _; - let package_constraint_map_ptr = - &mut package_constraint_map as *mut _; + let package_constraint_map_ptr = &mut package_constraint_map as *mut _; let name = name.clone(); let create = &create; move |spec: PhpMixed| -> anyhow::Result<()> { @@ -1129,10 +1106,8 @@ impl ComposerRepository { .iter() .map(|(k, v)| (k.clone(), (**v).clone())) .collect(); - let pcm: &IndexMap< - String, - Box, - > = unsafe { &*package_constraint_map_ptr }; + let pcm: &IndexMap> = + unsafe { &*package_constraint_map_ptr }; if let Some(adv) = create(&data_map, &name, pcm)? { entries.push(adv); } @@ -1183,10 +1158,7 @@ impl ComposerRepository { headers.push(Box::new(PhpMixed::String( "Content-type: application/x-www-form-urlencoded".to_string(), ))); - http_map.insert( - "header".to_string(), - Box::new(PhpMixed::List(headers)), - ); + http_map.insert("header".to_string(), Box::new(PhpMixed::List(headers))); http_map.insert("timeout".to_string(), Box::new(PhpMixed::Int(10))); let packages_list: Vec<(String, String)> = package_constraint_map .keys() @@ -1200,10 +1172,7 @@ impl ComposerRepository { "&", "=", ); - http_map.insert( - "content".to_string(), - Box::new(PhpMixed::String(body)), - ); + http_map.insert("content".to_string(), Box::new(PhpMixed::String(body))); } let response = self.http_downloader.get(&api_url, &options)?; @@ -1240,8 +1209,7 @@ impl ComposerRepository { .iter() .map(|(k, v)| (k.clone(), (**v).clone())) .collect(); - if let Some(adv) = - create(&data_map, name, &package_constraint_map)? + if let Some(adv) = create(&data_map, name, &package_constraint_map)? { entries.push(adv); } @@ -1312,9 +1280,8 @@ impl ComposerRepository { if self.has_partial_packages()? { if self.partial_packages_by_name.is_none() { return Err(LogicException { - message: - "hasPartialPackages failed to initialize $this->partialPackagesByName" - .to_string(), + message: "hasPartialPackages failed to initialize $this->partialPackagesByName" + .to_string(), code: 0, } .into()); @@ -1335,10 +1302,7 @@ impl ComposerRepository { continue; } let mut entry: IndexMap = IndexMap::new(); - entry.insert( - "name".to_string(), - PhpMixed::String(candidate_name.clone()), - ); + entry.insert("name".to_string(), PhpMixed::String(candidate_name.clone())); entry.insert( "description".to_string(), candidate @@ -1523,11 +1487,8 @@ impl ComposerRepository { if let Some(last_modified) = arr.get("last-modified").and_then(|v| v.as_string()) { - let response = self.fetch_file_if_last_modified( - &url, - &cache_key, - last_modified, - )?; + let response = + self.fetch_file_if_last_modified(&url, &cache_key, last_modified)?; match response { FetchFileIfLastModifiedResult::NotModified => { let map: IndexMap = arr @@ -1563,10 +1524,8 @@ impl ComposerRepository { ) { Ok(p) => { packages_opt = Some(p); - packages_source = Some(format!( - "downloaded file ({})", - Url::sanitize(url.clone()) - )); + packages_source = + Some(format!("downloaded file ({})", Url::sanitize(url.clone()))); } Err(e) => { // 404s are acceptable for lazy provider repos @@ -1583,20 +1542,15 @@ impl ComposerRepository { ) { let mut p: IndexMap = IndexMap::new(); - p.insert( - "packages".to_string(), - PhpMixed::Array(IndexMap::new()), - ); + p.insert("packages".to_string(), PhpMixed::Array(IndexMap::new())); packages_opt = Some(p); packages_source = Some(format!( "not-found file ({})", Url::sanitize(url.clone()) )); if status_code == 499 { - self.io.error(&format!( - "{}", - te.get_message() - )); + self.io + .error(&format!("{}", te.get_message())); } } else { return Err(e); @@ -1757,8 +1711,7 @@ impl ComposerRepository { // load acceptable packages in the providers let versions_to_load_vec: Vec> = versions_to_load.values().cloned().collect(); - let loaded_packages = - self.create_packages_flat(versions_to_load_vec, packages_source)?; + let loaded_packages = self.create_packages_flat(versions_to_load_vec, packages_source)?; let uids: Vec = versions_to_load.keys().cloned().collect(); for (index, mut package) in loaded_packages.into_iter().enumerate() { @@ -1785,7 +1738,10 @@ impl ComposerRepository { let repo_data = self.load_data_from_server()?; - let source = format!("root file ({})", Url::sanitize(self.get_packages_json_url())); + let source = format!( + "root file ({})", + Url::sanitize(self.get_packages_json_url()) + ); for package in self.create_packages_flat(repo_data, Some(source))? { self.add_package(package); } @@ -1815,9 +1771,12 @@ impl ComposerRepository { if self.lazy_providers_url.is_none() { return Err(LogicException { - message: "loadAsyncPackages only supports v2 protocol composer repos with a metadata-url".to_string(), + message: + "loadAsyncPackages only supports v2 protocol composer repos with a metadata-url" + .to_string(), code: 0, - }.into()); + } + .into()); } // load ~dev versions of the packages as well if needed @@ -1836,8 +1795,7 @@ impl ComposerRepository { package_names.insert(format!("{}~dev", name), constraint); } // if only dev stability is requested, we skip loading the non dev file - if acceptable_stabilities - .map_or(false, |m| m.contains_key("dev") && m.len() == 1) + if acceptable_stabilities.map_or(false, |m| m.contains_key("dev") && m.len() == 1) && stability_flags.map_or(false, |m| m.is_empty()) { package_names.shift_remove(&name); @@ -2043,7 +2001,9 @@ impl ComposerRepository { } let name = strtolower(file_name); - let package_name = package_name.map(|s| s.to_string()).unwrap_or_else(|| name.clone()); + let package_name = package_name + .map(|s| s.to_string()) + .unwrap_or_else(|| name.clone()); let url = self .lazy_providers_url @@ -2091,9 +2051,7 @@ impl ComposerRepository { contents .clone() .map(|m| { - PhpMixed::Array( - m.into_iter().map(|(k, v)| (k, Box::new(v))).collect(), - ) + PhpMixed::Array(m.into_iter().map(|(k, v)| (k, Box::new(v))).collect()) }) .unwrap_or(PhpMixed::Null) } else { @@ -2105,8 +2063,8 @@ impl ComposerRepository { .and_then(|a| a.get("packages")) .and_then(|v| v.as_array()) .map_or(false, |a| a.contains_key(&package_name)); - let has_advisories = response_arr - .map_or(false, |a| a.contains_key("security-advisories")); + let has_advisories = + response_arr.map_or(false, |a| a.contains_key("security-advisories")); if !has_pkg && !has_advisories { return Ok(PhpMixed::List(vec![ Box::new(PhpMixed::Null), @@ -2166,11 +2124,13 @@ impl ComposerRepository { acceptable_stabilities: Option<&IndexMap>, stability_flags: Option<&IndexMap>, ) -> anyhow::Result { - let mut versions: Vec = vec![version_data - .get("version_normalized") - .and_then(|v| v.as_string()) - .unwrap_or("") - .to_string()]; + let mut versions: Vec = vec![ + version_data + .get("version_normalized") + .and_then(|v| v.as_string()) + .unwrap_or("") + .to_string(), + ]; if let Some(alias) = loader.get_branch_alias(version_data) { versions.push(alias); @@ -2216,10 +2176,7 @@ impl ComposerRepository { format!("{}/packages.json", self.url) } - fn load_root_server_file( - &mut self, - root_max_age: Option, - ) -> anyhow::Result { + fn load_root_server_file(&mut self, root_max_age: Option) -> anyhow::Result { if let Some(rd) = &self.root_data { return Ok(clone_root_data(rd)); } @@ -2243,9 +2200,7 @@ impl ComposerRepository { .map(|(k, v)| (k.clone(), (**v).clone())) .collect(); let age = self.cache.get_age("packages.json"); - if root_max_age.is_some() - && age.is_some() - && age.unwrap() <= root_max_age.unwrap() + if root_max_age.is_some() && age.is_some() && age.unwrap() <= root_max_age.unwrap() { data = Some(cached_data); } else if let Some(last_modified) = cached_data @@ -2550,16 +2505,13 @@ impl ComposerRepository { return Err(InvalidArgumentException { message: "Expected a string with a value and not an empty string".to_string(), code: 0, - }.into()); + } + .into()); } if url.starts_with('/') { let mut matches: Vec = Vec::new(); - if Preg::is_match_with_matches( - r"{^[^:]++://[^/]*+}", - &self.url, - &mut matches, - )? { + if Preg::is_match_with_matches(r"{^[^:]++://[^/]*+}", &self.url, &mut matches)? { return Ok(format!( "{}{}", matches.get(0).cloned().unwrap_or_default(), @@ -2581,7 +2533,8 @@ impl ComposerRepository { message: "loadRootServerFile should not return true during initialization" .to_string(), code: 0, - }.into()); + } + .into()); } RootData::Data(d) => d, }; @@ -2597,10 +2550,7 @@ impl ComposerRepository { Ok(self.has_partial_packages) } - fn load_provider_listings( - &mut self, - data: &IndexMap, - ) -> anyhow::Result<()> { + fn load_provider_listings(&mut self, data: &IndexMap) -> anyhow::Result<()> { if let Some(providers) = data.get("providers").and_then(|v| v.as_array()) { if self.provider_listing.is_none() { self.provider_listing = Some(IndexMap::new()); @@ -2636,11 +2586,7 @@ impl ComposerRepository { .and_then(|v| v.as_string()) .unwrap_or("") .to_string(); - let url = format!( - "{}/{}", - self.base_url, - include.replace("%hash%", &sha256) - ); + let url = format!("{}/{}", self.base_url, include.replace("%hash%", &sha256)); let cache_key = include.replace("%hash%", "").replace("$", ""); let included_data: IndexMap = if self.cache.sha256(&cache_key).as_deref() == Some(sha256.as_str()) { @@ -2649,9 +2595,7 @@ impl ComposerRepository { decoded .as_array() .map(|a| { - a.iter() - .map(|(k, v)| (k.clone(), (**v).clone())) - .collect() + a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect() }) .unwrap_or_default() } else { @@ -2681,11 +2625,8 @@ impl ComposerRepository { if let Some(versions) = pkg.get("versions").and_then(|v| v.as_array()) { for (_, metadata) in versions.iter() { if let Some(m) = metadata.as_array() { - packages.push( - m.iter() - .map(|(k, v)| (k.clone(), (**v).clone())) - .collect(), - ); + packages + .push(m.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()); } } } @@ -2745,11 +2686,7 @@ impl ComposerRepository { let decoded = json_decode(&raw, true)?; decoded .as_array() - .map(|a| { - a.iter() - .map(|(k, v)| (k.clone(), (**v).clone())) - .collect() - }) + .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()) .unwrap_or_default() } else { self.fetch_file(include, None, None, false)? @@ -2795,10 +2732,8 @@ impl ComposerRepository { let mut results: Vec> = Vec::new(); for mut package in package_instances.into_iter() { if let Some(src_type) = package.get_source_type() { - if let Some(mirrors) = self - .source_mirrors - .as_ref() - .and_then(|m| m.get(src_type)) + if let Some(mirrors) = + self.source_mirrors.as_ref().and_then(|m| m.get(src_type)) { package.set_source_mirrors(mirrors); } @@ -2954,11 +2889,7 @@ impl ComposerRepository { let decoded = response.decode_json()?; let mut data_local: IndexMap = decoded .as_array() - .map(|a| { - a.iter() - .map(|(k, v)| (k.clone(), (**v).clone())) - .collect() - }) + .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()) .unwrap_or_default(); HttpDownloader::output_warnings(&*self.io, &self.url, &data_local); @@ -3025,9 +2956,7 @@ impl ComposerRepository { let map: IndexMap = parsed .as_array() .map(|a| { - a.iter() - .map(|(k, v)| (k.clone(), (**v).clone())) - .collect() + a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect() }) .unwrap_or_default(); data = Some(map); @@ -3061,7 +2990,8 @@ impl ComposerRepository { return Err(InvalidArgumentException { message: "$filename should not be an empty string".to_string(), code: 0, - }.into()); + } + .into()); } let mut filename = filename.to_string(); @@ -3143,11 +3073,7 @@ impl ComposerRepository { let decoded = response.decode_json()?; let mut data: IndexMap = decoded .as_array() - .map(|a| { - a.iter() - .map(|(k, v)| (k.clone(), (**v).clone())) - .collect() - }) + .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()) .unwrap_or_default(); HttpDownloader::output_warnings(&*self.io, &self.url, &data); @@ -3205,7 +3131,8 @@ impl ComposerRepository { return Err(InvalidArgumentException { message: "$filename should not be an empty string".to_string(), code: 0, - }.into()); + } + .into()); } if self.packagesNotFoundCache.contains_key(filename) { @@ -3318,11 +3245,7 @@ impl ComposerRepository { let decoded = response.decode_json()?; let mut data: IndexMap = decoded .as_array() - .map(|a| { - a.iter() - .map(|(k, v)| (k.clone(), (**v).clone())) - .collect() - }) + .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()) .unwrap_or_default(); let io_ref = unsafe { &*io_ptr }; HttpDownloader::output_warnings(io_ref, &url_owned, &data); @@ -3420,7 +3343,11 @@ impl ComposerRepository { }; self.partial_packages_by_name = Some(IndexMap::new()); - if let Some(packages) = root_data.get("packages").and_then(|v| v.as_array()).cloned() { + if let Some(packages) = root_data + .get("packages") + .and_then(|v| v.as_array()) + .cloned() + { for (package, versions_mixed) in packages.iter() { let versions = match versions_mixed.as_array() { Some(a) => a.clone(), diff --git a/crates/shirabe/src/repository/composite_repository.rs b/crates/shirabe/src/repository/composite_repository.rs index 9787b6a..5413bbe 100644 --- a/crates/shirabe/src/repository/composite_repository.rs +++ b/crates/shirabe/src/repository/composite_repository.rs @@ -18,7 +18,9 @@ pub struct CompositeRepository { impl CompositeRepository { pub fn new(repositories: Vec>) -> Self { - let mut this = Self { repositories: vec![] }; + let mut this = Self { + repositories: vec![], + }; for repo in repositories { this.add_repository(repo); } @@ -37,7 +39,9 @@ impl CompositeRepository { } pub fn add_repository(&mut self, repository: Box) { - if let Some(composite) = (repository.as_any() as &dyn Any).downcast_ref::() { + if let Some(composite) = + (repository.as_any() as &dyn Any).downcast_ref::() + { for repo in composite.get_repositories() { self.repositories.push(repo.clone_box()); } @@ -55,7 +59,11 @@ impl shirabe_php_shim::Countable for CompositeRepository { impl RepositoryInterface for CompositeRepository { fn get_repo_name(&self) -> String { - let names: Vec = self.repositories.iter().map(|r| r.get_repo_name()).collect(); + let names: Vec = self + .repositories + .iter() + .map(|r| r.get_repo_name()) + .collect(); format!("composite repo ({})", names.join(", ")) } @@ -68,7 +76,11 @@ impl RepositoryInterface for CompositeRepository { false } - fn find_package(&self, name: String, constraint: FindPackageConstraint) -> Option> { + fn find_package( + &self, + name: String, + constraint: FindPackageConstraint, + ) -> Option> { for repository in &self.repositories { let package = repository.find_package(name.clone(), constraint.clone()); if package.is_some() { @@ -78,7 +90,11 @@ impl RepositoryInterface for CompositeRepository { None } - fn find_packages(&self, name: String, constraint: Option) -> Vec> { + fn find_packages( + &self, + name: String, + constraint: Option, + ) -> Vec> { let mut packages = vec![]; for repository in &self.repositories { packages.extend(repository.find_packages(name.clone(), constraint.clone())); diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs index 5cbff22..4ca5ab1 100644 --- a/crates/shirabe/src/repository/filesystem_repository.rs +++ b/crates/shirabe/src/repository/filesystem_repository.rs @@ -6,10 +6,10 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - array_flip, dirname, file_get_contents, get_class, get_debug_type, in_array, is_array, - is_int, is_null, is_string, ksort, php_dir, r#eval, realpath, sort, sort_with_flags, - str_repeat, strtr, trim, usort, var_export, InvalidArgumentException, LogicException, - PhpMixed, Silencer, UnexpectedValueException, SORT_NATURAL, + InvalidArgumentException, LogicException, PhpMixed, SORT_NATURAL, Silencer, + UnexpectedValueException, array_flip, dirname, r#eval, file_get_contents, get_class, + get_debug_type, in_array, is_array, is_int, is_null, is_string, ksort, php_dir, realpath, sort, + sort_with_flags, str_repeat, strtr, trim, usort, var_export, }; use crate::installed_versions::InstalledVersions; @@ -141,12 +141,18 @@ impl FilesystemRepository { let mut loader = ArrayLoader::new(None, true); if let Some(packages_list) = packages.as_list() { for package_data in packages_list.iter() { - let package = loader.load((**package_data).clone(), "Composer\\Package\\CompletePackage")?; + let package = loader.load( + (**package_data).clone(), + "Composer\\Package\\CompletePackage", + )?; self.inner.add_package(package)?; } } else if let Some(packages_array) = packages.as_array() { for (_, package_data) in packages_array.iter() { - let package = loader.load((**package_data).clone(), "Composer\\Package\\CompletePackage")?; + let package = loader.load( + (**package_data).clone(), + "Composer\\Package\\CompletePackage", + )?; self.inner.add_package(package)?; } } @@ -179,9 +185,9 @@ impl FilesystemRepository { let repo_dir = dirname(self.file.get_path()); self.filesystem.ensure_directory_exists(&repo_dir); - let repo_dir = self.filesystem.normalize_path( - &realpath(&repo_dir).unwrap_or_default(), - ); + let repo_dir = self + .filesystem + .normalize_path(&realpath(&repo_dir).unwrap_or_default()); let mut install_paths: IndexMap> = IndexMap::new(); for package in self.inner.get_canonical_packages() { @@ -190,13 +196,18 @@ impl FilesystemRepository { let mut install_path: Option = None; if let Some(path_str) = &path { if !path_str.is_empty() { - let normalized_path = self.filesystem.normalize_path( - &if self.filesystem.is_absolute_path(path_str) { - path_str.clone() - } else { - format!("{}/{}", Platform::get_cwd(false).unwrap_or_default(), path_str) - }, - ); + let normalized_path = self.filesystem.normalize_path(&if self + .filesystem + .is_absolute_path(path_str) + { + path_str.clone() + } else { + format!( + "{}/{}", + Platform::get_cwd(false).unwrap_or_default(), + path_str + ) + }); install_path = Some(self.filesystem.find_shortest_path( &repo_dir, &normalized_path, @@ -215,7 +226,10 @@ impl FilesystemRepository { ); if let Some(PhpMixed::List(list)) = data.get_mut("packages") { list.push(Box::new(PhpMixed::Array( - pkg_array.into_iter().map(|(k, v)| (k, Box::new(v))).collect(), + pkg_array + .into_iter() + .map(|(k, v)| (k, Box::new(v))) + .collect(), ))); } @@ -273,20 +287,19 @@ impl FilesystemRepository { )?; if self.dump_versions { - let versions = - self.generate_installed_versions(installation_manager, &install_paths, dev_mode, &repo_dir)?; + let versions = self.generate_installed_versions( + installation_manager, + &install_paths, + dev_mode, + &repo_dir, + )?; self.filesystem.file_put_contents_if_modified( &format!("{}/installed.php", repo_dir), - &format!( - "\s*+__DIR__\s*+\.\s*+(['\"])}", + r#"{=>\s*+__DIR__\s*+\.\s*+(['\"])}"#, &format!( "=> {} . $1", var_export(&PhpMixed::String(dirname(path)), true), @@ -391,10 +404,7 @@ impl FilesystemRepository { } else if key == "install_path" && is_string(value) { let s = value.as_string().unwrap_or("").to_string(); if self.filesystem.is_absolute_path(&s) { - lines.push_str(&format!( - "{},\n", - var_export(&PhpMixed::String(s), true), - )); + lines.push_str(&format!("{},\n", var_export(&PhpMixed::String(s), true),)); } else { lines.push_str(&format!( "__DIR__ . {},\n", @@ -447,7 +457,9 @@ impl FilesystemRepository { let mut root_package = match &self.root_package { None => { return Err(LogicException { - message: "It should not be possible to dump packages if no root package is given".to_string(), + message: + "It should not be possible to dump packages if no root package is given" + .to_string(), code: 0, } .into()); @@ -460,8 +472,11 @@ impl FilesystemRepository { let mut current_root: Box = root_package; // packages.push(current_root.clone_box()); - while let Some(_alias) = (current_root.as_any() as &dyn Any).downcast_ref::() { - current_root = todo!("RootAliasPackage::get_alias_of() returning Box"); + while let Some(_alias) = + (current_root.as_any() as &dyn Any).downcast_ref::() + { + current_root = + todo!("RootAliasPackage::get_alias_of() returning Box"); // packages.push(current_root.clone_box()); } let mut versions: IndexMap = IndexMap::new(); @@ -480,18 +495,19 @@ impl FilesystemRepository { .collect(), ), ); - versions.insert( - "versions".to_string(), - PhpMixed::Array(IndexMap::new()), - ); + versions.insert("versions".to_string(), PhpMixed::Array(IndexMap::new())); // add real installed packages for package in &packages { - if (package.as_any() as &dyn Any).downcast_ref::().is_some() { + if (package.as_any() as &dyn Any) + .downcast_ref::() + .is_some() + { continue; } - let dumped = self.dump_installed_package(&**package, install_paths, repo_dir, &dev_packages); + let dumped = + self.dump_installed_package(&**package, install_paths, repo_dir, &dev_packages); if let Some(PhpMixed::Array(versions_map)) = versions.get_mut("versions") { versions_map.insert( package.get_name().to_string(), @@ -552,7 +568,10 @@ impl FilesystemRepository { }; // TODO(phase-b): mutate nested versions['versions'][name]['aliases'] todo!("append alias->getPrettyVersion() to versions['versions'][name]['aliases']"); - if (package.as_any() as &dyn Any).downcast_ref::().is_some() { + if (package.as_any() as &dyn Any) + .downcast_ref::() + .is_some() + { // TODO(phase-b): same mutation on versions['root']['aliases'] todo!("append alias->getPrettyVersion() to versions['root']['aliases']"); } @@ -614,17 +633,16 @@ impl FilesystemRepository { }; } - let install_path = if (package.as_any() as &dyn Any).downcast_ref::().is_some() { + let install_path = if (package.as_any() as &dyn Any) + .downcast_ref::() + .is_some() + { let to = self.filesystem.normalize_path( - &realpath(&Platform::get_cwd(false).unwrap_or_default()) - .unwrap_or_default(), + &realpath(&Platform::get_cwd(false).unwrap_or_default()).unwrap_or_default(), ); Some(self.filesystem.find_shortest_path(repo_dir, &to, true)) } else { - install_paths - .get(package.get_name()) - .cloned() - .flatten() + install_paths.get(package.get_name()).cloned().flatten() }; let mut data: IndexMap = IndexMap::new(); @@ -690,7 +708,9 @@ impl FilesystemRepository { ); result.insert( "pretty_version".to_string(), - data.get("pretty_version").cloned().unwrap_or(PhpMixed::Null), + data.get("pretty_version") + .cloned() + .unwrap_or(PhpMixed::Null), ); result.insert( "version".to_string(), @@ -710,7 +730,9 @@ impl FilesystemRepository { ); result.insert( "aliases".to_string(), - data.get("aliases").cloned().unwrap_or(PhpMixed::List(vec![])), + data.get("aliases") + .cloned() + .unwrap_or(PhpMixed::List(vec![])), ); result.insert("dev".to_string(), PhpMixed::Bool(dev_mode)); diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs index 3a65ef2..eeb1306 100644 --- a/crates/shirabe/src/repository/filter_repository.rs +++ b/crates/shirabe/src/repository/filter_repository.rs @@ -1,16 +1,18 @@ //! ref: composer/src/Composer/Repository/FilterRepository.php -use anyhow::Result; -use indexmap::IndexMap; -use shirabe_php_shim::{InvalidArgumentException, PhpMixed}; -use shirabe_external_packages::composer::pcre::preg::Preg; -use shirabe_semver::constraint::constraint_interface::ConstraintInterface; use crate::package::base_package::BasePackage; use crate::package::package_interface::PackageInterface; -use crate::repository::advisory_provider_interface::{AdvisoryProviderInterface, SecurityAdvisoryResult}; +use crate::repository::advisory_provider_interface::{ + AdvisoryProviderInterface, SecurityAdvisoryResult, +}; use crate::repository::repository_interface::{ FindPackageConstraint, LoadPackagesResult, ProviderInfo, RepositoryInterface, SearchResult, }; +use anyhow::Result; +use indexmap::IndexMap; +use shirabe_external_packages::composer::pcre::preg::Preg; +use shirabe_php_shim::{InvalidArgumentException, PhpMixed}; +use shirabe_semver::constraint::constraint_interface::ConstraintInterface; #[derive(Debug)] pub struct FilterRepository { @@ -21,7 +23,10 @@ pub struct FilterRepository { } impl FilterRepository { - pub fn new(repo: Box, options: IndexMap) -> Result { + pub fn new( + repo: Box, + options: IndexMap, + ) -> Result { let mut only: Option = None; let mut exclude: Option = None; let mut canonical = true; @@ -29,40 +34,66 @@ impl FilterRepository { if let Some(only_val) = options.get("only") { match only_val { PhpMixed::List(list) => { - let names: Vec = list.iter().filter_map(|v| { - if let PhpMixed::String(s) = v.as_ref() { Some(s.clone()) } else { None } - }).collect(); + let names: Vec = list + .iter() + .filter_map(|v| { + if let PhpMixed::String(s) = v.as_ref() { + Some(s.clone()) + } else { + None + } + }) + .collect(); only = Some(BasePackage::package_names_to_regexp(&names)); } _ => { return Err(InvalidArgumentException { - message: format!(r#""only" key for repository {} should be an array"#, repo.get_repo_name()), + message: format!( + r#""only" key for repository {} should be an array"#, + repo.get_repo_name() + ), code: 0, - }.into()); + } + .into()); } } } if let Some(exclude_val) = options.get("exclude") { match exclude_val { PhpMixed::List(list) => { - let names: Vec = list.iter().filter_map(|v| { - if let PhpMixed::String(s) = v.as_ref() { Some(s.clone()) } else { None } - }).collect(); + let names: Vec = list + .iter() + .filter_map(|v| { + if let PhpMixed::String(s) = v.as_ref() { + Some(s.clone()) + } else { + None + } + }) + .collect(); exclude = Some(BasePackage::package_names_to_regexp(&names)); } _ => { return Err(InvalidArgumentException { - message: format!(r#""exclude" key for repository {} should be an array"#, repo.get_repo_name()), + message: format!( + r#""exclude" key for repository {} should be an array"#, + repo.get_repo_name() + ), code: 0, - }.into()); + } + .into()); } } } if exclude.is_some() && only.is_some() { return Err(InvalidArgumentException { - message: format!(r#"Only one of "only" and "exclude" can be specified for repository {}"#, repo.get_repo_name()), + message: format!( + r#"Only one of "only" and "exclude" can be specified for repository {}"#, + repo.get_repo_name() + ), code: 0, - }.into()); + } + .into()); } if let Some(canonical_val) = options.get("canonical") { match canonical_val { @@ -71,14 +102,23 @@ impl FilterRepository { } _ => { return Err(InvalidArgumentException { - message: format!(r#""canonical" key for repository {} should be a boolean"#, repo.get_repo_name()), + message: format!( + r#""canonical" key for repository {} should be a boolean"#, + repo.get_repo_name() + ), code: 0, - }.into()); + } + .into()); } } } - Ok(Self { only, exclude, canonical, repo }) + Ok(Self { + only, + exclude, + canonical, + repo, + }) } pub fn get_repository(&self) -> &dyn RepositoryInterface { @@ -117,7 +157,11 @@ impl RepositoryInterface for FilterRepository { self.repo.has_package(package) } - fn find_package(&self, name: String, constraint: FindPackageConstraint) -> Option> { + fn find_package( + &self, + name: String, + constraint: FindPackageConstraint, + ) -> Option> { if !self.is_allowed(&name) { return None; } @@ -125,7 +169,11 @@ impl RepositoryInterface for FilterRepository { self.repo.find_package(name, constraint) } - fn find_packages(&self, name: String, constraint: Option) -> Vec> { + fn find_packages( + &self, + name: String, + constraint: Option, + ) -> Vec> { if !self.is_allowed(&name) { return Vec::new(); } @@ -143,10 +191,18 @@ impl RepositoryInterface for FilterRepository { package_name_map.retain(|name, _| self.is_allowed(name)); if package_name_map.is_empty() { - return LoadPackagesResult { names_found: Vec::new(), packages: Vec::new() }; + return LoadPackagesResult { + names_found: Vec::new(), + packages: Vec::new(), + }; } - let mut result = self.repo.load_packages(package_name_map, acceptable_stabilities, stability_flags, already_loaded); + let mut result = self.repo.load_packages( + package_name_map, + acceptable_stabilities, + stability_flags, + already_loaded, + ); if !self.canonical { result.names_found = Vec::new(); } @@ -219,7 +275,10 @@ impl AdvisoryProviderInterface for FilterRepository { package_constraint_map.retain(|name, _| self.is_allowed(name)); advisory_repo.get_security_advisories(package_constraint_map, allow_partial_advisories) } else { - Ok(SecurityAdvisoryResult { names_found: Vec::new(), advisories: IndexMap::new() }) + Ok(SecurityAdvisoryResult { + names_found: Vec::new(), + advisories: IndexMap::new(), + }) } } } diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs index f3b53ae..bb56c94 100644 --- a/crates/shirabe/src/repository/installed_repository.rs +++ b/crates/shirabe/src/repository/installed_repository.rs @@ -223,11 +223,7 @@ impl InstalledRepository { for pkg in self.find_packages(link.get_target().to_string(), None) { let version = Constraint::new("=", pkg.get_version()); if link.get_constraint().matches(&version) == invert { - results.push(DependentsEntry( - package.clone_box(), - link.clone(), - None, - )); + results.push(DependentsEntry(package.clone_box(), link.clone(), None)); } } } @@ -238,11 +234,7 @@ impl InstalledRepository { for pkg in self.find_packages(link.get_target().to_string(), None) { let version = Constraint::new("=", pkg.get_version()); if link.get_constraint().matches(&version) == invert { - results.push(DependentsEntry( - package.clone_box(), - link.clone(), - None, - )); + results.push(DependentsEntry(package.clone_box(), link.clone(), None)); } } } @@ -327,9 +319,7 @@ impl InstalledRepository { } for root_req in root_reqs.values() { if pkg.get_names().contains(&root_req.get_target().to_string()) - && !root_req - .get_constraint() - .matches(link.get_constraint()) + && !root_req.get_constraint().matches(link.get_constraint()) { results.push(DependentsEntry( package.clone_box(), diff --git a/crates/shirabe/src/repository/mod.rs b/crates/shirabe/src/repository/mod.rs new file mode 100644 index 0000000..e570051 --- /dev/null +++ b/crates/shirabe/src/repository/mod.rs @@ -0,0 +1,31 @@ +pub mod advisory_provider_interface; +pub mod array_repository; +pub mod artifact_repository; +pub mod canonical_packages_trait; +pub mod composer_repository; +pub mod composite_repository; +pub mod configurable_repository_interface; +pub mod filesystem_repository; +pub mod filter_repository; +pub mod installed_array_repository; +pub mod installed_filesystem_repository; +pub mod installed_repository; +pub mod installed_repository_interface; +pub mod invalid_repository_exception; +pub mod lock_array_repository; +pub mod package_repository; +pub mod path_repository; +pub mod pear_repository; +pub mod platform_repository; +pub mod repository_factory; +pub mod repository_interface; +pub mod repository_manager; +pub mod repository_security_exception; +pub mod repository_set; +pub mod repository_utils; +pub mod root_package_repository; +pub mod vcs; +pub mod vcs_repository; +pub mod version_cache_interface; +pub mod writable_array_repository; +pub mod writable_repository_interface; diff --git a/crates/shirabe/src/repository/path_repository.rs b/crates/shirabe/src/repository/path_repository.rs index f2b470d..c148880 100644 --- a/crates/shirabe/src/repository/path_repository.rs +++ b/crates/shirabe/src/repository/path_repository.rs @@ -3,8 +3,8 @@ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - defined, file_exists, file_get_contents, glob_with_flags, hash, realpath, serialize, - PhpMixed, RuntimeException, DIRECTORY_SEPARATOR, GLOB_BRACE, GLOB_MARK, GLOB_ONLYDIR, + DIRECTORY_SEPARATOR, GLOB_BRACE, GLOB_MARK, GLOB_ONLYDIR, PhpMixed, RuntimeException, defined, + file_exists, file_get_contents, glob_with_flags, hash, realpath, serialize, }; use crate::config::Config; @@ -65,8 +65,7 @@ impl PathRepository { .to_string(); let url = Platform::expand_path(&url_str); let process = process.unwrap_or_else(|| ProcessExecutor::new(&*io)); - let version_guesser = - VersionGuesser::new(&config, &process, VersionParser::new(), &*io); + let version_guesser = VersionGuesser::new(&config, &process, VersionParser::new(), &*io); let mut options = repo_config .get("options") .and_then(|v| v.as_array()) @@ -133,10 +132,7 @@ impl PathRepository { } for url in url_matches { - let path = format!( - "{}/", - realpath(&url).unwrap_or_default() - ); + let path = format!("{}/", realpath(&url).unwrap_or_default()); let composer_file_path = format!("{}composer.json", path); if !file_exists(&composer_file_path) { @@ -144,11 +140,14 @@ impl PathRepository { } let json = file_get_contents(&composer_file_path).unwrap_or_default(); - let mut package = JsonFile::parse_json(&json, Some(&composer_file_path))? - .unwrap_or_default(); + let mut package = + JsonFile::parse_json(&json, Some(&composer_file_path))?.unwrap_or_default(); let dist = { let mut dist = IndexMap::new(); - dist.insert("type".to_string(), Box::new(PhpMixed::String("path".to_string()))); + dist.insert( + "type".to_string(), + Box::new(PhpMixed::String("path".to_string())), + ); dist.insert("url".to_string(), Box::new(PhpMixed::String(url.clone()))); dist }; @@ -193,7 +192,11 @@ impl PathRepository { ); // use the version provided as option if available - if let Some(name) = package.get("name").and_then(|v| v.as_string()).map(|s| s.to_string()) { + if let Some(name) = package + .get("name") + .and_then(|v| v.as_string()) + .map(|s| s.to_string()) + { if let Some(version) = self .options .get("versions") @@ -226,9 +229,7 @@ impl PathRepository { { package.insert( "version".to_string(), - PhpMixed::String( - self.version_guesser.get_root_version_from_env(), - ), + PhpMixed::String(self.version_guesser.get_root_version_from_env()), ); } } @@ -236,20 +237,25 @@ impl PathRepository { } let mut output = String::new(); - let command = GitUtil::build_rev_list_command( - &self.process, - { - let mut args = vec!["-n1".to_string(), "--format=%H".to_string(), "HEAD".to_string()]; - args.extend(GitUtil::get_no_show_signature_flags(&self.process)); - args - }, - ); + let command = GitUtil::build_rev_list_command(&self.process, { + let mut args = vec![ + "-n1".to_string(), + "--format=%H".to_string(), + "HEAD".to_string(), + ]; + args.extend(GitUtil::get_no_show_signature_flags(&self.process)); + args + }); if reference == "auto" && shirabe_php_shim::is_dir(&format!("{}/.git", path.trim_end_matches('/'))) - && self.process.execute(&command, &mut output, Some(path.clone())) == 0 + && self + .process + .execute(&command, &mut output, Some(path.clone())) + == 0 { - let ref_val = - GitUtil::parse_rev_list_output(&output, &self.process).trim().to_string(); + let ref_val = GitUtil::parse_rev_list_output(&output, &self.process) + .trim() + .to_string(); if let Some(PhpMixed::Array(ref mut dist)) = package.get_mut("dist") { dist.insert("reference".to_string(), Box::new(PhpMixed::String(ref_val))); } @@ -294,12 +300,17 @@ impl PathRepository { } self.inner - .add_package(self.loader.load(package.clone()).map_err(|e| { - RuntimeException { - message: format!("Failed loading the package in {}", composer_file_path), - code: 0, - } - })?); + .add_package( + self.loader + .load(package.clone()) + .map_err(|e| RuntimeException { + message: format!( + "Failed loading the package in {}", + composer_file_path + ), + code: 0, + })?, + ); } Ok(()) @@ -324,7 +335,11 @@ impl PathRepository { // Ensure environment-specific path separators are normalized to URL separators Ok(glob_with_flags(&self.url, flags) .into_iter() - .map(|val| val.replace(DIRECTORY_SEPARATOR, "/").trim_end_matches('/').to_string()) + .map(|val| { + val.replace(DIRECTORY_SEPARATOR, "/") + .trim_end_matches('/') + .to_string() + }) .collect()) } } diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs index 6f3f774..5c6bec7 100644 --- a/crates/shirabe/src/repository/platform_repository.rs +++ b/crates/shirabe/src/repository/platform_repository.rs @@ -7,9 +7,9 @@ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_external_packages::composer::xdebug_handler::xdebug_handler::XdebugHandler; use shirabe_php_shim::{ - array_map_str_fn, array_slice, array_slice_strs, explode, get_class, implode, in_array, - is_string, sprintf, str_replace, str_starts_with, strpos, strtolower, var_export, - InvalidArgumentException, PhpMixed, UnexpectedValueException, + InvalidArgumentException, PhpMixed, UnexpectedValueException, array_map_str_fn, array_slice, + array_slice_strs, explode, get_class, implode, in_array, is_string, sprintf, str_replace, + str_starts_with, strpos, strtolower, var_export, }; use shirabe_semver::constraint::constraint::Constraint; @@ -27,8 +27,7 @@ use crate::repository::array_repository::ArrayRepository; use crate::repository::repository_interface::RepositoryInterface; use crate::util::silencer::Silencer; -static LAST_SEEN_PLATFORM_PHP: LazyLock>> = - LazyLock::new(|| Mutex::new(None)); +static LAST_SEEN_PLATFORM_PHP: LazyLock>> = LazyLock::new(|| Mutex::new(None)); static IS_PLATFORM_PACKAGE_CACHE: LazyLock>> = LazyLock::new(|| Mutex::new(IndexMap::new())); @@ -153,7 +152,11 @@ impl PlatformRepository { .as_ref() .unwrap() .normalize(&pretty_version, None)?; - let mut composer = CompletePackage::new("composer".to_string(), version.clone(), pretty_version.clone()); + let mut composer = CompletePackage::new( + "composer".to_string(), + version.clone(), + pretty_version.clone(), + ); composer.set_description("Composer package".to_string()); self.add_package(Box::new(composer))?; @@ -163,8 +166,11 @@ impl PlatformRepository { .as_ref() .unwrap() .normalize(&pretty_version, None)?; - let mut composer_plugin_api = - CompletePackage::new("composer-plugin-api".to_string(), version.clone(), pretty_version.clone()); + let mut composer_plugin_api = CompletePackage::new( + "composer-plugin-api".to_string(), + version.clone(), + pretty_version.clone(), + ); composer_plugin_api.set_description("The Composer Plugin API".to_string()); self.add_package(Box::new(composer_plugin_api))?; @@ -174,8 +180,11 @@ impl PlatformRepository { .as_ref() .unwrap() .normalize(&pretty_version, None)?; - let mut composer_runtime_api = - CompletePackage::new("composer-runtime-api".to_string(), version.clone(), pretty_version.clone()); + let mut composer_runtime_api = CompletePackage::new( + "composer-runtime-api".to_string(), + version.clone(), + pretty_version.clone(), + ); composer_runtime_api.set_description("The Composer Runtime API".to_string()); self.add_package(Box::new(composer_runtime_api))?; @@ -195,8 +204,8 @@ impl PlatformRepository { version = v; } Err(_) => { - pretty_version = - Preg::replace("#^([^~+-]+).*$#", "$1", &php_version_str).unwrap_or(php_version_str); + pretty_version = Preg::replace("#^([^~+-]+).*$#", "$1", &php_version_str) + .unwrap_or(php_version_str); version = self .version_parser .as_ref() @@ -205,22 +214,38 @@ impl PlatformRepository { } } - let mut php = CompletePackage::new("php".to_string(), version.clone(), pretty_version.clone()); + let mut php = + CompletePackage::new("php".to_string(), version.clone(), pretty_version.clone()); php.set_description("The PHP interpreter".to_string()); self.add_package(Box::new(php))?; - if self.runtime.get_constant("PHP_DEBUG", None).as_bool().unwrap_or(false) { - let mut phpdebug = - CompletePackage::new("php-debug".to_string(), version.clone(), pretty_version.clone()); + if self + .runtime + .get_constant("PHP_DEBUG", None) + .as_bool() + .unwrap_or(false) + { + let mut phpdebug = CompletePackage::new( + "php-debug".to_string(), + version.clone(), + pretty_version.clone(), + ); phpdebug.set_description("The PHP interpreter, with debugging symbols".to_string()); self.add_package(Box::new(phpdebug))?; } if self.runtime.has_constant("PHP_ZTS", None) - && self.runtime.get_constant("PHP_ZTS", None).as_bool().unwrap_or(false) + && self + .runtime + .get_constant("PHP_ZTS", None) + .as_bool() + .unwrap_or(false) { - let mut phpzts = - CompletePackage::new("php-zts".to_string(), version.clone(), pretty_version.clone()); + let mut phpzts = CompletePackage::new( + "php-zts".to_string(), + version.clone(), + pretty_version.clone(), + ); phpzts.set_description("The PHP interpreter, with Zend Thread Safety".to_string()); self.add_package(Box::new(phpzts))?; } @@ -232,8 +257,11 @@ impl PlatformRepository { .map(|v| v == 8) .unwrap_or(false) { - let mut php64 = - CompletePackage::new("php-64bit".to_string(), version.clone(), pretty_version.clone()); + let mut php64 = CompletePackage::new( + "php-64bit".to_string(), + version.clone(), + pretty_version.clone(), + ); php64.set_description("The PHP interpreter, 64bit".to_string()); self.add_package(Box::new(php64))?; } @@ -254,8 +282,11 @@ impl PlatformRepository { }) .unwrap_or(PhpMixed::Bool(false)); if has_inet6 || !matches!(inet_pton_check, PhpMixed::Bool(false)) { - let mut php_ipv6 = - CompletePackage::new("php-ipv6".to_string(), version.clone(), pretty_version.clone()); + let mut php_ipv6 = CompletePackage::new( + "php-ipv6".to_string(), + version.clone(), + pretty_version.clone(), + ); php_ipv6.set_description("The PHP interpreter, with IPv6 support".to_string()); self.add_package(Box::new(php_ipv6))?; } @@ -376,16 +407,9 @@ impl PlatformRepository { .unwrap_or_default(); self.add_library( &mut libraries, - &format!( - "{}-openssl{}", - name, - if is_fips { "-fips" } else { "" } - ), + &format!("{}-openssl{}", name, if is_fips { "-fips" } else { "" }), Some(&parsed_version), - Some(&format!( - "curl OpenSSL version ({})", - parsed_version - )), + Some(&format!("curl OpenSSL version ({})", parsed_version)), &[], if is_fips { &["curl-openssl".to_string()] @@ -442,10 +466,9 @@ impl PlatformRepository { } // ZLib Version => 1.2.8 - if let Ok(Some(zlib_matches)) = Preg::is_match_strict_groups( - "{^ZLib Version => (?.+)$}im", - &info, - ) { + if let Ok(Some(zlib_matches)) = + Preg::is_match_strict_groups("{^ZLib Version => (?.+)$}im", &info) + { self.add_library( &mut libraries, &format!("{}-zlib", name), @@ -486,9 +509,7 @@ impl PlatformRepository { &info, ) { // If the timezonedb is provided by ext/timezonedb, register that version as a replacement - if external - && loaded_extensions.iter().any(|n| n == "timezonedb") - { + if external && loaded_extensions.iter().any(|n| n == "timezonedb") { self.add_library( &mut libraries, "timezonedb-zoneinfo", @@ -552,8 +573,8 @@ impl PlatformRepository { "/^libJPEG Version => (?.+?)(?: compatible)?$/im", &info, ) { - let parsed = Version::parse_libjpeg(&libjpeg_matches["version"]) - .unwrap_or_default(); + let parsed = + Version::parse_libjpeg(&libjpeg_matches["version"]).unwrap_or_default(); self.add_library( &mut libraries, &format!("{}-libjpeg", name), @@ -596,8 +617,7 @@ impl PlatformRepository { "/^libXpm Version => (?\\d+)$/im", &info, ) { - let version_id: i64 = - libxpm_matches["versionId"].parse().unwrap_or(0); + let version_id: i64 = libxpm_matches["versionId"].parse().unwrap_or(0); let converted = Version::convert_libxpm_version_id(version_id).unwrap_or_default(); self.add_library( @@ -649,8 +669,7 @@ impl PlatformRepository { let description = "The ICU unicode and globalization support library"; // Truthy check is for testing only so we can make the condition fail if self.runtime.has_constant("INTL_ICU_VERSION", None) { - let intl_icu_version = - self.runtime.get_constant("INTL_ICU_VERSION", None); + let intl_icu_version = self.runtime.get_constant("INTL_ICU_VERSION", None); let intl_icu_str = match &intl_icu_version { PhpMixed::String(s) => Some(s.clone()), _ => None, @@ -663,10 +682,9 @@ impl PlatformRepository { &[], &[], )?; - } else if let Ok(Some(matches)) = Preg::is_match_strict_groups( - "/^ICU version => (?.+)$/im", - &info, - ) { + } else if let Ok(Some(matches)) = + Preg::is_match_strict_groups("/^ICU version => (?.+)$/im", &info) + { self.add_library( &mut libraries, "icu", @@ -740,8 +758,7 @@ impl PlatformRepository { ])], ); let sliced = array_slice(&intl_char_versions, 0, Some(3)); - let joined = - implode(".", &Self::php_array_to_string_vec(&sliced)); + let joined = implode(".", &Self::php_array_to_string_vec(&sliced)); self.add_library( &mut libraries, "icu-unicode", @@ -754,10 +771,7 @@ impl PlatformRepository { } "imagick" => { - let image_magick_version = self.runtime.construct( - "Imagick", - Vec::new(), - )?; + let image_magick_version = self.runtime.construct("Imagick", Vec::new())?; // TODO(plugin): `->getVersion()` is a dynamic method call on Imagick let image_magick_version_str = Self::imagick_get_version_string(&image_magick_version); @@ -791,10 +805,7 @@ impl PlatformRepository { "/^Vendor Version => (?\\d+)$/im", &info, ), - Preg::is_match_strict_groups( - "/^Vendor Name => (?.+)$/im", - &info, - ), + Preg::is_match_strict_groups("/^Vendor Name => (?.+)$/im", &info), ) { let version_id: i64 = matches["versionId"].parse().unwrap_or(0); let converted = @@ -1102,15 +1113,9 @@ impl PlatformRepository { let version_built = sprintf( "%d.%d.%d", &[ - PhpMixed::Int( - (lib_rd_kafka_version_int & 0x7F000000) >> 24, - ), - PhpMixed::Int( - (lib_rd_kafka_version_int & 0x00FF0000) >> 16, - ), - PhpMixed::Int( - (lib_rd_kafka_version_int & 0x0000FF00) >> 8, - ), + PhpMixed::Int((lib_rd_kafka_version_int & 0x7F000000) >> 24), + PhpMixed::Int((lib_rd_kafka_version_int & 0x00FF0000) >> 16), + PhpMixed::Int((lib_rd_kafka_version_int & 0x0000FF00) >> 8), ], ); self.add_library( @@ -1236,7 +1241,10 @@ impl PlatformRepository { } "zip" => { - if self.runtime.has_constant("LIBZIP_VERSION", Some("ZipArchive")) { + if self + .runtime + .has_constant("LIBZIP_VERSION", Some("ZipArchive")) + { let libzip = self .runtime .get_constant("LIBZIP_VERSION", Some("ZipArchive")); @@ -1308,8 +1316,8 @@ impl PlatformRepository { version = v; } Err(_) => { - pretty_version = - Preg::replace("#^([^~+-]+).*$#", "$1", &hhvm_version).unwrap_or(hhvm_version); + pretty_version = Preg::replace("#^([^~+-]+).*$#", "$1", &hhvm_version) + .unwrap_or(hhvm_version); version = self .version_parser .as_ref() @@ -1373,8 +1381,10 @@ impl PlatformRepository { name: self.overrides["php"].name.clone(), version: self.overrides["php"].version.clone(), }; - let mut overrider = - self.add_overridden_package(&php_override, Some(package.get_pretty_name().to_string()))?; + let mut overrider = self.add_overridden_package( + &php_override, + Some(package.get_pretty_name().to_string()), + )?; let actual_text = if package.get_version() == overrider.get_version() { "same as actual".to_string() } else { @@ -1457,8 +1467,7 @@ impl PlatformRepository { { Ok(v) => v, Err(_) => { - extra_description = - Some(format!(" (actual version: {})", pretty_version)); + extra_description = Some(format!(" (actual version: {})", pretty_version)); if let Ok(Some(m)) = Preg::is_match_strict_groups( "{^(\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?)}", &pretty_version, @@ -1540,7 +1549,11 @@ impl PlatformRepository { .map(|s| s.to_string()) .unwrap_or_else(|| format!("The {} library", name)); - let mut lib = CompletePackage::new(format!("lib-{}", name), version.clone(), pretty_version.to_string()); + let mut lib = CompletePackage::new( + format!("lib-{}", name), + version.clone(), + pretty_version.to_string(), + ); lib.set_description(description); let mut replace_links: IndexMap = IndexMap::new(); diff --git a/crates/shirabe/src/repository/repository_factory.rs b/crates/shirabe/src/repository/repository_factory.rs index feb2f3d..794cd3f 100644 --- a/crates/shirabe/src/repository/repository_factory.rs +++ b/crates/shirabe/src/repository/repository_factory.rs @@ -2,7 +2,9 @@ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; -use shirabe_php_shim::{get_debug_type, json_encode, InvalidArgumentException, PhpMixed, UnexpectedValueException}; +use shirabe_php_shim::{ + InvalidArgumentException, PhpMixed, UnexpectedValueException, get_debug_type, json_encode, +}; use crate::config::Config; use crate::event_dispatcher::event_dispatcher::EventDispatcher; @@ -18,7 +20,12 @@ use crate::util::process_executor::ProcessExecutor; pub struct RepositoryFactory; impl RepositoryFactory { - pub fn config_from_string(io: &dyn IOInterface, config: &Config, repository: &str, allow_filesystem: bool) -> anyhow::Result> { + pub fn config_from_string( + io: &dyn IOInterface, + config: &Config, + repository: &str, + allow_filesystem: bool, + ) -> anyhow::Result> { if repository.starts_with("http") { let mut repo_config = IndexMap::new(); repo_config.insert("type".to_string(), PhpMixed::String("composer".to_string())); @@ -32,23 +39,35 @@ impl RepositoryFactory { .unwrap_or(""); if extension == "json" { - let json = JsonFile::new(repository.to_string(), Some(Factory::create_http_downloader(io, config)?)); + let json = JsonFile::new( + repository.to_string(), + Some(Factory::create_http_downloader(io, config)?), + ); let data = json.read()?; let has_packages = data.get("packages").map_or(false, |v| !v.is_null()); let has_includes = data.get("includes").map_or(false, |v| !v.is_null()); - let has_provider_includes = data.get("provider-includes").map_or(false, |v| !v.is_null()); + let has_provider_includes = data + .get("provider-includes") + .map_or(false, |v| !v.is_null()); if has_packages || has_includes || has_provider_includes { - let real_path = std::fs::canonicalize(repository).ok() + let real_path = std::fs::canonicalize(repository) + .ok() .and_then(|p| p.to_str().map(|s| s.to_string())) .unwrap_or_else(|| repository.to_string()) .replace('\\', "/"); let mut repo_config = IndexMap::new(); repo_config.insert("type".to_string(), PhpMixed::String("composer".to_string())); - repo_config.insert("url".to_string(), PhpMixed::String(format!("file://{}", real_path))); + repo_config.insert( + "url".to_string(), + PhpMixed::String(format!("file://{}", real_path)), + ); return Ok(repo_config); } else if allow_filesystem { let mut repo_config = IndexMap::new(); - repo_config.insert("type".to_string(), PhpMixed::String("filesystem".to_string())); + repo_config.insert( + "type".to_string(), + PhpMixed::String("filesystem".to_string()), + ); repo_config.insert("json".to_string(), PhpMixed::String(repository.to_string())); return Ok(repo_config); } else { @@ -70,12 +89,23 @@ impl RepositoryFactory { }.into()) } - pub fn from_string(io: &dyn IOInterface, config: &Config, repository: &str, allow_filesystem: bool, rm: Option<&mut RepositoryManager>) -> anyhow::Result> { + pub fn from_string( + io: &dyn IOInterface, + config: &Config, + repository: &str, + allow_filesystem: bool, + rm: Option<&mut RepositoryManager>, + ) -> anyhow::Result> { let repo_config = Self::config_from_string(io, config, repository, allow_filesystem)?; Self::create_repo(io, config, repo_config, rm) } - pub fn create_repo(io: &dyn IOInterface, config: &Config, repo_config: IndexMap, rm: Option<&mut RepositoryManager>) -> anyhow::Result> { + pub fn create_repo( + io: &dyn IOInterface, + config: &Config, + repo_config: IndexMap, + rm: Option<&mut RepositoryManager>, + ) -> anyhow::Result> { let mut owned_rm; let rm = if let Some(rm) = rm { rm @@ -83,13 +113,23 @@ impl RepositoryFactory { owned_rm = Self::manager(io, config, None, None, None)?; &mut owned_rm }; - let mut repos = Self::create_repos(rm, vec![PhpMixed::Array( - repo_config.into_iter().map(|(k, v)| (k, Box::new(v))).collect() - )])?; + let mut repos = Self::create_repos( + rm, + vec![PhpMixed::Array( + repo_config + .into_iter() + .map(|(k, v)| (k, Box::new(v))) + .collect(), + )], + )?; Ok(repos.remove(0)) } - pub fn default_repos(io: Option<&dyn IOInterface>, config: Option, rm: Option<&mut RepositoryManager>) -> anyhow::Result>> { + pub fn default_repos( + io: Option<&dyn IOInterface>, + config: Option, + rm: Option<&mut RepositoryManager>, + ) -> anyhow::Result>> { let config = match config { Some(c) => c, None => Factory::create_config(None, None)?, @@ -103,10 +143,17 @@ impl RepositoryFactory { rm } else { let io = io.ok_or_else(|| InvalidArgumentException { - message: "This function requires either an IOInterface or a RepositoryManager".to_string(), + message: "This function requires either an IOInterface or a RepositoryManager" + .to_string(), code: 0, })?; - owned_rm = Self::manager(io, &config, Some(Factory::create_http_downloader(io, &config)?), None, None)?; + owned_rm = Self::manager( + io, + &config, + Some(Factory::create_http_downloader(io, &config)?), + None, + None, + )?; &mut owned_rm }; @@ -114,7 +161,13 @@ impl RepositoryFactory { Self::create_repos(rm, repo_configs) } - pub fn manager(io: &dyn IOInterface, config: &Config, http_downloader: Option, event_dispatcher: Option, process: Option) -> anyhow::Result { + pub fn manager( + io: &dyn IOInterface, + config: &Config, + http_downloader: Option, + event_dispatcher: Option, + process: Option, + ) -> anyhow::Result { let http_downloader = match http_downloader { Some(h) => h, None => Factory::create_http_downloader(io, config)?, @@ -148,14 +201,19 @@ impl RepositoryFactory { Ok(rm) } - pub fn default_repos_with_default_manager(io: &dyn IOInterface) -> anyhow::Result>> { + pub fn default_repos_with_default_manager( + io: &dyn IOInterface, + ) -> anyhow::Result>> { let config = Factory::create_config(Some(io), None)?; let mut manager = Self::manager(io, &config, None, None, None)?; io.load_configuration(&config); Self::default_repos(Some(io), Some(config), Some(&mut manager)) } - fn create_repos(rm: &mut RepositoryManager, repo_configs: Vec) -> anyhow::Result>> { + fn create_repos( + rm: &mut RepositoryManager, + repo_configs: Vec, + ) -> anyhow::Result>> { let mut repo_map: IndexMap> = IndexMap::new(); for (index, repo) in repo_configs.into_iter().enumerate() { @@ -169,27 +227,51 @@ impl RepositoryFactory { PhpMixed::Array(repo_arr) => { if !repo_arr.contains_key("type") { return Err(UnexpectedValueException { - message: format!("Repository \"{}\" ({}) must have a type defined", index, json_encode(&repo).unwrap_or_default()), + message: format!( + "Repository \"{}\" ({}) must have a type defined", + index, + json_encode(&repo).unwrap_or_default() + ), code: 0, - }.into()); + } + .into()); } - let repo_type = repo_arr.get("type").and_then(|v| v.as_string()).unwrap_or("").to_string(); - let repo_config_map: IndexMap = repo_arr.iter().map(|(k, v)| (k.clone(), *v.clone())).collect(); - let name = Self::generate_repository_name_indexed(index, &repo_config_map, &repo_map); + let repo_type = repo_arr + .get("type") + .and_then(|v| v.as_string()) + .unwrap_or("") + .to_string(); + let repo_config_map: IndexMap = repo_arr + .iter() + .map(|(k, v)| (k.clone(), *v.clone())) + .collect(); + let name = + Self::generate_repository_name_indexed(index, &repo_config_map, &repo_map); if repo_type == "filesystem" { - let json_path = repo_arr.get("json").and_then(|v| v.as_string()).unwrap_or("").to_string(); + let json_path = repo_arr + .get("json") + .and_then(|v| v.as_string()) + .unwrap_or("") + .to_string(); repo_map.insert(name, Box::new(FilesystemRepository::new(json_path)?)); } else { - let created = rm.create_repository(&repo_type, repo_config_map, &index.to_string())?; + let created = + rm.create_repository(&repo_type, repo_config_map, &index.to_string())?; repo_map.insert(name, created); } } _ => { return Err(UnexpectedValueException { - message: format!("Repository \"{}\" ({}) should be an array, {} given", index, json_encode(&repo).unwrap_or_default(), get_debug_type(&repo)), + message: format!( + "Repository \"{}\" ({}) should be an array, {} given", + index, + json_encode(&repo).unwrap_or_default(), + get_debug_type(&repo) + ), code: 0, - }.into()); + } + .into()); } } } @@ -197,7 +279,11 @@ impl RepositoryFactory { Ok(repo_map.into_values().collect()) } - pub fn generate_repository_name(index: &PhpMixed, repo: &IndexMap, existing_repos: &IndexMap>) -> String { + pub fn generate_repository_name( + index: &PhpMixed, + repo: &IndexMap, + existing_repos: &IndexMap>, + ) -> String { let mut name = match index { PhpMixed::Int(_) => { if let Some(url) = repo.get("url").and_then(|v| v.as_string()) { @@ -214,7 +300,11 @@ impl RepositoryFactory { name } - fn generate_repository_name_indexed(index: usize, repo: &IndexMap, existing_repos: &IndexMap>) -> String { + fn generate_repository_name_indexed( + index: usize, + repo: &IndexMap, + existing_repos: &IndexMap>, + ) -> String { let mut name = if let Some(url) = repo.get("url").and_then(|v| v.as_string()) { Preg::replace("{^https?://}i", "", url, -1).unwrap_or_else(|_| url.to_string()) } else { diff --git a/crates/shirabe/src/repository/repository_interface.rs b/crates/shirabe/src/repository/repository_interface.rs index f284afd..15c85f0 100644 --- a/crates/shirabe/src/repository/repository_interface.rs +++ b/crates/shirabe/src/repository/repository_interface.rs @@ -1,11 +1,11 @@ //! ref: composer/src/Composer/Repository/RepositoryInterface.php -use indexmap::IndexMap; -use shirabe_php_shim::Countable; -use shirabe_semver::constraint::constraint_interface::ConstraintInterface; use crate::package::base_package::BasePackage; use crate::package::package_interface::PackageInterface; use crate::repository::advisory_provider_interface::AdvisoryProviderInterface; +use indexmap::IndexMap; +use shirabe_php_shim::Countable; +use shirabe_semver::constraint::constraint_interface::ConstraintInterface; pub enum FindPackageConstraint { String(String), @@ -42,9 +42,17 @@ pub trait RepositoryInterface: Countable { fn has_package(&self, package: &dyn PackageInterface) -> bool; - fn find_package(&self, name: String, constraint: FindPackageConstraint) -> Option>; + fn find_package( + &self, + name: String, + constraint: FindPackageConstraint, + ) -> Option>; - fn find_packages(&self, name: String, constraint: Option) -> Vec>; + fn find_packages( + &self, + name: String, + constraint: Option, + ) -> Vec>; fn get_packages(&self) -> Vec>; diff --git a/crates/shirabe/src/repository/repository_manager.rs b/crates/shirabe/src/repository/repository_manager.rs index fd60e7b..cc43aed 100644 --- a/crates/shirabe/src/repository/repository_manager.rs +++ b/crates/shirabe/src/repository/repository_manager.rs @@ -1,7 +1,7 @@ //! ref: composer/src/Composer/Repository/RepositoryManager.php use indexmap::IndexMap; -use shirabe_php_shim::{json_encode, InvalidArgumentException, PhpMixed}; +use shirabe_php_shim::{InvalidArgumentException, PhpMixed, json_encode}; use shirabe_semver::constraint::constraint_interface::ConstraintInterface; use crate::config::Config; @@ -26,7 +26,13 @@ pub struct RepositoryManager { } impl RepositoryManager { - pub fn new(io: &dyn IOInterface, config: &Config, http_downloader: HttpDownloader, event_dispatcher: Option, process: Option) -> Self { + pub fn new( + io: &dyn IOInterface, + config: &Config, + http_downloader: HttpDownloader, + event_dispatcher: Option, + process: Option, + ) -> Self { let process = process.unwrap_or_else(|| ProcessExecutor::new(io)); Self { local_repository: None, @@ -40,7 +46,11 @@ impl RepositoryManager { } } - pub fn find_package(&self, name: &str, constraint: &dyn ConstraintInterface) -> Option> { + pub fn find_package( + &self, + name: &str, + constraint: &dyn ConstraintInterface, + ) -> Option> { for repository in &self.repositories { if let Some(package) = repository.find_package(name, constraint) { return Some(package); @@ -49,7 +59,11 @@ impl RepositoryManager { None } - pub fn find_packages(&self, name: &str, constraint: &dyn ConstraintInterface) -> Vec> { + pub fn find_packages( + &self, + name: &str, + constraint: &dyn ConstraintInterface, + ) -> Vec> { let mut packages: Vec> = vec![]; for repository in self.get_repositories() { packages.extend(repository.find_packages(name, constraint)); @@ -65,23 +79,41 @@ impl RepositoryManager { self.repositories.insert(0, repository); } - pub fn create_repository(&self, r#type: &str, config: IndexMap, name: Option<&str>) -> anyhow::Result> { + pub fn create_repository( + &self, + r#type: &str, + config: IndexMap, + name: Option<&str>, + ) -> anyhow::Result> { if !self.repository_classes.contains_key(r#type) { return Err(InvalidArgumentException { message: format!("Repository type is not registered: {}", r#type), code: 0, - }.into()); + } + .into()); } if config.get("packagist").and_then(|v| v.as_bool()) == Some(false) { - let config_json = json_encode(&PhpMixed::Array(config.iter().map(|(k, v)| (k.clone(), Box::new(v.clone()))).collect())).unwrap_or_default(); + let config_json = json_encode(&PhpMixed::Array( + config + .iter() + .map(|(k, v)| (k.clone(), Box::new(v.clone()))) + .collect(), + )) + .unwrap_or_default(); self.io.write_error(&format!("Repository \"{}\" ({}) has a packagist key which should be in its own repository definition", name.unwrap_or(""), config_json)); } let class = self.repository_classes[r#type].clone(); - let has_filter = config.contains_key("only") || config.contains_key("exclude") || config.contains_key("canonical"); - let filter_config = if has_filter { Some(config.clone()) } else { None }; + let has_filter = config.contains_key("only") + || config.contains_key("exclude") + || config.contains_key("canonical"); + let filter_config = if has_filter { + Some(config.clone()) + } else { + None + }; let mut cleaned_config = config; cleaned_config.remove("only"); @@ -98,12 +130,17 @@ impl RepositoryManager { Ok(repository) } - fn create_repository_by_class(&self, _class: &str, _config: IndexMap) -> anyhow::Result> { + fn create_repository_by_class( + &self, + _class: &str, + _config: IndexMap, + ) -> anyhow::Result> { todo!("Phase B: dynamic class instantiation by class name") } pub fn set_repository_class(&mut self, r#type: &str, class: &str) { - self.repository_classes.insert(r#type.to_string(), class.to_string()); + self.repository_classes + .insert(r#type.to_string(), class.to_string()); } pub fn get_repositories(&self) -> &Vec> { diff --git a/crates/shirabe/src/repository/repository_set.rs b/crates/shirabe/src/repository/repository_set.rs index 7134ed7..e25bd29 100644 --- a/crates/shirabe/src/repository/repository_set.rs +++ b/crates/shirabe/src/repository/repository_set.rs @@ -5,8 +5,8 @@ use std::any::Any; use anyhow::Result; use indexmap::IndexMap; use shirabe_php_shim::{ - array_merge, array_merge_recursive, ksort, strtolower, LogicException, PhpMixed, - RuntimeException, + LogicException, PhpMixed, RuntimeException, array_merge, array_merge_recursive, ksort, + strtolower, }; use shirabe_semver::constraint::constraint::Constraint; use shirabe_semver::constraint::constraint_interface::ConstraintInterface; @@ -184,7 +184,11 @@ impl RepositorySet { (repo.as_any() as &dyn Any).downcast_ref::() { // TODO(phase-b): clone composite.get_repositories() — Box cloning - composite.get_repositories().iter().map(|r| r.clone_box()).collect() + composite + .get_repositories() + .iter() + .map(|r| r.clone_box()) + .collect() } else { vec![repo] }; @@ -479,7 +483,8 @@ impl RepositorySet { .is_some(); if is_installed && !self.allow_installed_repositories { return Err(LogicException { - message: "The pool can not accept packages from an installed repository".to_string(), + message: "The pool can not accept packages from an installed repository" + .to_string(), code: 0, } .into()); @@ -503,7 +508,8 @@ impl RepositorySet { .is_some(); if is_installed && !self.allow_installed_repositories { return Err(LogicException { - message: "The pool can not accept packages from an installed repository".to_string(), + message: "The pool can not accept packages from an installed repository" + .to_string(), code: 0, } .into()); @@ -548,7 +554,14 @@ impl RepositorySet { } // TODO(phase-b): Pool::new signature - Ok(Pool::new(packages, vec![], IndexMap::new(), IndexMap::new(), IndexMap::new(), IndexMap::new())) + Ok(Pool::new( + packages, + vec![], + IndexMap::new(), + IndexMap::new(), + IndexMap::new(), + IndexMap::new(), + )) } pub fn create_pool_for_package( @@ -587,7 +600,15 @@ impl RepositorySet { request.restrict_packages(allowed_packages); } - self.create_pool(request, Box::new(NullIO::new()), None, None, vec![], None, None) + self.create_pool( + request, + Box::new(NullIO::new()), + None, + None, + vec![], + None, + None, + ) } /// @param array[] $aliases diff --git a/crates/shirabe/src/repository/repository_utils.rs b/crates/shirabe/src/repository/repository_utils.rs index 1ca98ee..526fae7 100644 --- a/crates/shirabe/src/repository/repository_utils.rs +++ b/crates/shirabe/src/repository/repository_utils.rs @@ -1,12 +1,12 @@ //! ref: composer/src/Composer/Repository/RepositoryUtils.php -use std::any::Any; -use indexmap::IndexMap; use crate::package::link::Link; use crate::package::package_interface::PackageInterface; use crate::repository::composite_repository::CompositeRepository; use crate::repository::filter_repository::FilterRepository; use crate::repository::repository_interface::RepositoryInterface; +use indexmap::IndexMap; +use std::any::Any; pub struct RepositoryUtils; @@ -33,7 +33,12 @@ impl RepositoryUtils { }); if !already_in_bucket { bucket.push(candidate.clone_box()); - bucket = Self::filter_required_packages(packages, candidate.as_ref(), false, bucket); + bucket = Self::filter_required_packages( + packages, + candidate.as_ref(), + false, + bucket, + ); } break; } @@ -48,7 +53,9 @@ impl RepositoryUtils { unwrap_filter_repos: bool, ) -> Vec> { let repo: Box = if unwrap_filter_repos { - if let Some(filter_repo) = (repo.as_any() as &dyn Any).downcast_ref::() { + if let Some(filter_repo) = + (repo.as_any() as &dyn Any).downcast_ref::() + { filter_repo.get_repository() } else { repo @@ -57,7 +64,9 @@ impl RepositoryUtils { repo }; - if let Some(composite_repo) = (repo.as_any() as &dyn Any).downcast_ref::() { + if let Some(composite_repo) = + (repo.as_any() as &dyn Any).downcast_ref::() + { let mut repos = Vec::new(); for r in composite_repo.get_repositories() { for r2 in Self::flatten_repositories(r, unwrap_filter_repos) { diff --git a/crates/shirabe/src/repository/vcs/forgejo_driver.rs b/crates/shirabe/src/repository/vcs/forgejo_driver.rs index 5d482b2..74f1e11 100644 --- a/crates/shirabe/src/repository/vcs/forgejo_driver.rs +++ b/crates/shirabe/src/repository/vcs/forgejo_driver.rs @@ -4,7 +4,7 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - base64_decode, extension_loaded, explode, urlencode, PhpMixed, RuntimeException, + PhpMixed, RuntimeException, base64_decode, explode, extension_loaded, urlencode, }; use crate::cache::Cache; @@ -215,8 +215,7 @@ impl ForgejoDriver { if self.branches.is_none() { let mut branches = IndexMap::new(); let api_url = self.forgejo_url.as_ref().unwrap().api_url.clone(); - let mut resource: Option = - Some(format!("{}/branches?per_page=100", api_url)); + let mut resource: Option = Some(format!("{}/branches?per_page=100", api_url)); while let Some(url) = resource { let response = self @@ -259,8 +258,7 @@ impl ForgejoDriver { if self.tags.is_none() { let mut tags = IndexMap::new(); let api_url = self.forgejo_url.as_ref().unwrap().api_url.clone(); - let mut resource: Option = - Some(format!("{}/tags?per_page=100", api_url)); + let mut resource: Option = Some(format!("{}/tags?per_page=100", api_url)); while let Some(url) = resource { let response = self @@ -330,7 +328,10 @@ impl ForgejoDriver { shirabe_php_shim::JSON_UNESCAPED_UNICODE | shirabe_php_shim::JSON_UNESCAPED_SLASHES, ); - self.inner.cache.as_ref().map(|c| c.write(identifier, &encoded)); + self.inner + .cache + .as_ref() + .map(|c| c.write(identifier, &encoded)); } } c @@ -347,8 +348,7 @@ impl ForgejoDriver { .get("support") .map_or(false, |v| v.as_array().is_none()); if support_not_array { - composer_map - .insert("support".to_string(), PhpMixed::Array(IndexMap::new())); + composer_map.insert("support".to_string(), PhpMixed::Array(IndexMap::new())); } let has_source = composer_map @@ -366,28 +366,26 @@ impl ForgejoDriver { let tags = self.get_tags()?; let branches = self.get_branches()?; - let source_url = if let Some(label) = - tags.into_iter().find(|(_, v)| v == identifier).map(|(k, _)| k) + let source_url = if let Some(label) = tags + .into_iter() + .find(|(_, v)| v == identifier) + .map(|(k, _)| k) { format!("{}/tag/{}", html_url, label) - } else if let Some(label) = - branches - .into_iter() - .find(|(_, v)| v == identifier) - .map(|(k, _)| k) + } else if let Some(label) = branches + .into_iter() + .find(|(_, v)| v == identifier) + .map(|(k, _)| k) { format!("{}/branch/{}", html_url, label) } else { format!("{}/commit/{}", html_url, identifier) }; - if let Some(PhpMixed::Array(ref mut support)) = - composer_map.get_mut("support") + if let Some(PhpMixed::Array(ref mut support)) = composer_map.get_mut("support") { - support.insert( - "source".to_string(), - Box::new(PhpMixed::String(source_url)), - ); + support + .insert("source".to_string(), Box::new(PhpMixed::String(source_url))); } } @@ -409,13 +407,10 @@ impl ForgejoDriver { .map(|r| r.html_url.clone()) .unwrap_or_default() ); - if let Some(PhpMixed::Array(ref mut support)) = - composer_map.get_mut("support") + if let Some(PhpMixed::Array(ref mut support)) = composer_map.get_mut("support") { - support.insert( - "issues".to_string(), - Box::new(PhpMixed::String(issues_url)), - ); + support + .insert("issues".to_string(), Box::new(PhpMixed::String(issues_url))); } } @@ -429,10 +424,16 @@ impl ForgejoDriver { } } - self.inner.info_cache.insert(identifier.to_string(), composer); + self.inner + .info_cache + .insert(identifier.to_string(), composer); } - Ok(self.inner.info_cache.get(identifier).and_then(|v| v.clone())) + Ok(self + .inner + .info_cache + .get(identifier) + .and_then(|v| v.clone())) } pub fn get_source(&mut self, identifier: &str) -> IndexMap { @@ -470,8 +471,9 @@ impl ForgejoDriver { let forgejo_domains = config.get("forgejo-domains"); let in_domains = if let Some(list) = forgejo_domains.as_list() { list.iter().any(|d| { - d.as_string() - .map_or(false, |s| s.to_lowercase() == forgejo_url.origin_url.to_lowercase()) + d.as_string().map_or(false, |s| { + s.to_lowercase() == forgejo_url.origin_url.to_lowercase() + }) }) } else { false @@ -570,82 +572,73 @@ impl ForgejoDriver { ) -> anyhow::Result { match self.inner.get_contents(url) { Ok(response) => Ok(response), - Err(e) => { - match e.get_code() { - 401 | 403 | 404 | 429 => { - if !fetching_repo_data { - return Err(e); - } + Err(e) => match e.get_code() { + 401 | 403 | 404 | 429 => { + if !fetching_repo_data { + return Err(e); + } - if !self.inner.io.is_interactive() { - self.attempt_clone_fallback() - .map_err(|inner_e| TransportException { - message: inner_e.to_string(), - code: 0, - headers: None, - response: None, - status_code: None, - response_info: vec![], - })?; - - return Ok(Response::new( - { - let mut m = IndexMap::new(); - m.insert( - "url".to_string(), - PhpMixed::String("dummy".to_string()), - ); - m - }, - Some(200), - vec![], - Some("null".to_string()), - ) - .unwrap() - .unwrap()); - } + if !self.inner.io.is_interactive() { + self.attempt_clone_fallback() + .map_err(|inner_e| TransportException { + message: inner_e.to_string(), + code: 0, + headers: None, + response: None, + status_code: None, + response_info: vec![], + })?; + + return Ok(Response::new( + { + let mut m = IndexMap::new(); + m.insert("url".to_string(), PhpMixed::String("dummy".to_string())); + m + }, + Some(200), + vec![], + Some("null".to_string()), + ) + .unwrap() + .unwrap()); + } - if !self.inner.io.has_authentication(&self.inner.origin_url) { - let origin_url = - self.forgejo_url.as_ref().unwrap().origin_url.clone(); - let message = if e.get_code() == 429 { - Some(format!( - "API limit exhausted. Enter your Forgejo credentials to get a larger API limit ({})", - self.inner.url - )) - } else { - None - }; - - let mut forgejo = Forgejo::new( - todo!("clone io for Forgejo OAuth"), - self.inner.config.clone(), - self.inner.http_downloader.clone(), - ); - let auth_result = forgejo - .authorize_o_auth_interactively( - &origin_url, - message.as_deref(), - ) - .map_err(|inner_e| TransportException { - message: inner_e.to_string(), - code: 0, - headers: None, - response: None, - status_code: None, - response_info: vec![], - })?; - - if let Ok(true) = auth_result { - return self.inner.get_contents(url); - } + if !self.inner.io.has_authentication(&self.inner.origin_url) { + let origin_url = self.forgejo_url.as_ref().unwrap().origin_url.clone(); + let message = if e.get_code() == 429 { + Some(format!( + "API limit exhausted. Enter your Forgejo credentials to get a larger API limit ({})", + self.inner.url + )) + } else { + None + }; + + let mut forgejo = Forgejo::new( + todo!("clone io for Forgejo OAuth"), + self.inner.config.clone(), + self.inner.http_downloader.clone(), + ); + let auth_result = forgejo + .authorize_o_auth_interactively(&origin_url, message.as_deref()) + .map_err(|inner_e| TransportException { + message: inner_e.to_string(), + code: 0, + headers: None, + response: None, + status_code: None, + response_info: vec![], + })?; + + if let Ok(true) = auth_result { + return self.inner.get_contents(url); } - - Err(e) } - _ => Err(e), + + Err(e) } - } + _ => Err(e), + }, } } diff --git a/crates/shirabe/src/repository/vcs/fossil_driver.rs b/crates/shirabe/src/repository/vcs/fossil_driver.rs index da81548..6e99f5f 100644 --- a/crates/shirabe/src/repository/vcs/fossil_driver.rs +++ b/crates/shirabe/src/repository/vcs/fossil_driver.rs @@ -3,7 +3,7 @@ use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; -use shirabe_php_shim::{dirname, is_dir, is_file, is_writable, PhpMixed, RuntimeException}; +use shirabe_php_shim::{PhpMixed, RuntimeException, dirname, is_dir, is_file, is_writable}; use crate::cache::Cache; use crate::config::Config; @@ -28,15 +28,29 @@ impl FossilDriver { self.check_fossil()?; // Ensure we are allowed to use this URL by config. - self.inner.config.prohibit_url_by_config(&self.inner.url, &*self.inner.io)?; + self.inner + .config + .prohibit_url_by_config(&self.inner.url, &*self.inner.io)?; // Only if url points to a locally accessible directory, assume it's the checkout directory. // Otherwise, it should be something fossil can clone from. if Filesystem::is_local_path(&self.inner.url) && is_dir(&self.inner.url) { self.checkout_dir = self.inner.url.clone(); } else { - let cache_repo_dir = self.inner.config.get("cache-repo-dir").as_string().unwrap_or("").to_string(); - let cache_vcs_dir = self.inner.config.get("cache-vcs-dir").as_string().unwrap_or("").to_string(); + let cache_repo_dir = self + .inner + .config + .get("cache-repo-dir") + .as_string() + .unwrap_or("") + .to_string(); + let cache_vcs_dir = self + .inner + .config + .get("cache-vcs-dir") + .as_string() + .unwrap_or("") + .to_string(); if !Cache::is_usable(&cache_repo_dir) || !Cache::is_usable(&cache_vcs_dir) { return Err(RuntimeException { message: "FossilDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(), diff --git a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs index 495b427..dc3b5f3 100644 --- a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs +++ b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs @@ -5,9 +5,9 @@ use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - array_key_exists, array_search_mixed, extension_loaded, http_build_query_mixed, implode, - in_array, is_array, sprintf, strpos, InvalidArgumentException, LogicException, PhpMixed, - RuntimeException, + InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_key_exists, + array_search_mixed, extension_loaded, http_build_query_mixed, implode, in_array, is_array, + sprintf, strpos, }; use crate::cache::Cache; @@ -94,11 +94,13 @@ impl GitBitbucketDriver { ), None, )); - self.inner - .cache - .as_mut() - .unwrap() - .set_read_only(self.inner.config.get("cache-read-only").as_bool().unwrap_or(false)); + self.inner.cache.as_mut().unwrap().set_read_only( + self.inner + .config + .get("cache-read-only") + .as_bool() + .unwrap_or(false), + ); Ok(()) } @@ -153,7 +155,11 @@ impl GitBitbucketDriver { self.parse_clone_urls(clone_links); self.has_issues = !shirabe_php_shim::empty( - repo_data.get("has_issues").cloned().as_ref().unwrap_or(&PhpMixed::Null), + repo_data + .get("has_issues") + .cloned() + .as_ref() + .unwrap_or(&PhpMixed::Null), ); self.branches_url = repo_data .get("links") @@ -214,21 +220,19 @@ impl GitBitbucketDriver { if !self.inner.info_cache.contains_key(identifier) { let mut composer: Option> = None; - if self.inner.should_cache(identifier) - && { - let res = self - .inner - .cache - .as_ref() - .and_then(|c| c.read(identifier).ok().flatten()); - if let Some(res) = res { - composer = Some(JsonFile::parse_json(&res, None)?); - true - } else { - false - } + if self.inner.should_cache(identifier) && { + let res = self + .inner + .cache + .as_ref() + .and_then(|c| c.read(identifier).ok().flatten()); + if let Some(res) = res { + composer = Some(JsonFile::parse_json(&res, None)?); + true + } else { + false } - { + } { // composer already set above } else { composer = self.inner.get_base_composer_information(identifier)?; @@ -258,10 +262,7 @@ impl GitBitbucketDriver { if composer_map.contains_key("support") && !is_array(composer_map.get("support").unwrap()) { - composer_map.insert( - "support".to_string(), - PhpMixed::Array(IndexMap::new()), - ); + composer_map.insert("support".to_string(), PhpMixed::Array(IndexMap::new())); } let support_has_source = composer_map .get("support") @@ -379,18 +380,16 @@ impl GitBitbucketDriver { composer = Some(composer_map); } - self.inner.info_cache.insert(identifier.to_string(), composer); + self.inner + .info_cache + .insert(identifier.to_string(), composer); } Ok(self.inner.info_cache.get(identifier).cloned().flatten()) } /// @inheritDoc - pub fn get_file_content( - &mut self, - file: &str, - identifier: &str, - ) -> Result> { + pub fn get_file_content(&mut self, file: &str, identifier: &str) -> Result> { if let Some(fallback) = self.fallback_driver.as_mut() { return fallback.get_file_content(file, identifier); } @@ -446,10 +445,7 @@ impl GitBitbucketDriver { .decode_json()?; // TODO(phase-b): port PHP `new \DateTimeImmutable($commit['date'])` - let date_str = commit - .get("date") - .and_then(|v| v.as_string()) - .unwrap_or(""); + let date_str = commit.get("date").and_then(|v| v.as_string()).unwrap_or(""); let date: DateTime = chrono::DateTime::parse_from_rfc3339(date_str) .map_err(|e| anyhow::anyhow!(e))? .with_timezone(&Utc); @@ -513,9 +509,7 @@ impl GitBitbucketDriver { m.insert("pagelen".to_string(), PhpMixed::Int(100)); m.insert( "fields".to_string(), - PhpMixed::String( - "values.name,values.target.hash,next".to_string(), - ), + PhpMixed::String("values.name,values.target.hash,next".to_string()), ); m.insert( "sort".to_string(), @@ -556,7 +550,11 @@ impl GitBitbucketDriver { } } if shirabe_php_shim::empty( - tags_data.get("next").cloned().as_ref().unwrap_or(&PhpMixed::Null), + tags_data + .get("next") + .cloned() + .as_ref() + .unwrap_or(&PhpMixed::Null), ) { has_next = false; } else { @@ -593,8 +591,7 @@ impl GitBitbucketDriver { m.insert( "fields".to_string(), PhpMixed::String( - "values.name,values.target.hash,values.heads,next" - .to_string(), + "values.name,values.target.hash,values.heads,next".to_string(), ), ); m.insert( @@ -636,7 +633,11 @@ impl GitBitbucketDriver { } } if shirabe_php_shim::empty( - branch_data.get("next").cloned().as_ref().unwrap_or(&PhpMixed::Null), + branch_data + .get("next") + .cloned() + .as_ref() + .unwrap_or(&PhpMixed::Null), ) { has_next = false; } else { @@ -684,7 +685,9 @@ impl GitBitbucketDriver { true, ); if in_set - || (401 == code && strpos(te.get_message(), "Could not authenticate against") == Some(0)) + || (401 == code + && strpos(te.get_message(), "Could not authenticate against") + == Some(0)) { if !self.inner.io.has_authentication(&self.inner.origin_url) && bitbucket_util.authorize_oauth(&self.inner.origin_url) @@ -696,11 +699,14 @@ impl GitBitbucketDriver { self.attempt_clone_fallback()?; let mut headers: IndexMap = IndexMap::new(); - headers.insert( - "url".to_string(), - PhpMixed::String("dummy".to_string()), - ); - return Ok(Response::new(headers, 200, IndexMap::new(), "null".to_string())); + headers + .insert("url".to_string(), PhpMixed::String("dummy".to_string())); + return Ok(Response::new( + headers, + 200, + IndexMap::new(), + "null".to_string(), + )); } } } @@ -785,9 +791,8 @@ impl GitBitbucketDriver { if !self.get_repo_data()? { if self.fallback_driver.is_none() { return Err(LogicException { - message: - "A fallback driver should be setup if getRepoData returns false" - .to_string(), + message: "A fallback driver should be setup if getRepoData returns false" + .to_string(), code: 0, } .into()); @@ -823,12 +828,7 @@ impl GitBitbucketDriver { } /// @inheritDoc - pub fn supports( - io: &dyn IOInterface, - _config: &Config, - url: &str, - _deep: bool, - ) -> bool { + pub fn supports(io: &dyn IOInterface, _config: &Config, url: &str, _deep: bool) -> bool { if !Preg::is_match( r"#^https?://bitbucket\.org/([^/]+)/([^/]+?)(\.git|/?)?$#i", url, diff --git a/crates/shirabe/src/repository/vcs/git_driver.rs b/crates/shirabe/src/repository/vcs/git_driver.rs index 5e2e547..0f8f841 100644 --- a/crates/shirabe/src/repository/vcs/git_driver.rs +++ b/crates/shirabe/src/repository/vcs/git_driver.rs @@ -5,8 +5,8 @@ use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - dirname, is_dir, is_writable, realpath, sys_get_temp_dir, InvalidArgumentException, - RuntimeException, + InvalidArgumentException, RuntimeException, dirname, is_dir, is_writable, realpath, + sys_get_temp_dir, }; use crate::cache::Cache; @@ -31,8 +31,7 @@ impl GitDriver { pub fn initialize(&mut self) -> anyhow::Result<()> { let cache_url; if Filesystem::is_local_path(&self.inner.url) { - self.inner.url = - Preg::replace(r"{[\\/]\.git/?$}", "", self.inner.url.clone())?; + self.inner.url = Preg::replace(r"{[\\/]\.git/?$}", "", self.inner.url.clone())?; if !is_dir(&self.inner.url) { return Err(RuntimeException { message: format!( @@ -64,11 +63,7 @@ impl GitDriver { self.repo_dir = format!( "{}/{}/", cache_vcs_dir, - Preg::replace( - r"{[^a-z0-9.]}i", - "-", - Url::sanitize(self.inner.url.clone()) - )? + Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(self.inner.url.clone()))? ); GitUtil::clean_env(&self.inner.process); @@ -88,9 +83,7 @@ impl GitDriver { .into()); } - if Preg::is_match(r"{^ssh://[^@]+@[^:]+:[^0-9]+}", &self.inner.url) - .unwrap_or(false) - { + if Preg::is_match(r"{^ssh://[^@]+@[^:]+:[^0-9]+}", &self.inner.url).unwrap_or(false) { return Err(InvalidArgumentException { message: format!( "The source URL {} is invalid, ssh URLs should have a port number after \":\".\nUse ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.", @@ -173,11 +166,8 @@ impl GitDriver { &Filesystem::new(), ); if !Filesystem::is_local_path(&self.inner.url) { - let default_branch = git_util.get_mirror_default_branch( - &self.inner.url, - &self.repo_dir, - false, - )?; + let default_branch = + git_util.get_mirror_default_branch(&self.inner.url, &self.repo_dir, false)?; if let Some(branch) = default_branch { self.root_identifier = Some(branch.clone()); return Ok(branch); @@ -198,9 +188,7 @@ impl GitDriver { if !branches.contains(&"* master".to_string()) { for branch in &branches { if !branch.is_empty() { - if let Some(caps) = - Preg::match_strict_groups(r"{^\* +(\S+)}", branch) - { + if let Some(caps) = Preg::match_strict_groups(r"{^\* +(\S+)}", branch) { if let Some(name) = caps.get("1") { self.root_identifier = Some(name.clone()); break; @@ -264,10 +252,7 @@ impl GitDriver { Ok(Some(content)) } - pub fn get_change_date( - &mut self, - identifier: &str, - ) -> anyhow::Result>> { + pub fn get_change_date(&mut self, identifier: &str) -> anyhow::Result>> { if identifier.starts_with('-') { return Err(RuntimeException { message: format!( @@ -292,8 +277,7 @@ impl GitDriver { .process .execute(&command, &mut output, Some(self.repo_dir.clone())); - let timestamp_str = - GitUtil::parse_rev_list_output(&output, &self.inner.process); + let timestamp_str = GitUtil::parse_rev_list_output(&output, &self.inner.process); let timestamp: i64 = timestamp_str.trim().parse().unwrap_or(0); Ok(Some(Utc.timestamp_opt(timestamp, 0).unwrap())) } @@ -319,9 +303,7 @@ impl GitDriver { r"{^([a-f0-9]{40}) refs/tags/(\S+?)(\^\{\})?$}", &tag, ) { - if let (Some(hash), Some(name)) = - (caps.get("1"), caps.get("2")) - { + if let (Some(hash), Some(name)) = (caps.get("1"), caps.get("2")) { self.tags .as_mut() .unwrap() @@ -359,8 +341,7 @@ impl GitDriver { r"{^(?:\* )? *(\S+) *([a-f0-9]+)(?: .*)?$}", &branch, ) { - if let (Some(name), Some(hash)) = (caps.get("1"), caps.get("2")) - { + if let (Some(name), Some(hash)) = (caps.get("1"), caps.get("2")) { if !name.starts_with('-') { branches.insert(name.clone(), hash.clone()); } diff --git a/crates/shirabe/src/repository/vcs/github_driver.rs b/crates/shirabe/src/repository/vcs/github_driver.rs index a75e2a0..bd2e2ad 100644 --- a/crates/shirabe/src/repository/vcs/github_driver.rs +++ b/crates/shirabe/src/repository/vcs/github_driver.rs @@ -5,9 +5,9 @@ use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - array_diff, array_key_exists, array_map, array_search_mixed, base64_decode, basename, count, - empty, explode, extension_loaded, in_array, parse_url_all, sprintf, strpos, strtolower, substr, - trim, urlencode, InvalidArgumentException, PhpMixed, RuntimeException, + InvalidArgumentException, PhpMixed, RuntimeException, array_diff, array_key_exists, array_map, + array_search_mixed, base64_decode, basename, count, empty, explode, extension_loaded, in_array, + parse_url_all, sprintf, strpos, strtolower, substr, trim, urlencode, }; use crate::cache::Cache; @@ -255,10 +255,7 @@ impl GitHubDriver { if composer.contains_key("support") && !matches!(composer.get("support"), Some(PhpMixed::Array(_))) { - composer.insert( - "support".to_string(), - PhpMixed::Array(IndexMap::new()), - ); + composer.insert("support".to_string(), PhpMixed::Array(IndexMap::new())); } let support_source_missing = !composer .get("support") @@ -294,12 +291,10 @@ impl GitHubDriver { .filter(|v| !matches!(v, PhpMixed::Bool(false) | PhpMixed::Null)) .unwrap_or_else(|| PhpMixed::String(identifier.to_string())); let label_str = label.as_string().unwrap_or(identifier).to_string(); - if let Some(support) = - composer.get_mut("support").and_then(|v| match v { - PhpMixed::Array(m) => Some(m), - _ => None, - }) - { + if let Some(support) = composer.get_mut("support").and_then(|v| match v { + PhpMixed::Array(m) => Some(m), + _ => None, + }) { support.insert( "source".to_string(), Box::new(PhpMixed::String(sprintf( @@ -320,12 +315,10 @@ impl GitHubDriver { .map(|m| m.contains_key("issues")) .unwrap_or(false); if issues_missing && self.has_issues { - if let Some(support) = - composer.get_mut("support").and_then(|v| match v { - PhpMixed::Array(m) => Some(m), - _ => None, - }) - { + if let Some(support) = composer.get_mut("support").and_then(|v| match v { + PhpMixed::Array(m) => Some(m), + _ => None, + }) { support.insert( "issues".to_string(), Box::new(PhpMixed::String(sprintf( @@ -390,15 +383,10 @@ impl GitHubDriver { ] { let mut options: IndexMap = IndexMap::new(); options.insert("retry-auth-failure".to_string(), PhpMixed::Bool(false)); - let response = self - .inner - .http_downloader - .get(file_url, &PhpMixed::Array( - options - .into_iter() - .map(|(k, v)| (k, Box::new(v))) - .collect(), - )); + let response = self.inner.http_downloader.get( + file_url, + &PhpMixed::Array(options.into_iter().map(|(k, v)| (k, Box::new(v))).collect()), + ); let response = match response { Ok(r) => r, Err(_) => continue, @@ -417,10 +405,8 @@ impl GitHubDriver { .and_then(|v| v.as_string()) .map(|s| s.is_empty()) .unwrap_or(true); - let encoding_not_base64 = response_map - .get("encoding") - .and_then(|v| v.as_string()) - != Some("base64"); + let encoding_not_base64 = + response_map.get("encoding").and_then(|v| v.as_string()) != Some("base64"); if content_empty || encoding_not_base64 { continue; } @@ -451,23 +437,18 @@ impl GitHubDriver { let mut key: Option = None; for line in Preg::split(r"{\r?\n}", &funding) { let line = trim(&line, None); - if let Some(m) = - Preg::is_match_strict_groups(r"{^(\w+)\s*:\s*(.+)$}", &line) - { + if let Some(m) = Preg::is_match_strict_groups(r"{^(\w+)\s*:\s*(.+)$}", &line) { let g1 = m.get(1).cloned().unwrap_or_default(); let g2 = m.get(2).cloned().unwrap_or_default(); if g2 == "[" { key = Some(g1); continue; } - if let Some(m2) = Preg::is_match_strict_groups( - r"{^\[(.*?)\](?:\s*#.*)?$}", - &g2, - ) { + if let Some(m2) = Preg::is_match_strict_groups(r"{^\[(.*?)\](?:\s*#.*)?$}", &g2) { let inner = m2.get(1).cloned().unwrap_or_default(); for item in array_map( |s: &String| trim(s, None), - &Preg::split(r"{[\'\"]?\s*,\s*[\'\"]?}", &inner), + &Preg::split(r#"{[\'\"]?\s*,\s*[\'\"]?}"#, &inner), ) { let mut entry = IndexMap::new(); entry.insert("type".to_string(), PhpMixed::String(g1.clone())); @@ -477,10 +458,9 @@ impl GitHubDriver { ); result.push(entry); } - } else if let Some(m2) = Preg::is_match_strict_groups( - r"{^([^#].*?)(?:\s+#.*)?$}", - &g2, - ) { + } else if let Some(m2) = + Preg::is_match_strict_groups(r"{^([^#].*?)(?:\s+#.*)?$}", &g2) + { let mut entry = IndexMap::new(); entry.insert("type".to_string(), PhpMixed::String(g1.clone())); entry.insert( @@ -493,15 +473,11 @@ impl GitHubDriver { result.push(entry); } key = None; - } else if let Some(m) = - Preg::is_match_strict_groups(r"{^(\w+)\s*:\s*#\s*$}", &line) - { + } else if let Some(m) = Preg::is_match_strict_groups(r"{^(\w+)\s*:\s*#\s*$}", &line) { key = Some(m.get(1).cloned().unwrap_or_default()); } else if key.is_some() - && (Preg::is_match_strict_groups(r"{^-\s*(.+)(?:\s+#.*)?$}", &line) - .is_some() - || Preg::is_match_strict_groups(r"{^(.+),(?:\s*#.*)?$}", &line) - .is_some()) + && (Preg::is_match_strict_groups(r"{^-\s*(.+)(?:\s+#.*)?$}", &line).is_some() + || Preg::is_match_strict_groups(r"{^(.+),(?:\s*#.*)?$}", &line).is_some()) { let m = Preg::is_match_strict_groups(r"{^-\s*(.+)(?:\s+#.*)?$}", &line) .or_else(|| Preg::is_match_strict_groups(r"{^(.+),(?:\s*#.*)?$}", &line)) @@ -513,10 +489,7 @@ impl GitHubDriver { ); entry.insert( "url".to_string(), - PhpMixed::String(trim( - &m.get(1).cloned().unwrap_or_default(), - Some("\"' "), - )), + PhpMixed::String(trim(&m.get(1).cloned().unwrap_or_default(), Some("\"' "))), ); result.push(entry); } else if key.is_some() && line == "]" { @@ -568,10 +541,7 @@ impl GitHubDriver { "liberapay" => { result[key_idx].insert( "url".to_string(), - PhpMixed::String(format!( - "https://liberapay.com/{}", - basename(&item_url) - )), + PhpMixed::String(format!("https://liberapay.com/{}", basename(&item_url))), ); } "open_collective" => { @@ -625,10 +595,7 @@ impl GitHubDriver { "otechie" => { result[key_idx].insert( "url".to_string(), - PhpMixed::String(format!( - "https://otechie.com/{}", - basename(&item_url) - )), + PhpMixed::String(format!("https://otechie.com/{}", basename(&item_url))), ); } "custom" => { @@ -712,16 +679,16 @@ impl GitHubDriver { PhpMixed::Array(ref m) => m.clone(), _ => IndexMap::new(), }; - let needs_git_url = (resource_map.get("content").and_then(|v| v.as_string()).is_none() + let needs_git_url = (resource_map + .get("content") + .and_then(|v| v.as_string()) + .is_none() || resource_map .get("content") .and_then(|v| v.as_string()) .map(|s| s.is_empty()) .unwrap_or(false)) - && resource_map - .get("encoding") - .and_then(|v| v.as_string()) - == Some("none") + && resource_map.get("encoding").and_then(|v| v.as_string()) == Some("none") && resource_map.contains_key("git_url"); if needs_git_url { let git_url = resource_map @@ -740,10 +707,8 @@ impl GitHubDriver { _ => IndexMap::new(), }; let has_content = resource_map.contains_key("content"); - let encoding_base64 = resource_map - .get("encoding") - .and_then(|v| v.as_string()) - == Some("base64"); + let encoding_base64 = + resource_map.get("encoding").and_then(|v| v.as_string()) == Some("base64"); let content = if has_content && encoding_base64 { base64_decode( resource_map @@ -922,11 +887,7 @@ impl GitHubDriver { .filter(|s| !s.is_empty()) .unwrap_or_else(|| matches.get(3).cloned().unwrap_or_default()); if !in_array( - PhpMixed::String(strtolower(&Preg::replace( - r"{^www\.}i", - "", - origin_url, - ))), + PhpMixed::String(strtolower(&Preg::replace(r"{^www\.}i", "", origin_url))), &config.get("github-domains"), false, ) { @@ -1001,20 +962,23 @@ impl GitHubDriver { } if !self.inner.io.is_interactive() { - self.attempt_clone_fallback(Some(&e)) - .map_err(|err| TransportException { + self.attempt_clone_fallback(Some(&e)).map_err(|err| { + TransportException { message: err.to_string(), code: 0, - })?; + } + })?; let mut req = IndexMap::new(); - req.insert( - "url".to_string(), - PhpMixed::String("dummy".to_string()), - ); - return Ok(Response::new(req, Some(200), vec![], Some("null".to_string())) - .unwrap() - .unwrap()); + req.insert("url".to_string(), PhpMixed::String("dummy".to_string())); + return Ok(Response::new( + req, + Some(200), + vec![], + Some("null".to_string()), + ) + .unwrap() + .unwrap()); } let mut scopes_issued: Vec = vec![]; @@ -1068,20 +1032,23 @@ impl GitHubDriver { } if !self.inner.io.is_interactive() && fetching_repo_data { - self.attempt_clone_fallback(Some(&e)) - .map_err(|err| TransportException { + self.attempt_clone_fallback(Some(&e)).map_err(|err| { + TransportException { message: err.to_string(), code: 0, - })?; + } + })?; let mut req = IndexMap::new(); - req.insert( - "url".to_string(), - PhpMixed::String("dummy".to_string()), - ); - return Ok(Response::new(req, Some(200), vec![], Some("null".to_string())) - .unwrap() - .unwrap()); + req.insert("url".to_string(), PhpMixed::String("dummy".to_string())); + return Ok(Response::new( + req, + Some(200), + vec![], + Some("null".to_string()), + ) + .unwrap() + .unwrap()); } let rate_limited = git_hub_util @@ -1186,11 +1153,8 @@ impl GitHubDriver { .unwrap_or("") .to_string(); - self.is_private = !empty( - &repo_data.get("private").cloned().unwrap_or(PhpMixed::Null), - ); - if let Some(default_branch) = repo_data.get("default_branch").and_then(|v| v.as_string()) - { + self.is_private = !empty(&repo_data.get("private").cloned().unwrap_or(PhpMixed::Null)); + if let Some(default_branch) = repo_data.get("default_branch").and_then(|v| v.as_string()) { self.root_identifier = default_branch.to_string(); } else if let Some(master_branch) = repo_data.get("master_branch").and_then(|v| v.as_string()) @@ -1205,12 +1169,7 @@ impl GitHubDriver { .cloned() .unwrap_or(PhpMixed::Null), ); - self.is_archived = !empty( - &repo_data - .get("archived") - .cloned() - .unwrap_or(PhpMixed::Null), - ); + self.is_archived = !empty(&repo_data.get("archived").cloned().unwrap_or(PhpMixed::Null)); Ok(()) } diff --git a/crates/shirabe/src/repository/vcs/gitlab_driver.rs b/crates/shirabe/src/repository/vcs/gitlab_driver.rs index 54147e9..cb0d0a2 100644 --- a/crates/shirabe/src/repository/vcs/gitlab_driver.rs +++ b/crates/shirabe/src/repository/vcs/gitlab_driver.rs @@ -5,9 +5,9 @@ use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - array_search_mixed, array_shift, ctype_alnum, empty, explode, extension_loaded, implode, - in_array, is_array, is_string, ord, sprintf, strpos, strtolower, InvalidArgumentException, - LogicException, PhpMixed, RuntimeException, + InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_search_mixed, + array_shift, ctype_alnum, empty, explode, extension_loaded, implode, in_array, is_array, + is_string, ord, sprintf, strpos, strtolower, }; use crate::cache::Cache; @@ -76,7 +76,8 @@ impl GitLabDriver { .filter(|s| !s.is_empty()) .unwrap_or_else(|| match_.get("domain2").cloned().unwrap_or_default()); let configured_domains = self.inner.config.get("gitlab-domains"); - let mut url_parts: Vec = explode("/", &match_.get("parts").cloned().unwrap_or_default()); + let mut url_parts: Vec = + explode("/", &match_.get("parts").cloned().unwrap_or_default()); let scheme_match = match_.get("scheme").cloned().unwrap_or_default(); self.scheme = if in_array( @@ -122,7 +123,10 @@ impl GitLabDriver { self.inner.origin_url = origin; let protocol_value = self.inner.config.get("gitlab-protocol"); - if let Some(protocol) = protocol_value.as_string().filter(|_| is_string(&protocol_value)) { + if let Some(protocol) = protocol_value + .as_string() + .filter(|_| is_string(&protocol_value)) + { // https treated as a synonym for http. if !in_array( PhpMixed::String(protocol.to_string()), @@ -250,10 +254,7 @@ impl GitLabDriver { if composer.contains_key("support") && !is_array(composer.get("support").cloned().unwrap_or(PhpMixed::Null)) { - composer.insert( - "support".to_string(), - PhpMixed::Array(IndexMap::new()), - ); + composer.insert("support".to_string(), PhpMixed::Array(IndexMap::new())); } let project = self.project.clone().unwrap_or_default(); let has_web_url = project.contains_key("web_url"); @@ -278,7 +279,8 @@ impl GitLabDriver { array_search_mixed( &PhpMixed::String(identifier.to_string()), &PhpMixed::Array( - self.get_branches().unwrap_or_default() + self.get_branches() + .unwrap_or_default() .into_iter() .map(|(k, v)| (k, Box::new(PhpMixed::String(v)))) .collect(), @@ -294,20 +296,15 @@ impl GitLabDriver { .and_then(|v| v.as_string()) .unwrap_or("") .to_string(); - if let Some(support) = composer.get_mut("support").and_then(|v| { - match v { - PhpMixed::Array(m) => Some(m), - _ => None, - } + if let Some(support) = composer.get_mut("support").and_then(|v| match v { + PhpMixed::Array(m) => Some(m), + _ => None, }) { support.insert( "source".to_string(), Box::new(PhpMixed::String(sprintf( "%s/-/tree/%s", - &[ - PhpMixed::String(web_url), - PhpMixed::String(label_str), - ], + &[PhpMixed::String(web_url), PhpMixed::String(label_str)], ))), ); } @@ -343,12 +340,7 @@ impl GitLabDriver { } } if !composer.contains_key("abandoned") - && !empty( - &project - .get("archived") - .cloned() - .unwrap_or(PhpMixed::Null), - ) + && !empty(&project.get("archived").cloned().unwrap_or(PhpMixed::Null)) { composer.insert("abandoned".to_string(), PhpMixed::Bool(true)); } @@ -559,12 +551,8 @@ impl GitLabDriver { Box::new(PhpMixed::String("_".to_string())), ]), true, - ) - { - format!( - "%{}", - sprintf("%02X", &[PhpMixed::Int(ord(&character))]) - ) + ) { + format!("%{}", sprintf("%02X", &[PhpMixed::Int(ord(&character))])) } else { character }; @@ -774,15 +762,13 @@ impl GitLabDriver { // Check both access levels (e.g. project, group) // - value will be null if no access is set // - value will be array with key access_level if set - if let Some(permissions) = json_map - .get("permissions") - .and_then(|v| v.as_array()) + if let Some(permissions) = + json_map.get("permissions").and_then(|v| v.as_array()) { for (_, permission) in permissions { if let Some(perm_map) = permission.as_array() { - if let Some(level) = perm_map - .get("access_level") - .and_then(|v| v.as_int()) + if let Some(level) = + perm_map.get("access_level").and_then(|v| v.as_int()) { if level >= 20 { more_than_guest_access = true; @@ -809,13 +795,15 @@ impl GitLabDriver { })?; let mut req = IndexMap::new(); - req.insert( - "url".to_string(), - PhpMixed::String("dummy".to_string()), - ); - return Ok(Response::new(req, Some(200), vec![], Some("null".to_string())) - .unwrap() - .unwrap()); + req.insert("url".to_string(), PhpMixed::String("dummy".to_string())); + return Ok(Response::new( + req, + Some(200), + vec![], + Some("null".to_string()), + ) + .unwrap() + .unwrap()); } } @@ -834,9 +822,7 @@ impl GitLabDriver { }); } - if !empty( - &json_map.get("id").cloned().unwrap_or(PhpMixed::Null), - ) { + if !empty(&json_map.get("id").cloned().unwrap_or(PhpMixed::Null)) { self.is_private = false; } @@ -885,13 +871,15 @@ impl GitLabDriver { })?; let mut req = IndexMap::new(); - req.insert( - "url".to_string(), - PhpMixed::String("dummy".to_string()), - ); - return Ok(Response::new(req, Some(200), vec![], Some("null".to_string())) - .unwrap() - .unwrap()); + req.insert("url".to_string(), PhpMixed::String("dummy".to_string())); + return Ok(Response::new( + req, + Some(200), + vec![], + Some("null".to_string()), + ) + .unwrap() + .unwrap()); } self.inner.io.write_error( PhpMixed::String(format!( @@ -927,13 +915,15 @@ impl GitLabDriver { })?; let mut req = IndexMap::new(); - req.insert( - "url".to_string(), - PhpMixed::String("dummy".to_string()), - ); - return Ok(Response::new(req, Some(200), vec![], Some("null".to_string())) - .unwrap() - .unwrap()); + req.insert("url".to_string(), PhpMixed::String("dummy".to_string())); + return Ok(Response::new( + req, + Some(200), + vec![], + Some("null".to_string()), + ) + .unwrap() + .unwrap()); } Err(e) @@ -1002,9 +992,7 @@ impl GitLabDriver { let links = explode(",", &header); for link in &links { - if let Some(match_) = - Preg::is_match_strict_groups(r#"{<(.+?)>; *rel="next"}"#, link) - { + if let Some(match_) = Preg::is_match_strict_groups(r#"{<(.+?)>; *rel="next"}"#, link) { return Some(match_.get(1).cloned().unwrap_or_default()); } } @@ -1059,11 +1047,7 @@ impl GitLabDriver { false, ) || (port_number.is_some() && in_array( - PhpMixed::String(Preg::replace( - r"{:\d+}", - "", - guessed_domain.clone(), - )), + PhpMixed::String(Preg::replace(r"{:\d+}", "", guessed_domain.clone())), configured_domains, false, )) @@ -1075,4 +1059,3 @@ impl GitLabDriver { None } } - diff --git a/crates/shirabe/src/repository/vcs/hg_driver.rs b/crates/shirabe/src/repository/vcs/hg_driver.rs index 7dc85e2..6b32a0a 100644 --- a/crates/shirabe/src/repository/vcs/hg_driver.rs +++ b/crates/shirabe/src/repository/vcs/hg_driver.rs @@ -1,9 +1,5 @@ //! ref: composer/src/Composer/Repository/Vcs/HgDriver.php -use chrono::{DateTime, Utc}; -use indexmap::IndexMap; -use shirabe_external_packages::composer::pcre::preg::Preg; -use shirabe_php_shim::{dirname, is_dir, is_writable, RuntimeException}; use crate::cache::Cache; use crate::config::Config; use crate::io::io_interface::IOInterface; @@ -11,6 +7,10 @@ use crate::repository::vcs::vcs_driver::VcsDriver; use crate::util::filesystem::Filesystem; use crate::util::hg::Hg as HgUtils; use crate::util::url::Url; +use chrono::{DateTime, Utc}; +use indexmap::IndexMap; +use shirabe_external_packages::composer::pcre::preg::Preg; +use shirabe_php_shim::{RuntimeException, dirname, is_dir, is_writable}; #[derive(Debug)] pub struct HgDriver { @@ -26,7 +26,13 @@ impl HgDriver { if Filesystem::is_local_path(&self.inner.url) { self.repo_dir = self.inner.url.clone(); } else { - let cache_vcs_dir = self.inner.config.get("cache-vcs-dir").as_string().unwrap_or("").to_string(); + let cache_vcs_dir = self + .inner + .config + .get("cache-vcs-dir") + .as_string() + .unwrap_or("") + .to_string(); if !Cache::is_usable(&cache_vcs_dir) { return Err(RuntimeException { message: "HgDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(), @@ -34,7 +40,8 @@ impl HgDriver { }.into()); } - let sanitized = Preg::replace(r"{[^a-z0-9]}i", "-", Url::sanitize(self.inner.url.clone())); + let sanitized = + Preg::replace(r"{[^a-z0-9]}i", "-", Url::sanitize(self.inner.url.clone())); self.repo_dir = format!("{}/{}/", cache_vcs_dir, sanitized); let fs = Filesystem::new(); @@ -50,12 +57,25 @@ impl HgDriver { }.into()); } - self.inner.config.prohibit_url_by_config(&self.inner.url, &*self.inner.io)?; + self.inner + .config + .prohibit_url_by_config(&self.inner.url, &*self.inner.io)?; let hg_utils = HgUtils::new(&*self.inner.io, &self.inner.config, &self.inner.process); - if is_dir(&self.repo_dir) && self.inner.process.execute(&["hg", "summary"].map(|s| s.to_string()).to_vec(), &mut String::new(), Some(self.repo_dir.clone())) == 0 { - if self.inner.process.execute(&["hg", "pull"].map(|s| s.to_string()).to_vec(), &mut String::new(), Some(self.repo_dir.clone())) != 0 { + if is_dir(&self.repo_dir) + && self.inner.process.execute( + &["hg", "summary"].map(|s| s.to_string()).to_vec(), + &mut String::new(), + Some(self.repo_dir.clone()), + ) == 0 + { + if self.inner.process.execute( + &["hg", "pull"].map(|s| s.to_string()).to_vec(), + &mut String::new(), + Some(self.repo_dir.clone()), + ) != 0 + { self.inner.io.write_error( format!("Failed to update {}, package information from this repository may be outdated ({})", self.inner.url, self.inner.process.get_error_output()).into(), true, @@ -68,7 +88,14 @@ impl HgDriver { let repo_dir = self.repo_dir.clone(); let command = move |url: String| -> Vec { - vec!["hg".to_string(), "clone".to_string(), "--noupdate".to_string(), "--".to_string(), url, repo_dir.clone()] + vec![ + "hg".to_string(), + "clone".to_string(), + "--noupdate".to_string(), + "--".to_string(), + url, + repo_dir.clone(), + ] }; hg_utils.run_command(command, self.inner.url.clone(), None)?; @@ -85,7 +112,9 @@ impl HgDriver { if self.root_identifier.is_none() { let mut output = String::new(); self.inner.process.execute( - &["hg", "tip", "--template", "{node}"].map(|s| s.to_string()).to_vec(), + &["hg", "tip", "--template", "{node}"] + .map(|s| s.to_string()) + .to_vec(), &mut output, Some(self.repo_dir.clone()), ); @@ -115,17 +144,27 @@ impl HgDriver { pub fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result> { if identifier.starts_with('-') { return Err(RuntimeException { - message: format!("Invalid hg identifier detected. Identifier must not start with a -, given: {}", identifier), + message: format!( + "Invalid hg identifier detected. Identifier must not start with a -, given: {}", + identifier + ), code: 0, - }.into()); + } + .into()); } let resource = vec![ - "hg".to_string(), "cat".to_string(), "-r".to_string(), identifier.to_string(), - "--".to_string(), file.to_string(), + "hg".to_string(), + "cat".to_string(), + "-r".to_string(), + identifier.to_string(), + "--".to_string(), + file.to_string(), ]; let mut content = String::new(); - self.inner.process.execute(&resource, &mut content, Some(self.repo_dir.clone())); + self.inner + .process + .execute(&resource, &mut content, Some(self.repo_dir.clone())); if content.trim().is_empty() { return Ok(None); @@ -137,22 +176,32 @@ impl HgDriver { pub fn get_change_date(&self, identifier: &str) -> anyhow::Result>> { if identifier.starts_with('-') { return Err(RuntimeException { - message: format!("Invalid hg identifier detected. Identifier must not start with a -, given: {}", identifier), + message: format!( + "Invalid hg identifier detected. Identifier must not start with a -, given: {}", + identifier + ), code: 0, - }.into()); + } + .into()); } let mut output = String::new(); self.inner.process.execute( - &["hg", "log", "--template", "{date|rfc3339date}", "-r", identifier] - .map(|s| s.to_string()) - .to_vec(), + &[ + "hg", + "log", + "--template", + "{date|rfc3339date}", + "-r", + identifier, + ] + .map(|s| s.to_string()) + .to_vec(), &mut output, Some(self.repo_dir.clone()), ); - let date = DateTime::parse_from_rfc3339(output.trim()) - .map(|d| d.with_timezone(&Utc))?; + let date = DateTime::parse_from_rfc3339(output.trim()).map(|d| d.with_timezone(&Utc))?; Ok(Some(date)) } @@ -231,7 +280,12 @@ impl HgDriver { } pub fn supports(io: &dyn IOInterface, config: &Config, url: &str, deep: bool) -> bool { - if Preg::is_match(r"#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\.kilnhg.com)#i", url).unwrap_or(false) { + if Preg::is_match( + r"#(^(?:https?|ssh)://(?:[^@]+@)?bitbucket.org|https://(?:.*?)\.kilnhg.com)#i", + url, + ) + .unwrap_or(false) + { return true; } @@ -243,7 +297,12 @@ impl HgDriver { let process = crate::util::process_executor::ProcessExecutor::new(io); let mut output = String::new(); - if process.execute(&["hg", "summary"].map(|s| s.to_string()).to_vec(), &mut output, Some(url)) == 0 { + if process.execute( + &["hg", "summary"].map(|s| s.to_string()).to_vec(), + &mut output, + Some(url), + ) == 0 + { return true; } } @@ -254,7 +313,13 @@ impl HgDriver { let process = crate::util::process_executor::ProcessExecutor::new(io); let mut ignored = String::new(); - let exit = process.execute(&["hg", "identify", "--", url].map(|s| s.to_string()).to_vec(), &mut ignored, None); + let exit = process.execute( + &["hg", "identify", "--", url] + .map(|s| s.to_string()) + .to_vec(), + &mut ignored, + None, + ); exit == 0 } diff --git a/crates/shirabe/src/repository/vcs/mod.rs b/crates/shirabe/src/repository/vcs/mod.rs new file mode 100644 index 0000000..4bbf4a6 --- /dev/null +++ b/crates/shirabe/src/repository/vcs/mod.rs @@ -0,0 +1,11 @@ +pub mod forgejo_driver; +pub mod fossil_driver; +pub mod git_bitbucket_driver; +pub mod git_driver; +pub mod github_driver; +pub mod gitlab_driver; +pub mod hg_driver; +pub mod perforce_driver; +pub mod svn_driver; +pub mod vcs_driver; +pub mod vcs_driver_interface; diff --git a/crates/shirabe/src/repository/vcs/perforce_driver.rs b/crates/shirabe/src/repository/vcs/perforce_driver.rs index f32f895..cd3b32b 100644 --- a/crates/shirabe/src/repository/vcs/perforce_driver.rs +++ b/crates/shirabe/src/repository/vcs/perforce_driver.rs @@ -22,12 +22,20 @@ pub struct PerforceDriver { impl PerforceDriver { pub fn initialize(&mut self) -> anyhow::Result<()> { - self.depot = self.inner.repo_config.get("depot") + self.depot = self + .inner + .repo_config + .get("depot") .and_then(|v| v.as_string()) .unwrap_or("") .to_string(); self.branch = String::new(); - if let Some(branch) = self.inner.repo_config.get("branch").and_then(|v| v.as_string()) { + if let Some(branch) = self + .inner + .repo_config + .get("branch") + .and_then(|v| v.as_string()) + { if !branch.is_empty() { self.branch = branch.to_string(); } @@ -48,7 +56,13 @@ impl PerforceDriver { return Ok(()); } - let cache_vcs_dir = self.inner.config.get("cache-vcs-dir").as_string().unwrap_or("").to_string(); + let cache_vcs_dir = self + .inner + .config + .get("cache-vcs-dir") + .as_string() + .unwrap_or("") + .to_string(); if !Cache::is_usable(&cache_vcs_dir) { return Err(RuntimeException { message: "PerforceDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(), @@ -57,16 +71,28 @@ impl PerforceDriver { } let repo_dir = format!("{}/{}", cache_vcs_dir, self.depot); - self.perforce = Some(Perforce::create(repo_config, &self.inner.url, &repo_dir, &self.inner.process, self.inner.io.as_ref())?); + self.perforce = Some(Perforce::create( + repo_config, + &self.inner.url, + &repo_dir, + &self.inner.process, + self.inner.io.as_ref(), + )?); Ok(()) } pub fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result> { - self.perforce.as_ref().unwrap().get_file_content(file, identifier) + self.perforce + .as_ref() + .unwrap() + .get_file_content(file, identifier) } - pub fn get_change_date(&self, _identifier: &str) -> anyhow::Result>> { + pub fn get_change_date( + &self, + _identifier: &str, + ) -> anyhow::Result>> { Ok(None) } @@ -89,9 +115,22 @@ impl PerforceDriver { pub fn get_source(&self, identifier: &str) -> IndexMap { let mut source = IndexMap::new(); source.insert("type".to_string(), PhpMixed::String("perforce".to_string())); - source.insert("url".to_string(), self.inner.repo_config.get("url").cloned().unwrap_or(PhpMixed::Null)); - source.insert("reference".to_string(), PhpMixed::String(identifier.to_string())); - source.insert("p4user".to_string(), PhpMixed::String(self.perforce.as_ref().unwrap().get_user().to_string())); + source.insert( + "url".to_string(), + self.inner + .repo_config + .get("url") + .cloned() + .unwrap_or(PhpMixed::Null), + ); + source.insert( + "reference".to_string(), + PhpMixed::String(identifier.to_string()), + ); + source.insert( + "p4user".to_string(), + PhpMixed::String(self.perforce.as_ref().unwrap().get_user().to_string()), + ); source } @@ -101,14 +140,19 @@ impl PerforceDriver { pub fn has_composer_file(&self, identifier: &str) -> bool { let path = format!("//{}/{}", self.depot, identifier); - self.perforce.as_ref().unwrap().get_composer_information(&path).map_or(false, |info| !info.is_empty()) + self.perforce + .as_ref() + .unwrap() + .get_composer_information(&path) + .map_or(false, |info| !info.is_empty()) } pub fn get_contents(&self, _url: &str) -> anyhow::Result { Err(BadMethodCallException { message: "Not implemented/used in PerforceDriver".to_string(), code: 0, - }.into()) + } + .into()) } pub fn supports(io: &dyn IOInterface, config: &Config, url: &str, deep: bool) -> bool { diff --git a/crates/shirabe/src/repository/vcs/svn_driver.rs b/crates/shirabe/src/repository/vcs/svn_driver.rs index 4bfcf91..7c32e4a 100644 --- a/crates/shirabe/src/repository/vcs/svn_driver.rs +++ b/crates/shirabe/src/repository/vcs/svn_driver.rs @@ -5,8 +5,8 @@ use chrono::{DateTime, TimeZone, Utc}; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - array_key_exists, is_array, max, sprintf, stripos, strrpos, strtr, substr, trim, PhpMixed, - RuntimeException, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, + JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, PhpMixed, RuntimeException, array_key_exists, + is_array, max, sprintf, stripos, strrpos, strtr, substr, trim, }; use crate::cache::Cache; @@ -51,9 +51,7 @@ pub struct SvnDriver { impl SvnDriver { pub fn initialize(&mut self) -> Result<()> { let normalized = Self::normalize_url(&self.inner.url); - self.inner.url = normalized - .trim_end_matches('/') - .to_string(); + self.inner.url = normalized.trim_end_matches('/').to_string(); self.base_url = self.inner.url.clone(); SvnUtil::clean_env(); @@ -90,24 +88,24 @@ impl SvnDriver { todo!("self.inner.io clone"), &format!( "{}/{}", - self.inner.config.get("cache-repo-dir").as_string().unwrap_or(""), + self.inner + .config + .get("cache-repo-dir") + .as_string() + .unwrap_or(""), Preg::replace(r"{[^a-z0-9.]}i", "-", Url::sanitize(self.base_url.clone())), ), None, None, false, )); - self.inner - .cache - .as_mut() - .unwrap() - .set_read_only( - self.inner - .config - .get("cache-read-only") - .as_bool() - .unwrap_or(false), - ); + self.inner.cache.as_mut().unwrap().set_read_only( + self.inner + .config + .get("cache-read-only") + .as_bool() + .unwrap_or(false), + ); self.get_branches(); self.get_tags(); @@ -172,24 +170,22 @@ impl SvnDriver { } // TODO(phase-b): use anyhow::Result> to model PHP try/catch - let composer: Option> = match self - .inner - .get_base_composer_information(identifier) - { - Ok(c) => c, - Err(e) => { - // TODO(phase-b): downcast to TransportException - let _te: &TransportException = todo!("downcast e to TransportException"); - let message = e.to_string(); - if stripos(&message, "path not found").is_none() - && stripos(&message, "svn: warning: W160013").is_none() - { - return Err(e); + let composer: Option> = + match self.inner.get_base_composer_information(identifier) { + Ok(c) => c, + Err(e) => { + // TODO(phase-b): downcast to TransportException + let _te: &TransportException = todo!("downcast e to TransportException"); + let message = e.to_string(); + if stripos(&message, "path not found").is_none() + && stripos(&message, "svn: warning: W160013").is_none() + { + return Err(e); + } + // remember a not-existent composer.json + None } - // remember a not-existent composer.json - None - } - }; + }; if self.should_cache(identifier) { let encoded = JsonFile::encode( @@ -221,10 +217,7 @@ impl SvnDriver { if cached.is_none() || !is_array( // TODO(phase-b): wrap IndexMap to PhpMixed for is_array check - &cached - .clone() - .map(PhpMixed::from) - .unwrap_or(PhpMixed::Null), + &cached.clone().map(PhpMixed::from).unwrap_or(PhpMixed::Null), ) { return Ok(None); @@ -233,11 +226,7 @@ impl SvnDriver { Ok(cached) } - pub fn get_file_content( - &mut self, - file: &str, - identifier: &str, - ) -> Result> { + pub fn get_file_content(&mut self, file: &str, identifier: &str) -> Result> { let identifier = format!("/{}/", trim(identifier, Some("/"))); let (path, rev) = if let Ok(Some(m)) = @@ -296,10 +285,9 @@ impl SvnDriver { )?; for line in self.inner.process.split_lines(&output) { if !line.is_empty() { - if let Some(m) = Preg::is_match_strict_groups( - r"{^Last Changed Date: ([^(]+)}", - &line, - ) { + if let Some(m) = + Preg::is_match_strict_groups(r"{^Last Changed Date: ([^(]+)}", &line) + { let date_str = m.get(1).cloned().unwrap_or_default(); // PHP: new \DateTimeImmutable($match[1], new \DateTimeZone('UTC')) return Ok(Utc @@ -318,24 +306,22 @@ impl SvnDriver { // PHP: if ($this->tagsPath !== false) — tagsPath is "string"; treat empty string as false if !self.tags_path.is_empty() { - let output = self.execute( - vec![ - "svn".to_string(), - "ls".to_string(), - "--verbose".to_string(), - ], - &format!("{}/{}", self.base_url, self.tags_path), - ).unwrap_or_default(); + let output = self + .execute( + vec!["svn".to_string(), "ls".to_string(), "--verbose".to_string()], + &format!("{}/{}", self.base_url, self.tags_path), + ) + .unwrap_or_default(); if !output.is_empty() { let mut last_rev: i64 = 0; for line in self.inner.process.split_lines(&output) { let line = trim(&line, None); if !line.is_empty() { - if let Some(m) = Preg::is_match_strict_groups( - r"{^\s*(\S+).*?(\S+)\s*$}", - &line, - ) { - let rev: i64 = m.get(1).map(|s| s.parse().unwrap_or(0)).unwrap_or(0); + if let Some(m) = + Preg::is_match_strict_groups(r"{^\s*(\S+).*?(\S+)\s*$}", &line) + { + let rev: i64 = + m.get(1).map(|s| s.parse().unwrap_or(0)).unwrap_or(0); let path = m.get(2).cloned().unwrap_or_default(); if path == "./" { last_rev = rev; @@ -370,11 +356,7 @@ impl SvnDriver { let output = self .execute( - vec![ - "svn".to_string(), - "ls".to_string(), - "--verbose".to_string(), - ], + vec!["svn".to_string(), "ls".to_string(), "--verbose".to_string()], &trunk_parent, ) .unwrap_or_default(); @@ -382,10 +364,9 @@ impl SvnDriver { for line in self.inner.process.split_lines(&output) { let line = trim(&line, None); if !line.is_empty() { - if let Some(m) = Preg::is_match_strict_groups( - r"{^\s*(\S+).*?(\S+)\s*$}", - &line, - ) { + if let Some(m) = + Preg::is_match_strict_groups(r"{^\s*(\S+).*?(\S+)\s*$}", &line) + { let rev: i64 = m.get(1).map(|s| s.parse().unwrap_or(0)).unwrap_or(0); let path = m.get(2).cloned().unwrap_or_default(); if path == "./" { @@ -407,11 +388,7 @@ impl SvnDriver { if !self.branches_path.is_empty() { let output = self .execute( - vec![ - "svn".to_string(), - "ls".to_string(), - "--verbose".to_string(), - ], + vec!["svn".to_string(), "ls".to_string(), "--verbose".to_string()], &format!("{}/{}", self.base_url, self.branches_path), ) .unwrap_or_default(); @@ -420,10 +397,9 @@ impl SvnDriver { for line in self.inner.process.split_lines(&trim(&output, None)) { let line = trim(&line, None); if !line.is_empty() { - if let Some(m) = Preg::is_match_strict_groups( - r"{^\s*(\S+).*?(\S+)\s*$}", - &line, - ) { + if let Some(m) = + Preg::is_match_strict_groups(r"{^\s*(\S+).*?(\S+)\s*$}", &line) + { let rev: i64 = m.get(1).map(|s| s.parse().unwrap_or(0)).unwrap_or(0); let path = m.get(2).cloned().unwrap_or_default(); @@ -528,7 +504,12 @@ impl SvnDriver { } // TODO(phase-b): use anyhow::Result> to model PHP try/catch - match self.util.as_mut().unwrap().execute(command, url, None, None, false) { + match self + .util + .as_mut() + .unwrap() + .execute(command, url, None, None, false) + { Ok(o) => Ok(o), Err(e) => { if self.util.as_mut().unwrap().binary_version().is_none() { diff --git a/crates/shirabe/src/repository/vcs/vcs_driver.rs b/crates/shirabe/src/repository/vcs/vcs_driver.rs index 8db411d..a16930f 100644 --- a/crates/shirabe/src/repository/vcs/vcs_driver.rs +++ b/crates/shirabe/src/repository/vcs/vcs_driver.rs @@ -2,7 +2,9 @@ use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; -use shirabe_php_shim::{extension_loaded, PhpMixed, JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE}; +use shirabe_php_shim::{ + JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, PhpMixed, extension_loaded, +}; use crate::cache::Cache; use crate::config::Config; @@ -42,7 +44,11 @@ impl VcsDriver { } } - let url = repo_config.get("url").and_then(|v| v.as_string()).unwrap_or("").to_string(); + let url = repo_config + .get("url") + .and_then(|v| v.as_string()) + .unwrap_or("") + .to_string(); Self { origin_url: url.clone(), @@ -61,7 +67,10 @@ impl VcsDriver { self.cache.is_some() && Preg::is_match("{^[a-f0-9]{40}$}iD", identifier).unwrap_or(false) } - pub fn get_composer_information(&mut self, identifier: &str) -> anyhow::Result>> { + pub fn get_composer_information( + &mut self, + identifier: &str, + ) -> anyhow::Result>> { if !self.info_cache.contains_key(identifier) { if self.should_cache(identifier) { if let Some(res) = self.cache.as_ref().and_then(|c| c.read(identifier)) { @@ -75,7 +84,10 @@ impl VcsDriver { if self.should_cache(identifier) { if let Some(ref composer_map) = composer { - let encoded = JsonFile::encode_with_options(composer_map, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + let encoded = JsonFile::encode_with_options( + composer_map, + JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES, + ); self.cache.as_ref().map(|c| c.write(identifier, &encoded)); } } @@ -86,7 +98,10 @@ impl VcsDriver { Ok(self.info_cache.get(identifier).and_then(|v| v.clone())) } - pub(crate) fn get_base_composer_information(&mut self, identifier: &str) -> anyhow::Result>> { + pub(crate) fn get_base_composer_information( + &mut self, + identifier: &str, + ) -> anyhow::Result>> { let composer_file_content = self.get_file_content("composer.json", identifier)?; let composer_file_content = match composer_file_content { @@ -95,7 +110,10 @@ impl VcsDriver { Some(c) => c, }; - let composer = JsonFile::parse_json(&composer_file_content, Some(&format!("{}:composer.json", identifier)))?; + let composer = JsonFile::parse_json( + &composer_file_content, + Some(&format!("{}:composer.json", identifier)), + )?; let mut composer = match composer { None => return Ok(None), @@ -103,9 +121,16 @@ impl VcsDriver { Some(c) => c, }; - if !composer.contains_key("time") || composer.get("time").map_or(true, |v| v.as_string().map_or(true, |s| s.is_empty())) { + if !composer.contains_key("time") + || composer + .get("time") + .map_or(true, |v| v.as_string().map_or(true, |s| s.is_empty())) + { if let Some(change_date) = self.get_change_date(identifier)? { - composer.insert("time".to_string(), PhpMixed::String(change_date.to_rfc3339())); + composer.insert( + "time".to_string(), + PhpMixed::String(change_date.to_rfc3339()), + ); } } @@ -127,18 +152,29 @@ impl VcsDriver { } pub(crate) fn get_contents(&self, url: &str) -> anyhow::Result { - let options = self.repo_config.get("options").cloned().unwrap_or(PhpMixed::Array(IndexMap::new())); + let options = self + .repo_config + .get("options") + .cloned() + .unwrap_or(PhpMixed::Array(IndexMap::new())); self.http_downloader.get(url, &options) } pub fn cleanup(&self) {} // abstract methods to be implemented by subclasses (via VcsDriverInterface trait) - pub(crate) fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result> { + pub(crate) fn get_file_content( + &self, + file: &str, + identifier: &str, + ) -> anyhow::Result> { todo!() } - pub(crate) fn get_change_date(&self, identifier: &str) -> anyhow::Result>> { + pub(crate) fn get_change_date( + &self, + identifier: &str, + ) -> anyhow::Result>> { todo!() } } diff --git a/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs b/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs index a17acad..5b15c2c 100644 --- a/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs +++ b/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs @@ -1,15 +1,18 @@ //! ref: composer/src/Composer/Repository/Vcs/VcsDriverInterface.php +use crate::config::Config; +use crate::io::io_interface::IOInterface; use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_php_shim::PhpMixed; -use crate::config::Config; -use crate::io::io_interface::IOInterface; pub trait VcsDriverInterface { fn initialize(&mut self) -> anyhow::Result<()>; - fn get_composer_information(&self, identifier: &str) -> anyhow::Result>>; + fn get_composer_information( + &self, + identifier: &str, + ) -> anyhow::Result>>; fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result>; diff --git a/crates/shirabe/src/repository/vcs_repository.rs b/crates/shirabe/src/repository/vcs_repository.rs index fcfd101..57e44a5 100644 --- a/crates/shirabe/src/repository/vcs_repository.rs +++ b/crates/shirabe/src/repository/vcs_repository.rs @@ -4,8 +4,8 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - array_search_mixed, count, get_class, in_array, str_replace, strpos, InvalidArgumentException, - PhpMixed, + InvalidArgumentException, PhpMixed, array_search_mixed, count, get_class, in_array, + str_replace, strpos, }; use shirabe_semver::constraint::constraint::Constraint; @@ -135,7 +135,10 @@ impl VcsRepository { }); let url = Platform::expand_path( - repo_config.get("url").and_then(|v| v.as_string()).unwrap_or(""), + repo_config + .get("url") + .and_then(|v| v.as_string()) + .unwrap_or(""), ); repo_config.insert("url".to_string(), PhpMixed::String(url.clone())); let r#type = repo_config @@ -145,7 +148,8 @@ impl VcsRepository { .to_string(); let is_verbose = io.is_verbose(); let is_very_verbose = io.is_very_verbose(); - let process_executor = process.unwrap_or_else(|| ProcessExecutor::new(Some(Box::new(&*io)), None)); + let process_executor = + process.unwrap_or_else(|| ProcessExecutor::new(Some(Box::new(&*io)), None)); Ok(Self { inner, @@ -189,11 +193,7 @@ impl VcsRepository { .unwrap_or(driver_class); let _ = driver; - format!( - "vcs repo ({} {})", - driver_type, - Url::sanitize(&self.url) - ) + format!("vcs repo ({} {})", driver_type, Url::sanitize(&self.url)) } pub fn get_repo_config(&self) -> &IndexMap { @@ -292,7 +292,12 @@ impl VcsRepository { let mut has_root_identifier_composer_json = false; let root_identifier_result = self.driver.as_mut().unwrap().get_root_identifier(); if let Ok(root_identifier) = root_identifier_result { - match self.driver.as_mut().unwrap().has_composer_file(&root_identifier) { + match self + .driver + .as_mut() + .unwrap() + .has_composer_file(&root_identifier) + { Ok(b) => { has_root_identifier_composer_json = b; if has_root_identifier_composer_json { @@ -348,7 +353,9 @@ impl VcsRepository { let mut tag = tag; let msg = format!( "Reading composer.json of {} ({})", - self.package_name.clone().unwrap_or_else(|| self.url.clone()), + self.package_name + .clone() + .unwrap_or_else(|| self.url.clone()), tag ); @@ -411,14 +418,12 @@ impl VcsRepository { // manually versioned package if data.contains_key("version") { - let normalized = self - .version_parser - .as_ref() - .unwrap() - .normalize( - data.get("version").and_then(|v| v.as_string()).unwrap_or(""), - None, - )?; + let normalized = self.version_parser.as_ref().unwrap().normalize( + data.get("version") + .and_then(|v| v.as_string()) + .unwrap_or(""), + None, + )?; data.insert( "version_normalized".to_string(), PhpMixed::String(normalized), @@ -438,7 +443,9 @@ impl VcsRepository { PhpMixed::String(Preg::replace( r"{[.-]?dev$}i", "", - data.get("version").and_then(|v| v.as_string()).unwrap_or(""), + data.get("version") + .and_then(|v| v.as_string()) + .unwrap_or(""), )), ); data.insert( @@ -503,16 +510,14 @@ impl VcsRepository { } if is_very_verbose { - self.io.write_error(&format!( - "Importing tag {} ({})", - tag, version_normalized - )); + self.io + .write_error(&format!("Importing tag {} ({})", tag, version_normalized)); } let driver = self.driver.as_mut().unwrap(); let processed = self.pre_process(&**driver, data, &identifier)?; let loaded = self.loader.as_ref().unwrap().load(processed, None)?; - self.inner.add_package(Box::new(loaded as Box))?; + self.inner.add_package(Box::new(loaded))?; Ok(()) })(); if let Err(e) = result { @@ -575,7 +580,9 @@ impl VcsRepository { for (branch, identifier) in branches { let msg = format!( "Reading composer.json of {} ({})", - self.package_name.clone().unwrap_or_else(|| self.url.clone()), + self.package_name + .clone() + .unwrap_or_else(|| self.url.clone()), branch ); if is_very_verbose { @@ -609,7 +616,11 @@ impl VcsRepository { version = format!("dev-{}", str_replace("#", "+", &branch)); parsed_branch = str_replace("#", "+", &parsed_branch); } else { - let prefix = if strpos(&branch, "v") == Some(0) { "v" } else { "" }; + let prefix = if strpos(&branch, "v") == Some(0) { + "v" + } else { + "" + }; version = format!( "{}{}", prefix, @@ -617,8 +628,7 @@ impl VcsRepository { ); } - let is_default_branch = - self.driver.as_mut().unwrap().get_root_identifier()? == branch; + let is_default_branch = self.driver.as_mut().unwrap().get_root_identifier()? == branch; let cached_package = self.get_cached_package_version( &version, &identifier, @@ -666,26 +676,29 @@ impl VcsRepository { self.io.write_error(&format!( "Importing branch {} ({})", branch, - data.get("version").and_then(|v| v.as_string()).unwrap_or("") + data.get("version") + .and_then(|v| v.as_string()) + .unwrap_or("") )); } let package_data = self.pre_process(&**driver, data, &identifier)?; - let package = self.loader.as_ref().unwrap().load(package_data.clone(), None)?; + let package = self + .loader + .as_ref() + .unwrap() + .load(package_data.clone(), None)?; // TODO(phase-b): `$this->loader instanceof ValidatingArrayLoader` downcast let loader_as_validating: Option<&ValidatingArrayLoader> = None; if let Some(validating) = loader_as_validating { if count(&PhpMixed::Null) > 0 { let _ = validating; - return Err(InvalidPackageException::new( - vec![], - vec![], - package_data, - ) - .into()); + return Err( + InvalidPackageException::new(vec![], vec![], package_data).into() + ); } } - self.inner.add_package(Box::new(package as Box))?; + self.inner.add_package(Box::new(package))?; Ok(()) })(); if let Err(e) = result { @@ -712,10 +725,8 @@ impl VcsRepository { self.io.write_error(""); } self.branch_error_occurred = true; - self.io.write_error(&format!( - "Skipped branch {}, {}", - branch, e - )); + self.io + .write_error(&format!("Skipped branch {}, {}", branch, e)); self.io.write_error(""); continue; } @@ -810,12 +821,10 @@ impl VcsRepository { _ => None, }) .unwrap_or(false); - let source_reference = data - .get("source") - .and_then(|v| match v { - PhpMixed::Array(m) => m.get("reference").cloned(), - _ => None, - }); + let source_reference = data.get("source").and_then(|v| match v { + PhpMixed::Array(m) => m.get("reference").cloned(), + _ => None, + }); if dist_is_array && dist_lacks_reference && source_reference.is_some() { if let Some(PhpMixed::Array(dist_map)) = data.get_mut("dist") { dist_map.insert("reference".to_string(), source_reference.unwrap()); @@ -889,7 +898,9 @@ impl VcsRepository { if let VersionCacheResult::Package(ref mut data) = cached_package { let msg = format!( "Found cached composer.json of {} ({})", - self.package_name.clone().unwrap_or_else(|| self.url.clone()), + self.package_name + .clone() + .unwrap_or_else(|| self.url.clone()), version ); if is_very_verbose { @@ -908,7 +919,11 @@ impl VcsRepository { data.insert("default-branch".to_string(), PhpMixed::Bool(true)); } - let name = data.get("name").and_then(|v| v.as_string()).unwrap_or("").to_string(); + let name = data + .get("name") + .and_then(|v| v.as_string()) + .unwrap_or("") + .to_string(); let version_normalized = data .get("version_normalized") .and_then(|v| v.as_string()) @@ -930,7 +945,7 @@ impl VcsRepository { if let VersionCacheResult::Package(data) = cached_package { let loaded = self.loader.as_ref().unwrap().load(data, None)?; - return Ok(CachedPackageResult::Package(Box::new(loaded as Box))); + return Ok(CachedPackageResult::Package(Box::new(loaded))); } Ok(CachedPackageResult::None) diff --git a/crates/shirabe/src/repository/writable_array_repository.rs b/crates/shirabe/src/repository/writable_array_repository.rs index 54e4b04..5d77fee 100644 --- a/crates/shirabe/src/repository/writable_array_repository.rs +++ b/crates/shirabe/src/repository/writable_array_repository.rs @@ -1,8 +1,8 @@ //! ref: composer/src/Composer/Repository/WritableArrayRepository.php -use anyhow::Result; use crate::installer::installation_manager::InstallationManager; use crate::repository::array_repository::ArrayRepository; +use anyhow::Result; #[derive(Debug)] pub struct WritableArrayRepository { @@ -25,7 +25,11 @@ impl WritableArrayRepository { &self.dev_package_names } - pub fn write(&mut self, dev_mode: bool, _installation_manager: &InstallationManager) -> Result<()> { + pub fn write( + &mut self, + dev_mode: bool, + _installation_manager: &InstallationManager, + ) -> Result<()> { self.dev_mode = Some(dev_mode); Ok(()) } diff --git a/crates/shirabe/src/repository/writable_repository_interface.rs b/crates/shirabe/src/repository/writable_repository_interface.rs index 3cb8b00..5648ef5 100644 --- a/crates/shirabe/src/repository/writable_repository_interface.rs +++ b/crates/shirabe/src/repository/writable_repository_interface.rs @@ -1,9 +1,9 @@ //! ref: composer/src/Composer/Repository/WritableRepositoryInterface.php -use anyhow::Result; use crate::installer::installation_manager::InstallationManager; use crate::package::package_interface::PackageInterface; use crate::repository::repository_interface::RepositoryInterface; +use anyhow::Result; pub trait WritableRepositoryInterface: RepositoryInterface { fn write(&mut self, dev_mode: bool, installation_manager: &InstallationManager) -> Result<()>; -- cgit v1.3.1