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/advisory_provider_interface.rs20
-rw-r--r--crates/shirabe/src/repository/composer_repository.rs20
-rw-r--r--crates/shirabe/src/repository/filesystem_repository.rs1
-rw-r--r--crates/shirabe/src/repository/handle.rs64
-rw-r--r--crates/shirabe/src/repository/package_repository.rs14
-rw-r--r--crates/shirabe/src/repository/platform_repository.rs5
-rw-r--r--crates/shirabe/src/repository/repository_set.rs26
-rw-r--r--crates/shirabe/src/repository/vcs/svn_driver.rs20
8 files changed, 110 insertions, 60 deletions
diff --git a/crates/shirabe/src/repository/advisory_provider_interface.rs b/crates/shirabe/src/repository/advisory_provider_interface.rs
index 0de9c42..4b93eca 100644
--- a/crates/shirabe/src/repository/advisory_provider_interface.rs
+++ b/crates/shirabe/src/repository/advisory_provider_interface.rs
@@ -1,29 +1,13 @@
//! ref: composer/src/Composer/Repository/AdvisoryProviderInterface.php
-use crate::advisory::PartialSecurityAdvisory;
-use crate::advisory::SecurityAdvisory;
+use crate::advisory::{PartialOrFullSecurityAdvisory, PartialSecurityAdvisory, SecurityAdvisory};
use indexmap::IndexMap;
use shirabe_semver::constraint::AnyConstraint;
#[derive(Debug)]
-pub enum PartialOrSecurityAdvisory {
- Partial(PartialSecurityAdvisory),
- Full(SecurityAdvisory),
-}
-
-impl PartialOrSecurityAdvisory {
- pub fn advisory_id(&self) -> &str {
- match self {
- PartialOrSecurityAdvisory::Partial(p) => &p.advisory_id,
- PartialOrSecurityAdvisory::Full(s) => s.advisory_id(),
- }
- }
-}
-
-#[derive(Debug)]
pub struct SecurityAdvisoryResult {
pub names_found: Vec<String>,
- pub advisories: IndexMap<String, Vec<PartialOrSecurityAdvisory>>,
+ pub advisories: IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>,
}
pub trait AdvisoryProviderInterface {
diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs
index d39fd82..1f2fcbf 100644
--- a/crates/shirabe/src/repository/composer_repository.rs
+++ b/crates/shirabe/src/repository/composer_repository.rs
@@ -15,7 +15,7 @@ use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
use shirabe_semver::constraint::SimpleConstraint;
-use crate::advisory::PartialSecurityAdvisory;
+use crate::advisory::{PartialOrFullSecurityAdvisory, PartialSecurityAdvisory};
use crate::cache::Cache;
use crate::config::Config;
use crate::downloader::TransportException;
@@ -41,7 +41,7 @@ use crate::repository::RepositoryInterface;
use crate::repository::RepositoryInterfaceHandle;
use crate::repository::RepositoryInterfaceWeakHandle;
use crate::repository::RepositorySecurityException;
-use crate::repository::{PartialOrSecurityAdvisory, SecurityAdvisoryResult};
+use crate::repository::SecurityAdvisoryResult;
use crate::repository::{SEARCH_FULLTEXT, SEARCH_VENDOR};
use crate::util::HttpDownloader;
use crate::util::Url;
@@ -1038,7 +1038,7 @@ impl ComposerRepository {
});
}
- let mut advisories: IndexMap<String, Vec<PartialOrSecurityAdvisory>> = IndexMap::new();
+ let mut advisories: IndexMap<String, Vec<PartialOrFullSecurityAdvisory>> = IndexMap::new();
let mut names_found: IndexMap<String, bool> = IndexMap::new();
let api_url = self
@@ -1062,9 +1062,9 @@ impl ComposerRepository {
let create = |data: &IndexMap<String, PhpMixed>,
name: &str,
package_constraint_map: &IndexMap<String, AnyConstraint>|
- -> anyhow::Result<Option<PartialOrSecurityAdvisory>> {
+ -> anyhow::Result<Option<PartialOrFullSecurityAdvisory>> {
let advisory = PartialSecurityAdvisory::create(name, data, &semver_parser)?;
- let is_full = matches!(advisory, PartialOrSecurityAdvisory::Full(_));
+ let is_full = matches!(advisory, PartialOrFullSecurityAdvisory::Full(_));
if !allow_partial_advisories && !is_full {
let data_mixed = PhpMixed::Array(
data.iter()
@@ -1084,8 +1084,8 @@ impl ComposerRepository {
.into());
}
let affected_versions: &AnyConstraint = match &advisory {
- PartialOrSecurityAdvisory::Partial(p) => &p.affected_versions,
- PartialOrSecurityAdvisory::Full(p) => p.affected_versions(),
+ PartialOrFullSecurityAdvisory::Partial(p) => &p.affected_versions,
+ PartialOrFullSecurityAdvisory::Full(p) => p.affected_versions(),
};
let constraint = package_constraint_map.get(name);
if let Some(c) = constraint {
@@ -1138,7 +1138,7 @@ impl ComposerRepository {
names_found.insert(name.clone(), true);
if !sec_advs_arr.is_empty() {
- let mut entries: Vec<PartialOrSecurityAdvisory> = Vec::new();
+ let mut entries: Vec<PartialOrFullSecurityAdvisory> = Vec::new();
for (_k, data_mixed) in sec_advs_arr.iter() {
if let Some(data) = data_mixed.as_array() {
let data_map: IndexMap<String, PhpMixed> = data
@@ -1229,7 +1229,7 @@ impl ComposerRepository {
None => continue,
};
if !list.is_empty() {
- let mut entries: Vec<PartialOrSecurityAdvisory> = Vec::new();
+ let mut entries: Vec<PartialOrFullSecurityAdvisory> = Vec::new();
for data_mixed in list.iter() {
if let Some(data) = data_mixed.as_array() {
let data_map: IndexMap<String, PhpMixed> = data
@@ -1249,7 +1249,7 @@ impl ComposerRepository {
}
}
- let advisories_filtered: IndexMap<String, Vec<PartialOrSecurityAdvisory>> = advisories
+ let advisories_filtered: IndexMap<String, Vec<PartialOrFullSecurityAdvisory>> = advisories
.into_iter()
.filter(|(_, adv)| !adv.is_empty())
.collect();
diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs
index a721b4f..db9a8c6 100644
--- a/crates/shirabe/src/repository/filesystem_repository.rs
+++ b/crates/shirabe/src/repository/filesystem_repository.rs
@@ -94,7 +94,6 @@ impl FilesystemRepository {
return Ok(());
}
- // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
let packages: PhpMixed = match (|| -> Result<PhpMixed> {
let data = self.file.read()?;
let packages_value = if let PhpMixed::Array(ref m) = data {
diff --git a/crates/shirabe/src/repository/handle.rs b/crates/shirabe/src/repository/handle.rs
index a4225f7..38a4f28 100644
--- a/crates/shirabe/src/repository/handle.rs
+++ b/crates/shirabe/src/repository/handle.rs
@@ -11,7 +11,8 @@ use crate::package::BasePackageHandle;
use crate::package::PackageInterfaceHandle;
use crate::repository::{
FindPackageConstraint, InstalledRepositoryInterface, LoadPackagesResult, LockArrayRepository,
- ProviderInfo, RepositoryInterface, SearchResult, WritableRepositoryInterface,
+ PlatformRepository, ProviderInfo, RepositoryInterface, SearchResult,
+ WritableRepositoryInterface,
};
/// Shared reference to a repository. Corresponds to PHP `RepositoryInterface`.
@@ -173,8 +174,7 @@ impl std::hash::Hash for RepositoryInterfaceHandle {
}
}
-/// Typed shared handle over `LockArrayRepository`. Preserves the PHP `?LockArrayRepository`
-/// typing where a `RepositoryInterfaceHandle` would be too wide.
+/// Typed shared handle over `LockArrayRepository`.
#[derive(Debug, Clone)]
pub struct LockArrayRepositoryHandle(Rc<RefCell<LockArrayRepository>>);
@@ -231,3 +231,61 @@ impl std::hash::Hash for LockArrayRepositoryHandle {
self.ptr_id().hash(state);
}
}
+
+/// Typed shared handle over `PlatformRepository`.
+#[derive(Debug, Clone)]
+pub struct PlatformRepositoryHandle(Rc<RefCell<PlatformRepository>>);
+
+impl PlatformRepositoryHandle {
+ pub fn new(repository: PlatformRepository) -> Self {
+ let rc: Rc<RefCell<PlatformRepository>> = Rc::new(RefCell::new(repository));
+ let rc_dyn: Rc<RefCell<dyn RepositoryInterface>> = rc.clone();
+ rc.borrow().set_self_handle(Rc::downgrade(&rc_dyn));
+ Self(rc)
+ }
+
+ pub fn from_rc(rc: Rc<RefCell<PlatformRepository>>) -> Self {
+ Self(rc)
+ }
+
+ pub fn as_rc(&self) -> &Rc<RefCell<PlatformRepository>> {
+ &self.0
+ }
+
+ pub fn borrow(&self) -> Ref<'_, PlatformRepository> {
+ self.0.borrow()
+ }
+
+ pub fn borrow_mut(&self) -> RefMut<'_, PlatformRepository> {
+ self.0.borrow_mut()
+ }
+
+ pub fn ptr_eq(&self, other: &Self) -> bool {
+ Rc::ptr_eq(&self.0, &other.0)
+ }
+
+ pub fn ptr_id(&self) -> usize {
+ Rc::as_ptr(&self.0) as *const () as usize
+ }
+}
+
+impl From<PlatformRepositoryHandle> for RepositoryInterfaceHandle {
+ fn from(h: PlatformRepositoryHandle) -> Self {
+ let rc: Rc<RefCell<dyn RepositoryInterface>> = h.0;
+ RepositoryInterfaceHandle::from_rc(rc)
+ }
+}
+
+impl PartialEq for PlatformRepositoryHandle {
+ fn eq(&self, other: &Self) -> bool {
+ Rc::ptr_eq(&self.0, &other.0)
+ }
+}
+
+impl Eq for PlatformRepositoryHandle {}
+
+impl std::hash::Hash for PlatformRepositoryHandle {
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+ self.ptr_id().hash(state);
+ }
+}
diff --git a/crates/shirabe/src/repository/package_repository.rs b/crates/shirabe/src/repository/package_repository.rs
index b88de78..b5280a8 100644
--- a/crates/shirabe/src/repository/package_repository.rs
+++ b/crates/shirabe/src/repository/package_repository.rs
@@ -1,15 +1,13 @@
//! ref: composer/src/Composer/Repository/PackageRepository.php
-use crate::advisory::PartialSecurityAdvisory;
use crate::advisory::SecurityAdvisory;
+use crate::advisory::{PartialOrFullSecurityAdvisory, PartialSecurityAdvisory};
use crate::package::loader::ArrayLoader;
use crate::package::loader::ValidatingArrayLoader;
use crate::package::version::VersionParser;
use crate::repository::ArrayRepository;
use crate::repository::InvalidRepositoryException;
-use crate::repository::{
- AdvisoryProviderInterface, PartialOrSecurityAdvisory, SecurityAdvisoryResult,
-};
+use crate::repository::{AdvisoryProviderInterface, SecurityAdvisoryResult};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
use shirabe_php_shim::{Exception, PhpMixed, RuntimeException, var_export};
@@ -97,7 +95,7 @@ impl AdvisoryProviderInterface for PackageRepository {
let semver_parser = shirabe_semver::version_parser::VersionParser;
let _ = parser;
- let mut advisories: IndexMap<String, Vec<PartialOrSecurityAdvisory>> = IndexMap::new();
+ let mut advisories: IndexMap<String, Vec<PartialOrFullSecurityAdvisory>> = IndexMap::new();
for (package_name, package_advisories) in &self.security_advisories {
if !package_constraint_map.contains_key(package_name.as_str()) {
continue;
@@ -106,7 +104,7 @@ impl AdvisoryProviderInterface for PackageRepository {
PhpMixed::List(list) => list,
_ => continue,
};
- let mut items: Vec<PartialOrSecurityAdvisory> = Vec::new();
+ let mut items: Vec<PartialOrFullSecurityAdvisory> = Vec::new();
for data in list {
let data_map: IndexMap<String, PhpMixed> = match data.as_ref() {
PhpMixed::Array(m) => m.iter().map(|(k, v)| (k.clone(), *v.clone())).collect(),
@@ -121,7 +119,7 @@ impl AdvisoryProviderInterface for PackageRepository {
Err(_) => continue,
};
if !allow_partial_advisories
- && matches!(advisory, PartialOrSecurityAdvisory::Partial(_))
+ && matches!(advisory, PartialOrFullSecurityAdvisory::Partial(_))
{
return Err(anyhow::anyhow!(RuntimeException {
message: format!(
@@ -141,7 +139,7 @@ impl AdvisoryProviderInterface for PackageRepository {
}
let names_found: Vec<String> = advisories.keys().cloned().collect();
- let advisories: IndexMap<String, Vec<PartialOrSecurityAdvisory>> = advisories
+ let advisories: IndexMap<String, Vec<PartialOrFullSecurityAdvisory>> = advisories
.into_iter()
.filter(|(_, adv)| !adv.is_empty())
.collect();
diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs
index b8c4f52..0d10e3a 100644
--- a/crates/shirabe/src/repository/platform_repository.rs
+++ b/crates/shirabe/src/repository/platform_repository.rs
@@ -1903,9 +1903,8 @@ impl PlatformRepository {
// ---- helpers ----
- fn is_complete_package(_package: PackageInterfaceHandle) -> bool {
- // TODO(phase-b): use Any-style downcasting once the trait carries it.
- true
+ fn is_complete_package(package: PackageInterfaceHandle) -> bool {
+ package.as_complete().is_some()
}
fn resource_bundle_get(_value: &PhpMixed, _key: &str) -> PhpMixed {
diff --git a/crates/shirabe/src/repository/repository_set.rs b/crates/shirabe/src/repository/repository_set.rs
index 843af80..077c3f6 100644
--- a/crates/shirabe/src/repository/repository_set.rs
+++ b/crates/shirabe/src/repository/repository_set.rs
@@ -13,8 +13,7 @@ use shirabe_semver::constraint::MatchAllConstraint;
use shirabe_semver::constraint::MultiConstraint;
use shirabe_semver::constraint::SimpleConstraint;
-use crate::advisory::PartialSecurityAdvisory;
-use crate::advisory::SecurityAdvisory;
+use crate::advisory::{PartialOrFullSecurityAdvisory, PartialSecurityAdvisory, SecurityAdvisory};
use crate::dependency_resolver::Pool;
use crate::dependency_resolver::PoolBuilder;
use crate::dependency_resolver::PoolOptimizer;
@@ -29,12 +28,12 @@ use crate::package::BasePackageHandle;
use crate::package::CompleteAliasPackageHandle;
use crate::package::PackageInterfaceHandle;
use crate::package::version::StabilityFilter;
+use crate::repository::AdvisoryProviderInterface;
use crate::repository::CompositeRepository;
use crate::repository::InstalledRepository;
use crate::repository::InstalledRepositoryInterface;
use crate::repository::LockArrayRepositoryHandle;
use crate::repository::PlatformRepository;
-use crate::repository::{AdvisoryProviderInterface, PartialOrSecurityAdvisory};
use crate::repository::{FindPackageConstraint, RepositoryInterface, RepositoryInterfaceHandle};
#[derive(Debug, Clone)]
@@ -372,10 +371,9 @@ impl RepositorySet {
allow_partial_advisories: bool,
ignore_unreachable: bool,
unreachable_repos: &mut Vec<String>,
- ) -> Result<IndexMap<String, Vec<PartialOrSecurityAdvisory>>> {
- let mut repo_advisories: Vec<IndexMap<String, Vec<PartialOrSecurityAdvisory>>> = vec![];
+ ) -> Result<IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>> {
+ let mut repo_advisories: Vec<IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>> = vec![];
for repository in &self.repositories {
- // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
let attempt: Result<()> = (|| -> Result<()> {
let repo_ref = repository.borrow();
let Some(advisory_repo) = repo_ref.as_advisory_provider() else {
@@ -396,12 +394,20 @@ impl RepositorySet {
match attempt {
Ok(_) => {}
Err(e) => {
- // TODO(phase-b): downcast e to \Composer\Downloader\TransportException
- let _te: &TransportException = todo!("downcast e to TransportException");
+ // PHP catches only \Composer\Downloader\TransportException; other
+ // exceptions propagate uncaught.
+ if e.downcast_ref::<TransportException>().is_none() {
+ return Err(e);
+ }
if !ignore_unreachable {
return Err(e);
}
- unreachable_repos.push(e.to_string());
+ let message = e
+ .downcast_ref::<TransportException>()
+ .unwrap()
+ .message
+ .clone();
+ unreachable_repos.push(message);
}
}
}
@@ -646,6 +652,6 @@ impl RepositorySet {
#[derive(Debug)]
pub struct SecurityAdvisoriesResult {
- pub advisories: IndexMap<String, Vec<PartialOrSecurityAdvisory>>,
+ pub advisories: IndexMap<String, Vec<PartialOrFullSecurityAdvisory>>,
pub unreachable_repos: Vec<String>,
}
diff --git a/crates/shirabe/src/repository/vcs/svn_driver.rs b/crates/shirabe/src/repository/vcs/svn_driver.rs
index a793340..23ea703 100644
--- a/crates/shirabe/src/repository/vcs/svn_driver.rs
+++ b/crates/shirabe/src/repository/vcs/svn_driver.rs
@@ -171,7 +171,6 @@ impl SvnDriver {
}
}
- // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
let base_result =
self.get_file_content("composer.json", identifier)
.and_then(|file_content| {
@@ -184,9 +183,15 @@ impl SvnDriver {
let composer: Option<IndexMap<String, PhpMixed>> = match base_result {
Ok(c) => c,
Err(e) => {
- // TODO(phase-b): downcast to TransportException
- let _te: &TransportException = todo!("downcast e to TransportException");
- let message = e.to_string();
+ // PHP catches only TransportException; other exceptions propagate uncaught.
+ if e.downcast_ref::<TransportException>().is_none() {
+ return Err(e);
+ }
+ let message = e
+ .downcast_ref::<TransportException>()
+ .unwrap()
+ .message
+ .clone();
if stripos(&message, "path not found").is_none()
&& stripos(&message, "svn: warning: W160013").is_none()
{
@@ -253,14 +258,16 @@ impl SvnDriver {
(identifier.clone(), String::new())
};
- // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
let output: String = match self.execute(
vec!["svn".to_string(), "cat".to_string()],
&format!("{}{}{}", self.base_url, path, rev),
) {
Ok(o) => o,
Err(e) => {
- return Err(TransportException::new(e.to_string(), 0).into());
+ if let Some(e) = e.downcast_ref::<RuntimeException>() {
+ return Err(TransportException::new(e.message.clone(), 0).into());
+ }
+ return Err(e);
}
};
if trim(&output, None) == "" {
@@ -551,7 +558,6 @@ impl SvnDriver {
.set_cache_credentials(self.cache_credentials);
}
- // TODO(phase-b): use anyhow::Result<Result<T, E>> to model PHP try/catch
match self
.util
.as_mut()