aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-28 03:31:41 +0900
committernsfisis <nsfisis@gmail.com>2026-05-28 03:32:04 +0900
commitc7f53c5d7d581ebf76803650c63ec615b1558dc8 (patch)
treec6d83819e82a83cf93ca737b661094a8ea800cec
parentcc5d73c05a0abca2eebcc8a6afa0b1543ee49850 (diff)
downloadphp-shirabe-refactor/composer-handles.tar.gz
php-shirabe-refactor/composer-handles.tar.zst
php-shirabe-refactor/composer-handles.zip
refactor(composer): represent composer via trait-based handlesrefactor/composer-handles
Replace the PartialComposer/Composer structs and the single Rc<RefCell<PartialOrFullComposer>> enum with PartialComposer and Composer traits (Composer: PartialComposer), InnerPartialComposer / InnerFullComposer data structs, and the handle types FullComposerHandle (impl Composer) and AnyComposerHandle (polymorphic enum, impl PartialComposer), plus their weak variants. Factory builds the full and partial graphs via separate Rc::new_cyclic branches that share a build_composer_base helper. Call sites now use trait methods that encapsulate borrowing instead of borrow_partial() / composer_full*(). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
-rw-r--r--crates/shirabe/src/command/about_command.rs1
-rw-r--r--crates/shirabe/src/command/archive_command.rs9
-rw-r--r--crates/shirabe/src/command/audit_command.rs6
-rw-r--r--crates/shirabe/src/command/base_command.rs30
-rw-r--r--crates/shirabe/src/command/base_dependency_command.rs3
-rw-r--r--crates/shirabe/src/command/bump_command.rs3
-rw-r--r--crates/shirabe/src/command/check_platform_reqs_command.rs3
-rw-r--r--crates/shirabe/src/command/clear_cache_command.rs1
-rw-r--r--crates/shirabe/src/command/create_project_command.rs6
-rw-r--r--crates/shirabe/src/command/diagnose_command.rs4
-rw-r--r--crates/shirabe/src/command/dump_autoload_command.rs3
-rw-r--r--crates/shirabe/src/command/exec_command.rs5
-rw-r--r--crates/shirabe/src/command/fund_command.rs1
-rw-r--r--crates/shirabe/src/command/home_command.rs1
-rw-r--r--crates/shirabe/src/command/init_command.rs6
-rw-r--r--crates/shirabe/src/command/install_command.rs3
-rw-r--r--crates/shirabe/src/command/licenses_command.rs3
-rw-r--r--crates/shirabe/src/command/mod.rs2
-rw-r--r--crates/shirabe/src/command/package_discovery_trait.rs15
-rw-r--r--crates/shirabe/src/command/reinstall_command.rs1
-rw-r--r--crates/shirabe/src/command/remove_command.rs7
-rw-r--r--crates/shirabe/src/command/require_command.rs10
-rw-r--r--crates/shirabe/src/command/run_script_command.rs1
-rw-r--r--crates/shirabe/src/command/script_alias_command.rs1
-rw-r--r--crates/shirabe/src/command/search_command.rs1
-rw-r--r--crates/shirabe/src/command/self_update_command.rs1
-rw-r--r--crates/shirabe/src/command/show_command.rs26
-rw-r--r--crates/shirabe/src/command/status_command.rs3
-rw-r--r--crates/shirabe/src/command/suggests_command.rs3
-rw-r--r--crates/shirabe/src/command/update_command.rs6
-rw-r--r--crates/shirabe/src/command/validate_command.rs3
-rw-r--r--crates/shirabe/src/composer.rs723
-rw-r--r--crates/shirabe/src/console/application.rs8
-rw-r--r--crates/shirabe/src/event_dispatcher/event_dispatcher.rs14
-rw-r--r--crates/shirabe/src/factory.rs434
-rw-r--r--crates/shirabe/src/installer.rs4
-rw-r--r--crates/shirabe/src/installer/installer_event.rs8
-rw-r--r--crates/shirabe/src/installer/library_installer.rs16
-rw-r--r--crates/shirabe/src/installer/package_event.rs8
-rw-r--r--crates/shirabe/src/installer/plugin_installer.rs4
-rw-r--r--crates/shirabe/src/plugin/plugin_interface.rs8
-rw-r--r--crates/shirabe/src/plugin/plugin_manager.rs39
-rw-r--r--crates/shirabe/src/repository/platform_repository.rs1
-rw-r--r--crates/shirabe/src/script/event.rs8
-rw-r--r--crates/shirabe/src/util/http_downloader.rs1
-rw-r--r--crates/shirabe/src/util/stream_context_factory.rs1
46 files changed, 720 insertions, 725 deletions
diff --git a/crates/shirabe/src/command/about_command.rs b/crates/shirabe/src/command/about_command.rs
index 3e74d6e..e3c3614 100644
--- a/crates/shirabe/src/command/about_command.rs
+++ b/crates/shirabe/src/command/about_command.rs
@@ -4,7 +4,6 @@ use crate::command::BaseCommand;
use crate::command::BaseCommandData;
use crate::command::HasBaseCommandData;
use crate::composer;
-use crate::composer::ComposerHandle;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
use shirabe_external_packages::symfony::component::console::input::InputInterface;
diff --git a/crates/shirabe/src/command/archive_command.rs b/crates/shirabe/src/command/archive_command.rs
index aab7b51..c777f54 100644
--- a/crates/shirabe/src/command/archive_command.rs
+++ b/crates/shirabe/src/command/archive_command.rs
@@ -8,7 +8,7 @@ use shirabe_external_packages::symfony::component::console::output::OutputInterf
use shirabe_php_shim::{LogicException, get_debug_type};
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::config::Config;
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
@@ -67,10 +67,10 @@ impl ArchiveCommand {
let composer = self.try_composer(None, None);
let config = if let Some(ref composer) = composer {
- let config = composer.borrow_partial().get_config();
+ let config = composer.get_config();
// TODO(plugin): dispatch CommandEvent
let command_event = CommandEvent::new(PluginEvents::COMMAND, "archive", input, output);
- let event_dispatcher = composer.borrow_partial().get_event_dispatcher();
+ let event_dispatcher = composer.get_event_dispatcher();
event_dispatcher
.borrow_mut()
.dispatch(Some(command_event.get_name()), None);
@@ -138,7 +138,6 @@ impl ArchiveCommand {
&& let Some(ref composer) = composer
{
composer
- .borrow_partial()
.get_event_dispatcher()
.borrow_mut()
.dispatch_script(
@@ -162,7 +161,7 @@ impl ArchiveCommand {
dest: &str,
file_name: Option<String>,
ignore_filters: bool,
- composer: Option<&PartialComposerHandle>,
+ composer: Option<&AnyComposerHandle>,
) -> Result<i64> {
let composer_guard = composer.map(crate::command::composer_full);
let owned_archive_manager;
diff --git a/crates/shirabe/src/command/audit_command.rs b/crates/shirabe/src/command/audit_command.rs
index ec8b495..5868b15 100644
--- a/crates/shirabe/src/command/audit_command.rs
+++ b/crates/shirabe/src/command/audit_command.rs
@@ -3,7 +3,7 @@
use crate::advisory::AuditConfig;
use crate::advisory::Auditor;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::console::input::InputOption;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -144,10 +144,10 @@ impl AuditCommand {
fn get_packages(
&self,
- composer: &PartialComposerHandle,
+ composer: &AnyComposerHandle,
input: &dyn InputInterface,
) -> Result<Vec<crate::package::PackageInterfaceHandle>> {
- let mut composer = crate::command::composer_full_mut(composer);
+ let composer = crate::command::composer_full(composer);
if input.get_option("locked").as_bool().unwrap_or(false) {
let locker = composer.get_locker().clone();
let mut locker = locker.borrow_mut();
diff --git a/crates/shirabe/src/command/base_command.rs b/crates/shirabe/src/command/base_command.rs
index 6b673ed..cf121dc 100644
--- a/crates/shirabe/src/command/base_command.rs
+++ b/crates/shirabe/src/command/base_command.rs
@@ -19,7 +19,7 @@ use std::rc::Rc;
use crate::advisory::AuditConfig;
use crate::advisory::Auditor;
use crate::command::SelfUpdateCommand;
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, PartialComposer};
use crate::config::Config;
use crate::console::Application;
use crate::console::input::InputArgument;
@@ -163,23 +163,23 @@ pub trait BaseCommand {
required: bool,
disable_plugins: Option<bool>,
disable_scripts: Option<bool>,
- ) -> Result<Option<PartialComposerHandle>>;
+ ) -> Result<Option<AnyComposerHandle>>;
/// Retrieves the default Composer\Composer instance or throws
fn require_composer(
&mut self,
disable_plugins: Option<bool>,
disable_scripts: Option<bool>,
- ) -> Result<PartialComposerHandle>;
+ ) -> Result<AnyComposerHandle>;
/// Retrieves the default Composer\Composer instance or null
fn try_composer(
&mut self,
disable_plugins: Option<bool>,
disable_scripts: Option<bool>,
- ) -> Option<PartialComposerHandle>;
+ ) -> Option<AnyComposerHandle>;
- fn set_composer(&mut self, composer: PartialComposerHandle);
+ fn set_composer(&mut self, composer: AnyComposerHandle);
/// Removes the cached composer instance
fn reset_composer(&mut self) -> Result<()>;
@@ -208,7 +208,7 @@ pub trait BaseCommand {
config: Option<IndexMap<String, PhpMixed>>,
disable_plugins: bool,
disable_scripts: Option<bool>,
- ) -> Result<PartialComposerHandle>;
+ ) -> Result<AnyComposerHandle>;
/// Returns preferSource and preferDist values based on the configuration.
fn get_preferred_install_options(
@@ -256,7 +256,7 @@ pub trait BaseCommand {
#[derive(Debug)]
pub struct BaseCommandData {
- pub(crate) composer: Option<PartialComposerHandle>,
+ pub(crate) composer: Option<AnyComposerHandle>,
pub(crate) io: Option<Rc<RefCell<dyn IOInterface>>>,
}
@@ -264,11 +264,11 @@ pub trait HasBaseCommandData {
fn base_command_data(&self) -> &BaseCommandData;
fn base_command_data_mut(&mut self) -> &mut BaseCommandData;
- fn composer(&self) -> Option<PartialComposerHandle> {
+ fn composer(&self) -> Option<AnyComposerHandle> {
self.base_command_data().composer.clone()
}
- fn composer_mut(&mut self) -> &mut Option<PartialComposerHandle> {
+ fn composer_mut(&mut self) -> &mut Option<AnyComposerHandle> {
&mut self.base_command_data_mut().composer
}
@@ -292,7 +292,7 @@ impl<C: HasBaseCommandData> BaseCommand for C {
required: bool,
disable_plugins: Option<bool>,
disable_scripts: Option<bool>,
- ) -> Result<Option<PartialComposerHandle>> {
+ ) -> Result<Option<AnyComposerHandle>> {
if required {
return Ok(Some(
self.require_composer(disable_plugins, disable_scripts)?,
@@ -306,7 +306,7 @@ impl<C: HasBaseCommandData> BaseCommand for C {
&mut self,
_disable_plugins: Option<bool>,
_disable_scripts: Option<bool>,
- ) -> Result<PartialComposerHandle> {
+ ) -> Result<AnyComposerHandle> {
// TODO(phase-b): depends on Application::get_composer, which is still stubbed.
let _ = RuntimeException {
message: String::new(),
@@ -319,12 +319,12 @@ impl<C: HasBaseCommandData> BaseCommand for C {
&mut self,
_disable_plugins: Option<bool>,
_disable_scripts: Option<bool>,
- ) -> Option<PartialComposerHandle> {
+ ) -> Option<AnyComposerHandle> {
// TODO(phase-b): depends on Application::get_composer, which is still stubbed.
todo!("try_composer pending Application::get_composer")
}
- fn set_composer(&mut self, composer: PartialComposerHandle) {
+ fn set_composer(&mut self, composer: AnyComposerHandle) {
*self.composer_mut() = Some(composer);
}
@@ -388,7 +388,7 @@ impl<C: HasBaseCommandData> BaseCommand for C {
);
// TODO(phase-b): event_dispatcher.dispatch expects Option<Event>; need wrapper from
// PreCommandRunEvent.
- let _ = composer.borrow_partial().get_event_dispatcher();
+ let _ = composer.get_event_dispatcher();
let _ = pre_command_run_event.get_name();
}
@@ -481,7 +481,7 @@ impl<C: HasBaseCommandData> BaseCommand for C {
config: Option<IndexMap<String, PhpMixed>>,
disable_plugins: bool,
disable_scripts: Option<bool>,
- ) -> Result<PartialComposerHandle> {
+ ) -> Result<AnyComposerHandle> {
let disable_plugins =
disable_plugins || input.has_parameter_option(&["--no-plugins"], false);
let disable_scripts = disable_scripts.unwrap_or(false)
diff --git a/crates/shirabe/src/command/base_dependency_command.rs b/crates/shirabe/src/command/base_dependency_command.rs
index 7a5300a..8634fa4 100644
--- a/crates/shirabe/src/command/base_dependency_command.rs
+++ b/crates/shirabe/src/command/base_dependency_command.rs
@@ -10,6 +10,7 @@ use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::Bound;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
use crate::package::CompletePackageInterface;
@@ -50,7 +51,7 @@ pub trait BaseDependencyCommand: BaseCommand {
inverted: bool,
) -> anyhow::Result<i64> {
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
// TODO(plugin): dispatch CommandEvent(PluginEvents::COMMAND, self.get_name(), input, output) via composer.get_event_dispatcher()
let mut repos: Vec<Box<dyn RepositoryInterface>> = vec![];
diff --git a/crates/shirabe/src/command/bump_command.rs b/crates/shirabe/src/command/bump_command.rs
index a1e5f35..784f570 100644
--- a/crates/shirabe/src/command/bump_command.rs
+++ b/crates/shirabe/src/command/bump_command.rs
@@ -9,6 +9,7 @@ use shirabe_external_packages::symfony::component::console::output::OutputInterf
use shirabe_php_shim::{PhpMixed, file_get_contents, file_put_contents, is_writable, strtolower};
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::factory::Factory;
@@ -134,7 +135,7 @@ impl BumpCommand {
}
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
let has_lock_file_disabled = !composer.get_config().borrow().has("lock")
|| composer
.get_config()
diff --git a/crates/shirabe/src/command/check_platform_reqs_command.rs b/crates/shirabe/src/command/check_platform_reqs_command.rs
index fd5edd9..a89ce15 100644
--- a/crates/shirabe/src/command/check_platform_reqs_command.rs
+++ b/crates/shirabe/src/command/check_platform_reqs_command.rs
@@ -9,6 +9,7 @@ use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputOption;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -55,7 +56,7 @@ impl CheckPlatformReqsCommand {
_output: &dyn OutputInterface,
) -> Result<i64> {
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
let io = self.get_io();
let no_dev = input.get_option("no-dev").as_bool().unwrap_or(false);
diff --git a/crates/shirabe/src/command/clear_cache_command.rs b/crates/shirabe/src/command/clear_cache_command.rs
index 4859a46..152b7a1 100644
--- a/crates/shirabe/src/command/clear_cache_command.rs
+++ b/crates/shirabe/src/command/clear_cache_command.rs
@@ -2,7 +2,6 @@
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
use crate::composer;
-use crate::composer::ComposerHandle;
use crate::factory::Factory;
use indexmap::IndexMap;
use shirabe_external_packages::symfony::component::console::input::InputInterface;
diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs
index d5a8a0c..14cf1f5 100644
--- a/crates/shirabe/src/command/create_project_command.rs
+++ b/crates/shirabe/src/command/create_project_command.rs
@@ -15,7 +15,7 @@ use shirabe_php_shim::{
use crate::advisory::Auditor;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::config::Config;
use crate::config::ConfigSourceInterface;
use crate::config::JsonConfigSource;
@@ -349,7 +349,7 @@ impl CreateProjectCommand {
}
}
- let mut composer = crate::command::composer_full_mut(&composer_handle);
+ let composer = crate::command::composer_full(&composer_handle);
let process = composer
.get_loop()
@@ -962,7 +962,7 @@ impl CreateProjectCommand {
config: Option<indexmap::IndexMap<String, PhpMixed>>,
disable_plugins: bool,
disable_scripts: Option<bool>,
- ) -> Result<PartialComposerHandle> {
+ ) -> Result<AnyComposerHandle> {
self.create_composer_instance(input, io, config, disable_plugins, disable_scripts)
}
diff --git a/crates/shirabe/src/command/diagnose_command.rs b/crates/shirabe/src/command/diagnose_command.rs
index c64fc39..a75e8c0 100644
--- a/crates/shirabe/src/command/diagnose_command.rs
+++ b/crates/shirabe/src/command/diagnose_command.rs
@@ -21,7 +21,7 @@ use shirabe_php_shim::{
use crate::advisory::Auditor;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
use crate::composer;
-use crate::composer::ComposerHandle;
+use crate::composer::{Composer, PartialComposer};
use crate::config::Config;
use crate::downloader::TransportException;
use crate::factory::Factory;
@@ -248,7 +248,7 @@ impl DiagnoseCommand {
));
if let Some(ref mut c) = composer {
- let mut c = crate::command::composer_full_mut(c);
+ let c = crate::command::composer_full(c);
io.write(&format!(
"Active plugins: {}",
implode(
diff --git a/crates/shirabe/src/command/dump_autoload_command.rs b/crates/shirabe/src/command/dump_autoload_command.rs
index 6f361da..bdab00a 100644
--- a/crates/shirabe/src/command/dump_autoload_command.rs
+++ b/crates/shirabe/src/command/dump_autoload_command.rs
@@ -6,6 +6,7 @@ use shirabe_external_packages::symfony::component::console::output::OutputInterf
use shirabe_php_shim::{InvalidArgumentException, PhpMixed, file_exists};
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputOption;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -48,7 +49,7 @@ impl DumpAutoloadCommand {
output: &dyn OutputInterface,
) -> Result<i64> {
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
// TODO(plugin): dispatch CommandEvent
let command_event =
diff --git a/crates/shirabe/src/command/exec_command.rs b/crates/shirabe/src/command/exec_command.rs
index 3f70cf8..824f09e 100644
--- a/crates/shirabe/src/command/exec_command.rs
+++ b/crates/shirabe/src/command/exec_command.rs
@@ -6,6 +6,7 @@ use shirabe_external_packages::symfony::component::console::output::OutputInterf
use shirabe_php_shim::{PhpMixed, RuntimeException, basename, chdir, getcwd, glob};
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::io::IOInterface;
@@ -87,7 +88,7 @@ impl ExecCommand {
{
let bins = self.get_binaries(true)?;
if bins.is_empty() {
- let bin_dir = crate::command::composer_full_mut(&composer)
+ let bin_dir = crate::command::composer_full(&composer)
.get_config()
.borrow_mut()
.get("bin-dir")
@@ -155,7 +156,7 @@ impl ExecCommand {
fn get_binaries(&mut self, for_display: bool) -> Result<Vec<String>> {
let composer = self.require_composer(None, None)?;
- let composer_ref = crate::command::composer_full_mut(&composer);
+ let composer_ref = crate::command::composer_full(&composer);
let bin_dir = composer_ref
.get_config()
.borrow_mut()
diff --git a/crates/shirabe/src/command/fund_command.rs b/crates/shirabe/src/command/fund_command.rs
index 340424f..3a671bd 100644
--- a/crates/shirabe/src/command/fund_command.rs
+++ b/crates/shirabe/src/command/fund_command.rs
@@ -13,6 +13,7 @@ use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchAllConstraint;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputOption;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
diff --git a/crates/shirabe/src/command/home_command.rs b/crates/shirabe/src/command/home_command.rs
index c048bfd..bd0e3aa 100644
--- a/crates/shirabe/src/command/home_command.rs
+++ b/crates/shirabe/src/command/home_command.rs
@@ -6,6 +6,7 @@ use shirabe_external_packages::symfony::component::console::output::OutputInterf
use shirabe_php_shim::{FILTER_VALIDATE_URL, PhpMixed, filter_var};
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::io::IOInterface;
diff --git a/crates/shirabe/src/command/init_command.rs b/crates/shirabe/src/command/init_command.rs
index 730658c..6fc34f2 100644
--- a/crates/shirabe/src/command/init_command.rs
+++ b/crates/shirabe/src/command/init_command.rs
@@ -19,7 +19,7 @@ use shirabe_php_shim::{
use crate::command::PackageDiscoveryTrait;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::console::input::InputOption;
use crate::factory::Factory;
use crate::io::IOInterface;
@@ -57,7 +57,7 @@ impl PackageDiscoveryTrait for InitCommand {
todo!()
}
- fn try_composer(&self) -> Option<PartialComposerHandle> {
+ fn try_composer(&self) -> Option<AnyComposerHandle> {
todo!()
}
@@ -65,7 +65,7 @@ impl PackageDiscoveryTrait for InitCommand {
&self,
disable_plugins: Option<bool>,
disable_scripts: Option<bool>,
- ) -> PartialComposerHandle {
+ ) -> AnyComposerHandle {
todo!()
}
diff --git a/crates/shirabe/src/command/install_command.rs b/crates/shirabe/src/command/install_command.rs
index 4c869f4..29c8aa1 100644
--- a/crates/shirabe/src/command/install_command.rs
+++ b/crates/shirabe/src/command/install_command.rs
@@ -7,6 +7,7 @@ use shirabe_php_shim::PhpMixed;
use crate::advisory::Auditor;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::installer::Installer;
@@ -102,7 +103,7 @@ impl InstallCommand {
}
let composer_handle = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer_handle);
+ let composer = crate::command::composer_full(&composer_handle);
if !composer.get_locker().borrow_mut().is_locked() && !HttpDownloader::is_curl_enabled() {
io.write_error("<warning>Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.</warning>");
diff --git a/crates/shirabe/src/command/licenses_command.rs b/crates/shirabe/src/command/licenses_command.rs
index add5b0b..9dbc3b5 100644
--- a/crates/shirabe/src/command/licenses_command.rs
+++ b/crates/shirabe/src/command/licenses_command.rs
@@ -12,6 +12,7 @@ use shirabe_external_packages::symfony::console::style::SymfonyStyle;
use shirabe_php_shim::{PhpMixed, RuntimeException, UnexpectedValueException};
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputOption;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -81,7 +82,7 @@ impl LicensesCommand {
output: &dyn OutputInterface,
) -> Result<i64> {
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
// TODO(plugin): dispatch COMMAND event for plugin hooks
let command_event = CommandEvent::new(PluginEvents::COMMAND, "licenses", input, output);
diff --git a/crates/shirabe/src/command/mod.rs b/crates/shirabe/src/command/mod.rs
index 4452f85..5e1b437 100644
--- a/crates/shirabe/src/command/mod.rs
+++ b/crates/shirabe/src/command/mod.rs
@@ -37,7 +37,7 @@ pub mod suggests_command;
pub mod update_command;
pub mod validate_command;
-pub(crate) use crate::composer::{composer_full, composer_full_mut};
+pub(crate) use crate::composer::composer_full;
pub use about_command::*;
pub use archive_command::*;
diff --git a/crates/shirabe/src/command/package_discovery_trait.rs b/crates/shirabe/src/command/package_discovery_trait.rs
index d0574c6..e43f401 100644
--- a/crates/shirabe/src/command/package_discovery_trait.rs
+++ b/crates/shirabe/src/command/package_discovery_trait.rs
@@ -15,7 +15,7 @@ use shirabe_php_shim::{
trim,
};
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, PartialComposer};
use crate::factory::Factory;
use crate::filter::platform_requirement_filter::IgnoreAllPlatformRequirementFilter;
use crate::filter::platform_requirement_filter::PlatformRequirementFilterFactory;
@@ -40,12 +40,12 @@ pub trait PackageDiscoveryTrait {
// PHP: trait dependencies (provided by BaseCommand)
fn get_io(&self) -> std::rc::Rc<std::cell::RefCell<dyn IOInterface>>;
- fn try_composer(&self) -> Option<PartialComposerHandle>;
+ fn try_composer(&self) -> Option<AnyComposerHandle>;
fn require_composer(
&self,
disable_plugins: Option<bool>,
disable_scripts: Option<bool>,
- ) -> PartialComposerHandle;
+ ) -> AnyComposerHandle;
fn get_platform_requirement_filter(
&self,
input: &dyn InputInterface,
@@ -218,10 +218,7 @@ pub trait PackageDiscoveryTrait {
// Collect existing packages
let composer = self.try_composer();
- let composer_ref = composer.as_ref().map(|c| c.borrow_partial());
- let repository_manager = composer_ref
- .as_ref()
- .map(|c| c.get_repository_manager().clone());
+ let repository_manager = composer.as_ref().map(|c| c.get_repository_manager());
let repository_manager_ref = repository_manager.as_ref().map(|rm| rm.borrow());
let installed_repo = repository_manager_ref
.as_ref()
@@ -236,7 +233,6 @@ pub trait PackageDiscoveryTrait {
drop(installed_repo);
drop(repository_manager_ref);
drop(repository_manager);
- drop(composer_ref);
drop(composer);
let io = self.get_io();
@@ -816,8 +812,7 @@ pub trait PackageDiscoveryTrait {
let mut similar_packages: IndexMap<String, i64> = IndexMap::new();
let composer_for_installed = self.require_composer(None, None);
- let composer_for_installed = composer_for_installed.borrow_partial();
- let repository_manager = composer_for_installed.get_repository_manager().clone();
+ let repository_manager = composer_for_installed.get_repository_manager();
let repository_manager = repository_manager.borrow();
let installed_repo = repository_manager.get_local_repository();
diff --git a/crates/shirabe/src/command/reinstall_command.rs b/crates/shirabe/src/command/reinstall_command.rs
index ad4739b..49f842a 100644
--- a/crates/shirabe/src/command/reinstall_command.rs
+++ b/crates/shirabe/src/command/reinstall_command.rs
@@ -9,6 +9,7 @@ use shirabe_external_packages::symfony::component::console::output::OutputInterf
use shirabe_php_shim::InvalidArgumentException;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputDefinitionItem;
use crate::console::input::InputOption;
diff --git a/crates/shirabe/src/command/remove_command.rs b/crates/shirabe/src/command/remove_command.rs
index 9ea7329..2b90f80 100644
--- a/crates/shirabe/src/command/remove_command.rs
+++ b/crates/shirabe/src/command/remove_command.rs
@@ -9,6 +9,7 @@ use shirabe_php_shim::{PhpMixed, UnexpectedValueException, array_map, strtolower
use crate::advisory::Auditor;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::config::ConfigSourceInterface;
use crate::config::JsonConfigSource;
use crate::console::input::InputArgument;
@@ -184,7 +185,7 @@ impl RemoveCommand {
if input.get_option("unused").as_bool().unwrap_or(false) {
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
{
let locker = composer.get_locker().clone();
let mut locker = locker.borrow_mut();
@@ -430,7 +431,7 @@ impl RemoveCommand {
// TODO(plugin): deactivate installed plugins
if let Some(composer_opt) = self.try_composer(None, None) {
- let mut composer_opt = crate::command::composer_full_mut(&composer_opt);
+ let composer_opt = crate::command::composer_full(&composer_opt);
composer_opt
.get_plugin_manager()
.borrow_mut()
@@ -439,7 +440,7 @@ impl RemoveCommand {
self.reset_composer();
let composer_handle = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer_handle);
+ let composer = crate::command::composer_full(&composer_handle);
if dry_run {
// TODO(phase-b): composer.get_package() returns &dyn RootPackageInterface; set_requires/set_dev_requires need &mut self; needs shared-ownership refactor
diff --git a/crates/shirabe/src/command/require_command.rs b/crates/shirabe/src/command/require_command.rs
index bf5f159..27626e7 100644
--- a/crates/shirabe/src/command/require_command.rs
+++ b/crates/shirabe/src/command/require_command.rs
@@ -17,7 +17,7 @@ use shirabe_php_shim::{
use crate::advisory::Auditor;
use crate::command::PackageDiscoveryTrait;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::dependency_resolver::Request;
@@ -72,7 +72,7 @@ impl PackageDiscoveryTrait for RequireCommand {
todo!()
}
- fn try_composer(&self) -> Option<PartialComposerHandle> {
+ fn try_composer(&self) -> Option<AnyComposerHandle> {
todo!()
}
@@ -80,7 +80,7 @@ impl PackageDiscoveryTrait for RequireCommand {
&self,
disable_plugins: Option<bool>,
disable_scripts: Option<bool>,
- ) -> PartialComposerHandle {
+ ) -> AnyComposerHandle {
todo!()
}
@@ -688,7 +688,7 @@ impl RequireCommand {
// Update packages
self.reset_composer()?;
let composer_handle = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer_handle);
+ let composer = crate::command::composer_full(&composer_handle);
self.dependency_resolution_completed = false;
// TODO(phase-b): add_listener expects a Callable enum; PHP closure should set
@@ -930,7 +930,7 @@ impl RequireCommand {
fixed: bool,
) -> Result<i64> {
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
let locker_is_locked = composer.get_locker().borrow_mut().is_locked();
let mut requirements: IndexMap<String, String> = IndexMap::new();
let mut version_selector = VersionSelector::new(
diff --git a/crates/shirabe/src/command/run_script_command.rs b/crates/shirabe/src/command/run_script_command.rs
index 9118463..8eb6cf2 100644
--- a/crates/shirabe/src/command/run_script_command.rs
+++ b/crates/shirabe/src/command/run_script_command.rs
@@ -7,6 +7,7 @@ use shirabe_external_packages::symfony::component::console::output::OutputInterf
use shirabe_php_shim::{InvalidArgumentException, PhpMixed, RuntimeException};
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::io::IOInterface;
diff --git a/crates/shirabe/src/command/script_alias_command.rs b/crates/shirabe/src/command/script_alias_command.rs
index 6499002..4306605 100644
--- a/crates/shirabe/src/command/script_alias_command.rs
+++ b/crates/shirabe/src/command/script_alias_command.rs
@@ -1,6 +1,7 @@
//! ref: composer/src/Composer/Command/ScriptAliasCommand.php
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::io::IOInterface;
diff --git a/crates/shirabe/src/command/search_command.rs b/crates/shirabe/src/command/search_command.rs
index 2033cfc..313f8b2 100644
--- a/crates/shirabe/src/command/search_command.rs
+++ b/crates/shirabe/src/command/search_command.rs
@@ -1,6 +1,7 @@
//! ref: composer/src/Composer/Command/SearchCommand.php
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::io::IOInterface;
diff --git a/crates/shirabe/src/command/self_update_command.rs b/crates/shirabe/src/command/self_update_command.rs
index fc22ab7..4f0fcf6 100644
--- a/crates/shirabe/src/command/self_update_command.rs
+++ b/crates/shirabe/src/command/self_update_command.rs
@@ -21,7 +21,6 @@ use shirabe_php_shim::{
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
use crate::composer;
-use crate::composer::ComposerHandle;
use crate::config::Config;
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs
index b72a986..3b50add 100644
--- a/crates/shirabe/src/command/show_command.rs
+++ b/crates/shirabe/src/command/show_command.rs
@@ -16,7 +16,7 @@ use shirabe_php_shim::{
use shirabe_semver::constraint::AnyConstraint;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::console::input::InputOption;
use crate::dependency_resolver::DefaultPolicy;
use crate::dependency_resolver::PolicyInterface;
@@ -277,7 +277,7 @@ impl ShowCommand {
installed_repo = Box::new(ir);
}
} else if input.get_option("all").as_bool() == Some(true) && composer.is_some() {
- let mut composer_ref = crate::command::composer_full_mut(composer.as_ref().unwrap());
+ let composer_ref = crate::command::composer_full(composer.as_ref().unwrap());
let local_repo_cloned = composer_ref
.get_repository_manager()
.borrow()
@@ -335,7 +335,7 @@ impl ShowCommand {
repos = Box::new(CompositeRepository::new(composite_input));
} else if input.get_option("locked").as_bool() == Some(true) {
if composer.is_none()
- || !crate::command::composer_full_mut(composer.as_ref().unwrap())
+ || !crate::command::composer_full(composer.as_ref().unwrap())
.get_locker()
.borrow_mut()
.is_locked()
@@ -346,7 +346,7 @@ impl ShowCommand {
}
.into());
}
- let mut composer_ref = crate::command::composer_full_mut(composer.as_ref().unwrap());
+ let composer_ref = crate::command::composer_full(composer.as_ref().unwrap());
let locker_rc = composer_ref.get_locker().clone();
let mut locker = locker_rc.borrow_mut();
let mut lr =
@@ -366,19 +366,9 @@ impl ShowCommand {
// TODO(phase-b): PHP shares the Composer object by reference. Phase B
// can't clone Composer, so we re-fetch via require_composer when missing
// but otherwise borrow the existing Option.
- let composer_local_owned;
- // Borrow guards that keep the Ref alive for the duration of the block.
- let _guard_from_existing;
let composer_local = match composer.as_ref() {
- Some(c) => {
- _guard_from_existing = crate::command::composer_full(c);
- &*_guard_from_existing
- }
- None => {
- composer_local_owned = self.require_composer(None, None)?;
- _guard_from_existing = crate::command::composer_full(&composer_local_owned);
- &*_guard_from_existing
- }
+ Some(c) => crate::command::composer_full(c),
+ None => crate::command::composer_full(&self.require_composer(None, None)?),
};
let root_pkg = composer_local.get_package();
@@ -2542,7 +2532,7 @@ impl ShowCommand {
fn find_latest_package(
&mut self,
package: PackageInterfaceHandle,
- composer: &PartialComposerHandle,
+ composer: &AnyComposerHandle,
platform_repo: &PlatformRepository,
major_only: bool,
minor_only: bool,
@@ -2680,7 +2670,7 @@ impl ShowCommand {
fn get_repository_set(
&mut self,
- composer: &PartialComposerHandle,
+ composer: &AnyComposerHandle,
) -> anyhow::Result<&mut RepositorySet> {
let composer = crate::command::composer_full(composer);
if self.repository_set.is_none() {
diff --git a/crates/shirabe/src/command/status_command.rs b/crates/shirabe/src/command/status_command.rs
index 9f66adf..87ab320 100644
--- a/crates/shirabe/src/command/status_command.rs
+++ b/crates/shirabe/src/command/status_command.rs
@@ -6,6 +6,7 @@ use shirabe_external_packages::symfony::component::console::input::InputInterfac
use shirabe_external_packages::symfony::component::console::output::OutputInterface;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputOption;
use crate::io::IOInterface;
use crate::package::dumper::ArrayDumper;
@@ -85,7 +86,7 @@ impl StatusCommand {
fn do_execute(&mut self, input: &dyn InputInterface) -> Result<i64> {
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
// TODO(phase-b): release the &mut self borrow held by get_io via clone_box.
let io_box = self.get_io().clone();
let io_ref = io_box.borrow();
diff --git a/crates/shirabe/src/command/suggests_command.rs b/crates/shirabe/src/command/suggests_command.rs
index aa1ae15..cab1ec8 100644
--- a/crates/shirabe/src/command/suggests_command.rs
+++ b/crates/shirabe/src/command/suggests_command.rs
@@ -1,6 +1,7 @@
//! ref: composer/src/Composer/Command/SuggestsCommand.php
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::installer::SuggestedPackagesReporter;
@@ -45,7 +46,7 @@ impl SuggestsCommand {
_output: &dyn OutputInterface,
) -> Result<i64> {
let composer = self.require_composer(None, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
let root_package_handle: crate::package::RootPackageInterfaceHandle =
composer.get_package().clone();
diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs
index f879283..c61e28a 100644
--- a/crates/shirabe/src/command/update_command.rs
+++ b/crates/shirabe/src/command/update_command.rs
@@ -18,7 +18,7 @@ use shirabe_semver::intervals::Intervals;
use crate::advisory::Auditor;
use crate::command::BumpCommand;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::dependency_resolver::request::{self, Request, UpdateAllowTransitiveDeps};
@@ -460,7 +460,7 @@ impl UpdateCommand {
io: &dyn IOInterface,
input: &dyn InputInterface,
output: &dyn OutputInterface,
- composer: &PartialComposerHandle,
+ composer: &AnyComposerHandle,
packages: Vec<String>,
) -> Result<Vec<String>> {
if !input.is_interactive() {
@@ -618,7 +618,7 @@ impl UpdateCommand {
.into())
}
- fn create_version_selector(&self, composer: &PartialComposerHandle) -> Result<VersionSelector> {
+ fn create_version_selector(&self, composer: &AnyComposerHandle) -> Result<VersionSelector> {
let composer = crate::command::composer_full(composer);
let mut repository_set = RepositorySet::new(
&composer.get_package().get_minimum_stability(),
diff --git a/crates/shirabe/src/command/validate_command.rs b/crates/shirabe/src/command/validate_command.rs
index 12eadd7..3e8fbf1 100644
--- a/crates/shirabe/src/command/validate_command.rs
+++ b/crates/shirabe/src/command/validate_command.rs
@@ -5,6 +5,7 @@ use shirabe_external_packages::symfony::component::console::input::InputInterfac
use shirabe_external_packages::symfony::component::console::output::OutputInterface;
use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData};
+use crate::composer::{Composer, PartialComposer};
use crate::console::input::InputArgument;
use crate::console::input::InputOption;
use crate::factory::Factory;
@@ -158,7 +159,7 @@ impl ValidateCommand {
let mut lock_errors: Vec<String> = vec![];
let composer = self.create_composer_instance(input, io_box.clone(), None, false, None)?;
- let mut composer = crate::command::composer_full_mut(&composer);
+ let composer = crate::command::composer_full(&composer);
let check_lock = (check_lock
&& composer
.get_config()
diff --git a/crates/shirabe/src/composer.rs b/crates/shirabe/src/composer.rs
index fe700cf..6a2337a 100644
--- a/crates/shirabe/src/composer.rs
+++ b/crates/shirabe/src/composer.rs
@@ -31,255 +31,315 @@ pub fn get_version() -> String {
VERSION.to_string()
}
+/// Interface for \Composer\PartialComposer. Implemented by every composer handle, since both a
+/// partial and a full composer expose these common members.
+pub trait PartialComposer {
+ fn set_package(&self, package: RootPackageInterfaceHandle);
+ fn get_package(&self) -> RootPackageInterfaceHandle;
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>);
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>>;
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>);
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>>;
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>);
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>>;
+ fn set_installation_manager(
+ &self,
+ manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
+ );
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>>;
+ fn set_event_dispatcher(
+ &self,
+ event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
+ );
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>>;
+ fn is_global(&self) -> bool;
+ fn set_global(&self);
+}
+
+/// Interface for \Composer\Composer (`extends PartialComposer`). Implemented only by fully-loaded
+/// composer handles, which additionally expose the full-only members below.
+pub trait Composer: PartialComposer {
+ fn set_locker(&self, locker: std::rc::Rc<std::cell::RefCell<Locker>>);
+ fn get_locker(&self) -> std::rc::Rc<std::cell::RefCell<Locker>>;
+ fn set_download_manager(&self, manager: std::rc::Rc<std::cell::RefCell<DownloadManager>>);
+ fn get_download_manager(&self) -> std::rc::Rc<std::cell::RefCell<DownloadManager>>;
+ // TODO(plugin): set_plugin_manager is part of the plugin API
+ fn set_plugin_manager(&self, manager: std::rc::Rc<std::cell::RefCell<PluginManager>>);
+ // TODO(plugin): get_plugin_manager is part of the plugin API
+ fn get_plugin_manager(&self) -> std::rc::Rc<std::cell::RefCell<PluginManager>>;
+ fn set_autoload_generator(
+ &self,
+ autoload_generator: std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>,
+ );
+ fn get_autoload_generator(&self) -> std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>;
+ fn set_archive_manager(&self, manager: std::rc::Rc<std::cell::RefCell<ArchiveManager>>);
+ fn get_archive_manager(&self) -> std::rc::Rc<std::cell::RefCell<ArchiveManager>>;
+}
+
/// Internal data type corresponding to \Composer\PartialComposer.
#[derive(Debug, Default)]
-pub struct PartialComposer {
- global: bool,
- package: Option<RootPackageInterfaceHandle>,
- r#loop: Option<std::rc::Rc<std::cell::RefCell<Loop>>>,
- repository_manager: Option<std::rc::Rc<std::cell::RefCell<RepositoryManager>>>,
- installation_manager: Option<std::rc::Rc<std::cell::RefCell<InstallationManager>>>,
- config: Option<std::rc::Rc<std::cell::RefCell<Config>>>,
- event_dispatcher: Option<std::rc::Rc<std::cell::RefCell<EventDispatcher>>>,
+pub(crate) struct InnerPartialComposer {
+ pub(crate) global: bool,
+ pub(crate) package: Option<RootPackageInterfaceHandle>,
+ pub(crate) r#loop: Option<std::rc::Rc<std::cell::RefCell<Loop>>>,
+ pub(crate) repository_manager: Option<std::rc::Rc<std::cell::RefCell<RepositoryManager>>>,
+ pub(crate) installation_manager: Option<std::rc::Rc<std::cell::RefCell<InstallationManager>>>,
+ pub(crate) config: Option<std::rc::Rc<std::cell::RefCell<Config>>>,
+ pub(crate) event_dispatcher: Option<std::rc::Rc<std::cell::RefCell<EventDispatcher>>>,
}
-impl PartialComposer {
- pub fn set_package(&mut self, package: RootPackageInterfaceHandle) {
- self.package = Some(package);
- }
+/// Internal data type corresponding to \Composer\Composer.
+#[derive(Debug, Default)]
+pub(crate) struct InnerFullComposer {
+ pub(crate) partial: InnerPartialComposer,
+ pub(crate) locker: Option<std::rc::Rc<std::cell::RefCell<Locker>>>,
+ pub(crate) download_manager: Option<std::rc::Rc<std::cell::RefCell<DownloadManager>>>,
+ // TODO(plugin): plugin_manager is part of the plugin API
+ pub(crate) plugin_manager: Option<std::rc::Rc<std::cell::RefCell<PluginManager>>>,
+ pub(crate) autoload_generator: Option<std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>>,
+ pub(crate) archive_manager: Option<std::rc::Rc<std::cell::RefCell<ArchiveManager>>>,
+}
- pub fn get_package(&self) -> &RootPackageInterfaceHandle {
- self.package.as_ref().unwrap()
- }
+/// Shared reference to a fully-loaded \Composer\Composer.
+/// Use this for parameters or fields typed as \Composer\Composer in PHP.
+#[derive(Debug, Clone)]
+pub struct FullComposerHandle(std::rc::Rc<std::cell::RefCell<InnerFullComposer>>);
- pub fn set_config(&mut self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
- self.config = Some(config);
+impl FullComposerHandle {
+ pub(crate) fn from_rc(rc: std::rc::Rc<std::cell::RefCell<InnerFullComposer>>) -> Self {
+ Self(rc)
}
- pub fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
- self.config.as_ref().unwrap().clone()
+ pub(crate) fn as_rc(&self) -> &std::rc::Rc<std::cell::RefCell<InnerFullComposer>> {
+ &self.0
}
- pub fn set_loop(&mut self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
- self.r#loop = Some(r#loop);
+ pub fn downgrade(&self) -> FullComposerWeakHandle {
+ FullComposerWeakHandle(std::rc::Rc::downgrade(&self.0))
}
+}
- pub fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
- self.r#loop.as_ref().unwrap().clone()
+impl PartialComposer for FullComposerHandle {
+ fn set_package(&self, package: RootPackageInterfaceHandle) {
+ self.0.borrow_mut().partial.package = Some(package);
}
-
- pub fn set_repository_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>,
- ) {
- self.repository_manager = Some(manager);
+ fn get_package(&self) -> RootPackageInterfaceHandle {
+ self.0.borrow().partial.package.as_ref().unwrap().clone()
}
-
- pub fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
- self.repository_manager.as_ref().unwrap().clone()
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
+ self.0.borrow_mut().partial.config = Some(config);
}
-
- pub fn set_installation_manager(
- &mut self,
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
+ self.0.borrow().partial.config.as_ref().unwrap().clone()
+ }
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
+ self.0.borrow_mut().partial.r#loop = Some(r#loop);
+ }
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
+ self.0.borrow().partial.r#loop.as_ref().unwrap().clone()
+ }
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>) {
+ self.0.borrow_mut().partial.repository_manager = Some(manager);
+ }
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
+ self.0
+ .borrow()
+ .partial
+ .repository_manager
+ .as_ref()
+ .unwrap()
+ .clone()
+ }
+ fn set_installation_manager(
+ &self,
manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
) {
- self.installation_manager = Some(manager);
+ self.0.borrow_mut().partial.installation_manager = Some(manager);
}
-
- pub fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
- self.installation_manager.as_ref().unwrap().clone()
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
+ self.0
+ .borrow()
+ .partial
+ .installation_manager
+ .as_ref()
+ .unwrap()
+ .clone()
}
-
- pub fn set_event_dispatcher(
- &mut self,
+ fn set_event_dispatcher(
+ &self,
event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
) {
- self.event_dispatcher = Some(event_dispatcher);
+ self.0.borrow_mut().partial.event_dispatcher = Some(event_dispatcher);
}
-
- pub fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
- self.event_dispatcher.as_ref().unwrap().clone()
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
+ self.0
+ .borrow()
+ .partial
+ .event_dispatcher
+ .as_ref()
+ .unwrap()
+ .clone()
}
-
- pub fn is_global(&self) -> bool {
- self.global
+ fn is_global(&self) -> bool {
+ self.0.borrow().partial.global
}
-
- pub fn set_global(&mut self) {
- self.global = true;
+ fn set_global(&self) {
+ self.0.borrow_mut().partial.global = true;
}
}
-/// Internal data type corresponding to \Composer\Composer.
-#[derive(Debug)]
-pub struct Composer {
- partial: PartialComposer,
- locker: Option<std::rc::Rc<std::cell::RefCell<Locker>>>,
- download_manager: Option<std::rc::Rc<std::cell::RefCell<DownloadManager>>>,
- // TODO(plugin): plugin_manager is part of the plugin API
- plugin_manager: Option<std::rc::Rc<std::cell::RefCell<PluginManager>>>,
- autoload_generator: Option<std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>>,
- archive_manager: Option<std::rc::Rc<std::cell::RefCell<ArchiveManager>>>,
-}
-
-impl Composer {
- pub fn new() -> Self {
- Self {
- partial: PartialComposer::default(),
- locker: None,
- download_manager: None,
- plugin_manager: None,
- autoload_generator: None,
- archive_manager: None,
- }
+impl Composer for FullComposerHandle {
+ fn set_locker(&self, locker: std::rc::Rc<std::cell::RefCell<Locker>>) {
+ self.0.borrow_mut().locker = Some(locker);
}
-
- pub fn set_locker(&mut self, locker: std::rc::Rc<std::cell::RefCell<Locker>>) {
- self.locker = Some(locker);
+ fn get_locker(&self) -> std::rc::Rc<std::cell::RefCell<Locker>> {
+ self.0.borrow().locker.as_ref().unwrap().clone()
}
-
- pub fn get_locker(&self) -> std::rc::Rc<std::cell::RefCell<Locker>> {
- self.locker.as_ref().unwrap().clone()
+ fn set_download_manager(&self, manager: std::rc::Rc<std::cell::RefCell<DownloadManager>>) {
+ self.0.borrow_mut().download_manager = Some(manager);
}
-
- pub fn set_download_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<DownloadManager>>,
- ) {
- self.download_manager = Some(manager);
+ fn get_download_manager(&self) -> std::rc::Rc<std::cell::RefCell<DownloadManager>> {
+ self.0.borrow().download_manager.as_ref().unwrap().clone()
}
-
- pub fn get_download_manager(&self) -> std::rc::Rc<std::cell::RefCell<DownloadManager>> {
- self.download_manager.as_ref().unwrap().clone()
+ fn set_plugin_manager(&self, manager: std::rc::Rc<std::cell::RefCell<PluginManager>>) {
+ self.0.borrow_mut().plugin_manager = Some(manager);
}
-
- pub fn set_archive_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<ArchiveManager>>,
+ fn get_plugin_manager(&self) -> std::rc::Rc<std::cell::RefCell<PluginManager>> {
+ self.0.borrow().plugin_manager.as_ref().unwrap().clone()
+ }
+ fn set_autoload_generator(
+ &self,
+ autoload_generator: std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>,
) {
- self.archive_manager = Some(manager);
+ self.0.borrow_mut().autoload_generator = Some(autoload_generator);
}
-
- pub fn get_archive_manager(&self) -> std::rc::Rc<std::cell::RefCell<ArchiveManager>> {
- self.archive_manager.as_ref().unwrap().clone()
+ fn get_autoload_generator(&self) -> std::rc::Rc<std::cell::RefCell<AutoloadGenerator>> {
+ self.0.borrow().autoload_generator.as_ref().unwrap().clone()
}
-
- // TODO(plugin): set_plugin_manager is part of the plugin API
- pub fn set_plugin_manager(&mut self, manager: std::rc::Rc<std::cell::RefCell<PluginManager>>) {
- self.plugin_manager = Some(manager);
+ fn set_archive_manager(&self, manager: std::rc::Rc<std::cell::RefCell<ArchiveManager>>) {
+ self.0.borrow_mut().archive_manager = Some(manager);
}
-
- // TODO(plugin): get_plugin_manager is part of the plugin API
- pub fn get_plugin_manager(&self) -> std::rc::Rc<std::cell::RefCell<PluginManager>> {
- self.plugin_manager.as_ref().unwrap().clone()
+ fn get_archive_manager(&self) -> std::rc::Rc<std::cell::RefCell<ArchiveManager>> {
+ self.0.borrow().archive_manager.as_ref().unwrap().clone()
}
+}
- pub fn set_autoload_generator(
- &mut self,
- autoload_generator: std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>,
- ) {
- self.autoload_generator = Some(autoload_generator);
- }
+/// Shared weak reference to a fully-loaded \Composer\Composer.
+#[derive(Debug, Clone)]
+pub struct FullComposerWeakHandle(std::rc::Weak<std::cell::RefCell<InnerFullComposer>>);
- pub fn get_autoload_generator(&self) -> std::rc::Rc<std::cell::RefCell<AutoloadGenerator>> {
- self.autoload_generator.as_ref().unwrap().clone()
+impl FullComposerWeakHandle {
+ pub(crate) fn from_weak(weak: std::rc::Weak<std::cell::RefCell<InnerFullComposer>>) -> Self {
+ Self(weak)
}
- pub fn as_partial(&self) -> &PartialComposer {
- &self.partial
+ pub fn upgrade(&self) -> Option<FullComposerHandle> {
+ self.0.upgrade().map(FullComposerHandle)
}
- pub fn as_partial_mut(&mut self) -> &mut PartialComposer {
- &mut self.partial
+ fn upgraded(&self) -> FullComposerHandle {
+ self.upgrade()
+ .expect("Composer has been dropped before its weak reference")
}
+}
- pub fn set_package(&mut self, package: RootPackageInterfaceHandle) {
- self.partial.set_package(package);
+impl PartialComposer for FullComposerWeakHandle {
+ fn set_package(&self, package: RootPackageInterfaceHandle) {
+ self.upgraded().set_package(package);
}
-
- pub fn get_package(&self) -> &RootPackageInterfaceHandle {
- self.partial.get_package()
+ fn get_package(&self) -> RootPackageInterfaceHandle {
+ self.upgraded().get_package()
}
-
- pub fn set_config(&mut self, config: std::rc::Rc<std::cell::RefCell<crate::config::Config>>) {
- self.partial.set_config(config);
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
+ self.upgraded().set_config(config);
}
-
- pub fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<crate::config::Config>> {
- self.partial.get_config()
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
+ self.upgraded().get_config()
}
-
- pub fn set_loop(&mut self, r#loop: std::rc::Rc<std::cell::RefCell<crate::util::r#loop::Loop>>) {
- self.partial.set_loop(r#loop);
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
+ self.upgraded().set_loop(r#loop);
}
-
- pub fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<crate::util::r#loop::Loop>> {
- self.partial.get_loop()
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
+ self.upgraded().get_loop()
}
-
- pub fn set_repository_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<crate::repository::RepositoryManager>>,
- ) {
- self.partial.set_repository_manager(manager);
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>) {
+ self.upgraded().set_repository_manager(manager);
}
-
- pub fn get_repository_manager(
- &self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::repository::RepositoryManager>> {
- self.partial.get_repository_manager()
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
+ self.upgraded().get_repository_manager()
}
-
- pub fn set_installation_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<crate::installer::InstallationManager>>,
+ fn set_installation_manager(
+ &self,
+ manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
) {
- self.partial.set_installation_manager(manager);
+ self.upgraded().set_installation_manager(manager);
}
-
- pub fn get_installation_manager(
- &self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::installer::InstallationManager>> {
- self.partial.get_installation_manager()
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
+ self.upgraded().get_installation_manager()
}
-
- pub fn set_event_dispatcher(
- &mut self,
- dispatcher: std::rc::Rc<std::cell::RefCell<crate::event_dispatcher::EventDispatcher>>,
+ fn set_event_dispatcher(
+ &self,
+ event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
) {
- self.partial.set_event_dispatcher(dispatcher);
+ self.upgraded().set_event_dispatcher(event_dispatcher);
+ }
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
+ self.upgraded().get_event_dispatcher()
+ }
+ fn is_global(&self) -> bool {
+ self.upgraded().is_global()
+ }
+ fn set_global(&self) {
+ self.upgraded().set_global();
}
+}
- pub fn get_event_dispatcher(
+impl Composer for FullComposerWeakHandle {
+ fn set_locker(&self, locker: std::rc::Rc<std::cell::RefCell<Locker>>) {
+ self.upgraded().set_locker(locker);
+ }
+ fn get_locker(&self) -> std::rc::Rc<std::cell::RefCell<Locker>> {
+ self.upgraded().get_locker()
+ }
+ fn set_download_manager(&self, manager: std::rc::Rc<std::cell::RefCell<DownloadManager>>) {
+ self.upgraded().set_download_manager(manager);
+ }
+ fn get_download_manager(&self) -> std::rc::Rc<std::cell::RefCell<DownloadManager>> {
+ self.upgraded().get_download_manager()
+ }
+ fn set_plugin_manager(&self, manager: std::rc::Rc<std::cell::RefCell<PluginManager>>) {
+ self.upgraded().set_plugin_manager(manager);
+ }
+ fn get_plugin_manager(&self) -> std::rc::Rc<std::cell::RefCell<PluginManager>> {
+ self.upgraded().get_plugin_manager()
+ }
+ fn set_autoload_generator(
&self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::event_dispatcher::EventDispatcher>> {
- self.partial.get_event_dispatcher()
+ autoload_generator: std::rc::Rc<std::cell::RefCell<AutoloadGenerator>>,
+ ) {
+ self.upgraded().set_autoload_generator(autoload_generator);
}
-
- pub fn is_global(&self) -> bool {
- self.partial.is_global()
+ fn get_autoload_generator(&self) -> std::rc::Rc<std::cell::RefCell<AutoloadGenerator>> {
+ self.upgraded().get_autoload_generator()
}
-
- pub fn set_global(&mut self) {
- self.partial.set_global();
+ fn set_archive_manager(&self, manager: std::rc::Rc<std::cell::RefCell<ArchiveManager>>) {
+ self.upgraded().set_archive_manager(manager);
+ }
+ fn get_archive_manager(&self) -> std::rc::Rc<std::cell::RefCell<ArchiveManager>> {
+ self.upgraded().get_archive_manager()
}
}
-#[derive(Debug)]
-pub enum PartialOrFullComposer {
- Full(Composer),
- Partial(PartialComposer),
+/// Shared reference to a \Composer\PartialComposer that may at runtime be either a partial composer
+/// or a full \Composer\Composer. Use this for parameters or fields typed as \Composer\PartialComposer
+/// in PHP; downcast with [`AnyComposerHandle::as_full`] (`$composer instanceof Composer`).
+#[derive(Debug, Clone)]
+pub enum AnyComposerHandle {
+ Partial(std::rc::Rc<std::cell::RefCell<InnerPartialComposer>>),
+ Full(FullComposerHandle),
}
-impl PartialOrFullComposer {
- pub fn new_full() -> Self {
- Self::Full(Composer::new())
- }
-
- pub fn new_partial() -> Self {
- Self::Partial(PartialComposer::default())
- }
-
+impl AnyComposerHandle {
pub fn is_full(&self) -> bool {
matches!(self, Self::Full(_))
}
@@ -288,274 +348,199 @@ impl PartialOrFullComposer {
matches!(self, Self::Partial(_))
}
- pub fn as_full(&self) -> Option<&Composer> {
+ /// Downcast to a full Composer handle. PHP `$composer instanceof Composer`.
+ pub fn as_full(&self) -> Option<FullComposerHandle> {
match self {
- Self::Full(full) => Some(full),
+ Self::Full(full) => Some(full.clone()),
Self::Partial(_) => None,
}
}
- pub fn as_full_mut(&mut self) -> Option<&mut Composer> {
+ pub fn downgrade(&self) -> AnyComposerWeakHandle {
match self {
- Self::Full(full) => Some(full),
- Self::Partial(_) => None,
+ Self::Partial(rc) => AnyComposerWeakHandle::Partial(std::rc::Rc::downgrade(rc)),
+ Self::Full(full) => AnyComposerWeakHandle::Full(full.downgrade()),
}
}
+}
- pub fn as_partial(&self) -> &PartialComposer {
- match self {
- Self::Full(full) => full.as_partial(),
- Self::Partial(partial) => partial,
- }
+impl From<FullComposerHandle> for AnyComposerHandle {
+ fn from(h: FullComposerHandle) -> Self {
+ Self::Full(h)
}
+}
- pub fn as_partial_mut(&mut self) -> &mut PartialComposer {
+impl PartialComposer for AnyComposerHandle {
+ fn set_package(&self, package: RootPackageInterfaceHandle) {
match self {
- Self::Full(full) => full.as_partial_mut(),
- Self::Partial(partial) => partial,
+ Self::Partial(rc) => rc.borrow_mut().package = Some(package),
+ Self::Full(f) => f.set_package(package),
}
}
-
- pub fn set_package(&mut self, package: RootPackageInterfaceHandle) {
+ fn get_package(&self) -> RootPackageInterfaceHandle {
match self {
- Self::Full(full) => full.set_package(package),
- Self::Partial(partial) => partial.set_package(package),
+ Self::Partial(rc) => rc.borrow().package.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_package(),
}
}
-
- pub fn get_package(&self) -> &RootPackageInterfaceHandle {
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
match self {
- Self::Full(full) => full.get_package(),
- Self::Partial(partial) => partial.get_package(),
+ Self::Partial(rc) => rc.borrow_mut().config = Some(config),
+ Self::Full(f) => f.set_config(config),
}
}
-
- pub fn set_config(&mut self, config: std::rc::Rc<std::cell::RefCell<crate::config::Config>>) {
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
match self {
- Self::Full(full) => full.set_config(config),
- Self::Partial(partial) => partial.set_config(config),
+ Self::Partial(rc) => rc.borrow().config.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_config(),
}
}
-
- pub fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<crate::config::Config>> {
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
match self {
- Self::Full(full) => full.get_config(),
- Self::Partial(partial) => partial.get_config(),
+ Self::Partial(rc) => rc.borrow_mut().r#loop = Some(r#loop),
+ Self::Full(f) => f.set_loop(r#loop),
}
}
-
- pub fn set_loop(&mut self, r#loop: std::rc::Rc<std::cell::RefCell<crate::util::r#loop::Loop>>) {
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
match self {
- Self::Full(full) => full.set_loop(r#loop),
- Self::Partial(partial) => partial.set_loop(r#loop),
+ Self::Partial(rc) => rc.borrow().r#loop.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_loop(),
}
}
-
- pub fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<crate::util::r#loop::Loop>> {
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>) {
match self {
- Self::Full(full) => full.get_loop(),
- Self::Partial(partial) => partial.get_loop(),
+ Self::Partial(rc) => rc.borrow_mut().repository_manager = Some(manager),
+ Self::Full(f) => f.set_repository_manager(manager),
}
}
-
- pub fn set_repository_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<crate::repository::RepositoryManager>>,
- ) {
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
match self {
- Self::Full(full) => full.set_repository_manager(manager),
- Self::Partial(partial) => partial.set_repository_manager(manager),
+ Self::Partial(rc) => rc.borrow().repository_manager.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_repository_manager(),
}
}
-
- pub fn get_repository_manager(
+ fn set_installation_manager(
&self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::repository::RepositoryManager>> {
- match self {
- Self::Full(full) => full.get_repository_manager(),
- Self::Partial(partial) => partial.get_repository_manager(),
- }
- }
-
- pub fn set_installation_manager(
- &mut self,
- manager: std::rc::Rc<std::cell::RefCell<crate::installer::InstallationManager>>,
+ manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
) {
match self {
- Self::Full(full) => full.set_installation_manager(manager),
- Self::Partial(partial) => partial.set_installation_manager(manager),
+ Self::Partial(rc) => rc.borrow_mut().installation_manager = Some(manager),
+ Self::Full(f) => f.set_installation_manager(manager),
}
}
-
- pub fn get_installation_manager(
- &self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::installer::InstallationManager>> {
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
match self {
- Self::Full(full) => full.get_installation_manager(),
- Self::Partial(partial) => partial.get_installation_manager(),
+ Self::Partial(rc) => rc.borrow().installation_manager.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_installation_manager(),
}
}
-
- pub fn set_event_dispatcher(
- &mut self,
- dispatcher: std::rc::Rc<std::cell::RefCell<crate::event_dispatcher::EventDispatcher>>,
+ fn set_event_dispatcher(
+ &self,
+ event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
) {
match self {
- Self::Full(full) => full.set_event_dispatcher(dispatcher),
- Self::Partial(partial) => partial.set_event_dispatcher(dispatcher),
+ Self::Partial(rc) => rc.borrow_mut().event_dispatcher = Some(event_dispatcher),
+ Self::Full(f) => f.set_event_dispatcher(event_dispatcher),
}
}
-
- pub fn get_event_dispatcher(
- &self,
- ) -> std::rc::Rc<std::cell::RefCell<crate::event_dispatcher::EventDispatcher>> {
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
match self {
- Self::Full(full) => full.get_event_dispatcher(),
- Self::Partial(partial) => partial.get_event_dispatcher(),
+ Self::Partial(rc) => rc.borrow().event_dispatcher.as_ref().unwrap().clone(),
+ Self::Full(f) => f.get_event_dispatcher(),
}
}
-
- pub fn is_global(&self) -> bool {
+ fn is_global(&self) -> bool {
match self {
- Self::Full(full) => full.is_global(),
- Self::Partial(partial) => partial.is_global(),
+ Self::Partial(rc) => rc.borrow().global,
+ Self::Full(f) => f.is_global(),
}
}
-
- pub fn set_global(&mut self) {
+ fn set_global(&self) {
match self {
- Self::Full(full) => full.set_global(),
- Self::Partial(partial) => partial.set_global(),
+ Self::Partial(rc) => rc.borrow_mut().global = true,
+ Self::Full(f) => f.set_global(),
}
}
}
-/// Shared reference to \Composer\PartialComposer or \Composer\Composer.
-/// Use this for parameters or fields typed as \Composer\PartialComposer in PHP.
+/// Shared weak reference to a \Composer\PartialComposer that may at runtime be either partial or full.
#[derive(Debug, Clone)]
-pub struct PartialComposerHandle(std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>>);
-
-impl PartialComposerHandle {
- pub fn borrow_partial(&self) -> std::cell::Ref<'_, PartialComposer> {
- std::cell::Ref::map(self.0.borrow(), |c| c.as_partial())
- }
-
- pub fn borrow_partial_mut(&self) -> std::cell::RefMut<'_, PartialComposer> {
- std::cell::RefMut::map(self.0.borrow_mut(), |c| c.as_partial_mut())
- }
-
- pub fn is_full(&self) -> bool {
- self.0.borrow().is_full()
- }
+pub enum AnyComposerWeakHandle {
+ Partial(std::rc::Weak<std::cell::RefCell<InnerPartialComposer>>),
+ Full(FullComposerWeakHandle),
+}
- /// Downcast to a full Composer handle. PHP `$composer instanceof Composer`.
- pub fn as_full(&self) -> Option<ComposerHandle> {
- if self.0.borrow().is_full() {
- Some(ComposerHandle::from_rc_unchecked(self.0.clone()))
- } else {
- None
+impl AnyComposerWeakHandle {
+ pub fn upgrade(&self) -> Option<AnyComposerHandle> {
+ match self {
+ Self::Partial(p) => p.upgrade().map(AnyComposerHandle::Partial),
+ Self::Full(f) => f.upgrade().map(AnyComposerHandle::Full),
}
}
- pub fn downgrade(&self) -> PartialComposerWeakHandle {
- PartialComposerWeakHandle(std::rc::Rc::downgrade(&self.0))
+ fn upgraded(&self) -> AnyComposerHandle {
+ self.upgrade()
+ .expect("PartialComposer has been dropped before its weak reference")
}
+}
- pub fn from_rc(rc: std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>>) -> Self {
- Self(rc)
+impl PartialComposer for AnyComposerWeakHandle {
+ fn set_package(&self, package: RootPackageInterfaceHandle) {
+ self.upgraded().set_package(package);
}
-
- pub fn as_rc(&self) -> &std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>> {
- &self.0
+ fn get_package(&self) -> RootPackageInterfaceHandle {
+ self.upgraded().get_package()
}
-}
-
-/// Shared weak reference to \Composer\PartialComposer or \Composer\Composer.
-#[derive(Debug, Clone)]
-pub struct PartialComposerWeakHandle(std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>);
-
-impl PartialComposerWeakHandle {
- pub fn upgrade(&self) -> Option<PartialComposerHandle> {
- self.0.upgrade().map(PartialComposerHandle)
+ fn set_config(&self, config: std::rc::Rc<std::cell::RefCell<Config>>) {
+ self.upgraded().set_config(config);
}
-
- pub fn from_weak(weak: std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>) -> Self {
- Self(weak)
+ fn get_config(&self) -> std::rc::Rc<std::cell::RefCell<Config>> {
+ self.upgraded().get_config()
}
-}
-
-/// Shared reference to \Composer\Composer.
-/// Use this for parameters or fields typed as \Composer\Composer in PHP.
-#[derive(Debug, Clone)]
-pub struct ComposerHandle(std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>>);
-
-impl ComposerHandle {
- pub fn borrow(&self) -> std::cell::Ref<'_, Composer> {
- std::cell::Ref::map(self.0.borrow(), |c| {
- c.as_full()
- .expect("Composer handle invariant: inner is Full")
- })
+ fn set_loop(&self, r#loop: std::rc::Rc<std::cell::RefCell<Loop>>) {
+ self.upgraded().set_loop(r#loop);
}
-
- pub fn borrow_mut(&self) -> std::cell::RefMut<'_, Composer> {
- std::cell::RefMut::map(self.0.borrow_mut(), |c| {
- c.as_full_mut()
- .expect("Composer handle invariant: inner is Full")
- })
+ fn get_loop(&self) -> std::rc::Rc<std::cell::RefCell<Loop>> {
+ self.upgraded().get_loop()
}
-
- pub fn upcast(&self) -> PartialComposerHandle {
- PartialComposerHandle::from_rc(self.0.clone())
+ fn set_repository_manager(&self, manager: std::rc::Rc<std::cell::RefCell<RepositoryManager>>) {
+ self.upgraded().set_repository_manager(manager);
}
-
- pub fn downgrade(&self) -> ComposerWeakHandle {
- ComposerWeakHandle(std::rc::Rc::downgrade(&self.0))
+ fn get_repository_manager(&self) -> std::rc::Rc<std::cell::RefCell<RepositoryManager>> {
+ self.upgraded().get_repository_manager()
}
-
- pub fn from_rc_unchecked(rc: std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>>) -> Self {
- Self(rc)
+ fn set_installation_manager(
+ &self,
+ manager: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
+ ) {
+ self.upgraded().set_installation_manager(manager);
}
-
- pub fn as_rc(&self) -> &std::rc::Rc<std::cell::RefCell<PartialOrFullComposer>> {
- &self.0
+ fn get_installation_manager(&self) -> std::rc::Rc<std::cell::RefCell<InstallationManager>> {
+ self.upgraded().get_installation_manager()
}
-}
-
-impl From<ComposerHandle> for PartialComposerHandle {
- fn from(c: ComposerHandle) -> Self {
- c.upcast()
+ fn set_event_dispatcher(
+ &self,
+ event_dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
+ ) {
+ self.upgraded().set_event_dispatcher(event_dispatcher);
}
-}
-
-/// Shared weak reference to \Composer\Composer.
-#[derive(Debug, Clone)]
-pub struct ComposerWeakHandle(std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>);
-
-impl ComposerWeakHandle {
- pub fn upgrade(&self) -> Option<ComposerHandle> {
- self.0.upgrade().map(ComposerHandle)
+ fn get_event_dispatcher(&self) -> std::rc::Rc<std::cell::RefCell<EventDispatcher>> {
+ self.upgraded().get_event_dispatcher()
}
-
- pub fn from_weak(weak: std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>) -> Self {
- Self(weak)
+ fn is_global(&self) -> bool {
+ self.upgraded().is_global()
+ }
+ fn set_global(&self) {
+ self.upgraded().set_global();
}
}
-/// Borrows a polymorphic `PartialComposer` as a fully-loaded `Composer`.
+/// Downcasts a polymorphic composer handle to a fully-loaded \Composer\Composer.
///
/// Commands obtain their Composer through `require_composer` / `create_composer_instance`,
/// which always yield a fully-loaded instance, so the downcast is infallible here.
-pub fn composer_full(composer: &PartialComposerHandle) -> std::cell::Ref<'_, Composer> {
- std::cell::Ref::map(composer.as_rc().borrow(), |c| {
- c.as_full()
- .expect("a fully loaded Composer is required here")
- })
-}
-
-/// Mutably borrows a polymorphic `PartialComposer` as a fully-loaded `Composer`. See [`composer_full`].
-pub fn composer_full_mut(composer: &PartialComposerHandle) -> std::cell::RefMut<'_, Composer> {
- std::cell::RefMut::map(composer.as_rc().borrow_mut(), |c| {
- c.as_full_mut()
- .expect("a fully loaded Composer is required here")
- })
+pub fn composer_full(composer: &AnyComposerHandle) -> FullComposerHandle {
+ composer
+ .as_full()
+ .expect("a fully loaded Composer is required here")
}
diff --git a/crates/shirabe/src/console/application.rs b/crates/shirabe/src/console/application.rs
index f27ed79..c8f8e43 100644
--- a/crates/shirabe/src/console/application.rs
+++ b/crates/shirabe/src/console/application.rs
@@ -67,8 +67,7 @@ use crate::command::SuggestsCommand;
use crate::command::UpdateCommand;
use crate::command::ValidateCommand;
use crate::composer;
-use crate::composer::ComposerHandle;
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::console::GithubActionError;
use crate::downloader::TransportException;
use crate::event_dispatcher::ScriptExecutionException;
@@ -89,7 +88,7 @@ use crate::util::Silencer;
#[derive(Debug)]
pub struct Application {
inner: BaseApplication,
- pub(crate) composer: Option<PartialComposerHandle>,
+ pub(crate) composer: Option<AnyComposerHandle>,
pub(crate) io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
has_plugin_commands: bool,
disable_plugins_by_default: bool,
@@ -854,7 +853,6 @@ impl Application {
let composer = self.get_composer(false, Some(true), None)?;
if composer.is_some() && function_exists("disk_free_space") {
let composer = composer.unwrap();
- let composer = composer.borrow_partial();
let config = composer.get_config();
let min_space_free: f64 = 100.0 * 1024.0 * 1024.0;
@@ -986,7 +984,7 @@ impl Application {
required: bool,
disable_plugins: Option<bool>,
disable_scripts: Option<bool>,
- ) -> anyhow::Result<Option<PartialComposerHandle>> {
+ ) -> anyhow::Result<Option<AnyComposerHandle>> {
let disable_plugins = disable_plugins.unwrap_or(self.disable_plugins_by_default);
let disable_scripts = disable_scripts.unwrap_or(self.disable_scripts_by_default);
diff --git a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
index ef02660..49775d1 100644
--- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
+++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs
@@ -19,8 +19,7 @@ use shirabe_php_shim::{
};
use crate::autoload::ClassLoader;
-use crate::composer::PartialComposerHandle;
-use crate::composer::PartialComposerWeakHandle;
+use crate::composer::{AnyComposerHandle, AnyComposerWeakHandle, Composer, PartialComposer};
use crate::dependency_resolver::Transaction;
use crate::dependency_resolver::operation::OperationInterface;
use crate::event_dispatcher::Event;
@@ -62,7 +61,7 @@ pub enum Callable {
/// `$dispatcher->dispatch(ScriptEvents::POST_INSTALL_CMD);`
#[derive(Debug)]
pub struct EventDispatcher {
- pub(crate) composer: PartialComposerWeakHandle,
+ pub(crate) composer: AnyComposerWeakHandle,
pub(crate) io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
pub(crate) loader: Option<ClassLoader>,
pub(crate) process: std::rc::Rc<std::cell::RefCell<ProcessExecutor>>,
@@ -76,7 +75,7 @@ pub struct EventDispatcher {
impl EventDispatcher {
pub fn new(
- composer: PartialComposerWeakHandle,
+ composer: AnyComposerWeakHandle,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
process: Option<std::rc::Rc<std::cell::RefCell<ProcessExecutor>>>,
) -> Self {
@@ -704,7 +703,6 @@ impl EventDispatcher {
.composer
.upgrade()
.expect("Composer was dropped before EventDispatcher use")
- .borrow_partial()
.get_package()
.get_binaries();
if !possible_local_binaries.is_empty() {
@@ -1081,7 +1079,6 @@ impl EventDispatcher {
/// Finds all listeners defined as scripts in the package
fn get_script_listeners(&self, event: &Event) -> Vec<Callable> {
let composer = self.composer();
- let composer = composer.borrow_partial();
let package = composer.get_package();
let scripts = package.get_scripts();
@@ -1163,7 +1160,6 @@ impl EventDispatcher {
// add the bin dir to the PATH to make local binaries of deps usable in scripts
let bin_dir = self
.composer()
- .borrow_partial()
.get_config()
.borrow_mut()
.get("bin-dir")
@@ -1234,8 +1230,6 @@ impl EventDispatcher {
let Some(composer) = composer.as_full() else {
return;
};
- let composer = composer.borrow_mut();
-
let callable_key = match callable {
Callable::ArrayCallable(first, method) => {
let prefix = if let PhpMixed::String(s) = first.as_ref() {
@@ -1316,7 +1310,7 @@ impl EventDispatcher {
todo!("clone std::rc::Rc<std::cell::RefCell<dyn IOInterface>>")
}
- fn composer(&self) -> PartialComposerHandle {
+ fn composer(&self) -> AnyComposerHandle {
self.composer
.upgrade()
.expect("EventDispatcher must lives longer than Composer")
diff --git a/crates/shirabe/src/factory.rs b/crates/shirabe/src/factory.rs
index 80f1548..73197ce 100644
--- a/crates/shirabe/src/factory.rs
+++ b/crates/shirabe/src/factory.rs
@@ -15,8 +15,10 @@ use shirabe_php_shim::{
use crate::autoload::AutoloadGenerator;
use crate::cache::Cache;
-use crate::composer::{ComposerWeakHandle, PartialOrFullComposer};
-use crate::composer::{PartialComposerHandle, PartialComposerWeakHandle};
+use crate::composer::{
+ AnyComposerHandle, AnyComposerWeakHandle, Composer, FullComposerHandle, FullComposerWeakHandle,
+ InnerFullComposer, InnerPartialComposer, PartialComposer,
+};
use crate::config::Config;
use crate::config::JsonConfigSource;
use crate::downloader::DownloadManager;
@@ -90,6 +92,16 @@ impl DisablePlugins {
}
}
+/// Shared managers produced while building the common (partial) part of a Composer, reused by the
+/// full-load branch to wire the full-only managers (download/autoload/archive/locker).
+struct ComposerBuildArtifacts {
+ http_downloader: std::rc::Rc<std::cell::RefCell<HttpDownloader>>,
+ process: std::rc::Rc<std::cell::RefCell<ProcessExecutor>>,
+ r#loop: std::rc::Rc<std::cell::RefCell<Loop>>,
+ dispatcher: std::rc::Rc<std::cell::RefCell<EventDispatcher>>,
+ im: std::rc::Rc<std::cell::RefCell<InstallationManager>>,
+}
+
/// Creates a configured instance of composer.
pub struct Factory;
@@ -436,7 +448,7 @@ impl Factory {
cwd: Option<&str>,
full_load: bool,
disable_scripts: bool,
- ) -> anyhow::Result<PartialComposerHandle> {
+ ) -> anyhow::Result<AnyComposerHandle> {
// if a custom composer.json path is given, we change the default cwd to be that file's directory
let mut local_config = local_config;
let mut cwd = cwd.map(|s| s.to_string());
@@ -577,161 +589,50 @@ impl Factory {
// PartialComposerWeak (Weak<RefCell<InnerComposer>>). The closure cannot return a
// Result, so construction errors are surfaced through `build_error`.
let mut build_error: Option<anyhow::Error> = None;
- let composer = std::rc::Rc::new_cyclic(
- |composer_weak: &std::rc::Weak<std::cell::RefCell<PartialOrFullComposer>>| {
- let mut build = || -> anyhow::Result<PartialOrFullComposer> {
- let mut composer: PartialOrFullComposer = if full_load {
- PartialOrFullComposer::new_full()
- } else {
- PartialOrFullComposer::new_partial()
- };
- composer.set_config(config.clone());
- if is_global {
- composer.set_global();
- }
-
- if full_load {
- // load auth configs into the IO instance
- // TODO(phase-b): load_configuration requires &mut IOInterface; create_composer takes &dyn IOInterface
- // io.load_configuration(&mut *config.borrow_mut())?;
-
- // load existing Composer\InstalledVersions instance if available and scripts/plugins are allowed, as they might need it
- // we only load if the InstalledVersions class wasn't defined yet so that this is only loaded once
- let installed_versions_path = format!(
- "{}/composer/installed.php",
- config.borrow_mut().get_str("vendor-dir")?
- );
- if !disable_plugins.is_disabled_at_all()
- && !disable_scripts
- && !class_exists("Composer\\InstalledVersions")
- && file_exists(&installed_versions_path)
- {
- // force loading the class at this point so it is loaded from the composer phar and not from the vendor dir
- // as we cannot guarantee integrity of that file
- if class_exists("Composer\\InstalledVersions") {
- FilesystemRepository::safely_load_installed_versions(
- &installed_versions_path,
- );
- }
- }
- }
-
- let http_downloader = std::rc::Rc::new(std::cell::RefCell::new(
- Self::create_http_downloader(io.clone(), &config, IndexMap::new())?,
+ let composer: AnyComposerHandle = if full_load {
+ let inner = std::rc::Rc::new_cyclic(
+ |composer_weak: &std::rc::Weak<std::cell::RefCell<InnerFullComposer>>| {
+ let weak = AnyComposerWeakHandle::Full(FullComposerWeakHandle::from_weak(
+ composer_weak.clone(),
));
- let process = std::rc::Rc::new(std::cell::RefCell::new(ProcessExecutor::new(
- Some(io.clone()),
- )));
- let r#loop = std::rc::Rc::new(std::cell::RefCell::new(Loop::new(
- http_downloader.clone(),
- Some(process.clone()),
- )));
- composer.set_loop(r#loop.clone());
-
- // initialize event dispatcher with the Composer back-reference
- let dispatcher = {
- let mut d = EventDispatcher::new(
- PartialComposerWeakHandle::from_weak(composer_weak.clone()),
+ let mut full = InnerFullComposer::default();
+ let mut build = || -> anyhow::Result<()> {
+ let artifacts = self.build_composer_base(
+ &mut full.partial,
+ weak,
io.clone(),
- Some(process.clone()),
- );
- d.set_run_scripts(!disable_scripts);
- std::rc::Rc::new(std::cell::RefCell::new(d))
- };
- composer.set_event_dispatcher(dispatcher.clone());
-
- // initialize repository manager
- let rm = std::rc::Rc::new(std::cell::RefCell::new(RepositoryFactory::manager(
- io.clone(),
- &config,
- Some(http_downloader.clone()),
- Some(dispatcher.clone()),
- Some(process.clone()),
- )?));
-
- // force-set the version of the global package if not defined as
- // guessing it adds no value and only takes time
- if !full_load && !local_config_data.contains_key("version") {
- local_config_data
- .insert("version".to_string(), PhpMixed::String("1.0.0".to_string()));
- }
-
- // load package
- let parser = VersionParser::new();
- let guesser = VersionGuesser::new(
- config.clone(),
- process.clone(),
- parser.clone(),
- Some(io.clone()),
- );
- let mut loader = self.load_root_package(
- rm.clone(),
- config.clone(),
- parser,
- guesser,
- io.clone(),
- );
- let package = loader.load(
- local_config_data
- .iter()
- .map(|(k, v)| (k.clone(), Box::new(v.clone())))
- .collect(),
- "Composer\\Package\\RootPackage",
- Some(&cwd),
- )?;
- // TODO(phase-b): set_package expects RootPackageInterface; loader returns BasePackage
- // composer.set_package(package);
- let _ = package;
-
- // load local repository
- self.add_local_repository(
- io.clone(),
- &mut rm.borrow_mut(),
- &vendor_dir,
- composer.get_package().clone(),
- Some(&process),
- );
- composer.set_repository_manager(rm.clone());
-
- // initialize installation manager
- let im = std::rc::Rc::new(std::cell::RefCell::new(
- self.create_installation_manager(
- r#loop.clone(),
- io.clone(),
- Some(dispatcher.clone()),
- ),
- ));
- composer.set_installation_manager(im.clone());
+ &config,
+ full_load,
+ is_global,
+ disable_plugins,
+ disable_scripts,
+ &mut local_config_data,
+ &cwd,
+ &vendor_dir,
+ )?;
- if let PartialOrFullComposer::Full(ref mut composer_full) = composer {
// initialize download manager
let dm = self.create_download_manager(
io.clone(),
&config,
- &http_downloader,
- &process,
- Some(&dispatcher),
+ &artifacts.http_downloader,
+ &artifacts.process,
+ Some(&artifacts.dispatcher),
)?;
- composer_full.set_download_manager(dm.clone());
+ full.download_manager = Some(dm.clone());
// initialize autoload generator
let generator =
- AutoloadGenerator::new(dispatcher.clone(), Some(io.clone()));
- composer_full.set_autoload_generator(std::rc::Rc::new(
- std::cell::RefCell::new(generator),
- ));
+ AutoloadGenerator::new(artifacts.dispatcher.clone(), Some(io.clone()));
+ full.autoload_generator =
+ Some(std::rc::Rc::new(std::cell::RefCell::new(generator)));
// initialize archive manager
- let am = self.create_archive_manager(&*config.borrow(), &dm, &r#loop)?;
- composer_full
- .set_archive_manager(std::rc::Rc::new(std::cell::RefCell::new(am)));
- }
-
- // add installers to the manager (must happen after download manager is created since they read it out of $composer)
- self.create_default_installers(&im, &composer, io.clone(), Some(&process));
+ let am =
+ self.create_archive_manager(&*config.borrow(), &dm, &artifacts.r#loop)?;
+ full.archive_manager = Some(std::rc::Rc::new(std::cell::RefCell::new(am)));
- // init locker if possible
- if let PartialOrFullComposer::Full(ref mut composer_full) = composer {
+ // init locker if possible
if let Some(ref composer_file_path) = composer_file {
let lock_file = Self::get_lock_file(composer_file_path);
let lock_enabled = config
@@ -741,13 +642,13 @@ impl Factory {
.unwrap_or(true);
if !lock_enabled && file_exists(&lock_file) {
io.write_error3(
- &format!(
- "<warning>{} is present but ignored as the \"lock\" config option is disabled.</warning>",
- lock_file
- ),
- true,
- crate::io::NORMAL,
- );
+ &format!(
+ "<warning>{} is present but ignored as the \"lock\" config option is disabled.</warning>",
+ lock_file
+ ),
+ true,
+ crate::io::NORMAL,
+ );
}
let locker = Locker::new(
@@ -761,12 +662,11 @@ impl Factory {
None,
Some(io.clone()),
)?,
- im.clone(),
+ artifacts.im.clone(),
&file_get_contents(composer_file_path).unwrap_or_default(),
- process.clone(),
+ artifacts.process.clone(),
);
- composer_full
- .set_locker(std::rc::Rc::new(std::cell::RefCell::new(locker)));
+ full.locker = Some(std::rc::Rc::new(std::cell::RefCell::new(locker)));
} else {
let lock_contents = JsonFile::encode(
&PhpMixed::Array(
@@ -780,26 +680,46 @@ impl Factory {
let locker = Locker::new(
io.clone(),
JsonFile::new(Platform::get_dev_null(), None, Some(io.clone()))?,
- im.clone(),
+ artifacts.im.clone(),
&lock_contents,
- process.clone(),
+ artifacts.process.clone(),
);
- composer_full
- .set_locker(std::rc::Rc::new(std::cell::RefCell::new(locker)));
+ full.locker = Some(std::rc::Rc::new(std::cell::RefCell::new(locker)));
}
+ Ok(())
+ };
+ if let Err(e) = build() {
+ build_error = Some(e);
}
-
- Ok(composer)
- };
- match build() {
- Ok(composer) => std::cell::RefCell::new(composer),
- Err(e) => {
+ std::cell::RefCell::new(full)
+ },
+ );
+ AnyComposerHandle::Full(FullComposerHandle::from_rc(inner))
+ } else {
+ let inner = std::rc::Rc::new_cyclic(
+ |composer_weak: &std::rc::Weak<std::cell::RefCell<InnerPartialComposer>>| {
+ let weak = AnyComposerWeakHandle::Partial(composer_weak.clone());
+ let mut partial = InnerPartialComposer::default();
+ if let Err(e) = self.build_composer_base(
+ &mut partial,
+ weak,
+ io.clone(),
+ &config,
+ full_load,
+ is_global,
+ disable_plugins,
+ disable_scripts,
+ &mut local_config_data,
+ &cwd,
+ &vendor_dir,
+ ) {
build_error = Some(e);
- std::cell::RefCell::new(PartialOrFullComposer::new_partial())
}
- }
- },
- );
+ std::cell::RefCell::new(partial)
+ },
+ );
+ AnyComposerHandle::Partial(inner)
+ };
if let Some(e) = build_error {
return Err(e);
}
@@ -809,11 +729,8 @@ impl Factory {
// PluginManager::new upgrades the Composer back-reference to read its config and locker, so
// it must be built after Rc::new_cyclic returns; inside the closure the Rc is not yet
// constructed and the weak handle cannot upgrade.
- let (is_full, is_global) = {
- let c = composer.borrow();
- (c.is_full(), c.is_global())
- };
- if is_full {
+ let is_global = composer.is_global();
+ if let Some(full) = composer.as_full() {
let global_composer = if !is_global {
self.create_global_composer(
io.clone(),
@@ -828,16 +745,12 @@ impl Factory {
let pm = self.create_plugin_manager(
io.clone(),
- ComposerWeakHandle::from_weak(std::rc::Rc::downgrade(&composer)),
+ full.downgrade(),
global_composer,
disable_plugins,
);
let pm = std::rc::Rc::new(std::cell::RefCell::new(pm));
- composer
- .borrow_mut()
- .as_full_mut()
- .unwrap()
- .set_plugin_manager(pm.clone());
+ full.set_plugin_manager(pm.clone());
if is_global {
pm.borrow_mut().set_running_in_global_dir(true);
@@ -850,7 +763,7 @@ impl Factory {
// the Composer through the dispatcher) is safe only after the Rc has been constructed.
let init_event = Event::from_name(PluginEvents::INIT.to_string());
let init_event_name = init_event.get_name().to_string();
- let dispatcher = composer.borrow().get_event_dispatcher();
+ let dispatcher = composer.get_event_dispatcher();
dispatcher
.borrow_mut()
.dispatch(Some(&init_event_name), Some(init_event))?;
@@ -861,14 +774,14 @@ impl Factory {
// self.purge_packages(rm.get_local_repository(), &mut im)?;
}
- Ok(PartialComposerHandle::from_rc(composer))
+ Ok(composer)
}
pub fn create_global(
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
disable_plugins: DisablePlugins,
disable_scripts: bool,
- ) -> Option<PartialComposerHandle> {
+ ) -> Option<AnyComposerHandle> {
let factory = Self;
let config = Self::create_config(Some(io.clone()), None).ok()?;
@@ -909,7 +822,7 @@ impl Factory {
disable_plugins: DisablePlugins,
disable_scripts: bool,
full_load: bool,
- ) -> Option<PartialComposerHandle> {
+ ) -> Option<AnyComposerHandle> {
// make sure if disable plugins was 'local' it is now turned off
let disable_plugins = if matches!(
disable_plugins,
@@ -1176,8 +1089,8 @@ impl Factory {
fn create_plugin_manager(
&self,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
- composer: ComposerWeakHandle,
- global_composer: Option<PartialComposerHandle>,
+ composer: FullComposerWeakHandle,
+ global_composer: Option<AnyComposerHandle>,
disable_plugins: DisablePlugins,
) -> PluginManager {
PluginManager::new(io, composer, global_composer, disable_plugins)
@@ -1192,10 +1105,143 @@ impl Factory {
InstallationManager::new(r#loop, io, event_dispatcher)
}
+ /// Builds the common (partial) part of a Composer into `composer`, returning the shared managers
+ /// the full-load branch needs to wire its full-only managers. PHP's PartialComposer constructor
+ /// flow lives here so both the partial and full `Rc::new_cyclic` branches can share it.
+ fn build_composer_base(
+ &self,
+ composer: &mut InnerPartialComposer,
+ composer_weak: AnyComposerWeakHandle,
+ io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
+ config: &std::rc::Rc<std::cell::RefCell<Config>>,
+ full_load: bool,
+ is_global: bool,
+ disable_plugins: DisablePlugins,
+ disable_scripts: bool,
+ local_config_data: &mut IndexMap<String, PhpMixed>,
+ cwd: &str,
+ vendor_dir: &str,
+ ) -> anyhow::Result<ComposerBuildArtifacts> {
+ composer.config = Some(config.clone());
+ if is_global {
+ composer.global = true;
+ }
+
+ if full_load {
+ // load auth configs into the IO instance
+ // TODO(phase-b): load_configuration requires &mut IOInterface; create_composer takes &dyn IOInterface
+ // io.load_configuration(&mut *config.borrow_mut())?;
+
+ // load existing Composer\InstalledVersions instance if available and scripts/plugins are allowed, as they might need it
+ // we only load if the InstalledVersions class wasn't defined yet so that this is only loaded once
+ let installed_versions_path = format!(
+ "{}/composer/installed.php",
+ config.borrow_mut().get_str("vendor-dir")?
+ );
+ if !disable_plugins.is_disabled_at_all()
+ && !disable_scripts
+ && !class_exists("Composer\\InstalledVersions")
+ && file_exists(&installed_versions_path)
+ {
+ // force loading the class at this point so it is loaded from the composer phar and not from the vendor dir
+ // as we cannot guarantee integrity of that file
+ if class_exists("Composer\\InstalledVersions") {
+ FilesystemRepository::safely_load_installed_versions(&installed_versions_path);
+ }
+ }
+ }
+
+ let http_downloader = std::rc::Rc::new(std::cell::RefCell::new(
+ Self::create_http_downloader(io.clone(), config, IndexMap::new())?,
+ ));
+ let process = std::rc::Rc::new(std::cell::RefCell::new(ProcessExecutor::new(Some(
+ io.clone(),
+ ))));
+ let r#loop = std::rc::Rc::new(std::cell::RefCell::new(Loop::new(
+ http_downloader.clone(),
+ Some(process.clone()),
+ )));
+ composer.r#loop = Some(r#loop.clone());
+
+ // initialize event dispatcher with the Composer back-reference
+ let dispatcher = {
+ let mut d = EventDispatcher::new(composer_weak, io.clone(), Some(process.clone()));
+ d.set_run_scripts(!disable_scripts);
+ std::rc::Rc::new(std::cell::RefCell::new(d))
+ };
+ composer.event_dispatcher = Some(dispatcher.clone());
+
+ // initialize repository manager
+ let rm = std::rc::Rc::new(std::cell::RefCell::new(RepositoryFactory::manager(
+ io.clone(),
+ config,
+ Some(http_downloader.clone()),
+ Some(dispatcher.clone()),
+ Some(process.clone()),
+ )?));
+
+ // force-set the version of the global package if not defined as
+ // guessing it adds no value and only takes time
+ if !full_load && !local_config_data.contains_key("version") {
+ local_config_data.insert("version".to_string(), PhpMixed::String("1.0.0".to_string()));
+ }
+
+ // load package
+ let parser = VersionParser::new();
+ let guesser = VersionGuesser::new(
+ config.clone(),
+ process.clone(),
+ parser.clone(),
+ Some(io.clone()),
+ );
+ let mut loader =
+ self.load_root_package(rm.clone(), config.clone(), parser, guesser, io.clone());
+ let package = loader.load(
+ local_config_data
+ .iter()
+ .map(|(k, v)| (k.clone(), Box::new(v.clone())))
+ .collect(),
+ "Composer\\Package\\RootPackage",
+ Some(cwd),
+ )?;
+ // TODO(phase-b): set_package expects RootPackageInterface; loader returns BasePackage
+ // composer.package = Some(package);
+ let _ = package;
+
+ // load local repository
+ self.add_local_repository(
+ io.clone(),
+ &mut rm.borrow_mut(),
+ vendor_dir,
+ composer.package.as_ref().unwrap().clone(),
+ Some(&process),
+ );
+ composer.repository_manager = Some(rm.clone());
+
+ // initialize installation manager
+ let im = std::rc::Rc::new(std::cell::RefCell::new(self.create_installation_manager(
+ r#loop.clone(),
+ io.clone(),
+ Some(dispatcher.clone()),
+ )));
+ composer.installation_manager = Some(im.clone());
+
+ // add installers to the manager (must happen after download manager is created since they read it out of $composer)
+ self.create_default_installers(&im, config, io.clone(), Some(&process));
+
+ Ok(ComposerBuildArtifacts {
+ http_downloader,
+ process,
+ r#loop,
+ dispatcher,
+ im,
+ })
+ }
+
fn create_default_installers(
&self,
im: &std::rc::Rc<std::cell::RefCell<InstallationManager>>,
- composer: &PartialOrFullComposer,
+ config: &std::rc::Rc<std::cell::RefCell<Config>>,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
process: Option<&std::rc::Rc<std::cell::RefCell<ProcessExecutor>>>,
) {
@@ -1203,21 +1249,15 @@ impl Factory {
process.map(std::rc::Rc::clone),
)));
let bin_dir = trim(
- &composer
- .get_config()
- .borrow_mut()
- .get_str("bin-dir")
- .unwrap_or_default(),
+ &config.borrow_mut().get_str("bin-dir").unwrap_or_default(),
Some("/"),
);
- let bin_compat = composer
- .get_config()
+ let bin_compat = config
.borrow_mut()
.get_str("bin-compat")
.unwrap_or_default();
let vendor_dir = trim(
- &composer
- .get_config()
+ &config
.borrow_mut()
.get_str("vendor-dir")
.unwrap_or_default(),
@@ -1266,7 +1306,7 @@ impl Factory {
config: Option<LocalConfigInput>,
disable_plugins: DisablePlugins,
disable_scripts: bool,
- ) -> anyhow::Result<PartialComposerHandle> {
+ ) -> anyhow::Result<AnyComposerHandle> {
let factory = Self;
// for BC reasons, if a config is passed in either as array or a path that is not the default composer.json path
diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs
index 14e75c0..30de843 100644
--- a/crates/shirabe/src/installer.rs
+++ b/crates/shirabe/src/installer.rs
@@ -45,7 +45,7 @@ use shirabe_semver;
use crate::advisory::AuditConfig;
use crate::advisory::Auditor;
use crate::autoload::AutoloadGenerator;
-use crate::composer::PartialComposerHandle;
+use crate::composer::{AnyComposerHandle, Composer, PartialComposer};
use crate::config::Config;
use crate::console::GithubActionError;
use crate::dependency_resolver::DefaultPolicy;
@@ -1646,7 +1646,7 @@ impl Installer {
/// Create Installer
pub fn create(
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
- composer: &PartialComposerHandle,
+ composer: &AnyComposerHandle,
) -> Self {
let composer = crate::composer::composer_full(composer);
Self::new(
diff --git a/crates/shirabe/src/installer/installer_event.rs b/crates/shirabe/src/installer/installer_event.rs
index 5adde1c..00a0096 100644
--- a/crates/shirabe/src/installer/installer_event.rs
+++ b/crates/shirabe/src/installer/installer_event.rs
@@ -1,6 +1,6 @@
//! ref: composer/src/Composer/Installer/InstallerEvent.php
-use crate::composer::ComposerWeakHandle;
+use crate::composer::FullComposerWeakHandle;
use crate::dependency_resolver::Transaction;
use crate::event_dispatcher::Event;
use crate::io::IOInterface;
@@ -8,7 +8,7 @@ use crate::io::IOInterface;
#[derive(Debug)]
pub struct InstallerEvent {
inner: Event,
- composer: ComposerWeakHandle,
+ composer: FullComposerWeakHandle,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
dev_mode: bool,
execute_operations: bool,
@@ -18,7 +18,7 @@ pub struct InstallerEvent {
impl InstallerEvent {
pub fn new(
event_name: String,
- composer: ComposerWeakHandle,
+ composer: FullComposerWeakHandle,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
dev_mode: bool,
execute_operations: bool,
@@ -35,7 +35,7 @@ impl InstallerEvent {
}
}
- pub fn get_composer(&self) -> &ComposerWeakHandle {
+ pub fn get_composer(&self) -> &FullComposerWeakHandle {
&self.composer
}
diff --git a/crates/shirabe/src/installer/library_installer.rs b/crates/shirabe/src/installer/library_installer.rs
index c1fedef..b50dbff 100644
--- a/crates/shirabe/src/installer/library_installer.rs
+++ b/crates/shirabe/src/installer/library_installer.rs
@@ -9,7 +9,7 @@ use shirabe_php_shim::{
realpath, rmdir, rtrim, strpos,
};
-use crate::composer::PartialComposerWeakHandle;
+use crate::composer::{AnyComposerWeakHandle, Composer, PartialComposer};
use crate::downloader::DownloadManager;
use crate::installer::BinaryInstaller;
use crate::installer::BinaryPresenceInterface;
@@ -24,7 +24,7 @@ use crate::util::Silencer;
/// Package installation manager.
#[derive(Debug)]
pub struct LibraryInstaller {
- pub(crate) composer: PartialComposerWeakHandle,
+ pub(crate) composer: AnyComposerWeakHandle,
pub(crate) vendor_dir: String,
pub(crate) download_manager: Option<std::rc::Rc<std::cell::RefCell<DownloadManager>>>,
pub(crate) io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
@@ -37,7 +37,7 @@ impl LibraryInstaller {
/// Initializes library installer.
pub fn new(
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
- composer: PartialComposerWeakHandle,
+ composer: AnyComposerWeakHandle,
r#type: Option<String>,
filesystem: Option<std::rc::Rc<std::cell::RefCell<Filesystem>>>,
binary_installer: Option<BinaryInstaller>,
@@ -48,15 +48,13 @@ impl LibraryInstaller {
let download_manager = composer_rc
.as_full()
- .map(|full| full.borrow().get_download_manager());
-
- let composer_ref = composer_rc.borrow_partial();
+ .map(|full| full.get_download_manager());
let filesystem = filesystem
.unwrap_or_else(|| std::rc::Rc::new(std::cell::RefCell::new(Filesystem::new(None))));
let vendor_dir = rtrim(
// TODO(phase-b): Config::get returns PhpMixed; coerce to String via get_str.
- &composer_ref
+ &composer_rc
.get_config()
.borrow_mut()
.get_str("vendor-dir")
@@ -68,7 +66,7 @@ impl LibraryInstaller {
// TODO(phase-b): pass io by reference/clone
todo!("io reference"),
rtrim(
- &composer_ref
+ &composer_rc
.get_config()
.borrow_mut()
.get_str("bin-dir")
@@ -76,7 +74,7 @@ impl LibraryInstaller {
Some("/"),
),
// TODO(phase-b): Config::get returns PhpMixed; coerce to String via get_str.
- composer_ref
+ composer_rc
.get_config()
.borrow_mut()
.get_str("bin-compat")
diff --git a/crates/shirabe/src/installer/package_event.rs b/crates/shirabe/src/installer/package_event.rs
index 342732d..62bc395 100644
--- a/crates/shirabe/src/installer/package_event.rs
+++ b/crates/shirabe/src/installer/package_event.rs
@@ -1,6 +1,6 @@
//! ref: composer/src/Composer/Installer/PackageEvent.php
-use crate::composer::ComposerWeakHandle;
+use crate::composer::FullComposerWeakHandle;
use crate::dependency_resolver::operation::OperationInterface;
use crate::event_dispatcher::Event;
use crate::io::IOInterface;
@@ -10,7 +10,7 @@ use indexmap::IndexMap;
#[derive(Debug)]
pub struct PackageEvent {
inner: Event,
- composer: ComposerWeakHandle,
+ composer: FullComposerWeakHandle,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
dev_mode: bool,
local_repo: Box<dyn RepositoryInterface>,
@@ -21,7 +21,7 @@ pub struct PackageEvent {
impl PackageEvent {
pub fn new(
event_name: String,
- composer: ComposerWeakHandle,
+ composer: FullComposerWeakHandle,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
dev_mode: bool,
local_repo: Box<dyn RepositoryInterface>,
@@ -43,7 +43,7 @@ impl PackageEvent {
self.inner.get_name()
}
- pub fn get_composer(&self) -> &ComposerWeakHandle {
+ pub fn get_composer(&self) -> &FullComposerWeakHandle {
&self.composer
}
diff --git a/crates/shirabe/src/installer/plugin_installer.rs b/crates/shirabe/src/installer/plugin_installer.rs
index 38fcb0d..8776103 100644
--- a/crates/shirabe/src/installer/plugin_installer.rs
+++ b/crates/shirabe/src/installer/plugin_installer.rs
@@ -1,6 +1,6 @@
//! ref: composer/src/Composer/Installer/PluginInstaller.php
-use crate::composer::PartialComposerWeakHandle;
+use crate::composer::AnyComposerWeakHandle;
use crate::installer::BinaryInstaller;
use crate::installer::InstallerInterface;
use crate::installer::LibraryInstaller;
@@ -22,7 +22,7 @@ pub struct PluginInstaller {
impl PluginInstaller {
pub fn new(
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
- composer: PartialComposerWeakHandle,
+ composer: AnyComposerWeakHandle,
fs: Option<std::rc::Rc<std::cell::RefCell<Filesystem>>>,
binary_installer: Option<BinaryInstaller>,
) -> Self {
diff --git a/crates/shirabe/src/plugin/plugin_interface.rs b/crates/shirabe/src/plugin/plugin_interface.rs
index ae5e3b6..852c69b 100644
--- a/crates/shirabe/src/plugin/plugin_interface.rs
+++ b/crates/shirabe/src/plugin/plugin_interface.rs
@@ -1,17 +1,17 @@
//! ref: composer/src/Composer/Plugin/PluginInterface.php
-use crate::composer::ComposerHandle;
+use crate::composer::FullComposerHandle;
use crate::io::IOInterface;
use crate::plugin::Capable;
pub const PLUGIN_API_VERSION: &'static str = "2.9.0";
pub trait PluginInterface: std::fmt::Debug {
- fn activate(&mut self, composer: &ComposerHandle, io: &dyn IOInterface);
+ fn activate(&mut self, composer: &FullComposerHandle, io: &dyn IOInterface);
- fn deactivate(&mut self, composer: &ComposerHandle, io: &dyn IOInterface);
+ fn deactivate(&mut self, composer: &FullComposerHandle, io: &dyn IOInterface);
- fn uninstall(&mut self, composer: &ComposerHandle, io: &dyn IOInterface);
+ fn uninstall(&mut self, composer: &FullComposerHandle, io: &dyn IOInterface);
fn clone_box(&self) -> Box<dyn PluginInterface> {
todo!()
diff --git a/crates/shirabe/src/plugin/plugin_manager.rs b/crates/shirabe/src/plugin/plugin_manager.rs
index e2528ff..5f62047 100644
--- a/crates/shirabe/src/plugin/plugin_manager.rs
+++ b/crates/shirabe/src/plugin/plugin_manager.rs
@@ -16,8 +16,9 @@ use shirabe_php_shim::{
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
-use crate::composer::PartialComposerHandle;
-use crate::composer::{ComposerHandle, ComposerWeakHandle};
+use crate::composer::{
+ AnyComposerHandle, Composer, FullComposerHandle, FullComposerWeakHandle, PartialComposer,
+};
use crate::event_dispatcher::EventSubscriberInterface;
use crate::factory::DisablePlugins;
use crate::installer::InstallerInterface;
@@ -42,9 +43,9 @@ use crate::util::PackageSorter;
#[derive(Debug)]
pub struct PluginManager {
- pub(crate) composer: ComposerWeakHandle,
+ pub(crate) composer: FullComposerWeakHandle,
pub(crate) io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
- pub(crate) global_composer: Option<PartialComposerHandle>,
+ pub(crate) global_composer: Option<AnyComposerHandle>,
pub(crate) version_parser: VersionParser,
pub(crate) disable_plugins: DisablePlugins,
pub(crate) plugins: Vec<Box<dyn PluginInterface>>,
@@ -65,20 +66,19 @@ static mut CLASS_COUNTER: i64 = 0;
impl PluginManager {
pub fn new(
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
- composer: ComposerWeakHandle,
- global_composer: Option<PartialComposerHandle>,
+ composer: FullComposerWeakHandle,
+ global_composer: Option<AnyComposerHandle>,
disable_plugins: DisablePlugins,
) -> Self {
let composer_rc = composer
.upgrade()
.expect("PluginManager must not outlive Composer");
let allow_plugins_config = composer_rc
- .borrow()
.get_config()
.borrow()
.get("allow-plugins")
.clone();
- let locker = composer_rc.borrow().get_locker().clone();
+ let locker = composer_rc.get_locker().clone();
let mut locker = locker.borrow_mut();
let allow_plugin_rules =
Self::parse_allowed_plugins(allow_plugins_config, Some(&mut *locker));
@@ -86,13 +86,7 @@ impl PluginManager {
let allow_global_plugin_rules = Self::parse_allowed_plugins(
global_composer
.as_ref()
- .map(|gc| {
- gc.borrow_partial()
- .get_config()
- .borrow_mut()
- .get("allow-plugins")
- .clone()
- })
+ .map(|gc| gc.get_config().borrow_mut().get("allow-plugins").clone())
.unwrap_or(PhpMixed::Bool(false)),
None,
);
@@ -116,7 +110,7 @@ impl PluginManager {
/// Upgrades the weak Composer back-reference to a full handle. PHP holds a strong
/// `Composer`; the Rust port keeps it weak to break the Composer/PluginManager cycle.
- fn composer_full(&self) -> ComposerHandle {
+ fn composer_full(&self) -> FullComposerHandle {
self.composer
.upgrade()
.expect("PluginManager must not outlive Composer")
@@ -131,14 +125,13 @@ impl PluginManager {
// `&mut self`. The Rust port should eventually share via Rc<RefCell<_>>.
let repo: Box<dyn RepositoryInterface> = self
.composer_full()
- .borrow()
.get_repository_manager()
.borrow()
.get_local_repository()
.clone_box();
// The root package borrow is also tied to `self.composer`; clone the package handle
// (shared Rc) for the same reason as above.
- let root_package = self.composer_full().borrow().get_package().clone();
+ let root_package = self.composer_full().get_package().clone();
self.load_repository(&*repo, false, Some(root_package))?;
}
@@ -147,7 +140,6 @@ impl PluginManager {
.global_composer
.as_ref()
.unwrap()
- .borrow_partial()
.get_repository_manager()
.borrow()
.get_local_repository()
@@ -163,7 +155,6 @@ impl PluginManager {
if !self.are_plugins_disabled("local") {
let repo: Box<dyn RepositoryInterface> = self
.composer_full()
- .borrow()
.get_repository_manager()
.borrow()
.get_local_repository()
@@ -176,7 +167,6 @@ impl PluginManager {
.global_composer
.as_ref()
.unwrap()
- .borrow_partial()
.get_repository_manager()
.borrow()
.get_local_repository()
@@ -198,7 +188,7 @@ impl PluginManager {
}
/// Gets global composer or null when main composer is not fully loaded
- pub fn get_global_composer(&self) -> Option<&PartialComposerHandle> {
+ pub fn get_global_composer(&self) -> Option<&AnyComposerHandle> {
self.global_composer.as_ref()
}
@@ -357,7 +347,6 @@ impl PluginManager {
match plugin {
PluginOrInstaller::Installer(inst) => {
self.composer_full()
- .borrow()
.get_installation_manager()
.borrow_mut()
.remove_installer(&*inst);
@@ -384,7 +373,6 @@ impl PluginManager {
match plugin {
PluginOrInstaller::Installer(inst) => {
self.composer_full()
- .borrow()
.get_installation_manager()
.borrow_mut()
.remove_installer(&*inst);
@@ -635,7 +623,6 @@ impl PluginManager {
if !global {
return self
.composer_full()
- .borrow()
.get_installation_manager()
.borrow_mut()
.get_install_path(package);
@@ -645,7 +632,6 @@ impl PluginManager {
self.global_composer
.as_ref()
.unwrap()
- .borrow_partial()
.get_installation_manager()
.borrow_mut()
.get_install_path(package)
@@ -862,7 +848,6 @@ impl PluginManager {
.composer
.upgrade()
.expect("PluginManager must not outlive Composer")
- .borrow()
.get_config()
.clone();
diff --git a/crates/shirabe/src/repository/platform_repository.rs b/crates/shirabe/src/repository/platform_repository.rs
index 1b95ff7..4290f15 100644
--- a/crates/shirabe/src/repository/platform_repository.rs
+++ b/crates/shirabe/src/repository/platform_repository.rs
@@ -15,7 +15,6 @@ use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
use crate::composer;
-use crate::composer::ComposerHandle;
use crate::package::CompletePackage;
use crate::package::CompletePackageHandle;
use crate::package::CompletePackageInterface;
diff --git a/crates/shirabe/src/script/event.rs b/crates/shirabe/src/script/event.rs
index 60557b0..26f85ca 100644
--- a/crates/shirabe/src/script/event.rs
+++ b/crates/shirabe/src/script/event.rs
@@ -1,6 +1,6 @@
//! ref: composer/src/Composer/Script/Event.php
-use crate::composer::ComposerWeakHandle;
+use crate::composer::FullComposerWeakHandle;
use crate::event_dispatcher::Event as BaseEvent;
use crate::io::IOInterface;
use indexmap::IndexMap;
@@ -9,7 +9,7 @@ use shirabe_php_shim::PhpMixed;
#[derive(Debug)]
pub struct Event {
inner: BaseEvent,
- composer: ComposerWeakHandle,
+ composer: FullComposerWeakHandle,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
dev_mode: bool,
originating_event: Option<Box<BaseEvent>>,
@@ -18,7 +18,7 @@ pub struct Event {
impl Event {
pub fn new(
name: String,
- composer: ComposerWeakHandle,
+ composer: FullComposerWeakHandle,
io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>,
dev_mode: bool,
args: Vec<String>,
@@ -33,7 +33,7 @@ impl Event {
}
}
- pub fn get_composer(&self) -> &ComposerWeakHandle {
+ pub fn get_composer(&self) -> &FullComposerWeakHandle {
&self.composer
}
diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs
index 610bd3a..2a9f491 100644
--- a/crates/shirabe/src/util/http_downloader.rs
+++ b/crates/shirabe/src/util/http_downloader.rs
@@ -14,7 +14,6 @@ use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
use crate::composer;
-use crate::composer::ComposerHandle;
use crate::config::Config;
use crate::downloader::TransportException;
use crate::io::IOInterface;
diff --git a/crates/shirabe/src/util/stream_context_factory.rs b/crates/shirabe/src/util/stream_context_factory.rs
index 488d807..d1c281b 100644
--- a/crates/shirabe/src/util/stream_context_factory.rs
+++ b/crates/shirabe/src/util/stream_context_factory.rs
@@ -9,7 +9,6 @@ use shirabe_php_shim::{
};
use crate::composer;
-use crate::composer::ComposerHandle;
use crate::downloader::TransportException;
use crate::repository::PlatformRepository;
use crate::util::Filesystem;