diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-17 02:53:53 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-17 02:53:53 +0900 |
| commit | a1c7e6908a26e10f6e1f23a51721664b5e2d838d (patch) | |
| tree | c575c76f1b43359ed74913da4c6a2636643f1ba0 /crates/shirabe/src/repository/vcs | |
| parent | 7f606f36fef0c0467c3c0db3d0da33af486dae8a (diff) | |
| download | php-shirabe-a1c7e6908a26e10f6e1f23a51721664b5e2d838d.tar.gz php-shirabe-a1c7e6908a26e10f6e1f23a51721664b5e2d838d.tar.zst php-shirabe-a1c7e6908a26e10f6e1f23a51721664b5e2d838d.zip | |
chore(style): cargo fmt
Diffstat (limited to 'crates/shirabe/src/repository/vcs')
| -rw-r--r-- | crates/shirabe/src/repository/vcs/forgejo_driver.rs | 191 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/fossil_driver.rs | 22 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs | 118 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/git_driver.rs | 43 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/github_driver.rs | 175 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/gitlab_driver.rs | 123 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/hg_driver.rs | 117 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/mod.rs | 11 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/perforce_driver.rs | 66 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/svn_driver.rs | 139 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/vcs_driver.rs | 58 | ||||
| -rw-r--r-- | crates/shirabe/src/repository/vcs/vcs_driver_interface.rs | 9 |
12 files changed, 571 insertions, 501 deletions
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<String> = - Some(format!("{}/branches?per_page=100", api_url)); + let mut resource: Option<String> = 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<String> = - Some(format!("{}/tags?per_page=100", api_url)); + let mut resource: Option<String> = 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<String, String> { @@ -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<Response, TransportException> { 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![], - })?; + 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()); - } + 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 (<info>{}</info>)", - self.inner.url - )) - } else { - None - }; + 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 (<info>{}</info>)", + 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![], - })?; + 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 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<IndexMap<String, PhpMixed>> = 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<Option<String>> { + pub fn get_file_content(&mut self, file: &str, identifier: &str) -> Result<Option<String>> { 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<Utc> = 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<String, PhpMixed> = 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<Option<DateTime<Utc>>> { + pub fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> { 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<String, PhpMixed> = 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<String> = 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<String> = 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<String> = explode("/", &match_.get("parts").cloned().unwrap_or_default()); + let mut url_parts: Vec<String> = + 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!("<error>Failed to update {}, package information from this repository may be outdated ({})</error>", 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<String> { - 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<Option<String>> { 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<Option<DateTime<Utc>>> { 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<Option<String>> { - 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<Option<chrono::DateTime<chrono::Utc>>> { + pub fn get_change_date( + &self, + _identifier: &str, + ) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> { Ok(None) } @@ -89,9 +115,22 @@ impl PerforceDriver { pub fn get_source(&self, identifier: &str) -> IndexMap<String, PhpMixed> { 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<Response> { 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<Result<T, E>> to model PHP try/catch - let composer: Option<IndexMap<String, PhpMixed>> = 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<IndexMap<String, PhpMixed>> = + 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<Option<String>> { + pub fn get_file_content(&mut self, file: &str, identifier: &str) -> Result<Option<String>> { 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<Result<T, E>> 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<Option<IndexMap<String, PhpMixed>>> { + pub fn get_composer_information( + &mut self, + identifier: &str, + ) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>> { 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<Option<IndexMap<String, PhpMixed>>> { + pub(crate) fn get_base_composer_information( + &mut self, + identifier: &str, + ) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>> { 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<Response, TransportException> { - 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<Option<String>> { + pub(crate) fn get_file_content( + &self, + file: &str, + identifier: &str, + ) -> anyhow::Result<Option<String>> { todo!() } - pub(crate) fn get_change_date(&self, identifier: &str) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> { + pub(crate) fn get_change_date( + &self, + identifier: &str, + ) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> { 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<Option<IndexMap<String, PhpMixed>>>; + fn get_composer_information( + &self, + identifier: &str, + ) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>>; fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>>; |
