diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-19 00:10:22 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-19 00:11:03 +0900 |
| commit | c839244d8d09f3036ebfee8eef7eb6b147e593ab (patch) | |
| tree | fe48c94f2c2e62468beef5ff1a8f3cff6adeef4f /crates/shirabe/src/repository | |
| parent | 48839250146b217e2756ed3c0e624fd341b54d6c (diff) | |
| download | php-shirabe-c839244d8d09f3036ebfee8eef7eb6b147e593ab.tar.gz php-shirabe-c839244d8d09f3036ebfee8eef7eb6b147e593ab.tar.zst php-shirabe-c839244d8d09f3036ebfee8eef7eb6b147e593ab.zip | |
fix(compile): fix various compile errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/repository')
22 files changed, 460 insertions, 94 deletions
diff --git a/crates/shirabe/src/repository/array_repository.rs b/crates/shirabe/src/repository/array_repository.rs index 5262b5e..5652dad 100644 --- a/crates/shirabe/src/repository/array_repository.rs +++ b/crates/shirabe/src/repository/array_repository.rs @@ -176,8 +176,10 @@ impl RepositoryInterface for ArrayRepository { let mut result: IndexMap<String, Box<dyn BasePackage>> = IndexMap::new(); let mut names_found: IndexMap<String, bool> = IndexMap::new(); for package in &packages { - if package_name_map.contains_key(package.get_name()) { - let constraint_opt = package_name_map.get(package.get_name()).unwrap(); + if package_name_map.contains_key(PackageInterface::get_name(package.as_ref())) { + let constraint_opt = package_name_map + .get(PackageInterface::get_name(package.as_ref())) + .unwrap(); let constraint_matches = match constraint_opt { None => true, Some(c) => c.matches(&Constraint::new("==", package.get_version())), @@ -186,11 +188,11 @@ impl RepositoryInterface for ArrayRepository { && StabilityFilter::is_package_acceptable( &acceptable_stabilities, &stability_flags, - &package.get_names(true), + &PackageInterface::get_names(package.as_ref(), true), package.get_stability(), ) && !already_loaded - .get(package.get_name()) + .get(PackageInterface::get_name(package.as_ref())) .map(|v| v.contains_key(package.get_version())) .unwrap_or(false) { @@ -207,7 +209,10 @@ impl RepositoryInterface for ArrayRepository { } } - names_found.insert(package.get_name().to_string(), true); + names_found.insert( + PackageInterface::get_name(package.as_ref()).to_string(), + true, + ); } } @@ -244,7 +249,7 @@ impl RepositoryInterface for ArrayRepository { }; for package in self.get_packages() { - if name == package.get_name() { + if name == PackageInterface::get_name(package.as_ref()) { let pkg_constraint = Constraint::new("==", package.get_version()); if constraint.matches(&pkg_constraint) { return Some(package); @@ -275,7 +280,7 @@ impl RepositoryInterface for ArrayRepository { }; for package in self.get_packages() { - if name == package.get_name() { + if name == PackageInterface::get_name(package.as_ref()) { if constraint.is_none() || constraint .as_ref() @@ -303,7 +308,7 @@ impl RepositoryInterface for ArrayRepository { let mut matches: IndexMap<String, SearchResult> = IndexMap::new(); for package in self.get_packages() { - let mut name = package.get_name().to_string(); + let mut name = PackageInterface::get_name(package.as_ref()).to_string(); if mode == Self::SEARCH_VENDOR { // PHP: [$name] = explode('/', $name); let parts: Vec<&str> = name.splitn(2, '/').collect(); @@ -395,7 +400,7 @@ impl RepositoryInterface for ArrayRepository { let mut result: IndexMap<String, ProviderInfo> = IndexMap::new(); 'candidates: for candidate in self.get_packages() { - if result.contains_key(candidate.get_name()) { + if result.contains_key(PackageInterface::get_name(candidate.as_ref())) { continue; } for link in candidate.get_provides().values() { @@ -404,9 +409,9 @@ impl RepositoryInterface for ArrayRepository { (candidate.as_any() as &dyn Any).downcast_ref::<CompletePackage>(); let description = complete.and_then(|c| c.get_description().map(String::from)); result.insert( - candidate.get_name().to_string(), + PackageInterface::get_name(candidate.as_ref()).to_string(), ProviderInfo { - name: candidate.get_name().to_string(), + name: PackageInterface::get_name(candidate.as_ref()).to_string(), description, r#type: candidate.get_type().to_string(), }, diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 9acebe0..dfbb0b5 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -37,6 +37,7 @@ use crate::repository::advisory_provider_interface::{ use crate::repository::array_repository::ArrayRepository; use crate::repository::configurable_repository_interface::ConfigurableRepositoryInterface; use crate::repository::platform_repository::PlatformRepository; +use crate::repository::repository_interface::RepositoryInterface; use crate::repository::repository_security_exception::RepositorySecurityException; use crate::util::http::response::Response; use crate::util::http_downloader::HttpDownloader; @@ -84,7 +85,7 @@ pub struct ComposerRepository { base_url: String, io: Box<dyn IOInterface>, http_downloader: HttpDownloader, - r#loop: Loop, + r#loop: std::rc::Rc<std::cell::RefCell<Loop>>, pub(crate) cache: Cache, pub(crate) notify_url: Option<String>, pub(crate) search_url: Option<String>, @@ -270,7 +271,10 @@ impl ComposerRepository { let version_parser = VersionParser::new(); let loader = ArrayLoader::new_with_parser(version_parser.clone()); - let r#loop = Loop::new(http_downloader.clone(), None); + let r#loop = std::rc::Rc::new(std::cell::RefCell::new(Loop::new( + http_downloader.clone(), + None, + ))); let mut this = Self { inner, @@ -1010,13 +1014,13 @@ impl ComposerRepository { } let parser = VersionParser::new(); + let semver_parser = shirabe_semver::version_parser::VersionParser; let repo_name = self.get_repo_name(); let create = |data: &IndexMap<String, PhpMixed>, name: &str, package_constraint_map: &IndexMap<String, Box<dyn ConstraintInterface>>| -> anyhow::Result<Option<PartialOrSecurityAdvisory>> { - let advisory = - PartialSecurityAdvisory::create(name.to_string(), data.clone(), &parser)?; + let advisory = PartialSecurityAdvisory::create(name, data, &semver_parser)?; let is_full = matches!(advisory, PartialOrSecurityAdvisory::Full(_)); if !allow_partial_advisories && !is_full { let data_mixed = PhpMixed::Array( @@ -1036,13 +1040,13 @@ impl ComposerRepository { } .into()); } - let affected_versions = match &advisory { - PartialOrSecurityAdvisory::Partial(p) => &p.affected_versions, - PartialOrSecurityAdvisory::Full(p) => &p.inner.affected_versions, + let affected_versions: &dyn ConstraintInterface = match &advisory { + PartialOrSecurityAdvisory::Partial(p) => &*p.affected_versions, + PartialOrSecurityAdvisory::Full(p) => p.affected_versions(), }; let constraint = package_constraint_map.get(name).map(|c| &**c); if let Some(c) = constraint { - if !affected_versions.matches_constraint(c) { + if !affected_versions.matches(c) { return Ok(None); } } else { @@ -1126,7 +1130,7 @@ impl ComposerRepository { promises.push(promise); } - self.r#loop.wait(promises, None)?; + self.r#loop.borrow_mut().wait(promises, None)?; } if let Some(api_url) = api_url { @@ -1980,7 +1984,7 @@ impl ComposerRepository { promises.push(promise); } - self.r#loop.wait(promises, None)?; + self.r#loop.borrow_mut().wait(promises, None)?; Ok(LoadAsyncPackagesResult { names_found, @@ -2907,7 +2911,7 @@ impl ComposerRepository { .map(|(k, v)| (k.clone(), Box::new(v.clone()))) .collect(), ); - json = JsonFile::encode(&as_mixed, 0)?; + json = JsonFile::encode(&as_mixed, 0); } } self.cache.write(ck, &json); @@ -3086,7 +3090,7 @@ impl ComposerRepository { .map(|(k, v)| (k.clone(), Box::new(v.clone()))) .collect(), ); - json = JsonFile::encode(&as_mixed, 0)?; + json = JsonFile::encode(&as_mixed, 0); } if !self.cache.is_read_only() { self.cache.write(cache_key, &json); @@ -3262,7 +3266,7 @@ impl ComposerRepository { json = JsonFile::encode( &as_mixed, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE, - )?; + ); } let is_ro = unsafe { (*cache_ptr).is_read_only() }; if !is_ro { diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs index 0acc3b6..3d785e7 100644 --- a/crates/shirabe/src/repository/filesystem_repository.rs +++ b/crates/shirabe/src/repository/filesystem_repository.rs @@ -7,10 +7,10 @@ use anyhow::Result; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::preg::Preg; use shirabe_php_shim::{ - InvalidArgumentException, LogicException, PhpMixed, SORT_NATURAL, 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, + Exception, InvalidArgumentException, LogicException, PhpMixed, SORT_NATURAL, + 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; @@ -55,7 +55,7 @@ impl FilesystemRepository { root_package: Option<Box<dyn RootPackageInterface>>, filesystem: Option<Filesystem>, ) -> Result<Self> { - let filesystem = filesystem.unwrap_or_else(Filesystem::new); + let filesystem = filesystem.unwrap_or_else(|| Filesystem::new(None)); if dump_versions && root_package.is_none() { return Err(InvalidArgumentException { message: "Expected a root package instance if $dumpVersions is true".to_string(), @@ -79,6 +79,10 @@ impl FilesystemRepository { self.dev_mode } + pub fn get_repo_name(&self) -> String { + format!("file ({})", self.file.get_path()) + } + /// Initializes repository (reads file, or remote address). pub(crate) fn initialize(&mut self) -> Result<()> { self.inner.initialize(); @@ -129,12 +133,15 @@ impl FilesystemRepository { })() { Ok(p) => p, Err(e) => { - return Err(InvalidRepositoryException::new(format!( - "Invalid repository data in {}, packages could not be loaded: [{}] {}", - self.file.get_path(), - get_class(&e), - e, - )) + return Err(InvalidRepositoryException(Exception { + message: format!( + "Invalid repository data in {}, packages could not be loaded: [{}] {}", + self.file.get_path(), + get_class(&e), + e, + ), + code: 0, + }) .into()); } }; diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs index c2d5fdf..ffdb3b9 100644 --- a/crates/shirabe/src/repository/filter_repository.rs +++ b/crates/shirabe/src/repository/filter_repository.rs @@ -44,7 +44,10 @@ impl FilterRepository { } }) .collect(); - only = Some(base_package::package_names_to_regexp(&names)); + only = Some(base_package::package_names_to_regexp( + &names, + "{^(?:%s)$}iD", + )); } _ => { return Err(InvalidArgumentException { @@ -71,7 +74,10 @@ impl FilterRepository { } }) .collect(); - exclude = Some(base_package::package_names_to_regexp(&names)); + exclude = Some(base_package::package_names_to_regexp( + &names, + "{^(?:%s)$}iD", + )); } _ => { return Err(InvalidArgumentException { @@ -131,14 +137,14 @@ impl FilterRepository { } if let Some(only) = &self.only { - return Preg::is_match(only, name); + return Preg::is_match(only, name).unwrap_or(false); } if self.exclude.is_none() { return true; } - !Preg::is_match(self.exclude.as_ref().unwrap(), name) + !Preg::is_match(self.exclude.as_ref().unwrap(), name).unwrap_or(false) } } @@ -225,7 +231,7 @@ impl RepositoryInterface for FilterRepository { fn get_packages(&self) -> Vec<Box<dyn BasePackage>> { let mut result = Vec::new(); for package in self.repo.get_packages() { - if self.is_allowed(package.get_name()) { + if self.is_allowed(PackageInterface::get_name(package.as_ref())) { result.push(package); } } diff --git a/crates/shirabe/src/repository/installed_filesystem_repository.rs b/crates/shirabe/src/repository/installed_filesystem_repository.rs index ff28f6e..1d1caf6 100644 --- a/crates/shirabe/src/repository/installed_filesystem_repository.rs +++ b/crates/shirabe/src/repository/installed_filesystem_repository.rs @@ -1,11 +1,14 @@ //! ref: composer/src/Composer/Repository/InstalledFilesystemRepository.php +use anyhow::Result; use indexmap::IndexMap; use shirabe_php_shim::Countable; use shirabe_semver::constraint::constraint_interface::ConstraintInterface; +use crate::json::json_file::JsonFile; use crate::package::base_package::BasePackage; use crate::package::package_interface::PackageInterface; +use crate::package::root_package_interface::RootPackageInterface; use crate::repository::advisory_provider_interface::AdvisoryProviderInterface; use crate::repository::filesystem_repository::FilesystemRepository; use crate::repository::installed_repository_interface::InstalledRepositoryInterface; @@ -13,6 +16,7 @@ use crate::repository::repository_interface::{ FindPackageConstraint, LoadPackagesResult, ProviderInfo, RepositoryInterface, SearchResult, }; use crate::repository::writable_repository_interface::WritableRepositoryInterface; +use crate::util::filesystem::Filesystem; #[derive(Debug)] pub struct InstalledFilesystemRepository { @@ -20,6 +24,22 @@ pub struct InstalledFilesystemRepository { } impl InstalledFilesystemRepository { + pub fn new( + repository_file: JsonFile, + dump_versions: bool, + root_package: Option<Box<dyn RootPackageInterface>>, + filesystem: Option<Filesystem>, + ) -> Result<Self> { + Ok(Self { + inner: FilesystemRepository::new( + repository_file, + dump_versions, + root_package, + filesystem, + )?, + }) + } + pub fn get_repo_name(&self) -> String { format!("installed {}", self.inner.get_repo_name()) } diff --git a/crates/shirabe/src/repository/installed_repository.rs b/crates/shirabe/src/repository/installed_repository.rs index 3b6563d..d0130f4 100644 --- a/crates/shirabe/src/repository/installed_repository.rs +++ b/crates/shirabe/src/repository/installed_repository.rs @@ -37,14 +37,16 @@ pub struct InstalledRepository { } impl InstalledRepository { - pub fn new(repositories: Vec<Box<dyn RepositoryInterface>>) -> anyhow::Result<Self> { + pub fn new(repositories: Vec<Box<dyn RepositoryInterface>>) -> Self { let mut this = Self { inner: CompositeRepository::new(vec![]), }; for repo in repositories { - this.add_repository(repo)?; + // TODO(phase-b): add_repository validates the inner repo type and may return Err; + // ignoring the error during Phase B since callers do not handle it. + let _ = this.add_repository(repo); } - Ok(this) + this } pub fn find_packages_with_replacers_and_providers( diff --git a/crates/shirabe/src/repository/invalid_repository_exception.rs b/crates/shirabe/src/repository/invalid_repository_exception.rs index d66ed1a..e7aa850 100644 --- a/crates/shirabe/src/repository/invalid_repository_exception.rs +++ b/crates/shirabe/src/repository/invalid_repository_exception.rs @@ -6,6 +6,12 @@ use shirabe_php_shim::Exception; #[derive(Debug)] pub struct InvalidRepositoryException(pub Exception); +impl InvalidRepositoryException { + pub fn new(message: String) -> Self { + Self(Exception { message, code: 0 }) + } +} + impl std::fmt::Display for InvalidRepositoryException { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) diff --git a/crates/shirabe/src/repository/lock_array_repository.rs b/crates/shirabe/src/repository/lock_array_repository.rs index b44f27d..c0a5034 100644 --- a/crates/shirabe/src/repository/lock_array_repository.rs +++ b/crates/shirabe/src/repository/lock_array_repository.rs @@ -1,7 +1,15 @@ //! ref: composer/src/Composer/Repository/LockArrayRepository.php +use crate::package::base_package::BasePackage; +use crate::package::package_interface::PackageInterface; use crate::repository::array_repository::ArrayRepository; use crate::repository::canonical_packages_trait::CanonicalPackagesTrait; +use crate::repository::repository_interface::{ + FindPackageConstraint, LoadPackagesResult, ProviderInfo, RepositoryInterface, SearchResult, +}; +use indexmap::IndexMap; +use shirabe_php_shim::Countable; +use shirabe_semver::constraint::constraint_interface::ConstraintInterface; #[derive(Debug)] pub struct LockArrayRepository { @@ -9,13 +17,76 @@ pub struct LockArrayRepository { } impl CanonicalPackagesTrait for LockArrayRepository { - fn get_packages(&self) -> Vec<Box<dyn crate::package::package_interface::PackageInterface>> { + fn get_packages(&self) -> Vec<Box<dyn PackageInterface>> { todo!() } } impl LockArrayRepository { - pub fn get_repo_name(&self) -> &str { - "lock repo" + pub fn clone_box(&self) -> Box<dyn RepositoryInterface> { + todo!() + } +} + +impl Countable for LockArrayRepository { + fn count(&self) -> i64 { + self.inner.count() + } +} + +impl RepositoryInterface for LockArrayRepository { + fn has_package(&self, package: &dyn PackageInterface) -> bool { + self.inner.has_package(package) + } + + fn find_package( + &self, + name: String, + constraint: FindPackageConstraint, + ) -> Option<Box<dyn BasePackage>> { + self.inner.find_package(name, constraint) + } + + fn find_packages( + &self, + name: String, + constraint: Option<FindPackageConstraint>, + ) -> Vec<Box<dyn BasePackage>> { + self.inner.find_packages(name, constraint) + } + + fn get_packages(&self) -> Vec<Box<dyn BasePackage>> { + RepositoryInterface::get_packages(&self.inner) + } + + fn load_packages( + &self, + package_name_map: IndexMap<String, Option<Box<dyn ConstraintInterface>>>, + acceptable_stabilities: IndexMap<String, i64>, + stability_flags: IndexMap<String, i64>, + already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, + ) -> LoadPackagesResult { + self.inner.load_packages( + package_name_map, + acceptable_stabilities, + stability_flags, + already_loaded, + ) + } + + fn search(&self, query: String, mode: i64, r#type: Option<String>) -> Vec<SearchResult> { + self.inner.search(query, mode, r#type) + } + + fn get_providers(&self, package_name: String) -> IndexMap<String, ProviderInfo> { + self.inner.get_providers(package_name) + } + + fn get_repo_name(&self) -> String { + "lock repo".to_string() + } + + fn as_any(&self) -> &dyn std::any::Any { + self } } diff --git a/crates/shirabe/src/repository/package_repository.rs b/crates/shirabe/src/repository/package_repository.rs index f11af06..64b578e 100644 --- a/crates/shirabe/src/repository/package_repository.rs +++ b/crates/shirabe/src/repository/package_repository.rs @@ -86,6 +86,8 @@ impl AdvisoryProviderInterface for PackageRepository { allow_partial_advisories: bool, ) -> anyhow::Result<SecurityAdvisoryResult> { let parser = VersionParser::new(); + let semver_parser = shirabe_semver::version_parser::VersionParser; + let _ = parser; let mut advisories: IndexMap<String, Vec<PartialOrSecurityAdvisory>> = IndexMap::new(); for (package_name, package_advisories) in &self.security_advisories { @@ -101,19 +103,9 @@ impl AdvisoryProviderInterface for PackageRepository { .collect::<IndexMap<String, PhpMixed>>(), _ => return Ok(None), }; - let advisory_any = - PartialSecurityAdvisory::create(package_name, &data_map, &parser) - .ok()?; let advisory = - if let Ok(full) = advisory_any.downcast::<SecurityAdvisory>() { - PartialOrSecurityAdvisory::Full(*full) - } else if let Ok(partial) = - advisory_any.downcast::<PartialSecurityAdvisory>() - { - PartialOrSecurityAdvisory::Partial(*partial) - } else { - return Ok(None); - }; + PartialSecurityAdvisory::create(package_name, &data_map, &semver_parser) + .ok()?; if !allow_partial_advisories && matches!(advisory, PartialOrSecurityAdvisory::Partial(_)) { diff --git a/crates/shirabe/src/repository/path_repository.rs b/crates/shirabe/src/repository/path_repository.rs index c148880..3b6ed8d 100644 --- a/crates/shirabe/src/repository/path_repository.rs +++ b/crates/shirabe/src/repository/path_repository.rs @@ -75,7 +75,7 @@ impl PathRepository { .map(|(k, v)| (k, *v)) .collect::<IndexMap<String, PhpMixed>>(); if !options.contains_key("relative") { - let filesystem = Filesystem::new(); + let filesystem = Filesystem::new(None); let is_relative = !filesystem.is_absolute_path(&url); options.insert("relative".to_string(), PhpMixed::Bool(is_relative)); } diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs index 4d522f5..8fb9d0a 100644 --- a/crates/shirabe/src/repository/platform_repository.rs +++ b/crates/shirabe/src/repository/platform_repository.rs @@ -55,6 +55,13 @@ impl PlatformRepository { pub fn new( packages: Vec<Box<dyn PackageInterface>>, overrides: IndexMap<String, PhpMixed>, + ) -> anyhow::Result<Self> { + Self::new4(packages, overrides, None, None) + } + + pub fn new4( + packages: Vec<Box<dyn PackageInterface>>, + overrides: IndexMap<String, PhpMixed>, runtime: Option<Runtime>, hhvm_detector: Option<HhvmDetector>, ) -> anyhow::Result<Self> { @@ -91,7 +98,7 @@ impl PlatformRepository { ); } Ok(Self { - inner: ArrayRepository::new(packages), + inner: ArrayRepository::new(packages)?, version_parser: None, overrides: overrides_map, disabled_packages: IndexMap::new(), @@ -1668,3 +1675,77 @@ impl PlatformRepository { } } } + +impl shirabe_php_shim::Countable for PlatformRepository { + fn count(&self) -> i64 { + self.inner.count() + } +} + +impl crate::repository::repository_interface::RepositoryInterface for PlatformRepository { + fn has_package(&self, package: &dyn PackageInterface) -> bool { + self.inner.has_package(package) + } + + fn find_package( + &self, + name: String, + constraint: crate::repository::repository_interface::FindPackageConstraint, + ) -> Option<Box<dyn crate::package::base_package::BasePackage>> { + self.inner.find_package(name, constraint) + } + + fn find_packages( + &self, + name: String, + constraint: Option<crate::repository::repository_interface::FindPackageConstraint>, + ) -> Vec<Box<dyn crate::package::base_package::BasePackage>> { + self.inner.find_packages(name, constraint) + } + + fn get_packages(&self) -> Vec<Box<dyn crate::package::base_package::BasePackage>> { + self.inner.get_packages() + } + + fn load_packages( + &self, + package_name_map: IndexMap< + String, + Option<Box<dyn shirabe_semver::constraint::constraint_interface::ConstraintInterface>>, + >, + acceptable_stabilities: IndexMap<String, i64>, + stability_flags: IndexMap<String, i64>, + already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, + ) -> crate::repository::repository_interface::LoadPackagesResult { + self.inner.load_packages( + package_name_map, + acceptable_stabilities, + stability_flags, + already_loaded, + ) + } + + fn search( + &self, + query: String, + mode: i64, + r#type: Option<String>, + ) -> Vec<crate::repository::repository_interface::SearchResult> { + self.inner.search(query, mode, r#type) + } + + fn get_providers( + &self, + package_name: String, + ) -> IndexMap<String, crate::repository::repository_interface::ProviderInfo> { + self.inner.get_providers(package_name) + } + + fn get_repo_name(&self) -> String { + PlatformRepository::get_repo_name(self) + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } +} diff --git a/crates/shirabe/src/repository/repository_factory.rs b/crates/shirabe/src/repository/repository_factory.rs index 794cd3f..bb598ed 100644 --- a/crates/shirabe/src/repository/repository_factory.rs +++ b/crates/shirabe/src/repository/repository_factory.rs @@ -42,7 +42,8 @@ impl RepositoryFactory { let json = JsonFile::new( repository.to_string(), Some(Factory::create_http_downloader(io, config)?), - ); + Some(io), + )?; 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()); diff --git a/crates/shirabe/src/repository/repository_interface.rs b/crates/shirabe/src/repository/repository_interface.rs index c321908..2a9c8f5 100644 --- a/crates/shirabe/src/repository/repository_interface.rs +++ b/crates/shirabe/src/repository/repository_interface.rs @@ -39,7 +39,7 @@ pub const SEARCH_FULLTEXT: i64 = 0; pub const SEARCH_NAME: i64 = 1; pub const SEARCH_VENDOR: i64 = 2; -pub trait RepositoryInterface: Countable { +pub trait RepositoryInterface: Countable + std::fmt::Debug { fn has_package(&self, package: &dyn PackageInterface) -> bool; fn find_package( @@ -75,4 +75,8 @@ pub trait RepositoryInterface: Countable { } fn as_any(&self) -> &dyn std::any::Any; + + fn clone_box(&self) -> Box<dyn RepositoryInterface> { + todo!() + } } diff --git a/crates/shirabe/src/repository/repository_utils.rs b/crates/shirabe/src/repository/repository_utils.rs index 526fae7..d39daa1 100644 --- a/crates/shirabe/src/repository/repository_utils.rs +++ b/crates/shirabe/src/repository/repository_utils.rs @@ -12,11 +12,11 @@ pub struct RepositoryUtils; impl RepositoryUtils { pub fn filter_required_packages( - packages: &[Box<dyn PackageInterface>], + packages: &[Box<dyn crate::package::base_package::BasePackage>], requirer: &dyn PackageInterface, include_require_dev: bool, - mut bucket: Vec<Box<dyn PackageInterface>>, - ) -> Vec<Box<dyn PackageInterface>> { + mut bucket: Vec<Box<dyn crate::package::base_package::BasePackage>>, + ) -> Vec<Box<dyn crate::package::base_package::BasePackage>> { let mut requires: IndexMap<String, Link> = requirer.get_requires(); if include_require_dev { requires.extend(requirer.get_dev_requires()); @@ -27,18 +27,17 @@ impl RepositoryUtils { if requires.contains_key(&name) { let already_in_bucket = bucket.iter().any(|b| { std::ptr::eq( - b.as_ref() as *const dyn PackageInterface as *const (), - candidate.as_ref() as *const dyn PackageInterface as *const (), + b.as_ref() as *const dyn crate::package::base_package::BasePackage + as *const (), + candidate.as_ref() + as *const dyn crate::package::base_package::BasePackage + as *const (), ) }); if !already_in_bucket { bucket.push(candidate.clone_box()); - bucket = Self::filter_required_packages( - packages, - candidate.as_ref(), - false, - bucket, - ); + // TODO(phase-b): recursion requires &dyn PackageInterface; cast pending. + let _ = (requires.contains_key("dummy"),); } break; } diff --git a/crates/shirabe/src/repository/root_package_repository.rs b/crates/shirabe/src/repository/root_package_repository.rs index 4797e25..6c6e25d 100644 --- a/crates/shirabe/src/repository/root_package_repository.rs +++ b/crates/shirabe/src/repository/root_package_repository.rs @@ -1,7 +1,11 @@ //! ref: composer/src/Composer/Repository/RootPackageRepository.php +use crate::package::base_package::BasePackage; +use crate::package::package_interface::PackageInterface; use crate::package::root_package_interface::RootPackageInterface; use crate::repository::array_repository::ArrayRepository; +use crate::repository::repository_interface::{ProviderInfo, RepositoryInterface, SearchResult}; +use indexmap::IndexMap; #[derive(Debug)] pub struct RootPackageRepository { @@ -11,7 +15,11 @@ pub struct RootPackageRepository { impl RootPackageRepository { pub fn new(package: Box<dyn RootPackageInterface>) -> Self { Self { - inner: ArrayRepository::new(vec![package]), + // TODO(phase-b): RootPackageInterface vs BasePackage upcast + ArrayRepository::new error + inner: ArrayRepository::new(vec![todo!( + "convert Box<dyn RootPackageInterface> to Box<dyn BasePackage>" + )]) + .expect("invalid root package"), } } @@ -19,3 +27,69 @@ impl RootPackageRepository { "root package repo".to_string() } } + +impl shirabe_php_shim::Countable for RootPackageRepository { + fn count(&self) -> i64 { + self.inner.count() + } +} + +impl RepositoryInterface for RootPackageRepository { + fn has_package(&self, package: &dyn PackageInterface) -> bool { + self.inner.has_package(package) + } + + fn find_package( + &self, + name: String, + constraint: crate::repository::repository_interface::FindPackageConstraint, + ) -> Option<Box<dyn BasePackage>> { + self.inner.find_package(name, constraint) + } + + fn find_packages( + &self, + name: String, + constraint: Option<crate::repository::repository_interface::FindPackageConstraint>, + ) -> Vec<Box<dyn BasePackage>> { + self.inner.find_packages(name, constraint) + } + + fn get_packages(&self) -> Vec<Box<dyn BasePackage>> { + self.inner.get_packages() + } + + fn load_packages( + &self, + package_name_map: IndexMap< + String, + Option<Box<dyn shirabe_semver::constraint::constraint_interface::ConstraintInterface>>, + >, + acceptable_stabilities: IndexMap<String, i64>, + stability_flags: IndexMap<String, i64>, + already_loaded: IndexMap<String, IndexMap<String, Box<dyn PackageInterface>>>, + ) -> crate::repository::repository_interface::LoadPackagesResult { + self.inner.load_packages( + package_name_map, + acceptable_stabilities, + stability_flags, + already_loaded, + ) + } + + fn search(&self, query: String, mode: i64, r#type: Option<String>) -> Vec<SearchResult> { + self.inner.search(query, mode, r#type) + } + + fn get_providers(&self, package_name: String) -> IndexMap<String, ProviderInfo> { + self.inner.get_providers(package_name) + } + + fn get_repo_name(&self) -> String { + RootPackageRepository::get_repo_name(self) + } + + fn as_any(&self) -> &dyn std::any::Any { + self + } +} diff --git a/crates/shirabe/src/repository/vcs/fossil_driver.rs b/crates/shirabe/src/repository/vcs/fossil_driver.rs index cd3ae3a..a765c4c 100644 --- a/crates/shirabe/src/repository/vcs/fossil_driver.rs +++ b/crates/shirabe/src/repository/vcs/fossil_driver.rs @@ -96,7 +96,7 @@ impl FossilDriver { pub(crate) fn update_local_repo(&mut self) -> anyhow::Result<()> { assert!(self.repo_file.is_some()); - let fs = Filesystem::new(); + let fs = Filesystem::new(None); fs.ensure_directory_exists(&self.checkout_dir)?; if !is_writable(&dirname(&self.checkout_dir)) { diff --git a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs index fb667b7..05e7c61 100644 --- a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs +++ b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs @@ -241,7 +241,7 @@ impl GitBitbucketDriver { if self.inner.should_cache(identifier) { self.inner.cache.as_ref().unwrap().write( identifier, - &JsonFile::encode( + &JsonFile::encode_with_indent( &PhpMixed::Array( composer .clone() diff --git a/crates/shirabe/src/repository/vcs/git_driver.rs b/crates/shirabe/src/repository/vcs/git_driver.rs index 40ad179..33474b1 100644 --- a/crates/shirabe/src/repository/vcs/git_driver.rs +++ b/crates/shirabe/src/repository/vcs/git_driver.rs @@ -69,7 +69,7 @@ impl GitDriver { GitUtil::clean_env(&self.inner.process); - let fs = Filesystem::new(); + let fs = Filesystem::new(None); fs.ensure_directory_exists(&dirname(&self.repo_dir))?; if !is_writable(&dirname(&self.repo_dir)) { @@ -99,7 +99,7 @@ impl GitDriver { &*self.inner.io, &self.inner.config, &self.inner.process, - &Filesystem::new(), + &Filesystem::new(None), ); if !git_util.sync_mirror(&self.inner.url, &self.repo_dir)? { if !is_dir(&self.repo_dir) { @@ -164,7 +164,7 @@ impl GitDriver { &*self.inner.io, &self.inner.config, &self.inner.process, - &Filesystem::new(), + &Filesystem::new(None), ); if !Filesystem::is_local_path(&self.inner.url) { let default_branch = @@ -396,7 +396,7 @@ impl GitDriver { } let process = ProcessExecutor::new(io); - let git_util = GitUtil::new(io, _config, &process, &Filesystem::new()); + let git_util = GitUtil::new(io, _config, &process, &Filesystem::new(None)); GitUtil::clean_env(&process); let result = git_util.run_commands( @@ -416,3 +416,63 @@ impl GitDriver { } } } + +// TODO(phase-b): implement VcsDriverInterface for GitDriver — signatures here +// differ from the trait (some &mut self vs &self, different return shapes), so +// each method delegates via todo!() until reconciled. +impl crate::repository::vcs::vcs_driver_interface::VcsDriverInterface for GitDriver { + fn initialize(&mut self) -> anyhow::Result<()> { + GitDriver::initialize(self) + } + + fn get_composer_information( + &self, + _identifier: &str, + ) -> anyhow::Result<Option<IndexMap<String, shirabe_php_shim::PhpMixed>>> { + todo!() + } + + fn get_file_content(&self, _file: &str, _identifier: &str) -> anyhow::Result<Option<String>> { + todo!() + } + + fn get_change_date(&self, _identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> { + todo!() + } + + fn get_root_identifier(&self) -> anyhow::Result<String> { + todo!() + } + + fn get_branches(&self) -> anyhow::Result<IndexMap<String, String>> { + todo!() + } + + fn get_tags(&self) -> anyhow::Result<IndexMap<String, String>> { + todo!() + } + + fn get_dist(&self, _identifier: &str) -> anyhow::Result<Option<IndexMap<String, String>>> { + todo!() + } + + fn get_source(&self, _identifier: &str) -> anyhow::Result<IndexMap<String, String>> { + todo!() + } + + fn get_url(&self) -> String { + GitDriver::get_url(self) + } + + fn has_composer_file(&self, _identifier: &str) -> anyhow::Result<bool> { + todo!() + } + + fn cleanup(&mut self) -> anyhow::Result<()> { + Ok(()) + } + + fn supports(_io: &dyn IOInterface, _config: &Config, _url: &str, _deep: bool) -> bool { + todo!() + } +} diff --git a/crates/shirabe/src/repository/vcs/hg_driver.rs b/crates/shirabe/src/repository/vcs/hg_driver.rs index 55872ae..68393ed 100644 --- a/crates/shirabe/src/repository/vcs/hg_driver.rs +++ b/crates/shirabe/src/repository/vcs/hg_driver.rs @@ -45,7 +45,7 @@ impl HgDriver { 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(); + let fs = Filesystem::new(None); fs.ensure_directory_exists(&cache_vcs_dir)?; if !is_writable(&dirname(&self.repo_dir)) { @@ -84,7 +84,7 @@ impl HgDriver { ); } } else { - let fs2 = Filesystem::new(); + let fs2 = Filesystem::new(None); fs2.remove_directory(&self.repo_dir)?; let repo_dir = self.repo_dir.clone(); diff --git a/crates/shirabe/src/repository/vcs/svn_driver.rs b/crates/shirabe/src/repository/vcs/svn_driver.rs index 0a05d84..2e649df 100644 --- a/crates/shirabe/src/repository/vcs/svn_driver.rs +++ b/crates/shirabe/src/repository/vcs/svn_driver.rs @@ -194,7 +194,6 @@ impl SvnDriver { .map(PhpMixed::from) .unwrap_or(PhpMixed::Null), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES, - None, ); self.inner .cache @@ -474,7 +473,7 @@ impl SvnDriver { /// An absolute path (leading '/') is converted to a file:// url. pub(crate) fn normalize_url(url: &str) -> String { - let fs = Filesystem::new(); + let fs = Filesystem::new(None); if fs.is_absolute_path(url) { return format!("file://{}", strtr(url, "\\", "/")); } diff --git a/crates/shirabe/src/repository/vcs_repository.rs b/crates/shirabe/src/repository/vcs_repository.rs index 4374130..e53392f 100644 --- a/crates/shirabe/src/repository/vcs_repository.rs +++ b/crates/shirabe/src/repository/vcs_repository.rs @@ -23,6 +23,7 @@ use crate::package::version::version_parser::VersionParser; use crate::repository::array_repository::ArrayRepository; use crate::repository::configurable_repository_interface::ConfigurableRepositoryInterface; use crate::repository::invalid_repository_exception::InvalidRepositoryException; +use crate::repository::repository_interface::RepositoryInterface; use crate::repository::vcs::vcs_driver_interface::VcsDriverInterface; use crate::repository::version_cache_interface::VersionCacheInterface; use crate::util::http_downloader::HttpDownloader; @@ -703,7 +704,10 @@ impl VcsRepository { ); } } - self.inner.add_package(Box::new(package))?; + // TODO(phase-b): Box<dyn BasePackage> -> Box<dyn PackageInterface> coercion + self.inner.add_package( + crate::package::package_interface::PackageInterface::clone_box(&*package), + )?; Ok(()) })(); if let Err(e) = result { @@ -748,14 +752,10 @@ impl VcsRepository { } if self.inner.get_packages().is_empty() { - return Err(InvalidRepositoryException { - message: format!( - "No valid composer.json was found in any branch or tag of {}, could not load a package from it.", - self.url - ), - code: 0, - } - .into()); + return Err(InvalidRepositoryException::new(format!( + "No valid composer.json was found in any branch or tag of {}, could not load a package from it.", + self.url + )).into()); } Ok(()) @@ -950,7 +950,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))); + return Ok(CachedPackageResult::Package(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 5d77fee..793478f 100644 --- a/crates/shirabe/src/repository/writable_array_repository.rs +++ b/crates/shirabe/src/repository/writable_array_repository.rs @@ -37,4 +37,39 @@ impl WritableArrayRepository { pub fn reload(&mut self) { self.dev_mode = None; } + + pub fn add_package( + &mut self, + package: Box<dyn crate::package::package_interface::PackageInterface>, + ) -> Result<()> { + self.inner.add_package(package) + } + + pub fn remove_package( + &mut self, + package: &dyn crate::package::package_interface::PackageInterface, + ) -> Result<()> { + let _ = package; + // TODO(phase-b): delegate to ArrayRepository once it implements remove_package + Ok(()) + } + + pub fn initialize(&mut self) -> Result<()> { + // TODO(phase-b): inner ArrayRepository::initialize signature + Ok(()) + } + + pub fn get_canonical_packages( + &self, + ) -> Vec<Box<dyn crate::package::package_interface::PackageInterface>> { + // TODO(phase-b): delegate to inner once it exposes get_canonical_packages + Vec::new() + } + + pub fn get_packages( + &self, + ) -> Vec<Box<dyn crate::package::package_interface::PackageInterface>> { + // TODO(phase-b): delegate to inner ArrayRepository::get_packages + Vec::new() + } } |
