aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/repository
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/repository')
-rw-r--r--crates/shirabe/src/repository/array_repository.rs27
-rw-r--r--crates/shirabe/src/repository/composer_repository.rs30
-rw-r--r--crates/shirabe/src/repository/filesystem_repository.rs29
-rw-r--r--crates/shirabe/src/repository/filter_repository.rs16
-rw-r--r--crates/shirabe/src/repository/installed_filesystem_repository.rs20
-rw-r--r--crates/shirabe/src/repository/installed_repository.rs8
-rw-r--r--crates/shirabe/src/repository/invalid_repository_exception.rs6
-rw-r--r--crates/shirabe/src/repository/lock_array_repository.rs77
-rw-r--r--crates/shirabe/src/repository/package_repository.rs16
-rw-r--r--crates/shirabe/src/repository/path_repository.rs2
-rw-r--r--crates/shirabe/src/repository/platform_repository.rs83
-rw-r--r--crates/shirabe/src/repository/repository_factory.rs3
-rw-r--r--crates/shirabe/src/repository/repository_interface.rs6
-rw-r--r--crates/shirabe/src/repository/repository_utils.rs21
-rw-r--r--crates/shirabe/src/repository/root_package_repository.rs76
-rw-r--r--crates/shirabe/src/repository/vcs/fossil_driver.rs2
-rw-r--r--crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs2
-rw-r--r--crates/shirabe/src/repository/vcs/git_driver.rs68
-rw-r--r--crates/shirabe/src/repository/vcs/hg_driver.rs4
-rw-r--r--crates/shirabe/src/repository/vcs/svn_driver.rs3
-rw-r--r--crates/shirabe/src/repository/vcs_repository.rs20
-rw-r--r--crates/shirabe/src/repository/writable_array_repository.rs35
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()
+ }
}