//! ref: composer/src/Composer/Util/ComposerMirror.php use shirabe_php_shim::{hash, php_regex, preg_is_match, preg_match, preg_replace}; pub struct ComposerMirror; impl ComposerMirror { pub fn process_url( mirror_url: &str, package_name: &str, version: &str, reference: Option<&str>, r#type: Option<&str>, pretty_version: Option<&str>, ) -> String { let reference = reference.map(|r| { if preg_is_match(php_regex!(r"{^([a-f0-9]*|%reference%)$}"), r) { r.to_string() } else { hash("md5", r) } }); let version = if !version.contains('/') { version.to_string() } else { hash("md5", version) }; let mut from = vec!["%package%", "%version%", "%reference%", "%type%"]; let mut to: Vec<&str> = vec![ package_name, &version, reference.as_deref().unwrap_or(""), r#type.unwrap_or(""), ]; if let Some(pv) = pretty_version { from.push("%prettyVersion%"); to.push(pv); } let url = from .iter() .zip(to.iter()) .fold(mirror_url.to_string(), |acc, (f, t)| acc.replace(f, t)); assert!(!url.is_empty()); url } pub fn process_git_url( mirror_url: &str, package_name: &str, url: &str, r#type: Option<&str>, ) -> String { let normalized_url = if let Some(gh_matches) = preg_match( php_regex!( r"#^(?:(?:https?|git)://github\.com/|git@github\.com:)([^/]+)/(.+?)(?:\.git)?$#" ), url, ) { format!( "gh-{}/{}", gh_matches.get(1).unwrap_or_default(), gh_matches.get(2).unwrap_or_default(), ) } else if let Some(bb_matches) = preg_match( php_regex!(r"#^https://bitbucket\.org/([^/]+)/(.+?)(?:\.git)?/?$#"), url, ) { format!( "bb-{}/{}", bb_matches.get(1).unwrap_or_default(), bb_matches.get(2).unwrap_or_default(), ) } else { preg_replace(php_regex!(r"{[^a-z0-9_.-]}i"), "-", url.trim_matches('/')) }; ["%package%", "%normalizedUrl%", "%type%"] .iter() .zip([package_name, &normalized_url, r#type.unwrap_or("")]) .fold(mirror_url.to_string(), |acc, (f, t)| acc.replace(f, t)) } pub fn process_hg_url(mirror_url: &str, package_name: &str, url: &str, r#type: &str) -> String { Self::process_git_url(mirror_url, package_name, url, Some(r#type)) } }