aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/src/installer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe/src/installer')
-rw-r--r--crates/shirabe/src/installer/installation_manager.rs42
-rw-r--r--crates/shirabe/src/installer/installer_interface.rs17
-rw-r--r--crates/shirabe/src/installer/library_installer.rs12
-rw-r--r--crates/shirabe/src/installer/metapackage_installer.rs12
-rw-r--r--crates/shirabe/src/installer/noop_installer.rs12
-rw-r--r--crates/shirabe/src/installer/plugin_installer.rs47
-rw-r--r--crates/shirabe/src/installer/project_installer.rs10
7 files changed, 82 insertions, 70 deletions
diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs
index cf75469c..8d248a76 100644
--- a/crates/shirabe/src/installer/installation_manager.rs
+++ b/crates/shirabe/src/installer/installation_manager.rs
@@ -16,6 +16,7 @@ use crate::io::IOInterfaceImmutable;
use crate::io::io_interface;
use crate::package::PackageInterfaceHandle;
use crate::repository::InstalledRepositoryInterface;
+use crate::repository::InstalledRepositoryInterfaceHandle;
use crate::util::Platform;
use crate::util::r#loop::Loop;
use crate::util::sync_executor;
@@ -198,17 +199,18 @@ impl InstallationManager {
/// Checks whether provided package is installed in one of the registered installers.
pub fn is_package_installed(
&self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<bool> {
// For testing only (ref InstallationManagerMock::isPackageInstalled).
if self.mock.is_some() {
- return repo.has_package(package);
+ return repo.borrow_mut().has_package(package);
}
if let Some(alias) = package.as_alias() {
let alias_of: PackageInterfaceHandle = alias.get_alias_of().into();
- return Ok(repo.has_package(package)? && self.is_package_installed(repo, alias_of)?);
+ return Ok(repo.borrow_mut().has_package(package)?
+ && self.is_package_installed(repo, alias_of)?);
}
self.get_installer(&package.get_type())?
@@ -236,7 +238,7 @@ impl InstallationManager {
/// Executes solver operation.
pub fn execute(
&mut self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
operations: Vec<AnyOperation>,
dev_mode: bool,
run_scripts: bool,
@@ -248,6 +250,7 @@ impl InstallationManager {
// borrowed across the loop without also borrowing `&self`.
if let Some(mock) = self.mock.as_mut() {
let _ = (dev_mode, run_scripts, download_only);
+ let mut repo = repo.borrow_mut();
for operation in operations {
let trace = shirabe_php_shim::strip_tags(&operation.to_string());
match operation {
@@ -318,11 +321,6 @@ impl InstallationManager {
let all_operations: Vec<AnyOperation> = operations.clone();
- // The concurrent operation chains share the repository; each chain borrows it only in
- // synchronous sections, never across an await.
- let repo_cell: std::cell::RefCell<&mut dyn InstalledRepositoryInterface> =
- std::cell::RefCell::new(repo);
-
let result: anyhow::Result<()> = (|| -> anyhow::Result<()> {
// execute operations in batches to make sure download-modifying-plugins are installed
// before the other packages get downloaded
@@ -363,7 +361,7 @@ impl InstallationManager {
for batch_to_execute in batches {
sync_executor::block_on(self.download_and_execute_batch(
- &repo_cell,
+ repo,
batch_to_execute,
&mut cleanup_promises,
dev_mode,
@@ -394,7 +392,7 @@ impl InstallationManager {
// do a last write so that we write the repository even if nothing changed
// as that can trigger an update of some files like InstalledVersions.php if
// running a new composer version
- repo_cell.into_inner().write(dev_mode, self);
+ repo.borrow_mut().write(dev_mode, self);
Ok(())
}
@@ -402,7 +400,7 @@ impl InstallationManager {
#[allow(clippy::too_many_arguments, reason = "to keep PHP signature")]
async fn download_and_execute_batch(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
operations: IndexMap<i64, AnyOperation>,
cleanup_promises: &mut IndexMap<
i64,
@@ -544,7 +542,7 @@ impl InstallationManager {
async fn execute_batch(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
operations: IndexMap<i64, AnyOperation>,
cleanup_promises: &IndexMap<
i64,
@@ -577,10 +575,10 @@ impl InstallationManager {
}
match &operation {
AnyOperation::MarkAliasInstalled(op) => {
- self.mark_alias_installed(&mut **repo.borrow_mut(), op)?;
+ self.mark_alias_installed(&mut *repo.borrow_mut(), op)?;
}
AnyOperation::MarkAliasUninstalled(op) => {
- self.mark_alias_uninstalled(&mut **repo.borrow_mut(), op);
+ self.mark_alias_uninstalled(&mut *repo.borrow_mut(), op);
}
_ => {}
}
@@ -701,7 +699,7 @@ impl InstallationManager {
/// Executes install operation.
pub async fn install(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
operation: &InstallOperation,
) -> anyhow::Result<Option<PhpMixed>> {
let package = operation.get_package();
@@ -716,7 +714,7 @@ impl InstallationManager {
/// Executes update operation.
pub async fn update(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
operation: &UpdateOperation,
) -> anyhow::Result<Option<PhpMixed>> {
let initial = operation.get_initial_package().clone();
@@ -744,7 +742,7 @@ impl InstallationManager {
/// Uninstalls package.
pub async fn uninstall(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
operation: &UninstallOperation,
) -> anyhow::Result<Option<PhpMixed>> {
let package = operation.get_package();
@@ -1017,13 +1015,13 @@ pub trait InstallationManagerInterface: std::fmt::Debug {
fn disable_plugins(&mut self);
fn is_package_installed(
&mut self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<bool>;
fn ensure_binaries_presence(&mut self, package: PackageInterfaceHandle);
fn execute(
&mut self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
operations: Vec<AnyOperation>,
dev_mode: bool,
run_scripts: bool,
@@ -1053,7 +1051,7 @@ impl InstallationManagerInterface for InstallationManager {
fn is_package_installed(
&mut self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<bool> {
InstallationManager::is_package_installed(self, repo, package)
@@ -1065,7 +1063,7 @@ impl InstallationManagerInterface for InstallationManager {
fn execute(
&mut self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
operations: Vec<AnyOperation>,
dev_mode: bool,
run_scripts: bool,
diff --git a/crates/shirabe/src/installer/installer_interface.rs b/crates/shirabe/src/installer/installer_interface.rs
index f2c0cd7c..bc464735 100644
--- a/crates/shirabe/src/installer/installer_interface.rs
+++ b/crates/shirabe/src/installer/installer_interface.rs
@@ -3,7 +3,7 @@
use crate::installer::BinaryPresenceInterface;
use crate::installer::PluginInstaller;
use crate::package::PackageInterfaceHandle;
-use crate::repository::InstalledRepositoryInterface;
+use crate::repository::InstalledRepositoryInterfaceHandle;
use shirabe_php_shim::PhpMixed;
#[async_trait::async_trait(?Send)]
@@ -12,7 +12,7 @@ pub trait InstallerInterface: std::fmt::Debug {
fn is_installed(
&self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<bool>;
@@ -29,25 +29,26 @@ pub trait InstallerInterface: std::fmt::Debug {
prev_package: Option<PackageInterfaceHandle>,
) -> anyhow::Result<Option<PhpMixed>>;
- // install/update/uninstall take the repository behind a RefCell: the concurrent operation
- // chains share it, and implementations must borrow it only in synchronous sections (never
- // across an await).
+ // install/update/uninstall take the repository as a shared handle: the concurrent operation
+ // chains share it (and re-entrant flows like plugin registration reach the same repository
+ // through RepositoryManager), so implementations must borrow it only in synchronous
+ // sections (never across an await).
async fn install(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>>;
async fn update(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
initial: PackageInterfaceHandle,
target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>>;
async fn uninstall(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>>;
diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs
index 976c5a1f..c5a9608e 100644
--- a/crates/shirabe/src/installer/library_installer.rs
+++ b/crates/shirabe/src/installer/library_installer.rs
@@ -8,7 +8,7 @@ use crate::installer::BinaryPresenceInterface;
use crate::installer::InstallerInterface;
use crate::io::IOInterface;
use crate::package::PackageInterfaceHandle;
-use crate::repository::InstalledRepositoryInterface;
+use crate::repository::InstalledRepositoryInterfaceHandle;
use crate::util::Filesystem;
use crate::util::Platform;
use crate::util::Silencer;
@@ -241,10 +241,10 @@ impl InstallerInterface for LibraryInstaller {
fn is_installed(
&self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<bool> {
- if !repo.has_package(package.clone())? {
+ if !repo.borrow_mut().has_package(package.clone())? {
return Ok(false);
}
@@ -315,7 +315,7 @@ impl InstallerInterface for LibraryInstaller {
async fn install(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
self.initialize_vendor_dir();
@@ -346,7 +346,7 @@ impl InstallerInterface for LibraryInstaller {
async fn update(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
initial: PackageInterfaceHandle,
target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
@@ -380,7 +380,7 @@ impl InstallerInterface for LibraryInstaller {
async fn uninstall(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
if !repo.borrow_mut().has_package(package.clone())? {
diff --git a/crates/shirabe/src/installer/metapackage_installer.rs b/crates/shirabe/src/installer/metapackage_installer.rs
index 26032a6d..e2821fd3 100644
--- a/crates/shirabe/src/installer/metapackage_installer.rs
+++ b/crates/shirabe/src/installer/metapackage_installer.rs
@@ -8,7 +8,7 @@ use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
use crate::io::io_interface;
use crate::package::PackageInterfaceHandle;
-use crate::repository::InstalledRepositoryInterface;
+use crate::repository::InstalledRepositoryInterfaceHandle;
use shirabe_php_shim::{InvalidArgumentException, PhpMixed};
#[derive(Debug)]
@@ -30,10 +30,10 @@ impl InstallerInterface for MetapackageInstaller {
fn is_installed(
&self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<bool> {
- repo.has_package(package)
+ repo.borrow_mut().has_package(package)
}
async fn download(
@@ -64,7 +64,7 @@ impl InstallerInterface for MetapackageInstaller {
async fn install(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
self.io.write_error3(
@@ -81,7 +81,7 @@ impl InstallerInterface for MetapackageInstaller {
async fn update(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
initial: PackageInterfaceHandle,
target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
@@ -111,7 +111,7 @@ impl InstallerInterface for MetapackageInstaller {
async fn uninstall(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
if !repo.borrow_mut().has_package(package.clone())? {
diff --git a/crates/shirabe/src/installer/noop_installer.rs b/crates/shirabe/src/installer/noop_installer.rs
index d76ad4ad..68a2b981 100644
--- a/crates/shirabe/src/installer/noop_installer.rs
+++ b/crates/shirabe/src/installer/noop_installer.rs
@@ -2,7 +2,7 @@
use crate::installer::InstallerInterface;
use crate::package::PackageInterfaceHandle;
-use crate::repository::InstalledRepositoryInterface;
+use crate::repository::InstalledRepositoryInterfaceHandle;
use shirabe_php_shim::{InvalidArgumentException, PhpMixed};
#[derive(Debug)]
@@ -16,10 +16,10 @@ impl InstallerInterface for NoopInstaller {
fn is_installed(
&self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<bool> {
- repo.has_package(package)
+ repo.borrow_mut().has_package(package)
}
async fn download(
@@ -50,7 +50,7 @@ impl InstallerInterface for NoopInstaller {
async fn install(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
let mut repo = repo.borrow_mut();
@@ -63,7 +63,7 @@ impl InstallerInterface for NoopInstaller {
async fn update(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
initial: PackageInterfaceHandle,
target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
@@ -86,7 +86,7 @@ impl InstallerInterface for NoopInstaller {
async fn uninstall(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
let mut repo = repo.borrow_mut();
diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs
index c0473fd0..1e7a2636 100644
--- a/crates/shirabe/src/installer/plugin_installer.rs
+++ b/crates/shirabe/src/installer/plugin_installer.rs
@@ -8,7 +8,7 @@ use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
use crate::package::PackageInterfaceHandle;
use crate::plugin::PluginManager;
-use crate::repository::InstalledRepositoryInterface;
+use crate::repository::InstalledRepositoryInterfaceHandle;
use crate::util::Filesystem;
use crate::util::Platform;
use shirabe_php_shim::{PhpMixed, UnexpectedValueException, empty};
@@ -46,7 +46,7 @@ impl PluginInstaller {
async fn rollback_install(
&self,
e: anyhow::Error,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<()> {
self.inner.io.write_error(&format!(
@@ -79,7 +79,7 @@ impl InstallerInterface for PluginInstaller {
fn is_installed(
&self,
- repo: &mut dyn InstalledRepositoryInterface,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<bool> {
self.inner.is_installed(repo, package)
@@ -135,43 +135,56 @@ impl InstallerInterface for PluginInstaller {
async fn install(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
- self.inner.install(repo, package).await?;
+ self.inner.install(repo, package.clone()).await?;
- // TODO(plugin): register package in plugin manager after install, rollback on failure
Platform::workaround_filesystem_issues();
- // self.get_plugin_manager().register_package(package, true)?;
- // On error: self.rollback_install(e, repo, package)?;
+ let result =
+ self.get_plugin_manager()
+ .borrow_mut()
+ .register_package(package.clone(), true, false);
+ if let Err(e) = result {
+ self.rollback_install(e, repo, package).await?;
+ }
Ok(None)
}
async fn update(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
initial: PackageInterfaceHandle,
target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
- self.inner.update(repo, initial, target).await?;
+ self.inner
+ .update(repo, initial.clone(), target.clone())
+ .await?;
- // TODO(plugin): deactivate initial and register target in plugin manager after update, rollback on failure
Platform::workaround_filesystem_issues();
- // self.get_plugin_manager().deactivate_package(initial);
- // self.get_plugin_manager().register_package(target, true)?;
- // On error: self.rollback_install(e, repo, target)?;
+ let result = (|| -> anyhow::Result<()> {
+ self.get_plugin_manager()
+ .borrow_mut()
+ .deactivate_package(initial)?;
+ self.get_plugin_manager()
+ .borrow_mut()
+ .register_package(target.clone(), true, false)?;
+ Ok(())
+ })();
+ if let Err(e) = result {
+ self.rollback_install(e, repo, target).await?;
+ }
Ok(None)
}
async fn uninstall(
&self,
- repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
- // TODO(plugin): uninstall package from plugin manager
self.get_plugin_manager()
.borrow_mut()
- .uninstall_package(package.clone());
+ .uninstall_package(package.clone())?;
self.inner.uninstall(repo, package).await
}
diff --git a/crates/shirabe/src/installer/project_installer.rs b/crates/shirabe/src/installer/project_installer.rs
index 628e4252..6fee682f 100644
--- a/crates/shirabe/src/installer/project_installer.rs
+++ b/crates/shirabe/src/installer/project_installer.rs
@@ -3,7 +3,7 @@
use crate::downloader::DownloadManagerInterface;
use crate::installer::InstallerInterface;
use crate::package::PackageInterfaceHandle;
-use crate::repository::InstalledRepositoryInterface;
+use crate::repository::InstalledRepositoryInterfaceHandle;
use crate::util::Filesystem;
use shirabe_php_shim::{InvalidArgumentException, PhpMixed};
@@ -37,7 +37,7 @@ impl InstallerInterface for ProjectInstaller {
fn is_installed(
&self,
- _repo: &mut dyn InstalledRepositoryInterface,
+ _repo: &InstalledRepositoryInterfaceHandle,
_package: PackageInterfaceHandle,
) -> anyhow::Result<bool> {
Ok(false)
@@ -94,7 +94,7 @@ impl InstallerInterface for ProjectInstaller {
async fn install(
&self,
- _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ _repo: &InstalledRepositoryInterfaceHandle,
package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
self.download_manager
@@ -105,7 +105,7 @@ impl InstallerInterface for ProjectInstaller {
async fn update(
&self,
- _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ _repo: &InstalledRepositoryInterfaceHandle,
_initial: PackageInterfaceHandle,
_target: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
@@ -118,7 +118,7 @@ impl InstallerInterface for ProjectInstaller {
async fn uninstall(
&self,
- _repo: &std::cell::RefCell<&mut dyn InstalledRepositoryInterface>,
+ _repo: &InstalledRepositoryInterfaceHandle,
_package: PackageInterfaceHandle,
) -> anyhow::Result<Option<PhpMixed>> {
Err(InvalidArgumentException {