aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/repository
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-08 22:14:12 +0900
committernsfisis <nsfisis@gmail.com>2026-08-08 22:14:12 +0900
commitf4cad2123b2af0de72bda4ce039e16e74f163f4e (patch)
tree21803308c5ff41e23c9d3b117433eea16b4ff663 /crates/shirabe/src/repository
parent0209f63210e5b547b5c6b73367bb80ea86c255ec (diff)
downloadphp-shirabe-f4cad2123b2af0de72bda4ce039e16e74f163f4e.tar.gz
php-shirabe-f4cad2123b2af0de72bda4ce039e16e74f163f4e.tar.zst
php-shirabe-f4cad2123b2af0de72bda4ce039e16e74f163f4e.zip
feat(php-shim): give ported exceptions PHP's class hierarchy
Ported exceptions were flat structs reached with `downcast_ref`, so Composer's `catch (\RuntimeException $e)` only matched the exact leaf type and `get_class($e)` had nothing to report. Each exception now embeds an instance of the class it extends and travels inside an `AnyThrowable`; `Catch::catch`/`catch_mut` walk that chain, and `PhpClass::php_class_name` yields the PHP FQCN. Dropping the `std::error::Error` impls from the exception types leaves `AnyThrowable` as the only route into an `anyhow::Error`, so the walk cannot be bypassed. A `no_exception_downcast` linter catches the `downcast::<X>()` calls that would now silently answer `None`. Three sites change behavior as a result: the `TransportException` exit-code override reaches `MaxFileSizeExceededException`, the `catch (\LogicException)` in findSimilar() reaches its subclasses, and rendered exception titles carry the real class name rather than a guess. `get_class_err()` is no longer a `todo!()`, which re-enables FilesystemRepositoryTest::testCorruptedRepositoryFile. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/repository')
-rw-r--r--crates/shirabe/src/repository/artifact_repository.rs26
-rw-r--r--crates/shirabe/src/repository/composer_repository.rs208
-rw-r--r--crates/shirabe/src/repository/filesystem_repository.rs47
-rw-r--r--crates/shirabe/src/repository/filter_repository.rs44
-rw-r--r--crates/shirabe/src/repository/invalid_repository_exception.rs14
-rw-r--r--crates/shirabe/src/repository/package_repository.rs25
-rw-r--r--crates/shirabe/src/repository/path_repository.rs38
-rw-r--r--crates/shirabe/src/repository/platform_repository.rs52
-rw-r--r--crates/shirabe/src/repository/repository_factory.rs62
-rw-r--r--crates/shirabe/src/repository/repository_manager.rs16
-rw-r--r--crates/shirabe/src/repository/repository_security_exception.rs12
-rw-r--r--crates/shirabe/src/repository/repository_set.rs35
-rw-r--r--crates/shirabe/src/repository/vcs/forgejo_driver.rs62
-rw-r--r--crates/shirabe/src/repository/vcs/fossil_driver.rs63
-rw-r--r--crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs38
-rw-r--r--crates/shirabe/src/repository/vcs/git_driver.rs78
-rw-r--r--crates/shirabe/src/repository/vcs/github_driver.rs60
-rw-r--r--crates/shirabe/src/repository/vcs/gitlab_driver.rs56
-rw-r--r--crates/shirabe/src/repository/vcs/hg_driver.rs41
-rw-r--r--crates/shirabe/src/repository/vcs/perforce_driver.rs14
-rw-r--r--crates/shirabe/src/repository/vcs/svn_driver.rs39
-rw-r--r--crates/shirabe/src/repository/vcs/vcs_driver.rs21
-rw-r--r--crates/shirabe/src/repository/vcs_repository.rs19
23 files changed, 439 insertions, 631 deletions
diff --git a/crates/shirabe/src/repository/artifact_repository.rs b/crates/shirabe/src/repository/artifact_repository.rs
index 99f340d1..2d16f137 100644
--- a/crates/shirabe/src/repository/artifact_repository.rs
+++ b/crates/shirabe/src/repository/artifact_repository.rs
@@ -47,10 +47,9 @@ impl ArtifactRepository {
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
) -> anyhow::Result<Self> {
if !extension_loaded("zip") {
- return Err(RuntimeException {
- message: "The artifact repository requires PHP's zip extension".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "The artifact repository requires PHP's zip extension".to_string(),
+ )
.into());
}
@@ -171,13 +170,10 @@ impl ArtifactRepository {
} else if file_extension == "zip" {
file_type = "zip";
} else {
- return Err(RuntimeException {
- message: format!(
- "Files with \"{}\" extensions aren't supported. Only ZIP and TAR/TAR.GZ/TGZ archives are supported.",
- file_extension
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Files with \"{}\" extensions aren't supported. Only ZIP and TAR/TAR.GZ/TGZ archives are supported.",
+ file_extension
+ ))
.into());
}
@@ -228,10 +224,10 @@ impl ArtifactRepository {
.unwrap_or_default();
match self.loader.load(cfg, None) {
Ok(package) => Ok(Some(package)),
- Err(exception) => Err(UnexpectedValueException {
- message: format!("Failed loading package in {}: {}", pathname, exception),
- code: 0,
- }
+ Err(exception) => Err(UnexpectedValueException::new(format!(
+ "Failed loading package in {}: {}",
+ pathname, exception
+ ))
.into()),
}
}
diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs
index b2476e1e..5371c2c3 100644
--- a/crates/shirabe/src/repository/composer_repository.rs
+++ b/crates/shirabe/src/repository/composer_repository.rs
@@ -38,6 +38,7 @@ use futures::stream::FuturesOrdered;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_metadata_minifier::MetadataMinifier;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
CmpOp, InvalidArgumentException, LogicException, PHP_EOL, PhpMixed, RuntimeException,
UnexpectedValueException, extension_loaded, hash, http_build_query, json_decode, parse_url_all,
@@ -183,10 +184,9 @@ impl ComposerRepository {
.to_string();
repo_config.insert("url".to_string(), PhpMixed::String(url_after.clone()));
if url_after.is_empty() {
- return Err(InvalidArgumentException {
- message: "The repository url must not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "The repository url must not be an empty string".to_string(),
+ )
.into());
}
@@ -214,10 +214,10 @@ impl ComposerRepository {
.and_then(|v| v.as_string())
.is_some_and(|s| !s.is_empty());
if url_bits_arr.is_none() || !scheme_present {
- return Err(UnexpectedValueException {
- message: format!("Invalid url given for Composer repository: {}", current_url),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Invalid url given for Composer repository: {}",
+ current_url
+ ))
.into());
}
@@ -387,12 +387,10 @@ impl ComposerRepository {
if self.has_partial_packages()? {
if self.partial_packages_by_name.is_none() {
- return Err(LogicException {
- message:
- "hasPartialPackages failed to initialize $this->partialPackagesByName"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "hasPartialPackages failed to initialize $this->partialPackagesByName"
+ .to_string(),
+ )
.into());
}
@@ -403,17 +401,11 @@ impl ComposerRepository {
.create_packages(flat, Some("packages.json inline packages".to_string()));
}
- return Err(LogicException {
- message: "Composer repositories that have lazy providers and no available-packages list can not load the complete list of packages, use getPackageNames instead.".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("Composer repositories that have lazy providers and no available-packages list can not load the complete list of packages, use getPackageNames instead.".to_string()).into());
}
if has_providers {
- return Err(LogicException {
- message: "Composer repositories that have providers can not load the complete list of packages, use getPackageNames instead.".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("Composer repositories that have providers can not load the complete list of packages, use getPackageNames instead.".to_string()).into());
}
// PHP relies on ArrayRepository::getPackages() invoking the virtual initialize(),
@@ -516,10 +508,9 @@ impl ComposerRepository {
fn load_package_list(&mut self, package_filter: Option<&str>) -> anyhow::Result<Vec<String>> {
if self.list_url.is_none() {
- return Err(LogicException {
- message: "Make sure to call loadRootServerFile before loadPackageList".to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "Make sure to call loadRootServerFile before loadPackageList".to_string(),
+ )
.into());
}
@@ -636,10 +627,7 @@ impl ComposerRepository {
let constraint = package_name_map.get(&name).and_then(|c| c.clone());
for (_uid, candidate) in candidates.iter() {
if candidate.get_name() != name {
- return Err(LogicException {
- message: "whatProvides should never return a package with a different name than the requested one".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("whatProvides should never return a package with a different name than the requested one".to_string()).into());
}
names_found.insert(name.clone(), true);
@@ -946,16 +934,13 @@ impl ComposerRepository {
if !allow_partial_advisories && !is_full {
let data_mixed =
PhpMixed::Array(data.iter().map(|(k, v)| (k.clone(), v.clone())).collect());
- return Err(RuntimeException {
- message: format!(
- "Advisory for {} could not be loaded as a full advisory from {}{}{}",
- name,
- repo_name,
- PHP_EOL,
- var_export(&data_mixed, true),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Advisory for {} could not be loaded as a full advisory from {}{}{}",
+ name,
+ repo_name,
+ PHP_EOL,
+ var_export(&data_mixed, true),
+ ))
.into());
}
let affected_versions: &AnyConstraint = advisory.affected_versions();
@@ -1151,7 +1136,7 @@ impl ComposerRepository {
) {
Ok(resp) => resp.decode_json()?,
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(404)
{
return Ok(result);
@@ -1183,11 +1168,10 @@ impl ComposerRepository {
if self.has_partial_packages()? {
if self.partial_packages_by_name.is_none() {
- return Err(LogicException {
- message: "hasPartialPackages failed to initialize $this->partialPackagesByName"
+ return Err(LogicException::new(
+ "hasPartialPackages failed to initialize $this->partialPackagesByName"
.to_string(),
- code: 0,
- }
+ )
.into());
}
for (_name, versions) in self.partial_packages_by_name.as_ref().unwrap().iter() {
@@ -1438,7 +1422,7 @@ impl ComposerRepository {
}
Err(e) => {
// 404s are acceptable for lazy provider repos
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
let status_code = te.get_status_code();
if self.lazy_providers_url.is_some()
&& matches!(status_code, Some(404 | 499))
@@ -1726,12 +1710,10 @@ impl ComposerRepository {
let mut names_found: IndexMap<String, bool> = IndexMap::new();
if self.lazy_providers_url.is_none() {
- return Err(LogicException {
- message:
- "loadAsyncPackages only supports v2 protocol composer repos with a metadata-url"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "loadAsyncPackages only supports v2 protocol composer repos with a metadata-url"
+ .to_string(),
+ )
.into());
}
@@ -1964,10 +1946,7 @@ impl ComposerRepository {
package_name: Option<&str>,
) -> anyhow::Result<PhpMixed> {
if self.lazy_providers_url.is_none() {
- return Err(LogicException {
- message: "startCachedAsyncDownload only supports v2 protocol composer repos with a metadata-url".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("startCachedAsyncDownload only supports v2 protocol composer repos with a metadata-url".to_string()).into());
}
let name = strtolower(file_name);
@@ -2142,13 +2121,11 @@ impl ComposerRepository {
}
if !extension_loaded("openssl") && self.url.starts_with("https") {
- return Err(RuntimeException {
- message: format!(
- "You must enable the openssl extension in your php.ini to load information from {}",
- self.url
- ),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(format!(
+ "You must enable the openssl extension in your php.ini to load information from {}",
+ self.url
+ ))
+ .into());
}
let mut data: Option<IndexMap<String, PhpMixed>> = None;
@@ -2387,13 +2364,10 @@ impl ComposerRepository {
api_url: api_url.clone(),
});
if api_url.is_none() && !self.has_available_package_list {
- return Err(UnexpectedValueException {
- message: format!(
- "Invalid security advisory configuration on {}: If the repository does not provide a security-advisories.api-url then available-packages or available-package-patterns are required to be provided for performance reason.",
- self.get_repo_name()
- ),
- code: 0,
- }.into());
+ return Err(UnexpectedValueException::new(format!(
+ "Invalid security advisory configuration on {}: If the repository does not provide a security-advisories.api-url then available-packages or available-package-patterns are required to be provided for performance reason.",
+ self.get_repo_name()
+ )).into());
}
}
}
@@ -2457,10 +2431,9 @@ impl ComposerRepository {
fn canonicalize_url(&self, url: &str) -> anyhow::Result<String> {
if url.is_empty() {
- return Err(InvalidArgumentException {
- message: "Expected a string with a value and not an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "Expected a string with a value and not an empty string".to_string(),
+ )
.into());
}
@@ -2491,11 +2464,9 @@ impl ComposerRepository {
let data = self.load_root_server_file(None)?;
let data = match data {
RootData::True => {
- return Err(LogicException {
- message: "loadRootServerFile should not return true during initialization"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "loadRootServerFile should not return true during initialization".to_string(),
+ )
.into());
}
RootData::Data(d) => d,
@@ -2724,19 +2695,16 @@ impl ComposerRepository {
})();
result.map_err(|e| {
- RuntimeException {
- message: format!(
- "Could not load packages in {}{}: [{}] {}",
- self.get_repo_name(),
- source
- .as_ref()
- .map(|s| format!(" from {}", s))
- .unwrap_or_default(),
- "Exception",
- e
- ),
- code: 0,
- }
+ RuntimeException::new(format!(
+ "Could not load packages in {}{}: [{}] {}",
+ self.get_repo_name(),
+ source
+ .as_ref()
+ .map(|s| format!(" from {}", s))
+ .unwrap_or_default(),
+ "Exception",
+ e
+ ))
.into()
})
}
@@ -2749,10 +2717,9 @@ impl ComposerRepository {
store_last_modified_time: bool,
) -> anyhow::Result<IndexMap<String, PhpMixed>> {
if filename.is_empty() {
- return Err(InvalidArgumentException {
- message: "$filename should not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "$filename should not be an empty string".to_string(),
+ )
.into());
}
@@ -2830,13 +2797,10 @@ impl ComposerRepository {
}
// TODO use scarier wording once we know for sure it doesn't do false positives anymore
- return Err(RepositorySecurityException(shirabe_php_shim::Exception {
- message: format!(
- "The contents of {} do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.",
- filename
- ),
- code: 0,
- }).into());
+ return Err(RepositorySecurityException::new(format!(
+ "The contents of {} do not match its signature. This could indicate a man-in-the-middle attack or e.g. antivirus software corrupting files. Try running composer again and report this if you think it is a mistake.",
+ filename
+ )).into());
}
if let Some(dispatcher) = self.event_dispatcher.as_ref() {
@@ -2904,15 +2868,15 @@ impl ComposerRepository {
if e.downcast_ref::<RetryMarker>().is_some() {
continue;
}
- if e.downcast_ref::<LogicException>().is_some() {
+ if e.is_instanceof::<LogicException>() {
return Err(e);
}
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(404)
{
return Err(e);
}
- if e.downcast_ref::<RepositorySecurityException>().is_some() {
+ if e.is_instanceof::<RepositorySecurityException>() {
return Err(e);
}
@@ -2948,10 +2912,7 @@ impl ComposerRepository {
match data {
Some(d) => Ok(d),
- None => Err(LogicException {
- message: "ComposerRepository: Undefined $data. Please report at https://github.com/composer/composer/issues/new.".to_string(),
- code: 0,
- }.into()),
+ None => Err(LogicException::new("ComposerRepository: Undefined $data. Please report at https://github.com/composer/composer/issues/new.".to_string()).into()),
}
}
@@ -2962,10 +2923,9 @@ impl ComposerRepository {
last_modified_time: &str,
) -> anyhow::Result<FetchFileIfLastModifiedResult> {
if filename.is_empty() {
- return Err(InvalidArgumentException {
- message: "$filename should not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "$filename should not be an empty string".to_string(),
+ )
.into());
}
@@ -3079,10 +3039,10 @@ impl ComposerRepository {
match result {
Ok(v) => Ok(v),
Err(e) => {
- if e.downcast_ref::<LogicException>().is_some() {
+ if e.is_instanceof::<LogicException>() {
return Err(e);
}
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(404)
{
return Err(e);
@@ -3109,10 +3069,9 @@ impl ComposerRepository {
last_modified_time: Option<&str>,
) -> anyhow::Result<PhpMixed> {
if filename.is_empty() {
- return Err(InvalidArgumentException {
- message: "$filename should not be an empty string".to_string(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "$filename should not be an empty string".to_string(),
+ )
.into());
}
@@ -3263,7 +3222,7 @@ impl ComposerRepository {
cache_key: &str,
last_modified_time: Option<&str>,
) -> anyhow::Result<PhpMixed> {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(404)
{
self.packages_not_found_cache
@@ -3289,7 +3248,7 @@ impl ComposerRepository {
}
// special error code returned when network is being artificially disabled
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& te.get_status_code() == Some(499)
{
let resp = Response::new(self.url.clone(), Some(404), Vec::new(), Some(String::new()));
@@ -3364,10 +3323,7 @@ impl ComposerRepository {
/// @return true if the package name is present in availablePackages or matched by availablePackagePatterns
pub(crate) fn lazy_providers_repo_contains(&self, name: &str) -> anyhow::Result<bool> {
if !self.has_available_package_list {
- return Err(LogicException {
- message: "lazyProvidersRepoContains should not be called unless hasAvailablePackageList is true".to_string(),
- code: 0,
- }.into());
+ return Err(LogicException::new("lazyProvidersRepoContains should not be called unless hasAvailablePackageList is true".to_string()).into());
}
if let Some(ref available) = self.available_packages
diff --git a/crates/shirabe/src/repository/filesystem_repository.rs b/crates/shirabe/src/repository/filesystem_repository.rs
index 47241bde..d9085bfd 100644
--- a/crates/shirabe/src/repository/filesystem_repository.rs
+++ b/crates/shirabe/src/repository/filesystem_repository.rs
@@ -19,9 +19,9 @@ use crate::util::Filesystem;
use crate::util::Platform;
use indexmap::IndexMap;
use shirabe_php_shim::{
- Exception, InvalidArgumentException, LogicException, PhpMixed, UnexpectedValueException,
- array_flip, dirname, get_class_err, get_debug_type, in_array_strict, is_array, is_null,
- is_string, ksort, realpath, str_repeat, usort, var_export,
+ AnyThrowable, InvalidArgumentException, LogicException, PhpClass as _, PhpMixed,
+ UnexpectedValueException, array_flip, dirname, get_debug_type, in_array_strict, is_array,
+ is_null, is_string, ksort, realpath, str_repeat, usort, var_export,
};
use shirabe_semver::constraint::AnyConstraint;
@@ -57,10 +57,9 @@ impl FilesystemRepository {
let filesystem = filesystem
.unwrap_or_else(|| std::rc::Rc::new(std::cell::RefCell::new(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(),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(
+ "Expected a root package instance if $dumpVersions is true".to_string(),
+ )
.into());
}
Ok(Self {
@@ -134,10 +133,9 @@ impl FilesystemRepository {
}
if !is_array(&packages_value) {
- return Err(UnexpectedValueException {
- message: "Could not parse package list from the repository".to_string(),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(
+ "Could not parse package list from the repository".to_string(),
+ )
.into());
}
@@ -145,15 +143,14 @@ impl FilesystemRepository {
})() {
Ok(p) => p,
Err(e) => {
- return Err(InvalidRepositoryException(Exception {
- message: format!(
- "Invalid repository data in {}, packages could not be loaded: [{}] {}",
- self.file.get_path(),
- get_class_err(&e),
- e,
- ),
- code: 0,
- })
+ return Err(InvalidRepositoryException::new(format!(
+ "Invalid repository data in {}, packages could not be loaded: [{}] {}",
+ self.file.get_path(),
+ AnyThrowable::of(e.as_ref())
+ .expect("PHP reaches this only with a caught \\Throwable")
+ .php_class_name(),
+ e,
+ ))
.into());
}
};
@@ -464,12 +461,10 @@ impl FilesystemRepository {
self.inner.get_packages()?.into_iter().collect();
let mut current_root: RootPackageInterfaceHandle = match &self.root_package {
None => {
- return Err(LogicException {
- message:
- "It should not be possible to dump packages if no root package is given"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "It should not be possible to dump packages if no root package is given"
+ .to_string(),
+ )
.into());
}
Some(r) => r.clone(),
diff --git a/crates/shirabe/src/repository/filter_repository.rs b/crates/shirabe/src/repository/filter_repository.rs
index d7be0a9f..98cef1d0 100644
--- a/crates/shirabe/src/repository/filter_repository.rs
+++ b/crates/shirabe/src/repository/filter_repository.rs
@@ -49,13 +49,10 @@ impl FilterRepository {
));
}
_ => {
- return Err(InvalidArgumentException {
- message: format!(
- r#""only" key for repository {} should be an array"#,
- repo.get_repo_name()?
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ r#""only" key for repository {} should be an array"#,
+ repo.get_repo_name()?
+ ))
.into());
}
}
@@ -79,25 +76,19 @@ impl FilterRepository {
));
}
_ => {
- return Err(InvalidArgumentException {
- message: format!(
- r#""exclude" key for repository {} should be an array"#,
- repo.get_repo_name()?
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ r#""exclude" key for repository {} should be an array"#,
+ repo.get_repo_name()?
+ ))
.into());
}
}
}
if exclude.is_some() && only.is_some() {
- return Err(InvalidArgumentException {
- message: format!(
- r#"Only one of "only" and "exclude" can be specified for repository {}"#,
- repo.get_repo_name()?
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ r#"Only one of "only" and "exclude" can be specified for repository {}"#,
+ repo.get_repo_name()?
+ ))
.into());
}
if let Some(canonical_val) = options.get("canonical") {
@@ -106,13 +97,10 @@ impl FilterRepository {
canonical = *b;
}
_ => {
- return Err(InvalidArgumentException {
- message: format!(
- r#""canonical" key for repository {} should be a boolean"#,
- repo.get_repo_name()?
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ r#""canonical" key for repository {} should be a boolean"#,
+ repo.get_repo_name()?
+ ))
.into());
}
}
diff --git a/crates/shirabe/src/repository/invalid_repository_exception.rs b/crates/shirabe/src/repository/invalid_repository_exception.rs
index e7aa8509..ed84759c 100644
--- a/crates/shirabe/src/repository/invalid_repository_exception.rs
+++ b/crates/shirabe/src/repository/invalid_repository_exception.rs
@@ -8,14 +8,12 @@ pub struct InvalidRepositoryException(pub Exception);
impl InvalidRepositoryException {
pub fn new(message: String) -> Self {
- Self(Exception { message, code: 0 })
+ Self(Exception::new(message))
}
}
-impl std::fmt::Display for InvalidRepositoryException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl std::error::Error for InvalidRepositoryException {}
+shirabe_php_shim::impl_php_exception!(
+ InvalidRepositoryException,
+ 0,
+ r"Composer\Repository\InvalidRepositoryException"
+);
diff --git a/crates/shirabe/src/repository/package_repository.rs b/crates/shirabe/src/repository/package_repository.rs
index 62c8c5b3..810b0e13 100644
--- a/crates/shirabe/src/repository/package_repository.rs
+++ b/crates/shirabe/src/repository/package_repository.rs
@@ -16,7 +16,7 @@ use crate::repository::{
};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
-use shirabe_php_shim::{Exception, PhpMixed, RuntimeException, php_regex, var_export};
+use shirabe_php_shim::{PhpMixed, RuntimeException, php_regex, var_export};
use shirabe_semver::constraint::AnyConstraint;
#[derive(Debug)]
@@ -72,10 +72,7 @@ impl PackageRepository {
e,
shirabe_php_shim::json_encode(package).unwrap_or_default()
);
- return Ok(Err(InvalidRepositoryException(Exception {
- message: msg,
- code: 0,
- })));
+ return Ok(Err(InvalidRepositoryException::new(msg)));
}
};
self.inner.add_package(package_loaded)?;
@@ -101,7 +98,7 @@ impl PackageRepository {
// skips re-initializing it.
fn ensure_initialized(&self) -> anyhow::Result<()> {
if !self.inner.is_initialized() {
- self.initialize()?.map_err(anyhow::Error::new)?;
+ self.initialize()?.map_err(anyhow::Error::from)?;
}
Ok(())
}
@@ -234,15 +231,13 @@ impl AdvisoryProviderInterface for PackageRepository {
};
if !allow_partial_advisories && matches!(advisory, AnySecurityAdvisory::Partial(_))
{
- return Err(anyhow::anyhow!(RuntimeException {
- message: format!(
- "Advisory for {} could not be loaded as a full advisory from {}\n{}",
- package_name,
- self.get_repo_name()?,
- var_export(data, true)
- ),
- code: 0,
- }));
+ return Err(RuntimeException::new(format!(
+ "Advisory for {} could not be loaded as a full advisory from {}\n{}",
+ package_name,
+ self.get_repo_name()?,
+ var_export(data, true)
+ ))
+ .into());
}
if !advisory.affected_versions().matches(package_constraint) {
diff --git a/crates/shirabe/src/repository/path_repository.rs b/crates/shirabe/src/repository/path_repository.rs
index ec2da043..313fc75e 100644
--- a/crates/shirabe/src/repository/path_repository.rs
+++ b/crates/shirabe/src/repository/path_repository.rs
@@ -56,11 +56,9 @@ impl PathRepository {
process: Option<std::rc::Rc<std::cell::RefCell<ProcessExecutor>>>,
) -> anyhow::Result<Self> {
if !repo_config.contains_key("url") {
- return Err(RuntimeException {
- message: "You must specify the `url` configuration for the path repository"
- .to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "You must specify the `url` configuration for the path repository".to_string(),
+ )
.into());
}
@@ -172,13 +170,10 @@ impl PathRepository {
}
}
- return Err(RuntimeException {
- message: format!(
- "The `url` supplied for the path ({}) repository does not exist",
- self.url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The `url` supplied for the path ({}) repository does not exist",
+ self.url
+ ))
.into());
}
@@ -355,10 +350,10 @@ impl PathRepository {
self.inner
.add_package(self.loader.load(package.clone(), None).map_err(|e| {
- RuntimeException {
- message: format!("Failed loading the package in {}", composer_file_path),
- code: 0,
- }
+ RuntimeException::new(format!(
+ "Failed loading the package in {}",
+ composer_file_path
+ ))
})?);
}
@@ -371,13 +366,10 @@ impl PathRepository {
if defined("GLOB_BRACE") {
flags |= GLOB_BRACE;
} else if self.url.contains('{') || self.url.contains('}') {
- return Err(RuntimeException {
- message: format!(
- "The operating system does not support GLOB_BRACE which is required for the url {}",
- self.url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "The operating system does not support GLOB_BRACE which is required for the url {}",
+ self.url
+ ))
.into());
}
diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs
index 944bb4db..0b32e157 100644
--- a/crates/shirabe/src/repository/platform_repository.rs
+++ b/crates/shirabe/src/repository/platform_repository.rs
@@ -65,24 +65,20 @@ impl PlatformRepository {
let mut overrides_map: IndexMap<String, PlatformOverride> = IndexMap::new();
for (name, version) in overrides {
if !is_string(&version) && !matches!(version, PhpMixed::Bool(false)) {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message: format!(
- "config.platform.{} should be a string or false, but got {} {}",
- name,
- shirabe_php_shim::get_debug_type(&version),
- var_export(&version, true)
- ),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(format!(
+ "config.platform.{} should be a string or false, but got {} {}",
+ name,
+ shirabe_php_shim::get_debug_type(&version),
+ var_export(&version, true)
+ ))
+ .into());
}
if name == "php" && matches!(version, PhpMixed::Bool(false)) {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message: format!(
- "config.platform.{} cannot be set to false as you cannot disable php entirely.",
- name
- ),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(format!(
+ "config.platform.{} cannot be set to false as you cannot disable php entirely.",
+ name
+ ))
+ .into());
}
overrides_map.insert(
strtolower(&name),
@@ -153,13 +149,11 @@ impl PlatformRepository {
for r#override in &overrides {
// Check that it's a platform package.
if !Self::is_platform_package(&r#override.name) {
- return Err(anyhow::anyhow!(InvalidArgumentException {
- message: format!(
- "Invalid platform package name in config.platform: {}",
- r#override.name
- ),
- code: 0,
- }));
+ return Err(InvalidArgumentException::new(format!(
+ "Invalid platform package name in config.platform: {}",
+ r#override.name
+ ))
+ .into());
}
if !matches!(r#override.version, PhpMixed::Bool(false)) {
@@ -1488,13 +1482,11 @@ impl PlatformRepository {
pub fn add_package(&mut self, package: PackageInterfaceHandle) -> anyhow::Result<()> {
if package.as_complete().is_none() {
- return Err(anyhow::anyhow!(UnexpectedValueException {
- message: format!(
- "Expected CompletePackage but got {}",
- get_class(&PhpMixed::Null)
- ),
- code: 0,
- }));
+ return Err(UnexpectedValueException::new(format!(
+ "Expected CompletePackage but got {}",
+ get_class(&PhpMixed::Null)
+ ))
+ .into());
}
let name = package.get_name();
diff --git a/crates/shirabe/src/repository/repository_factory.rs b/crates/shirabe/src/repository/repository_factory.rs
index 856f58ad..a15d3a97 100644
--- a/crates/shirabe/src/repository/repository_factory.rs
+++ b/crates/shirabe/src/repository/repository_factory.rs
@@ -73,10 +73,7 @@ impl RepositoryFactory {
repo_config.insert("json".to_string(), PhpMixed::String(repository.to_string()));
return Ok(repo_config);
} else {
- return Err(InvalidArgumentException {
- message: format!("Invalid repository URL ({}) given. This file does not contain a valid composer repository.", repository),
- code: 0,
- }.into());
+ return Err(InvalidArgumentException::new(format!("Invalid repository URL ({}) given. This file does not contain a valid composer repository.", repository)).into());
}
}
@@ -87,10 +84,7 @@ impl RepositoryFactory {
return Ok(repo_config);
}
- Err(InvalidArgumentException {
- message: format!("Invalid repository url ({}) given. Has to be a .json file, an http url or a JSON object.", repository),
- code: 0,
- }.into())
+ Err(InvalidArgumentException::new(format!("Invalid repository url ({}) given. Has to be a .json file, an http url or a JSON object.", repository)).into())
}
pub fn from_string(
@@ -121,13 +115,9 @@ impl RepositoryFactory {
let repos =
Self::create_repos(rm, vec![PhpMixed::Array(repo_config.into_iter().collect())])?;
// PHP: return current($repos);
- let (_, first) = repos
- .into_iter()
- .next()
- .ok_or_else(|| UnexpectedValueException {
- message: "create_repos returned no repository".to_string(),
- code: 0,
- })?;
+ let (_, first) = repos.into_iter().next().ok_or_else(|| {
+ UnexpectedValueException::new("create_repos returned no repository".to_string())
+ })?;
Ok(first)
}
@@ -149,10 +139,11 @@ impl RepositoryFactory {
let rm = if let Some(rm) = rm {
rm
} else {
- let io = io.ok_or_else(|| InvalidArgumentException {
- message: "This function requires either an IOInterface or a RepositoryManager"
- .to_string(),
- code: 0,
+ let io = io.ok_or_else(|| {
+ InvalidArgumentException::new(
+ "This function requires either an IOInterface or a RepositoryManager"
+ .to_string(),
+ )
})?;
owned_rm = Self::manager(
io.clone(),
@@ -243,21 +234,15 @@ impl RepositoryFactory {
for (index, repo) in repo_configs.into_iter().enumerate() {
match &repo {
PhpMixed::String(_) => {
- return Err(UnexpectedValueException {
- message: "\"repositories\" should be an array of repository definitions, only a single repository was given".to_string(),
- code: 0,
- }.into());
+ return Err(UnexpectedValueException::new("\"repositories\" should be an array of repository definitions, only a single repository was given".to_string()).into());
}
PhpMixed::Array(repo_arr) => {
if !repo_arr.contains_key("type") {
- return Err(UnexpectedValueException {
- message: format!(
- "Repository \"{}\" ({}) must have a type defined",
- index,
- json_encode(&repo).unwrap_or_default()
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Repository \"{}\" ({}) must have a type defined",
+ index,
+ json_encode(&repo).unwrap_or_default()
+ ))
.into());
}
let repo_type = repo_arr
@@ -296,15 +281,12 @@ impl RepositoryFactory {
}
}
_ => {
- return Err(UnexpectedValueException {
- message: format!(
- "Repository \"{}\" ({}) should be an array, {} given",
- index,
- json_encode(&repo).unwrap_or_default(),
- get_debug_type(&repo)
- ),
- code: 0,
- }
+ return Err(UnexpectedValueException::new(format!(
+ "Repository \"{}\" ({}) should be an array, {} given",
+ index,
+ json_encode(&repo).unwrap_or_default(),
+ get_debug_type(&repo)
+ ))
.into());
}
}
diff --git a/crates/shirabe/src/repository/repository_manager.rs b/crates/shirabe/src/repository/repository_manager.rs
index 7fd2f80a..10ac973d 100644
--- a/crates/shirabe/src/repository/repository_manager.rs
+++ b/crates/shirabe/src/repository/repository_manager.rs
@@ -100,10 +100,10 @@ impl RepositoryManager {
name: Option<&str>,
) -> anyhow::Result<RepositoryInterfaceHandle> {
if !self.repository_classes.contains_key(r#type) {
- return Err(InvalidArgumentException {
- message: format!("Repository type is not registered: {}", r#type),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "Repository type is not registered: {}",
+ r#type
+ ))
.into());
}
@@ -193,10 +193,10 @@ impl RepositoryManager {
)),
// TODO(plugin): `setRepositoryClass` lets a plugin register a repository class of
// its own, which needs a Rust-side counterpart before it can be built here.
- other => Err(anyhow::anyhow!(RuntimeException {
- message: format!("Repository class has no Rust implementation: {other}"),
- code: 0,
- })),
+ other => Err(RuntimeException::new(format!(
+ "Repository class has no Rust implementation: {other}"
+ ))
+ .into()),
}
}
diff --git a/crates/shirabe/src/repository/repository_security_exception.rs b/crates/shirabe/src/repository/repository_security_exception.rs
index b517cad9..13f2fe72 100644
--- a/crates/shirabe/src/repository/repository_security_exception.rs
+++ b/crates/shirabe/src/repository/repository_security_exception.rs
@@ -6,10 +6,14 @@ use shirabe_php_shim::Exception;
#[derive(Debug)]
pub struct RepositorySecurityException(pub Exception);
-impl std::fmt::Display for RepositorySecurityException {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- self.0.fmt(f)
+impl RepositorySecurityException {
+ pub fn new(message: String) -> Self {
+ Self(Exception::new(message))
}
}
-impl std::error::Error for RepositorySecurityException {}
+shirabe_php_shim::impl_php_exception!(
+ RepositorySecurityException,
+ 0,
+ r"Composer\Repository\RepositorySecurityException"
+);
diff --git a/crates/shirabe/src/repository/repository_set.rs b/crates/shirabe/src/repository/repository_set.rs
index def73f14..bd57ec20 100644
--- a/crates/shirabe/src/repository/repository_set.rs
+++ b/crates/shirabe/src/repository/repository_set.rs
@@ -21,6 +21,7 @@ use crate::repository::LockArrayRepositoryHandle;
use crate::repository::PlatformRepository;
use crate::repository::{FindPackageConstraint, RepositoryInterfaceHandle};
use indexmap::IndexMap;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{LogicException, RuntimeException, ksort, strtolower};
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
@@ -155,10 +156,7 @@ impl RepositorySet {
/// @param RepositoryInterface $repo A package repository
pub fn add_repository(&mut self, repo: RepositoryInterfaceHandle) -> anyhow::Result<()> {
if self.locked {
- return Err(RuntimeException {
- message: "Pool has already been created from this repository set, it cannot be modified anymore.".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("Pool has already been created from this repository set, it cannot be modified anymore.".to_string())
.into());
}
@@ -374,17 +372,17 @@ impl RepositorySet {
Err(e) => {
// PHP catches only \Composer\Downloader\TransportException; other
// exceptions propagate uncaught.
- if e.downcast_ref::<TransportException>().is_none() {
+ if !e.is_instanceof::<TransportException>() {
return Err(e);
}
if !ignore_unreachable {
return Err(e);
}
let message = e
- .downcast_ref::<TransportException>()
+ .catch::<TransportException>()
.unwrap()
- .message
- .clone();
+ .get_message()
+ .to_string();
unreachable_repos.push(message);
}
}
@@ -482,11 +480,9 @@ impl RepositorySet {
|| repo_ref.as_any().is::<InstalledRepository>()
};
if is_installed && !self.allow_installed_repositories {
- return Err(LogicException {
- message: "The pool can not accept packages from an installed repository"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "The pool can not accept packages from an installed repository".to_string(),
+ )
.into());
}
}
@@ -505,11 +501,9 @@ impl RepositorySet {
|| repo_ref.as_any().is::<InstalledRepository>()
};
if is_installed && !self.allow_installed_repositories {
- return Err(LogicException {
- message: "The pool can not accept packages from an installed repository"
- .to_string(),
- code: 0,
- }
+ return Err(LogicException::new(
+ "The pool can not accept packages from an installed repository".to_string(),
+ )
.into());
}
}
@@ -582,10 +576,7 @@ impl RepositorySet {
let mut allowed_packages: Vec<String> = vec![];
for package_name in &package_names {
if PlatformRepository::is_platform_package(package_name) {
- return Err(LogicException {
- message: "createPoolForPackage(s) can not be used for platform packages, as they are never loaded by the PoolBuilder which expects them to be fixed. Use createPoolWithAllPackages or pass in a proper request with the platform packages you need fixed in it.".to_string(),
- code: 0,
- }
+ return Err(LogicException::new("createPoolForPackage(s) can not be used for platform packages, as they are never loaded by the PoolBuilder which expects them to be fixed. Use createPoolWithAllPackages or pass in a proper request with the platform packages you need fixed in it.".to_string())
.into());
}
diff --git a/crates/shirabe/src/repository/vcs/forgejo_driver.rs b/crates/shirabe/src/repository/vcs/forgejo_driver.rs
index 0719701f..e4ebe379 100644
--- a/crates/shirabe/src/repository/vcs/forgejo_driver.rs
+++ b/crates/shirabe/src/repository/vcs/forgejo_driver.rs
@@ -16,6 +16,7 @@ use crate::util::ForgejoUrl;
use crate::util::http::Response;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, RuntimeException, base64_decode, explode, extension_loaded, php_regex, urlencode,
};
@@ -107,7 +108,7 @@ impl ForgejoDriver {
);
let response = self
.get_contents(&resource_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let mut resource = response.decode_json()?;
// The Forgejo contents API only returns files up to 1MB as base64 encoded files;
@@ -134,7 +135,7 @@ impl ForgejoDriver {
if let Some(git_url) = git_url {
resource = self
.get_contents(&git_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
}
}
@@ -157,22 +158,22 @@ impl ForgejoDriver {
Some(b64) => match base64_decode(&b64) {
Some(bytes) => match String::from_utf8(bytes) {
Ok(s) => Ok(Some(s)),
- Err(_) => Err(RuntimeException {
- message: format!("Could not retrieve {} for {}", file, identifier),
- code: 0,
- }
+ Err(_) => Err(RuntimeException::new(format!(
+ "Could not retrieve {} for {}",
+ file, identifier
+ ))
.into()),
},
- None => Err(RuntimeException {
- message: format!("Could not retrieve {} for {}", file, identifier),
- code: 0,
- }
+ None => Err(RuntimeException::new(format!(
+ "Could not retrieve {} for {}",
+ file, identifier
+ ))
.into()),
},
- None => Err(RuntimeException {
- message: format!("Could not retrieve {} for {}", file, identifier),
- code: 0,
- }
+ None => Err(RuntimeException::new(format!(
+ "Could not retrieve {} for {}",
+ file, identifier
+ ))
.into()),
}
}
@@ -193,7 +194,7 @@ impl ForgejoDriver {
);
let commit = self
.get_contents(&resource_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
let date_str = if let PhpMixed::Array(ref arr) = commit {
@@ -208,9 +209,8 @@ impl ForgejoDriver {
None
};
- let date_str = date_str.ok_or_else(|| RuntimeException {
- message: format!("Could not parse commit date for {}", identifier),
- code: 0,
+ let date_str = date_str.ok_or_else(|| {
+ RuntimeException::new(format!("Could not parse commit date for {}", identifier))
})?;
let date: chrono::DateTime<chrono::FixedOffset> = shirabe_php_shim::date_create(&date_str)?;
@@ -243,7 +243,7 @@ impl ForgejoDriver {
while let Some(url) = resource {
let response = self
.get_contents(&url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let branch_data = response.decode_json()?;
if let PhpMixed::List(ref list) = branch_data {
for branch in list {
@@ -286,7 +286,7 @@ impl ForgejoDriver {
while let Some(url) = resource {
let response = self
.get_contents(&url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let tags_data = response.decode_json()?;
if let PhpMixed::List(ref list) = tags_data {
for tag in list {
@@ -599,7 +599,7 @@ impl ForgejoDriver {
&mut self,
url: &str,
fetching_repo_data: bool,
- ) -> anyhow::Result<Response, TransportException> {
+ ) -> anyhow::Result<Response, Box<TransportException>> {
match self.inner.get_contents(url) {
Ok(response) => Ok(response),
Err(e) => match e.get_code() {
@@ -610,14 +610,7 @@ impl ForgejoDriver {
if !self.inner.io.is_interactive() {
self.attempt_clone_fallback()
- .map_err(|inner_e| TransportException {
- message: inner_e.to_string(),
- code: 0,
- headers: None,
- response: None,
- status_code: None,
- response_info: vec![],
- })?;
+ .map_err(|inner_e| TransportException::new(inner_e.to_string(), 0))?;
return Ok(Response::new(
"dummy".to_string(),
@@ -645,14 +638,7 @@ impl ForgejoDriver {
);
let auth_result = forgejo
.authorize_o_auth_interactively(&origin_url, message.as_deref())
- .map_err(|inner_e| TransportException {
- message: inner_e.to_string(),
- code: 0,
- headers: None,
- response: None,
- status_code: None,
- response_info: vec![],
- })?;
+ .map_err(|inner_e| TransportException::new(inner_e.to_string(), 0))?;
if let Ok(true) = auth_result {
return self.inner.get_contents(url);
@@ -734,7 +720,7 @@ impl crate::repository::vcs::VcsDriverInterface for ForgejoDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/fossil_driver.rs b/crates/shirabe/src/repository/vcs/fossil_driver.rs
index 1b61ed4d..3795d1ca 100644
--- a/crates/shirabe/src/repository/vcs/fossil_driver.rs
+++ b/crates/shirabe/src/repository/vcs/fossil_driver.rs
@@ -12,6 +12,7 @@ use crate::util::ProcessExecutor;
use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, RuntimeException, dirname, is_dir, is_file, is_writable, php_regex,
};
@@ -77,10 +78,7 @@ impl FossilDriver {
.unwrap_or("")
.to_string();
if !Cache::is_usable(&cache_repo_dir) || !Cache::is_usable(&cache_vcs_dir) {
- return Err(RuntimeException {
- message: "FossilDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("FossilDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string())
.into());
}
@@ -105,13 +103,10 @@ impl FossilDriver {
None,
) != 0
{
- return Err(RuntimeException {
- message: format!(
- "fossil was not found, check that it is installed and in your PATH env.\n\n{}",
- self.inner.process.borrow().get_error_output()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "fossil was not found, check that it is installed and in your PATH env.\n\n{}",
+ self.inner.process.borrow().get_error_output()
+ ))
.into());
}
Ok(())
@@ -124,13 +119,10 @@ impl FossilDriver {
fs.ensure_directory_exists(&self.checkout_dir)?;
if !is_writable(dirname(&self.checkout_dir)) {
- return Err(RuntimeException {
- message: format!(
- "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
- self.inner.url, self.checkout_dir
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
+ self.inner.url, self.checkout_dir
+ ))
.into());
}
@@ -173,13 +165,10 @@ impl FossilDriver {
) != 0
{
let output = self.inner.process.borrow().get_error_output().to_string();
- return Err(RuntimeException {
- message: format!(
- "Failed to clone {} to repository {}\n\n{}",
- self.inner.url, repo_file, output
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to clone {} to repository {}\n\n{}",
+ self.inner.url, repo_file, output
+ ))
.into());
}
@@ -192,13 +181,10 @@ impl FossilDriver {
) != 0
{
let output = self.inner.process.borrow().get_error_output().to_string();
- return Err(RuntimeException {
- message: format!(
- "Failed to open repository {} in {}\n\n{}",
- repo_file, self.checkout_dir, output
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to open repository {} in {}\n\n{}",
+ repo_file, self.checkout_dir, output
+ ))
.into());
}
}
@@ -231,13 +217,10 @@ impl FossilDriver {
pub fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid fossil identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid fossil identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -420,7 +403,7 @@ impl crate::repository::vcs::VcsDriverInterface for FossilDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
index 8fe93018..d833b576 100644
--- a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
+++ b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
@@ -16,6 +16,7 @@ use crate::util::http::Response;
use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_key_exists,
array_search_mixed, extension_loaded, http_build_query_mixed, implode, is_array, php_regex,
@@ -90,13 +91,10 @@ impl GitBitbucketDriver {
&self.inner.url,
Some(&mut m),
) {
- return Err(InvalidArgumentException {
- message: format!(
- "The Bitbucket repository URL {} is invalid. It must be the HTTPS URL of a Bitbucket repository.",
- self.inner.url.clone(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The Bitbucket repository URL {} is invalid. It must be the HTTPS URL of a Bitbucket repository.",
+ self.inner.url.clone(),
+ ))
.into());
}
@@ -706,7 +704,7 @@ impl GitBitbucketDriver {
if !self.inner.io.has_authentication(&self.inner.origin_url)
&& bitbucket_util.authorize_oauth(&self.inner.origin_url)
{
- return self.inner.get_contents(url).map_err(anyhow::Error::from);
+ return self.inner.get_contents(url).map_err(|e| (*e).into());
}
if !self.inner.io.is_interactive() && fetching_repo_data {
@@ -722,7 +720,7 @@ impl GitBitbucketDriver {
}
}
- Err(e.into())
+ Err((*e).into())
}
}
}
@@ -742,7 +740,7 @@ impl GitBitbucketDriver {
match self.setup_fallback_driver(&self.generate_ssh_url()) {
Ok(()) => Ok(true),
Err(e) => {
- if e.downcast_ref::<RuntimeException>().is_some() {
+ if e.is_instanceof::<RuntimeException>() {
self.fallback_driver = None;
self.inner.io.write_error(&format!(
@@ -799,11 +797,10 @@ impl GitBitbucketDriver {
if self.root_identifier.is_none() {
if !self.get_repo_data()? {
if self.fallback_driver.is_none() {
- return Err(LogicException {
- message: "A fallback driver should be setup if getRepoData returns false"
+ return Err(LogicException::new(
+ "A fallback driver should be setup if getRepoData returns false"
.to_string(),
- code: 0,
- }
+ )
.into());
}
@@ -811,13 +808,10 @@ impl GitBitbucketDriver {
}
if self.vcs_type.as_deref() != Some("git") {
- return Err(RuntimeException {
- message: format!(
- "{} does not appear to be a git repository, use {} but remember that Bitbucket no longer supports the mercurial repositories. https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket",
- self.inner.url, self.clone_https_url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "{} does not appear to be a git repository, use {} but remember that Bitbucket no longer supports the mercurial repositories. https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket",
+ self.inner.url, self.clone_https_url
+ ))
.into());
}
@@ -918,7 +912,7 @@ impl crate::repository::vcs::VcsDriverInterface for GitBitbucketDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/git_driver.rs b/crates/shirabe/src/repository/vcs/git_driver.rs
index 1376ebbc..9f8a6b32 100644
--- a/crates/shirabe/src/repository/vcs/git_driver.rs
+++ b/crates/shirabe/src/repository/vcs/git_driver.rs
@@ -15,6 +15,7 @@ use chrono::TimeZone;
use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, RuntimeException, dirname, is_dir, is_writable, realpath,
sys_get_temp_dir,
@@ -52,13 +53,10 @@ impl GitDriver {
if Filesystem::is_local_path(&self.inner.url) {
self.inner.url = Preg::replace(php_regex!(r"{[\\/]\.git/?$}"), "", &self.inner.url);
if !is_dir(&self.inner.url) {
- return Err(RuntimeException {
- message: format!(
- "Failed to read package information from {} as the path does not exist",
- self.inner.url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to read package information from {} as the path does not exist",
+ self.inner.url
+ ))
.into());
}
self.repo_dir = self.inner.url.clone();
@@ -73,10 +71,7 @@ impl GitDriver {
.unwrap_or("")
.to_string();
if !Cache::is_usable(&cache_vcs_dir) {
- return Err(RuntimeException {
- message: "GitDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new("GitDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string())
.into());
}
@@ -96,25 +91,19 @@ impl GitDriver {
fs.ensure_directory_exists(&dirname(&self.repo_dir))?;
if !is_writable(dirname(&self.repo_dir)) {
- return Err(RuntimeException {
- message: format!(
- "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
- self.inner.url,
- dirname(&self.repo_dir)
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
+ self.inner.url,
+ dirname(&self.repo_dir)
+ ))
.into());
}
if Preg::is_match(php_regex!(r"{^ssh://[^@]+@[^:]+:[^0-9]+}"), &self.inner.url) {
- return Err(InvalidArgumentException {
- message: format!(
- "The source URL {} is invalid, ssh URLs should have a port number after \":\".\nUse ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.",
- self.inner.url
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The source URL {} is invalid, ssh URLs should have a port number after \":\".\nUse ssh://git@example.com:22/path or just git@example.com:path if you do not want to provide a password or custom port.",
+ self.inner.url
+ ))
.into());
}
@@ -126,13 +115,10 @@ impl GitDriver {
);
if !git_util.sync_mirror(&self.inner.url, &self.repo_dir)? {
if !is_dir(&self.repo_dir) {
- return Err(RuntimeException {
- message: format!(
- "Failed to clone {} to read package information from it",
- self.inner.url
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to clone {} to read package information from it",
+ self.inner.url
+ ))
.into());
}
self.inner.io.write_error3(&format!(
@@ -250,13 +236,10 @@ impl GitDriver {
identifier: &str,
) -> anyhow::Result<Option<String>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid git identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid git identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -283,13 +266,10 @@ impl GitDriver {
identifier: &str,
) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid git identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid git identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -459,7 +439,7 @@ impl GitDriver {
) {
Ok(_) => Ok(true),
Err(e) => {
- if e.downcast_ref::<RuntimeException>().is_some() {
+ if e.is_instanceof::<RuntimeException>() {
Ok(false)
} else {
Err(e)
@@ -543,7 +523,7 @@ impl crate::repository::vcs::VcsDriverInterface for GitDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/github_driver.rs b/crates/shirabe/src/repository/vcs/github_driver.rs
index d656ae61..72bcc8ae 100644
--- a/crates/shirabe/src/repository/vcs/github_driver.rs
+++ b/crates/shirabe/src/repository/vcs/github_driver.rs
@@ -15,6 +15,7 @@ use crate::util::http::Response;
use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, PhpMixed, RuntimeException, array_diff, array_key_exists, array_map,
array_search_mixed, base64_decode, basename, empty, explode, extension_loaded, in_array_loose,
@@ -77,13 +78,10 @@ impl GitHubDriver {
&self.inner.url,
Some(&mut match_),
) {
- return Err(InvalidArgumentException {
- message: format!(
- "The GitHub repository URL {} is invalid.",
- self.inner.url.clone(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The GitHub repository URL {} is invalid.",
+ self.inner.url.clone(),
+ ))
.into());
}
@@ -737,7 +735,7 @@ impl GitHubDriver {
);
let mut resource = self
.get_contents(&resource_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
// The GitHub contents API only returns files up to 1MB as base64 encoded files
@@ -765,7 +763,7 @@ impl GitHubDriver {
.to_string();
resource = self
.get_contents(&git_url, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
}
@@ -789,10 +787,10 @@ impl GitHubDriver {
let content = match content {
Some(c) => String::from_utf8_lossy(&c).to_string(),
None => {
- return Err(RuntimeException {
- message: format!("Could not retrieve {} for {}", file, identifier),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Could not retrieve {} for {}",
+ file, identifier
+ ))
.into());
}
};
@@ -817,7 +815,7 @@ impl GitHubDriver {
);
let commit = self
.get_contents(&resource, false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
let date_str = match commit {
@@ -853,7 +851,7 @@ impl GitHubDriver {
loop {
let response = self
.get_contents(resource.as_deref().unwrap_or(""), false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let tags_data = response.decode_json()?;
if let PhpMixed::List(ref list) = tags_data {
for tag in list {
@@ -903,7 +901,7 @@ impl GitHubDriver {
loop {
let response = self
.get_contents(resource.as_deref().unwrap_or(""), false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let branch_data = response.decode_json()?;
if let PhpMixed::List(ref list) = branch_data {
for branch in list {
@@ -1015,7 +1013,7 @@ impl GitHubDriver {
&mut self,
url: &str,
fetching_repo_data: bool,
- ) -> anyhow::Result<Response, TransportException> {
+ ) -> anyhow::Result<Response, Box<TransportException>> {
let response_result = self.inner.get_contents(url);
match response_result {
Ok(r) => Ok(r),
@@ -1028,7 +1026,7 @@ impl GitHubDriver {
)
.map_err(|err| TransportException::new(err.to_string(), 0))?;
- match e.code {
+ match e.get_code() {
401 | 404 => {
// try to authorize only if we are fetching the main /repos/foo/bar data, otherwise it must be a real 404
if !fetching_repo_data {
@@ -1178,10 +1176,10 @@ impl GitHubDriver {
};
}
Err(e) => {
- if e.code == 499 {
+ if e.get_code() == 499 {
self.attempt_clone_fallback(Some(&e))?;
} else {
- return Err(e.into());
+ return Err((*e).into());
}
}
}
@@ -1232,13 +1230,11 @@ impl GitHubDriver {
e: Option<&TransportException>,
) -> anyhow::Result<bool> {
if !self.allow_git_fallback {
- return Err(RuntimeException {
- message: format!(
- "Fallback to git driver disabled{}",
- e.map(|e| format!(": {}", e.message)).unwrap_or_default()
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Fallback to git driver disabled{}",
+ e.map(|e| format!(": {}", e.get_message()))
+ .unwrap_or_default()
+ ))
.into());
}
@@ -1269,11 +1265,9 @@ impl GitHubDriver {
pub(crate) fn setup_git_driver(&mut self, url: &str) -> anyhow::Result<()> {
if !self.allow_git_fallback {
- return Err(RuntimeException {
- message: "Fallback to git driver disabled".to_string(),
- code: 0,
- }
- .into());
+ return Err(
+ RuntimeException::new("Fallback to git driver disabled".to_string()).into(),
+ );
}
let mut repo_config: IndexMap<String, PhpMixed> = IndexMap::new();
repo_config.insert("url".to_string(), PhpMixed::String(url.to_string()));
@@ -1377,7 +1371,7 @@ impl crate::repository::vcs::VcsDriverInterface for GitHubDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/gitlab_driver.rs b/crates/shirabe/src/repository/vcs/gitlab_driver.rs
index 5fe513f6..8432ed65 100644
--- a/crates/shirabe/src/repository/vcs/gitlab_driver.rs
+++ b/crates/shirabe/src/repository/vcs/gitlab_driver.rs
@@ -16,6 +16,7 @@ use crate::util::http::Response;
use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_search_mixed,
array_shift, ctype_alnum, empty, explode, extension_loaded, implode, in_array_loose, is_array,
@@ -82,13 +83,10 @@ impl GitLabDriver {
pub fn initialize(&mut self) -> anyhow::Result<()> {
let mut match_: IndexMap<CaptureKey, String> = IndexMap::new();
if !Preg::is_match3(Self::URL_REGEX, &self.inner.url, Some(&mut match_)) {
- return Err(InvalidArgumentException {
- message: format!(
- "The GitLab repository URL {} is invalid. It must be the HTTP URL of a GitLab project.",
- self.inner.url.clone(),
- ),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "The GitLab repository URL {} is invalid. It must be the HTTP URL of a GitLab project.",
+ self.inner.url.clone(),
+ ))
.into());
}
@@ -134,13 +132,10 @@ impl GitLabDriver {
let origin = match origin {
Some(o) => o,
None => {
- return Err(LogicException {
- message: format!(
- "It should not be possible to create a gitlab driver with an unparsable origin URL ({})",
- self.inner.url
- ),
- code: 0,
- }
+ return Err(LogicException::new(format!(
+ "It should not be possible to create a gitlab driver with an unparsable origin URL ({})",
+ self.inner.url
+ ))
.into());
}
};
@@ -153,10 +148,9 @@ impl GitLabDriver {
{
// https treated as a synonym for http.
if !matches!(protocol, "git" | "http" | "https") {
- return Err(RuntimeException {
- message: "gitlab-protocol must be one of git, http.".to_string(),
- code: 0,
- }
+ return Err(RuntimeException::new(
+ "gitlab-protocol must be one of git, http.".to_string(),
+ )
.into());
}
self.protocol = if protocol == "git" {
@@ -424,8 +418,8 @@ impl GitLabDriver {
let content = match self.get_contents(&resource, false) {
Ok(response) => response.get_body().map(|s| s.to_string()),
Err(e) => {
- if e.code != 404 {
- return Err(e.into());
+ if e.get_code() != 404 {
+ return Err((*e).into());
}
return Ok(None);
@@ -617,7 +611,7 @@ impl GitLabDriver {
loop {
let response = self
.get_contents(resource.as_deref().unwrap_or(""), false)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?;
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?;
let data = response.decode_json()?;
if let PhpMixed::List(ref list) = data {
@@ -676,7 +670,7 @@ impl GitLabDriver {
let resource = self.get_api_url();
let project = self
.get_contents(&resource, true)
- .map_err(|e| anyhow::anyhow!("{}", e.message))?
+ .map_err(|e| anyhow::anyhow!("{}", e.get_message()))?
.decode_json()?;
self.project = match project {
PhpMixed::Array(m) => Some(m),
@@ -769,7 +763,7 @@ impl GitLabDriver {
&mut self,
url: &str,
fetching_repo_data: bool,
- ) -> anyhow::Result<Response, TransportException> {
+ ) -> anyhow::Result<Response, Box<TransportException>> {
let response_result = self.inner.get_contents(url);
match response_result {
Ok(response) => {
@@ -839,21 +833,21 @@ impl GitLabDriver {
.and_then(|v| v.as_string())
== Some("disabled")
{
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"The GitLab repository is disabled in the project".to_string(),
400,
- ));
+ )));
}
if !empty(&json_map.get("id").cloned().unwrap_or(PhpMixed::Null)) {
self.is_private = false;
}
- return Err(TransportException::new(
+ return Err(Box::new(TransportException::new(
"GitLab API seems to not be authenticated as it did not return a default_branch"
.to_string(),
401,
- ));
+ )));
}
}
@@ -868,7 +862,7 @@ impl GitLabDriver {
)
.map_err(|err| TransportException::new(err.to_string(), 0))?;
- match e.code {
+ match e.get_code() {
401 | 404 => {
// try to authorize only if we are fetching the main /repos/foo/bar data, otherwise it must be a real 404
if !fetching_repo_data {
@@ -901,7 +895,9 @@ impl GitLabDriver {
self.inner.io.write_error3(
&format!(
"<warning>Failed to download {}/{}:{}</warning>",
- self.namespace, self.repository, e.message
+ self.namespace,
+ self.repository,
+ e.get_message()
),
true,
io_interface::NORMAL,
@@ -1142,7 +1138,7 @@ impl crate::repository::vcs::VcsDriverInterface for GitLabDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/hg_driver.rs b/crates/shirabe/src/repository/vcs/hg_driver.rs
index 0283ed38..41aeebd9 100644
--- a/crates/shirabe/src/repository/vcs/hg_driver.rs
+++ b/crates/shirabe/src/repository/vcs/hg_driver.rs
@@ -12,6 +12,7 @@ use crate::util::Url;
use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{PhpMixed, RuntimeException, dirname, is_dir, is_writable, php_regex};
#[derive(Debug)]
@@ -53,10 +54,7 @@ impl HgDriver {
.unwrap_or("")
.to_string();
if !Cache::is_usable(&cache_vcs_dir) {
- return Err(RuntimeException {
- message: "HgDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
- code: 0,
- }.into());
+ return Err(RuntimeException::new("HgDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string()).into());
}
let sanitized = Preg::replace(
@@ -70,13 +68,10 @@ impl HgDriver {
fs.ensure_directory_exists(&cache_vcs_dir)?;
if !is_writable(dirname(&self.repo_dir)) {
- return Err(RuntimeException {
- message: format!(
- "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
- self.inner.url, cache_vcs_dir
- ),
- code: 0,
- }.into());
+ return Err(RuntimeException::new(format!(
+ "Can not clone {} to access package information. The \"{}\" directory is not writable by the current user.",
+ self.inner.url, cache_vcs_dir
+ )).into());
}
self.inner.config.borrow_mut().prohibit_url_by_config(
@@ -167,13 +162,10 @@ impl HgDriver {
pub fn get_file_content(&self, file: &str, identifier: &str) -> anyhow::Result<Option<String>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -203,13 +195,10 @@ impl HgDriver {
identifier: &str,
) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
if identifier.starts_with('-') {
- return Err(RuntimeException {
- message: format!(
- "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
- identifier
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Invalid hg identifier detected. Identifier must not start with a -, given: {}",
+ identifier
+ ))
.into());
}
@@ -443,7 +432,7 @@ impl crate::repository::vcs::VcsDriverInterface for HgDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/perforce_driver.rs b/crates/shirabe/src/repository/vcs/perforce_driver.rs
index 452ac5a2..af16cd8c 100644
--- a/crates/shirabe/src/repository/vcs/perforce_driver.rs
+++ b/crates/shirabe/src/repository/vcs/perforce_driver.rs
@@ -79,10 +79,7 @@ impl PerforceDriver {
.unwrap_or("")
.to_string();
if !Cache::is_usable(&cache_vcs_dir) {
- return Err(RuntimeException {
- message: "PerforceDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string(),
- code: 0,
- }.into());
+ return Err(RuntimeException::new("PerforceDriver requires a usable cache directory, and it looks like you set it to be disabled".to_string()).into());
}
let repo_dir = format!("{}/{}", cache_vcs_dir, self.depot);
@@ -180,11 +177,10 @@ impl PerforceDriver {
}
pub fn get_contents(&self, _url: &str) -> anyhow::Result<Response> {
- Err(BadMethodCallException {
- message: "Not implemented/used in PerforceDriver".to_string(),
- code: 0,
- }
- .into())
+ Err(
+ BadMethodCallException::new("Not implemented/used in PerforceDriver".to_string())
+ .into(),
+ )
}
pub fn supports(
diff --git a/crates/shirabe/src/repository/vcs/svn_driver.rs b/crates/shirabe/src/repository/vcs/svn_driver.rs
index 716b1943..84e3a20d 100644
--- a/crates/shirabe/src/repository/vcs/svn_driver.rs
+++ b/crates/shirabe/src/repository/vcs/svn_driver.rs
@@ -14,6 +14,7 @@ use crate::util::Url;
use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
PhpMixed, RuntimeException, php_regex, stripos, strrpos, strtr, substr, trim,
};
@@ -199,14 +200,14 @@ impl SvnDriver {
Ok(c) => c,
Err(e) => {
// PHP catches only TransportException; other exceptions propagate uncaught.
- if e.downcast_ref::<TransportException>().is_none() {
+ if !e.is_instanceof::<TransportException>() {
return Err(e);
}
let message = e
- .downcast_ref::<TransportException>()
+ .catch::<TransportException>()
.unwrap()
- .message
- .clone();
+ .get_message()
+ .to_string();
if stripos(&message, "path not found").is_none()
&& stripos(&message, "svn: warning: W160013").is_none()
{
@@ -277,8 +278,8 @@ impl SvnDriver {
) {
Ok(o) => o,
Err(e) => {
- if let Some(e) = e.downcast_ref::<RuntimeException>() {
- return Err(TransportException::new(e.message.clone(), 0).into());
+ if let Some(e) = e.catch::<RuntimeException>() {
+ return Err(TransportException::new(e.get_message().to_string(), 0).into());
}
return Err(e);
}
@@ -567,24 +568,18 @@ impl SvnDriver {
Ok(o) => Ok(o),
Err(e) => {
if self.util.as_mut().unwrap().binary_version().is_none() {
- return Err(RuntimeException {
- message: format!(
- "Failed to load {}, svn was not found, check that it is installed and in your PATH env.\n\n{}",
- self.inner.url,
- self.inner.process.borrow().get_error_output(),
- ),
- code: 0,
- }
+ return Err(RuntimeException::new(format!(
+ "Failed to load {}, svn was not found, check that it is installed and in your PATH env.\n\n{}",
+ self.inner.url,
+ self.inner.process.borrow().get_error_output(),
+ ))
.into());
}
- Err(RuntimeException {
- message: format!(
- "Repository {} could not be processed, {}",
- self.inner.url, e,
- ),
- code: 0,
- }
+ Err(RuntimeException::new(format!(
+ "Repository {} could not be processed, {}",
+ self.inner.url, e,
+ ))
.into())
}
}
@@ -655,7 +650,7 @@ impl crate::repository::vcs::VcsDriverInterface for SvnDriver {
match self.get_composer_information(identifier) {
Ok(info) => Ok(info.is_some()),
Err(e) => {
- if e.downcast_ref::<TransportException>().is_some() {
+ if e.is_instanceof::<TransportException>() {
Ok(false)
} else {
Err(e)
diff --git a/crates/shirabe/src/repository/vcs/vcs_driver.rs b/crates/shirabe/src/repository/vcs/vcs_driver.rs
index 3321201c..42f679df 100644
--- a/crates/shirabe/src/repository/vcs/vcs_driver.rs
+++ b/crates/shirabe/src/repository/vcs/vcs_driver.rs
@@ -13,6 +13,7 @@ use crate::util::http::Response;
use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{DATE_RFC3339, PhpMixed, extension_loaded, php_regex};
#[derive(Debug)]
@@ -66,7 +67,7 @@ impl VcsDriverBase {
"http"
}
- pub fn get_contents(&self, url: &str) -> anyhow::Result<Response, TransportException> {
+ pub fn get_contents(&self, url: &str) -> anyhow::Result<Response, Box<TransportException>> {
let options_mixed = self
.repo_config
.get("options")
@@ -79,9 +80,11 @@ impl VcsDriverBase {
self.http_downloader
.borrow_mut()
.get(url, options)
- .map_err(|e| match e.downcast::<TransportException>() {
- Ok(te) => te,
- Err(other) => TransportException::new(other.to_string(), 0),
+ .map_err(|e| {
+ Box::new(match e.catch::<TransportException>() {
+ Some(te) => te.clone(),
+ None => TransportException::new(e.to_string(), 0),
+ })
})
}
@@ -299,7 +302,7 @@ pub trait VcsDriver: VcsDriverInterface {
"http"
}
- fn get_contents(&self, url: &str) -> anyhow::Result<Response, TransportException> {
+ fn get_contents(&self, url: &str) -> anyhow::Result<Response, Box<TransportException>> {
let options_mixed = self
.repo_config()
.get("options")
@@ -312,9 +315,11 @@ pub trait VcsDriver: VcsDriverInterface {
self.http_downloader()
.borrow_mut()
.get(url, options)
- .map_err(|e| match e.downcast::<TransportException>() {
- Ok(te) => te,
- Err(other) => TransportException::new(other.to_string(), 0),
+ .map_err(|e| {
+ Box::new(match e.catch::<TransportException>() {
+ Some(te) => te.clone(),
+ None => TransportException::new(e.to_string(), 0),
+ })
})
}
diff --git a/crates/shirabe/src/repository/vcs_repository.rs b/crates/shirabe/src/repository/vcs_repository.rs
index 521d7aea..2b811c78 100644
--- a/crates/shirabe/src/repository/vcs_repository.rs
+++ b/crates/shirabe/src/repository/vcs_repository.rs
@@ -28,6 +28,7 @@ use crate::util::ProcessExecutor;
use crate::util::Url;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
+use shirabe_php_shim::Catch as _;
use shirabe_php_shim::{
InvalidArgumentException, PhpClass, PhpMixed, php_regex, str_replace, strpos,
};
@@ -305,10 +306,10 @@ impl VcsRepository {
let driver_url = self.url.clone();
self.ensure_driver();
if self.driver.borrow().is_none() {
- return Err(InvalidArgumentException {
- message: format!("No driver found to handle VCS repository {}", driver_url),
- code: 0,
- }
+ return Err(InvalidArgumentException::new(format!(
+ "No driver found to handle VCS repository {}",
+ driver_url
+ ))
.into());
}
*self.version_parser.borrow_mut() = Some(VersionParser::new());
@@ -351,7 +352,7 @@ impl VcsRepository {
}
Ok(None) => {}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& self.should_rethrow_transport_exception(te)
{
return Err(e);
@@ -367,7 +368,7 @@ impl VcsRepository {
}
}
Err(e) => {
- if let Some(te) = e.downcast_ref::<TransportException>()
+ if let Some(te) = e.catch::<TransportException>()
&& self.should_rethrow_transport_exception(te)
{
return Err(e);
@@ -575,7 +576,7 @@ impl VcsRepository {
Ok(())
})();
if let Err(e) = result {
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
self.version_transport_exceptions
.borrow_mut()
.entry("tags".to_string())
@@ -589,7 +590,7 @@ impl VcsRepository {
}
}
if is_very_verbose {
- let detail = if let Some(te) = e.downcast_ref::<TransportException>() {
+ let detail = if let Some(te) = e.catch::<TransportException>() {
format!(
"no composer file was found ({} HTTP status code)",
te.get_code()
@@ -786,7 +787,7 @@ impl VcsRepository {
Ok(())
})();
if let Err(e) = result {
- if let Some(te) = e.downcast_ref::<TransportException>() {
+ if let Some(te) = e.catch::<TransportException>() {
self.version_transport_exceptions
.borrow_mut()
.entry("branches".to_string())