aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/installer
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-27 00:49:33 +0900
committernsfisis <nsfisis@gmail.com>2026-05-27 00:54:09 +0900
commitcc5d73c05a0abca2eebcc8a6afa0b1543ee49850 (patch)
tree091a0d01232d927f13f3ab22700701804980f231 /crates/shirabe/src/installer
parentc5850d62beabef0a6bcc4cf6a179589c0ba8f405 (diff)
downloadphp-shirabe-cc5d73c05a0abca2eebcc8a6afa0b1543ee49850.tar.gz
php-shirabe-cc5d73c05a0abca2eebcc8a6afa0b1543ee49850.tar.zst
php-shirabe-cc5d73c05a0abca2eebcc8a6afa0b1543ee49850.zip
refactor(package): pass package handles by value throughout
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/installer')
-rw-r--r--crates/shirabe/src/installer/binary_installer.rs14
-rw-r--r--crates/shirabe/src/installer/binary_presence_interface.rs4
-rw-r--r--crates/shirabe/src/installer/installation_manager.rs64
-rw-r--r--crates/shirabe/src/installer/installer_interface.rs25
-rw-r--r--crates/shirabe/src/installer/library_installer.rs128
-rw-r--r--crates/shirabe/src/installer/metapackage_installer.rs55
-rw-r--r--crates/shirabe/src/installer/noop_installer.rs41
-rw-r--r--crates/shirabe/src/installer/plugin_installer.rs29
-rw-r--r--crates/shirabe/src/installer/project_installer.rs30
-rw-r--r--crates/shirabe/src/installer/suggested_packages_reporter.rs24
10 files changed, 183 insertions, 231 deletions
diff --git a/crates/shirabe/src/installer/binary_installer.rs b/crates/shirabe/src/installer/binary_installer.rs
index a555d83..64908bf 100644
--- a/crates/shirabe/src/installer/binary_installer.rs
+++ b/crates/shirabe/src/installer/binary_installer.rs
@@ -11,7 +11,7 @@ use shirabe_php_shim::{
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
-use crate::package::PackageInterface;
+use crate::package::PackageInterfaceHandle;
use crate::util::Filesystem;
use crate::util::Platform;
use crate::util::ProcessExecutor;
@@ -48,11 +48,11 @@ impl BinaryInstaller {
pub fn install_binaries(
&mut self,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
install_path: &str,
warn_on_overwrite: bool,
) {
- let binaries = self.get_binaries(package);
+ let binaries = self.get_binaries(package.clone());
if binaries.is_empty() {
return;
}
@@ -123,7 +123,7 @@ impl BinaryInstaller {
}
if bin_compat == "full" {
- self.install_full_binaries(&bin_path, &link, bin, package);
+ self.install_full_binaries(&bin_path, &link, bin, package.clone());
} else {
self.install_unixy_proxy_binaries(&bin_path, &link);
}
@@ -134,7 +134,7 @@ impl BinaryInstaller {
}
}
- pub fn remove_binaries(&mut self, package: &dyn PackageInterface) {
+ pub fn remove_binaries(&mut self, package: PackageInterfaceHandle) {
self.initialize_bin_dir();
let binaries = self.get_binaries(package);
@@ -192,7 +192,7 @@ impl BinaryInstaller {
}
/// @return string[]
- pub(crate) fn get_binaries(&self, package: &dyn PackageInterface) -> Vec<String> {
+ pub(crate) fn get_binaries(&self, package: PackageInterfaceHandle) -> Vec<String> {
package.get_binaries()
}
@@ -201,7 +201,7 @@ impl BinaryInstaller {
bin_path: &str,
link: &str,
bin: &str,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
) {
let mut link = link.to_string();
// add unixy support for cygwin and similar environments
diff --git a/crates/shirabe/src/installer/binary_presence_interface.rs b/crates/shirabe/src/installer/binary_presence_interface.rs
index 8830bab..2c4b2cc 100644
--- a/crates/shirabe/src/installer/binary_presence_interface.rs
+++ b/crates/shirabe/src/installer/binary_presence_interface.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Installer/BinaryPresenceInterface.php
-use crate::package::PackageInterface;
+use crate::package::PackageInterfaceHandle;
pub trait BinaryPresenceInterface {
- fn ensure_binaries_presence(&self, package: &dyn PackageInterface);
+ fn ensure_binaries_presence(&self, package: PackageInterfaceHandle);
}
diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs
index 5f312b6..95a1870 100644
--- a/crates/shirabe/src/installer/installation_manager.rs
+++ b/crates/shirabe/src/installer/installation_manager.rs
@@ -134,25 +134,24 @@ impl InstallationManager {
pub fn is_package_installed(
&mut self,
repo: &dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> Result<bool> {
if let Some(alias) = package.as_alias() {
let alias_of: PackageInterfaceHandle = alias.get_alias_of().into();
return Ok(
- repo.has_package(package.as_rc().borrow().as_package_interface())
- && self.is_package_installed(repo, &alias_of)?,
+ repo.has_package(package.clone()) && self.is_package_installed(repo, alias_of)?
);
}
Ok(self
.get_installer(&package.get_type())?
- .is_installed(repo, package.as_rc().borrow().as_package_interface()))
+ .is_installed(repo, package.clone()))
}
/// Install binary for the given package.
/// If the installer associated to this package doesn't handle that function, it'll do nothing.
- pub fn ensure_binaries_presence(&mut self, package: &dyn PackageInterface) {
- let installer = self.get_installer(package.get_type());
+ pub fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) {
+ let installer = self.get_installer(&package.get_type());
let installer = match installer {
Ok(i) => i,
Err(_e) => {
@@ -212,7 +211,7 @@ impl InstallationManager {
// TODO(phase-b): instanceof downcasts for UpdateOperation/InstallOperation
let is_update_or_install = false;
if is_update_or_install {
- let package: Option<&dyn PackageInterface> = None;
+ let package: Option<PackageInterfaceHandle> = None;
let _ = package;
let extra: IndexMap<String, PhpMixed> = IndexMap::new();
if extra
@@ -307,8 +306,8 @@ impl InstallationManager {
continue;
}
- let package: &dyn PackageInterface;
- let initial_package: Option<&dyn PackageInterface>;
+ let package: PackageInterfaceHandle;
+ let initial_package: Option<PackageInterfaceHandle>;
// TODO(phase-b): downcast for UpdateOperation / Install/Mark/Uninstall variants
let update_op: Option<&UpdateOperation> = None;
if op_type == "update" {
@@ -325,7 +324,7 @@ impl InstallationManager {
package = operation.get_package();
initial_package = None;
}
- let installer = self.get_installer(package.get_type())?;
+ let installer = self.get_installer(&package.get_type())?;
// TODO(phase-b): closure captures installer + package; needs Rc-shared installer/package
let _ = installer;
@@ -349,7 +348,7 @@ impl InstallationManager {
if op_type != "uninstall" {
// TODO(phase-c-promise): PHP collects every download and runs them concurrently via
// Loop::wait; the single-threaded loop awaits each serially instead.
- let installer = self.get_installer(package.get_type())?;
+ let installer = self.get_installer(&package.get_type())?;
installer.download(package, initial_package).await?;
}
}
@@ -450,8 +449,8 @@ impl InstallationManager {
continue;
}
- let package: &dyn PackageInterface;
- let initial_package: Option<&dyn PackageInterface>;
+ let package: PackageInterfaceHandle;
+ let initial_package: Option<PackageInterfaceHandle>;
let update_op: Option<&UpdateOperation> = None;
if op_type == "update" {
if let Some(_u) = update_op {
@@ -488,7 +487,7 @@ impl InstallationManager {
let _dispatcher = self.event_dispatcher.as_ref();
let _io = self.io.as_ref();
- let installer = self.get_installer(package.get_type())?;
+ let installer = self.get_installer(&package.get_type())?;
// TODO(phase-c-promise): PHP chains prepare()->then(install/update/uninstall)->then(cleanup
// + repo.write); the single-threaded loop awaits prepare and leaves the rest as phase-b work.
installer
@@ -526,8 +525,8 @@ impl InstallationManager {
/// Executes download operation.
///
/// @phpstan-return PromiseInterface<void|null>|null
- pub async fn download(&mut self, package: &dyn PackageInterface) -> Option<PhpMixed> {
- let installer = self.get_installer(package.get_type()).ok()?;
+ pub async fn download(&mut self, package: PackageInterfaceHandle) -> Option<PhpMixed> {
+ let installer = self.get_installer(&package.get_type()).ok()?;
let promise = installer.cleanup("install", package, None).await.ok()?;
promise
@@ -541,11 +540,11 @@ impl InstallationManager {
repo: &mut dyn InstalledRepositoryInterface,
operation: &InstallOperation,
) -> Option<PhpMixed> {
- let package = operation.get_package().clone();
+ let package = operation.get_package();
let package_type = package.get_type();
let installer = self.get_installer(&package_type).ok()?;
- let promise = installer.install(repo, &package).await.ok()?;
- self.mark_for_notification(&package);
+ let promise = installer.install(repo, package.clone()).await.ok()?;
+ self.mark_for_notification(package.clone());
promise
}
@@ -566,19 +565,19 @@ impl InstallationManager {
let promise = if initial_type == target_type {
let installer = self.get_installer(&initial_type).ok()?;
- let promise = installer.update(repo, &initial, &target).await.ok()?;
- self.mark_for_notification(&target);
+ let promise = installer.update(repo, initial, target.clone()).await.ok()?;
+ self.mark_for_notification(target.clone());
promise
} else {
// PHP: uninstall initial, then install target via the target-type installer.
let _ = self
.get_installer(&initial_type)
.ok()?
- .uninstall(repo, &initial)
+ .uninstall(repo, initial)
.await
.ok()?;
let installer = self.get_installer(&target_type).ok()?;
- installer.install(repo, &target).await.ok()?
+ installer.install(repo, target).await.ok()?
};
promise
@@ -592,11 +591,11 @@ impl InstallationManager {
repo: &mut dyn InstalledRepositoryInterface,
operation: &UninstallOperation,
) -> Option<PhpMixed> {
- let package = operation.get_package().clone();
+ let package = operation.get_package();
let package_type = package.get_type();
let installer = self.get_installer(&package_type).ok()?;
- installer.uninstall(repo, &package).await.ok()?
+ installer.uninstall(repo, package).await.ok()?
}
/// Executes markAliasInstalled operation.
@@ -607,11 +606,8 @@ impl InstallationManager {
) {
let package = operation.get_package();
- if !repo.has_package(package) {
- // TODO(phase-c): MarkAliasInstalledOperation::get_package() yields a borrowed
- // &AliasPackage; add_package now wants a shared PackageInterfaceHandle.
- let package_handle: PackageInterfaceHandle = todo!();
- repo.add_package(package_handle);
+ if !repo.has_package(package.clone().into()) {
+ repo.add_package(package.into());
}
}
@@ -623,14 +619,14 @@ impl InstallationManager {
) {
let package = operation.get_package();
- repo.remove_package(package);
+ repo.remove_package(package.clone().into());
}
/// Returns the installation path of a package
///
/// @return string|null absolute path to install to, which does not end with a slash, or null if the package does not have anything installed on disk
- pub fn get_install_path(&mut self, package: &dyn PackageInterface) -> Option<String> {
- let installer = self.get_installer(package.get_type()).ok()?;
+ pub fn get_install_path(&mut self, package: PackageInterfaceHandle) -> Option<String> {
+ let installer = self.get_installer(&package.get_type()).ok()?;
installer.get_install_path(package)
}
@@ -767,7 +763,7 @@ impl InstallationManager {
self.reset();
}
- fn mark_for_notification(&mut self, package: &PackageInterfaceHandle) {
+ fn mark_for_notification(&mut self, package: PackageInterfaceHandle) {
if let Some(notification_url) = package.get_notification_url() {
self.notifiable_packages
.entry(notification_url)
diff --git a/crates/shirabe/src/installer/installer_interface.rs b/crates/shirabe/src/installer/installer_interface.rs
index 8ab7efd..3056429 100644
--- a/crates/shirabe/src/installer/installer_interface.rs
+++ b/crates/shirabe/src/installer/installer_interface.rs
@@ -1,6 +1,5 @@
//! ref: composer/src/Composer/Installer/InstallerInterface.php
-use crate::package::PackageInterface;
use crate::package::PackageInterfaceHandle;
use crate::repository::InstalledRepositoryInterface;
use shirabe_php_shim::PhpMixed;
@@ -12,49 +11,49 @@ pub trait InstallerInterface: std::fmt::Debug {
fn is_installed(
&self,
repo: &dyn InstalledRepositoryInterface,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
) -> bool;
async fn download(
&self,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>>;
async fn prepare(
&self,
r#type: &str,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>>;
async fn install(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>>;
async fn update(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- initial: &PackageInterfaceHandle,
- target: &PackageInterfaceHandle,
+ initial: PackageInterfaceHandle,
+ target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>>;
async fn uninstall(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>>;
async fn cleanup(
&self,
r#type: &str,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>>;
- fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String>;
+ fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String>;
fn clone_box(&self) -> Box<dyn InstallerInterface> {
todo!()
diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs
index 17ec8d4..c1fedef 100644
--- a/crates/shirabe/src/installer/library_installer.rs
+++ b/crates/shirabe/src/installer/library_installer.rs
@@ -15,7 +15,6 @@ use crate::installer::BinaryInstaller;
use crate::installer::BinaryPresenceInterface;
use crate::installer::InstallerInterface;
use crate::io::IOInterface;
-use crate::package::PackageInterface;
use crate::package::PackageInterfaceHandle;
use crate::repository::InstalledRepositoryInterface;
use crate::util::Filesystem;
@@ -100,8 +99,8 @@ impl LibraryInstaller {
}
/// Make sure binaries are installed for a given package.
- pub fn ensure_binaries_presence(&mut self, package: &dyn PackageInterface) {
- let install_path = self.get_install_path(package).unwrap();
+ pub fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle) {
+ let install_path = self.get_install_path(package.clone()).unwrap();
self.binary_installer
.install_binaries(package, &install_path, false);
}
@@ -110,8 +109,8 @@ impl LibraryInstaller {
///
/// It is used for BC as getInstallPath tends to be overridden by
/// installer plugins but not getPackageBasePath
- pub(crate) fn get_package_base_path(&self, package: &dyn PackageInterface) -> String {
- let install_path = self.get_install_path(package).unwrap();
+ pub(crate) fn get_package_base_path(&self, package: PackageInterfaceHandle) -> String {
+ let install_path = self.get_install_path(package.clone()).unwrap();
let target_dir = package.get_target_dir();
if let Some(target_dir) = target_dir {
@@ -135,9 +134,9 @@ impl LibraryInstaller {
/// @phpstan-return PromiseInterface<void|null>|null
pub(crate) async fn install_code(
&self,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
- let download_path = self.get_install_path(package).unwrap();
+ let download_path = self.get_install_path(package.clone()).unwrap();
self.get_download_manager()
.borrow()
@@ -149,11 +148,11 @@ impl LibraryInstaller {
/// @phpstan-return PromiseInterface<void|null>|null
pub(crate) async fn update_code(
&self,
- initial: &dyn PackageInterface,
- target: &dyn PackageInterface,
+ initial: PackageInterfaceHandle,
+ target: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
- let initial_download_path = self.get_install_path(initial).unwrap();
- let target_download_path = self.get_install_path(target).unwrap();
+ let initial_download_path = self.get_install_path(initial.clone()).unwrap();
+ let target_download_path = self.get_install_path(target.clone()).unwrap();
if target_download_path != initial_download_path {
// if the target and initial dirs intersect, we force a remove + install
// to avoid the rename wiping the target dir as part of the initial dir cleanup
@@ -180,9 +179,9 @@ impl LibraryInstaller {
/// @phpstan-return PromiseInterface<void|null>|null
pub(crate) async fn remove_code(
&self,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
- let download_path = self.get_package_base_path(package);
+ let download_path = self.get_package_base_path(package.clone());
self.get_download_manager()
.borrow()
@@ -229,9 +228,9 @@ impl InstallerInterface for LibraryInstaller {
fn is_installed(
&self,
repo: &dyn InstalledRepositoryInterface,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
) -> bool {
- if !repo.has_package(package) {
+ if !repo.has_package(package.clone()) {
return false;
}
@@ -258,12 +257,12 @@ impl InstallerInterface for LibraryInstaller {
async fn download(
&self,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
// TODO(phase-b): initialize_vendor_dir requires &mut self
// self.initialize_vendor_dir();
- let download_path = self.get_install_path(package).unwrap();
+ let download_path = self.get_install_path(package.clone()).unwrap();
self.get_download_manager()
.borrow()
@@ -274,12 +273,12 @@ impl InstallerInterface for LibraryInstaller {
async fn prepare(
&self,
r#type: &str,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
// TODO(phase-b): initialize_vendor_dir requires &mut self
// self.initialize_vendor_dir();
- let download_path = self.get_install_path(package).unwrap();
+ let download_path = self.get_install_path(package.clone()).unwrap();
self.get_download_manager()
.borrow()
@@ -290,12 +289,12 @@ impl InstallerInterface for LibraryInstaller {
async fn cleanup(
&self,
r#type: &str,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
// TODO(phase-b): initialize_vendor_dir requires &mut self
// self.initialize_vendor_dir();
- let download_path = self.get_install_path(package).unwrap();
+ let download_path = self.get_install_path(package.clone()).unwrap();
self.get_download_manager()
.borrow()
@@ -306,35 +305,23 @@ impl InstallerInterface for LibraryInstaller {
async fn install(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
// TODO(phase-b): initialize_vendor_dir requires &mut self
// self.initialize_vendor_dir();
- let download_path = self
- .get_install_path(package.as_rc().borrow().as_package_interface())
- .unwrap();
+ let download_path = self.get_install_path(package.clone()).unwrap();
// remove the binaries if it appears the package files are missing
- if !Filesystem::is_readable(&download_path)
- && repo.has_package(package.as_rc().borrow().as_package_interface())
- {
- self.binary_installer
- .remove_binaries(package.as_rc().borrow().as_package_interface());
+ if !Filesystem::is_readable(&download_path) && repo.has_package(package.clone()) {
+ self.binary_installer.remove_binaries(package.clone());
}
- let _ = self
- .install_code(package.as_rc().borrow().as_package_interface())
- .await?;
+ let _ = self.install_code(package.clone()).await?;
- let install_path = self
- .get_install_path(package.as_rc().borrow().as_package_interface())
- .unwrap();
- self.binary_installer.install_binaries(
- package.as_rc().borrow().as_package_interface(),
- &install_path,
- true,
- );
- if !repo.has_package(package.as_rc().borrow().as_package_interface()) {
+ let install_path = self.get_install_path(package.clone()).unwrap();
+ self.binary_installer
+ .install_binaries(package.clone(), &install_path, true);
+ if !repo.has_package(package.clone()) {
repo.add_package(package.clone());
}
@@ -344,10 +331,10 @@ impl InstallerInterface for LibraryInstaller {
async fn update(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- initial: &PackageInterfaceHandle,
- target: &PackageInterfaceHandle,
+ initial: PackageInterfaceHandle,
+ target: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
- if !repo.has_package(initial.as_rc().borrow().as_package_interface()) {
+ if !repo.has_package(initial.clone()) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", initial),
code: 0,
@@ -358,25 +345,14 @@ impl InstallerInterface for LibraryInstaller {
// TODO(phase-b): initialize_vendor_dir requires &mut self
// self.initialize_vendor_dir();
- self.binary_installer
- .remove_binaries(initial.as_rc().borrow().as_package_interface());
- let _ = self
- .update_code(
- initial.as_rc().borrow().as_package_interface(),
- target.as_rc().borrow().as_package_interface(),
- )
- .await?;
+ self.binary_installer.remove_binaries(initial.clone());
+ let _ = self.update_code(initial.clone(), target.clone()).await?;
- let install_path = self
- .get_install_path(target.as_rc().borrow().as_package_interface())
- .unwrap();
- self.binary_installer.install_binaries(
- target.as_rc().borrow().as_package_interface(),
- &install_path,
- true,
- );
- repo.remove_package(initial.as_rc().borrow().as_package_interface());
- if !repo.has_package(target.as_rc().borrow().as_package_interface()) {
+ let install_path = self.get_install_path(target.clone()).unwrap();
+ self.binary_installer
+ .install_binaries(target.clone(), &install_path, true);
+ repo.remove_package(initial.clone());
+ if !repo.has_package(target.clone()) {
repo.add_package(target.clone());
}
@@ -386,9 +362,9 @@ impl InstallerInterface for LibraryInstaller {
async fn uninstall(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
- if !repo.has_package(package.as_rc().borrow().as_package_interface()) {
+ if !repo.has_package(package.clone()) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", package),
code: 0,
@@ -396,15 +372,11 @@ impl InstallerInterface for LibraryInstaller {
.into());
}
- let _ = self
- .remove_code(package.as_rc().borrow().as_package_interface())
- .await?;
+ let _ = self.remove_code(package.clone()).await?;
- let download_path =
- self.get_package_base_path(package.as_rc().borrow().as_package_interface());
- self.binary_installer
- .remove_binaries(package.as_rc().borrow().as_package_interface());
- repo.remove_package(package.as_rc().borrow().as_package_interface());
+ let download_path = self.get_package_base_path(package.clone());
+ self.binary_installer.remove_binaries(package.clone());
+ repo.remove_package(package.clone());
if strpos(&package.get_name(), "/").map_or(false, |pos| pos != 0) {
let package_vendor_dir = dirname(&download_path);
@@ -421,7 +393,7 @@ impl InstallerInterface for LibraryInstaller {
Ok(None)
}
- fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> {
+ fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> {
// TODO(phase-b): initialize_vendor_dir requires &mut self
// self.initialize_vendor_dir();
@@ -449,7 +421,7 @@ impl InstallerInterface for LibraryInstaller {
}
impl BinaryPresenceInterface for LibraryInstaller {
- fn ensure_binaries_presence(&self, _package: &dyn PackageInterface) {
+ fn ensure_binaries_presence(&self, _package: PackageInterfaceHandle) {
// TODO(phase-b): trait takes &self but LibraryInstaller::ensure_binaries_presence
// requires &mut self due to BinaryInstaller::install_binaries(&mut self, ...).
// Revisit the trait or use interior mutability.
diff --git a/crates/shirabe/src/installer/metapackage_installer.rs b/crates/shirabe/src/installer/metapackage_installer.rs
index fe41dd3..820023b 100644
--- a/crates/shirabe/src/installer/metapackage_installer.rs
+++ b/crates/shirabe/src/installer/metapackage_installer.rs
@@ -7,7 +7,6 @@ use crate::installer::InstallerInterface;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
use crate::io::io_interface;
-use crate::package::PackageInterface;
use crate::package::PackageInterfaceHandle;
use crate::repository::InstalledRepositoryInterface;
use anyhow::Result;
@@ -33,15 +32,15 @@ impl InstallerInterface for MetapackageInstaller {
fn is_installed(
&self,
repo: &dyn InstalledRepositoryInterface,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
) -> bool {
- repo.has_package(package)
+ repo.has_package(package.clone())
}
async fn download(
&self,
- _package: &dyn PackageInterface,
- _prev_package: Option<&dyn PackageInterface>,
+ _package: PackageInterfaceHandle,
+ _prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
Ok(None)
}
@@ -49,8 +48,8 @@ impl InstallerInterface for MetapackageInstaller {
async fn prepare(
&self,
_type: &str,
- _package: &dyn PackageInterface,
- _prev_package: Option<&dyn PackageInterface>,
+ _package: PackageInterfaceHandle,
+ _prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
Ok(None)
}
@@ -58,8 +57,8 @@ impl InstallerInterface for MetapackageInstaller {
async fn cleanup(
&self,
_type: &str,
- _package: &dyn PackageInterface,
- _prev_package: Option<&dyn PackageInterface>,
+ _package: PackageInterfaceHandle,
+ _prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
Ok(None)
}
@@ -67,18 +66,15 @@ impl InstallerInterface for MetapackageInstaller {
async fn install(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
self.io.write_error3(
- &format!(
- " - {}",
- InstallOperation::format(package.as_rc().borrow().as_package_interface(), false)
- ),
+ &format!(" - {}", InstallOperation::format(package.clone(), false)),
true,
io_interface::NORMAL,
);
- repo.add_package(package.clone());
+ repo.add_package(package);
Ok(None)
}
@@ -86,10 +82,10 @@ impl InstallerInterface for MetapackageInstaller {
async fn update(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- initial: &PackageInterfaceHandle,
- target: &PackageInterfaceHandle,
+ initial: PackageInterfaceHandle,
+ target: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
- if !repo.has_package(initial.as_rc().borrow().as_package_interface()) {
+ if !repo.has_package(initial.clone()) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", initial),
code: 0,
@@ -100,18 +96,14 @@ impl InstallerInterface for MetapackageInstaller {
self.io.write_error3(
&format!(
" - {}",
- UpdateOperation::format(
- initial.as_rc().borrow().as_package_interface(),
- target.as_rc().borrow().as_package_interface(),
- false
- )
+ UpdateOperation::format(initial.clone(), target.clone(), false)
),
true,
io_interface::NORMAL,
);
- repo.remove_package(initial.as_rc().borrow().as_package_interface());
- repo.add_package(target.clone());
+ repo.remove_package(initial.clone());
+ repo.add_package(target);
Ok(None)
}
@@ -119,9 +111,9 @@ impl InstallerInterface for MetapackageInstaller {
async fn uninstall(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
- if !repo.has_package(package.as_rc().borrow().as_package_interface()) {
+ if !repo.has_package(package.clone()) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", package),
code: 0,
@@ -130,20 +122,17 @@ impl InstallerInterface for MetapackageInstaller {
}
self.io.write_error3(
- &format!(
- " - {}",
- UninstallOperation::format(package.as_rc().borrow().as_package_interface(), false)
- ),
+ &format!(" - {}", UninstallOperation::format(package.clone(), false)),
true,
io_interface::NORMAL,
);
- repo.remove_package(package.as_rc().borrow().as_package_interface());
+ repo.remove_package(package.clone());
Ok(None)
}
- fn get_install_path(&self, _package: &dyn PackageInterface) -> Option<String> {
+ fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> {
None
}
}
diff --git a/crates/shirabe/src/installer/noop_installer.rs b/crates/shirabe/src/installer/noop_installer.rs
index 12e7e95..dad5231 100644
--- a/crates/shirabe/src/installer/noop_installer.rs
+++ b/crates/shirabe/src/installer/noop_installer.rs
@@ -1,7 +1,6 @@
//! ref: composer/src/Composer/Installer/NoopInstaller.php
use crate::installer::InstallerInterface;
-use crate::package::PackageInterface;
use crate::package::PackageInterfaceHandle;
use crate::repository::InstalledRepositoryInterface;
use shirabe_php_shim::{InvalidArgumentException, PhpMixed};
@@ -18,15 +17,15 @@ impl InstallerInterface for NoopInstaller {
fn is_installed(
&self,
repo: &dyn InstalledRepositoryInterface,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
) -> bool {
- repo.has_package(package)
+ repo.has_package(package.clone())
}
async fn download(
&self,
- _package: &dyn PackageInterface,
- _prev_package: Option<&dyn PackageInterface>,
+ _package: PackageInterfaceHandle,
+ _prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>> {
Ok(None)
}
@@ -34,8 +33,8 @@ impl InstallerInterface for NoopInstaller {
async fn prepare(
&self,
_type: &str,
- _package: &dyn PackageInterface,
- _prev_package: Option<&dyn PackageInterface>,
+ _package: PackageInterfaceHandle,
+ _prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>> {
Ok(None)
}
@@ -43,8 +42,8 @@ impl InstallerInterface for NoopInstaller {
async fn cleanup(
&self,
_type: &str,
- _package: &dyn PackageInterface,
- _prev_package: Option<&dyn PackageInterface>,
+ _package: PackageInterfaceHandle,
+ _prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>> {
Ok(None)
}
@@ -52,9 +51,9 @@ impl InstallerInterface for NoopInstaller {
async fn install(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
- if !repo.has_package(package.as_rc().borrow().as_package_interface()) {
+ if !repo.has_package(package.clone()) {
repo.add_package(package.clone());
}
@@ -64,10 +63,10 @@ impl InstallerInterface for NoopInstaller {
async fn update(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- initial: &PackageInterfaceHandle,
- target: &PackageInterfaceHandle,
+ initial: PackageInterfaceHandle,
+ target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
- if !repo.has_package(initial.as_rc().borrow().as_package_interface()) {
+ if !repo.has_package(initial.clone()) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", initial),
code: 0,
@@ -75,8 +74,8 @@ impl InstallerInterface for NoopInstaller {
.into());
}
- repo.remove_package(initial.as_rc().borrow().as_package_interface());
- if !repo.has_package(target.as_rc().borrow().as_package_interface()) {
+ repo.remove_package(initial.clone());
+ if !repo.has_package(target.clone()) {
repo.add_package(target.clone());
}
@@ -86,28 +85,28 @@ impl InstallerInterface for NoopInstaller {
async fn uninstall(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
- if !repo.has_package(package.as_rc().borrow().as_package_interface()) {
+ if !repo.has_package(package.clone()) {
return Err(InvalidArgumentException {
message: format!("Package is not installed: {}", package),
code: 0,
}
.into());
}
- repo.remove_package(package.as_rc().borrow().as_package_interface());
+ repo.remove_package(package.clone());
Ok(None)
}
- fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> {
+ fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> {
let target_dir = package.get_target_dir();
let pretty_name = package.get_pretty_name();
Some(if let Some(dir) = target_dir {
format!("{}/{}", pretty_name, dir)
} else {
- pretty_name.to_string()
+ pretty_name
})
}
}
diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs
index deadcb7..38fcb0d 100644
--- a/crates/shirabe/src/installer/plugin_installer.rs
+++ b/crates/shirabe/src/installer/plugin_installer.rs
@@ -6,7 +6,6 @@ use crate::installer::InstallerInterface;
use crate::installer::LibraryInstaller;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
-use crate::package::PackageInterface;
use crate::package::PackageInterfaceHandle;
use crate::plugin::PluginManager;
use crate::repository::InstalledRepositoryInterface;
@@ -47,7 +46,7 @@ impl PluginInstaller {
&mut self,
e: anyhow::Error,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> Result<()> {
self.inner.io.write_error(&format!(
"Plugin initialization failed ({}), uninstalling plugin",
@@ -72,7 +71,7 @@ impl InstallerInterface for PluginInstaller {
fn is_installed(
&self,
repo: &dyn InstalledRepositoryInterface,
- package: &dyn PackageInterface,
+ package: PackageInterfaceHandle,
) -> bool {
self.inner.is_installed(repo, package)
}
@@ -80,8 +79,8 @@ impl InstallerInterface for PluginInstaller {
async fn prepare(
&self,
r#type: &str,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
if (r#type == "install" || r#type == "update")
&& !self
@@ -104,8 +103,8 @@ impl InstallerInterface for PluginInstaller {
async fn download(
&self,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
let extra = package.get_extra();
let class = extra.get("class").cloned().unwrap_or(PhpMixed::Null);
@@ -125,7 +124,7 @@ impl InstallerInterface for PluginInstaller {
async fn install(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
self.inner.install(repo, package).await?;
@@ -139,8 +138,8 @@ impl InstallerInterface for PluginInstaller {
async fn update(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- initial: &PackageInterfaceHandle,
- target: &PackageInterfaceHandle,
+ initial: PackageInterfaceHandle,
+ target: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
self.inner.update(repo, initial, target).await?;
@@ -155,12 +154,12 @@ impl InstallerInterface for PluginInstaller {
async fn uninstall(
&mut self,
repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> Result<Option<PhpMixed>> {
// TODO(plugin): uninstall package from plugin manager
self.get_plugin_manager()
.borrow_mut()
- .uninstall_package(package.as_rc().borrow().as_package_interface());
+ .uninstall_package(package.clone());
self.inner.uninstall(repo, package).await
}
@@ -168,13 +167,13 @@ impl InstallerInterface for PluginInstaller {
async fn cleanup(
&self,
r#type: &str,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> Result<Option<PhpMixed>> {
self.inner.cleanup(r#type, package, prev_package).await
}
- fn get_install_path(&self, package: &dyn PackageInterface) -> Option<String> {
+ fn get_install_path(&self, package: PackageInterfaceHandle) -> Option<String> {
self.inner.get_install_path(package)
}
}
diff --git a/crates/shirabe/src/installer/project_installer.rs b/crates/shirabe/src/installer/project_installer.rs
index 129810b..6c8a279 100644
--- a/crates/shirabe/src/installer/project_installer.rs
+++ b/crates/shirabe/src/installer/project_installer.rs
@@ -2,7 +2,6 @@
use crate::downloader::DownloadManager;
use crate::installer::InstallerInterface;
-use crate::package::PackageInterface;
use crate::package::PackageInterfaceHandle;
use crate::repository::InstalledRepositoryInterface;
use crate::util::Filesystem;
@@ -39,15 +38,15 @@ impl InstallerInterface for ProjectInstaller {
fn is_installed(
&self,
_repo: &dyn InstalledRepositoryInterface,
- _package: &dyn PackageInterface,
+ _package: PackageInterfaceHandle,
) -> bool {
false
}
async fn download(
&self,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>> {
let install_path = &self.install_path;
if std::path::Path::new(install_path).exists()
@@ -72,8 +71,8 @@ impl InstallerInterface for ProjectInstaller {
async fn prepare(
&self,
r#type: &str,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>> {
self.download_manager
.borrow()
@@ -84,8 +83,8 @@ impl InstallerInterface for ProjectInstaller {
async fn cleanup(
&self,
r#type: &str,
- package: &dyn PackageInterface,
- prev_package: Option<&dyn PackageInterface>,
+ package: PackageInterfaceHandle,
+ prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>> {
self.download_manager
.borrow()
@@ -96,22 +95,19 @@ impl InstallerInterface for ProjectInstaller {
async fn install(
&mut self,
_repo: &mut dyn InstalledRepositoryInterface,
- package: &PackageInterfaceHandle,
+ package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
self.download_manager
.borrow()
- .install(
- package.as_rc().borrow().as_package_interface(),
- &self.install_path,
- )
+ .install(package, &self.install_path)
.await
}
async fn update(
&mut self,
_repo: &mut dyn InstalledRepositoryInterface,
- _initial: &PackageInterfaceHandle,
- _target: &PackageInterfaceHandle,
+ _initial: PackageInterfaceHandle,
+ _target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
Err(InvalidArgumentException {
message: "not supported".to_string(),
@@ -123,7 +119,7 @@ impl InstallerInterface for ProjectInstaller {
async fn uninstall(
&mut self,
_repo: &mut dyn InstalledRepositoryInterface,
- _package: &PackageInterfaceHandle,
+ _package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
Err(InvalidArgumentException {
message: "not supported".to_string(),
@@ -132,7 +128,7 @@ impl InstallerInterface for ProjectInstaller {
.into())
}
- fn get_install_path(&self, _package: &dyn PackageInterface) -> Option<String> {
+ fn get_install_path(&self, _package: PackageInterfaceHandle) -> Option<String> {
Some(self.install_path.clone())
}
}
diff --git a/crates/shirabe/src/installer/suggested_packages_reporter.rs b/crates/shirabe/src/installer/suggested_packages_reporter.rs
index 8faae9c..087e1b5 100644
--- a/crates/shirabe/src/installer/suggested_packages_reporter.rs
+++ b/crates/shirabe/src/installer/suggested_packages_reporter.rs
@@ -2,7 +2,7 @@
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
-use crate::package::PackageInterface;
+use crate::package::PackageInterfaceHandle;
use crate::repository::InstalledRepository;
use crate::repository::RepositoryInterface;
use indexmap::IndexMap;
@@ -41,8 +41,8 @@ impl SuggestedPackagesReporter {
self
}
- pub fn add_suggestions_from_package(&mut self, package: &dyn PackageInterface) -> &mut Self {
- let source = package.get_pretty_name().to_string();
+ pub fn add_suggestions_from_package(&mut self, package: PackageInterfaceHandle) -> &mut Self {
+ let source = package.get_pretty_name();
for (target, reason) in package.get_suggests() {
self.add_package(source.clone(), target.clone(), reason.clone());
}
@@ -54,9 +54,10 @@ impl SuggestedPackagesReporter {
&self,
mode: i64,
installed_repo: Option<&InstalledRepository>,
- only_dependents_of: Option<&dyn PackageInterface>,
+ only_dependents_of: Option<PackageInterfaceHandle>,
) {
- let suggested_packages = self.get_filtered_suggestions(installed_repo, only_dependents_of);
+ let suggested_packages =
+ self.get_filtered_suggestions(installed_repo, only_dependents_of.clone());
let mut suggesters: IndexMap<String, IndexMap<String, String>> = IndexMap::new();
let mut suggested: IndexMap<String, IndexMap<String, String>> = IndexMap::new();
@@ -142,7 +143,7 @@ impl SuggestedPackagesReporter {
pub fn output_minimalistic(
&self,
installed_repo: Option<&InstalledRepository>,
- only_dependents_of: Option<&dyn PackageInterface>,
+ only_dependents_of: Option<PackageInterfaceHandle>,
) {
let suggested_packages = self.get_filtered_suggestions(installed_repo, only_dependents_of);
if !suggested_packages.is_empty() {
@@ -156,7 +157,7 @@ impl SuggestedPackagesReporter {
fn get_filtered_suggestions(
&self,
installed_repo: Option<&InstalledRepository>,
- only_dependents_of: Option<&dyn PackageInterface>,
+ only_dependents_of: Option<PackageInterfaceHandle>,
) -> Vec<IndexMap<String, String>> {
let suggested_packages = self.get_packages();
let mut installed_names: Vec<String> = Vec::new();
@@ -168,13 +169,14 @@ impl SuggestedPackagesReporter {
let mut source_filter: Vec<String> = Vec::new();
if let Some(only_dependents_of) = only_dependents_of {
- source_filter = only_dependents_of
- .get_requires()
+ let requires = only_dependents_of.get_requires();
+ let dev_requires = only_dependents_of.get_dev_requires();
+ source_filter = requires
.values()
- .chain(only_dependents_of.get_dev_requires().values())
+ .chain(dev_requires.values())
.map(|link| link.get_target().to_string())
.collect();
- source_filter.push(only_dependents_of.get_name().to_string());
+ source_filter.push(only_dependents_of.get_name());
}
let mut suggestions: Vec<IndexMap<String, String>> = Vec::new();