diff options
Diffstat (limited to 'crates')
41 files changed, 156 insertions, 141 deletions
diff --git a/crates/shirabe/src/command/bump_command.rs b/crates/shirabe/src/command/bump_command.rs index 0f62bb8..64ec54b 100644 --- a/crates/shirabe/src/command/bump_command.rs +++ b/crates/shirabe/src/command/bump_command.rs @@ -13,6 +13,7 @@ use crate::console::input::InputArgument; use crate::console::input::InputOption; use crate::factory::Factory; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::json::JsonFile; use crate::json::JsonManipulator; use crate::package::AliasPackage; @@ -72,10 +73,9 @@ impl BumpCommand { let dev_only = input.get_option("dev-only").as_bool().unwrap_or(false); let no_dev_only = input.get_option("no-dev-only").as_bool().unwrap_or(false); let dry_run = input.get_option("dry-run").as_bool().unwrap_or(false); - // TODO(phase-b): do_bump expects &dyn IOInterface but get_io() requires &mut self; needs IO sharing refactor - let io_ref: &dyn IOInterface = todo!("share IOInterface across calls in do_bump"); + let io = self.get_io().clone(); self.do_bump( - io_ref, + io, dev_only, no_dev_only, dry_run, @@ -86,7 +86,7 @@ impl BumpCommand { pub fn do_bump( &mut self, - io: &dyn IOInterface, + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, dev_only: bool, no_dev_only: bool, dry_run: bool, diff --git a/crates/shirabe/src/command/create_project_command.rs b/crates/shirabe/src/command/create_project_command.rs index c669aa5..e52fe39 100644 --- a/crates/shirabe/src/command/create_project_command.rs +++ b/crates/shirabe/src/command/create_project_command.rs @@ -816,7 +816,7 @@ impl CreateProjectCommand { &stability, None, 0, - Some(&*io.borrow()), + Some(io.clone()), PhpMixed::Bool(true), )?; @@ -926,7 +926,7 @@ impl CreateProjectCommand { true, false, )?; - im.notify_installs(&*io.borrow()); + im.notify_installs(io.clone()); // collect suggestions // TODO(phase-b): self.suggested_packages_reporter is on the outer scope via &self diff --git a/crates/shirabe/src/command/diagnose_command.rs b/crates/shirabe/src/command/diagnose_command.rs index 945d1e9..bcedf30 100644 --- a/crates/shirabe/src/command/diagnose_command.rs +++ b/crates/shirabe/src/command/diagnose_command.rs @@ -79,7 +79,7 @@ impl DiagnoseCommand { output: &dyn OutputInterface, ) -> anyhow::Result<i64> { let mut composer = self.try_composer(None, None); - let io_boxed: std::rc::Rc<std::cell::RefCell<dyn IOInterface>> = self.get_io().clone(); + let io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>> = self.get_io().clone(); let config: std::rc::Rc<std::cell::RefCell<Config>>; if let Some(ref mut c) = composer { @@ -104,7 +104,7 @@ impl DiagnoseCommand { .map(std::rc::Rc::clone) .unwrap_or_else(|| { std::rc::Rc::new(std::cell::RefCell::new(ProcessExecutor::new(Some( - io_boxed.clone(), + io.clone(), )))) }), ); @@ -112,14 +112,9 @@ impl DiagnoseCommand { config = std::rc::Rc::new(std::cell::RefCell::new(Factory::create_config(None, None)?)); self.process = Some(std::rc::Rc::new(std::cell::RefCell::new( - ProcessExecutor::new(Some(io_boxed.clone())), + ProcessExecutor::new(Some(io.clone())), ))); } - // TODO(phase-b): clone_box to release self borrow held by get_io. - let io_box = self.get_io().clone(); - let io_ref = io_box.borrow(); - let io: &dyn IOInterface = &*io_ref; - let mut config_inner: IndexMap<String, Box<PhpMixed>> = IndexMap::new(); config_inner.insert("secure-http".to_string(), Box::new(PhpMixed::Bool(false))); let mut secure_http_wrap: IndexMap<String, PhpMixed> = IndexMap::new(); @@ -130,12 +125,12 @@ impl DiagnoseCommand { .merge(&secure_http_wrap, Config::SOURCE_COMMAND); let _ = config.borrow_mut().prohibit_url_by_config( "http://repo.packagist.org", - Some(&NullIO::new()), + Some(std::rc::Rc::new(std::cell::RefCell::new(NullIO::new()))), &IndexMap::new(), ); self.http_downloader = Some(std::rc::Rc::new(std::cell::RefCell::new( - Factory::create_http_downloader(io_box.clone(), &config, indexmap::IndexMap::new())?, + Factory::create_http_downloader(io.clone(), &config, indexmap::IndexMap::new())?, ))); if strpos(file!(), "phar:") == Some(0) { diff --git a/crates/shirabe/src/command/home_command.rs b/crates/shirabe/src/command/home_command.rs index 0038add..067af8f 100644 --- a/crates/shirabe/src/command/home_command.rs +++ b/crates/shirabe/src/command/home_command.rs @@ -73,10 +73,7 @@ impl HomeCommand { _output: &dyn OutputInterface, ) -> Result<i64> { let repos = self.initialize_repos()?; - // TODO(phase-b): clone_box to release self borrow held by get_io. - let io_box = self.get_io().clone(); - let io_ref = io_box.borrow(); - let io: &dyn IOInterface = &*io_ref; + let io = self.get_io().clone(); let mut return_code: i64 = 0; let packages: Vec<String> = input diff --git a/crates/shirabe/src/command/install_command.rs b/crates/shirabe/src/command/install_command.rs index 4c869f4..768f75f 100644 --- a/crates/shirabe/src/command/install_command.rs +++ b/crates/shirabe/src/command/install_command.rs @@ -11,6 +11,7 @@ use crate::console::input::InputArgument; use crate::console::input::InputOption; use crate::installer::Installer; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::plugin::CommandEvent; use crate::plugin::PluginEvents; use crate::util::HttpDownloader; @@ -66,10 +67,7 @@ impl InstallCommand { input: &dyn InputInterface, output: &dyn OutputInterface, ) -> Result<i64> { - // TODO(phase-b): clone_box to release self borrow held by get_io. - let io_box = self.get_io().clone(); - let io_ref = io_box.borrow(); - let io: &dyn IOInterface = &*io_ref; + let io = self.get_io().clone(); if input.get_option("dev").as_bool().unwrap_or(false) { io.write_error("<warning>You are using the deprecated option \"--dev\". It has no effect and will break in Composer 3.</warning>"); @@ -115,7 +113,7 @@ impl InstallCommand { .borrow_mut() .dispatch(Some(command_event.get_name()), None); - let mut install = Installer::create(io_box.clone(), &composer_handle); + let mut install = Installer::create(io.clone(), &composer_handle); let config = composer.get_config(); let (prefer_source, prefer_dist) = diff --git a/crates/shirabe/src/command/package_discovery_trait.rs b/crates/shirabe/src/command/package_discovery_trait.rs index f036103..7da2b9a 100644 --- a/crates/shirabe/src/command/package_discovery_trait.rs +++ b/crates/shirabe/src/command/package_discovery_trait.rs @@ -178,10 +178,15 @@ pub trait PackageDiscoveryTrait { if !requirement.contains_key("version") { // determine the best version automatically - // TODO(phase-b): self.get_io() borrow conflicts with self.find_best_version_and_name_for_package - let (name, version): (String, String) = todo!( - "borrow conflict between get_io and find_best_version_and_name_for_package" - ); + let (name, version): (String, String) = self + .find_best_version_and_name_for_package( + io.clone(), + input, + requirement.get("name").map(|s| s.as_str()).unwrap_or(""), + platform_repo, + preferred_stability, + fixed, + )?; // replace package name from packagist.org requirement.insert("name".to_string(), name); @@ -431,10 +436,15 @@ pub trait PackageDiscoveryTrait { let constraint: String = match &constraint_mixed { PhpMixed::Bool(false) => { - // TODO(phase-b): self.get_io() borrow conflicts with self.find_best_version_and_name_for_package - let (_name, c): (String, String) = todo!( - "borrow conflict between get_io and find_best_version_and_name_for_package" - ); + let (_name, c): (String, String) = self + .find_best_version_and_name_for_package( + io.clone(), + input, + &package, + platform_repo, + preferred_stability, + fixed, + )?; io.write_error3( &sprintf( @@ -475,7 +485,7 @@ pub trait PackageDiscoveryTrait { /// @return array{string, string} name version fn find_best_version_and_name_for_package( &mut self, - io: &dyn IOInterface, + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, input: &dyn InputInterface, name: &str, platform_repo: Option<&PlatformRepository>, @@ -734,7 +744,7 @@ pub trait PackageDiscoveryTrait { if let Ok(idx) = idx_str.parse::<usize>() { if let Some(selected) = similar.get(idx) { return self.find_best_version_and_name_for_package( - io, + io.clone(), input, selected, platform_repo, diff --git a/crates/shirabe/src/command/remove_command.rs b/crates/shirabe/src/command/remove_command.rs index 9ea7329..a393f0f 100644 --- a/crates/shirabe/src/command/remove_command.rs +++ b/crates/shirabe/src/command/remove_command.rs @@ -511,10 +511,7 @@ impl RemoveCommand { .borrow_mut() .set_output_progress(!input.get_option("no-progress").as_bool().unwrap_or(false)); - // TODO(phase-b): Installer::create expects std::rc::Rc<std::cell::RefCell<dyn IOInterface>>; io here is &mut dyn IOInterface - let io_box: std::rc::Rc<std::cell::RefCell<dyn IOInterface>> = - todo!("share IOInterface as Box<dyn IOInterface>"); - let mut install = Installer::create(io_box, &composer_handle); + let mut install = Installer::create(self.get_io().clone(), &composer_handle); let update_dev_mode = !input.get_option("update-no-dev").as_bool().unwrap_or(false); let optimize = input diff --git a/crates/shirabe/src/command/require_command.rs b/crates/shirabe/src/command/require_command.rs index 93ec469..f59d60f 100644 --- a/crates/shirabe/src/command/require_command.rs +++ b/crates/shirabe/src/command/require_command.rs @@ -553,17 +553,9 @@ impl RequireCommand { .borrow_mut() .deactivate_installed_plugins(); - // try/catch/finally - // TODO(phase-b): do_update borrows io from self while also needing &mut self for state - // mutations; needs an Rc<dyn IOInterface> on self for clean sharing. - let do_update_result = self.do_update( - input, - output, - todo!("share io reference for do_update"), - &requirements, - require_key, - remove_key, - ); + let io = self.get_io().clone(); + let do_update_result = + self.do_update(input, output, io, &requirements, require_key, remove_key); let dry_run = input.get_option("dry-run").as_bool().unwrap_or(false); let result = match do_update_result { @@ -682,7 +674,7 @@ impl RequireCommand { &mut self, input: &dyn InputInterface, output: &dyn OutputInterface, - io: &dyn IOInterface, + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, requirements: &IndexMap<String, String>, require_key: &str, _remove_key: &str, @@ -848,12 +840,7 @@ impl RequireCommand { .borrow_mut() .set_output_progress(!input.get_option("no-progress").as_bool().unwrap_or(false)); - // TODO(phase-b): Installer::create takes std::rc::Rc<std::cell::RefCell<dyn IOInterface>> for ownership but io is a - // borrowed &dyn here; needs Rc<dyn IOInterface> for proper sharing. - let mut install = Installer::create( - todo!("share io as std::rc::Rc<std::cell::RefCell<dyn IOInterface>>"), - &composer_handle, - ); + let mut install = Installer::create(io.clone(), &composer_handle); let (prefer_source, prefer_dist) = self.get_preferred_install_options(&*composer.get_config().borrow(), input, false)?; diff --git a/crates/shirabe/src/command/self_update_command.rs b/crates/shirabe/src/command/self_update_command.rs index fc22ab7..9b960f0 100644 --- a/crates/shirabe/src/command/self_update_command.rs +++ b/crates/shirabe/src/command/self_update_command.rs @@ -143,7 +143,7 @@ impl SelfUpdateCommand { for channel in Versions::CHANNELS { if input.get_option(channel).as_bool().unwrap_or(false) { requested_channel = Some(channel.to_string()); - versions_util.set_channel(channel.to_string(), Some(&*io.borrow()))??; + versions_util.set_channel(channel.to_string(), Some(io.clone()))??; break; } } @@ -184,8 +184,7 @@ impl SelfUpdateCommand { } if input.get_option("update-keys").as_bool().unwrap_or(false) { - // TODO(phase-b): re-borrow `io` after fetch_keys conflicts with the earlier `let io = self.get_io()` borrow - let _ = io; + self.fetch_keys(io.clone(), &*config.borrow())?; return Ok(0); } @@ -656,7 +655,11 @@ RGv89BPD+2DLnJysngsvVaUCAwEAAQ==\n\ } /// @throws \Exception - pub(crate) fn fetch_keys(&self, io: &dyn IOInterface, config: &Config) -> Result<()> { + pub(crate) fn fetch_keys( + &self, + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, + config: &Config, + ) -> Result<()> { if !io.is_interactive() { return Err(RuntimeException { message: "Public keys can not be fetched in non-interactive mode, please run Composer interactively".to_string(), diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs index 5a9c676..19e7712 100644 --- a/crates/shirabe/src/command/show_command.rs +++ b/crates/shirabe/src/command/show_command.rs @@ -2674,7 +2674,7 @@ impl ShowCommand { &best_stability, None, 0, - Some(&*self.get_io().borrow()), + Some(self.get_io().clone()), PhpMixed::Bool(true), )?; while let Some(ref c) = candidate { diff --git a/crates/shirabe/src/command/status_command.rs b/crates/shirabe/src/command/status_command.rs index 9f66adf..dba4cc8 100644 --- a/crates/shirabe/src/command/status_command.rs +++ b/crates/shirabe/src/command/status_command.rs @@ -8,6 +8,7 @@ use shirabe_external_packages::symfony::component::console::output::OutputInterf use crate::command::{BaseCommand, BaseCommandData, HasBaseCommandData}; use crate::console::input::InputOption; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::package::dumper::ArrayDumper; use crate::package::version::VersionGuesser; use crate::package::version::VersionParser; @@ -86,10 +87,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); - // 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(); - let io: &dyn IOInterface = &*io_ref; + let io = self.get_io().clone(); let mut errors: IndexMap<String, String> = IndexMap::new(); let mut unpushed_changes: IndexMap<String, String> = IndexMap::new(); @@ -104,14 +102,14 @@ impl StatusCommand { .map(std::rc::Rc::clone) .unwrap_or_else(|| { std::rc::Rc::new(std::cell::RefCell::new(ProcessExecutor::new(Some( - io_box.clone(), + io.clone(), )))) }); let mut guesser = VersionGuesser::new( composer.get_config(), process_executor.clone(), parser.clone(), - Some(io_box.clone()), + Some(io.clone()), ); let dumper = ArrayDumper::new(); diff --git a/crates/shirabe/src/command/suggests_command.rs b/crates/shirabe/src/command/suggests_command.rs index 9105474..5006790 100644 --- a/crates/shirabe/src/command/suggests_command.rs +++ b/crates/shirabe/src/command/suggests_command.rs @@ -90,10 +90,7 @@ impl SuggestsCommand { } let installed_repo = InstalledRepository::new(installed_repos); - // TODO(phase-b): SuggestedPackagesReporter::new expects std::rc::Rc<std::cell::RefCell<dyn IOInterface>>; self.get_io() returns &mut dyn IOInterface - let io_box: std::rc::Rc<std::cell::RefCell<dyn IOInterface>> = - todo!("share IOInterface as Box<dyn IOInterface>"); - let mut reporter = SuggestedPackagesReporter::new(io_box); + let mut reporter = SuggestedPackagesReporter::new(self.get_io().clone()); let filter = input.get_argument("packages"); let mut packages = RepositoryInterface::get_packages(&installed_repo); diff --git a/crates/shirabe/src/command/update_command.rs b/crates/shirabe/src/command/update_command.rs index f1b05af..22ce506 100644 --- a/crates/shirabe/src/command/update_command.rs +++ b/crates/shirabe/src/command/update_command.rs @@ -24,6 +24,7 @@ use crate::console::input::InputOption; use crate::dependency_resolver::request::{self, Request, UpdateAllowTransitiveDeps}; use crate::installer::Installer; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::package::loader::RootPackageLoader; use crate::package::version::VersionParser; use crate::package::version::VersionSelector; @@ -75,11 +76,7 @@ impl UpdateCommand { input: &dyn InputInterface, output: &dyn OutputInterface, ) -> Result<i64> { - // TODO(phase-b): clone_box avoids the &mut self conflict with require_composer - // below; revisit when get_io can return an Rc/Arc owned handle. - let io_box = self.get_io().clone(); - let io_ref = io_box.borrow(); - let io: &dyn IOInterface = &*io_ref; + let io = self.get_io().clone(); if input.get_option("dev").as_bool().unwrap_or(false) { io.write_error3( "<warning>You are using the deprecated option \"--dev\". It has no effect and will break in Composer 3.</warning>", @@ -248,8 +245,13 @@ impl UpdateCommand { } if input.get_option("interactive").as_bool().unwrap_or(false) { - packages = - self.get_packages_interactively(io, input, output, &composer_handle, packages)?; + packages = self.get_packages_interactively( + io.clone(), + input, + output, + &composer_handle, + packages, + )?; } if input.get_option("root-reqs").as_bool().unwrap_or(false) { @@ -312,7 +314,7 @@ impl UpdateCommand { .borrow_mut() .set_output_progress(!input.get_option("no-progress").as_bool().unwrap_or(false)); - let mut install = Installer::create(io_box.clone(), &composer_handle); + let mut install = Installer::create(io.clone(), &composer_handle); let config = composer.get_config(); let (prefer_source, prefer_dist) = @@ -432,7 +434,7 @@ impl UpdateCommand { // set_composer here requires a shared PartialComposer handle. // bump_command.set_composer(composer); result = bump_command.do_bump( - io, + io.clone(), bump_after_update.as_string() == Some("dev"), bump_after_update.as_string() == Some("no-dev"), input.get_option("dry-run").as_bool().unwrap_or(false), @@ -457,7 +459,7 @@ impl UpdateCommand { /// @return array<string> fn get_packages_interactively( &self, - io: &dyn IOInterface, + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, input: &dyn InputInterface, output: &dyn OutputInterface, composer: &PartialComposerHandle, diff --git a/crates/shirabe/src/command/validate_command.rs b/crates/shirabe/src/command/validate_command.rs index 12eadd7..da76eca 100644 --- a/crates/shirabe/src/command/validate_command.rs +++ b/crates/shirabe/src/command/validate_command.rs @@ -9,6 +9,7 @@ use crate::console::input::InputArgument; use crate::console::input::InputOption; use crate::factory::Factory; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::package::loader::ValidatingArrayLoader; use crate::plugin::CommandEvent; use crate::plugin::PluginEvents; @@ -118,10 +119,7 @@ impl ValidateCommand { .map(|s| s.to_string()) .map(Ok) .unwrap_or_else(Factory::get_composer_file)?; - // TODO(phase-b): get_io() takes &mut self via BaseCommand; clone_box to release the borrow. - let io_box = self.get_io().clone(); - let io_ref = io_box.borrow(); - let io: &dyn IOInterface = &*io_ref; + let io = self.get_io().clone(); if !std::path::Path::new(&file).exists() { io.write_error(&format!("<error>{} not found.</error>", file)); @@ -132,7 +130,7 @@ impl ValidateCommand { return Ok(3); } - let validator = ConfigValidator::new(io_box.clone()); + let validator = ConfigValidator::new(io.clone()); let check_all = if input.get_option("no-check-all").as_bool().unwrap_or(false) { 0 } else { @@ -157,7 +155,7 @@ impl ValidateCommand { validator.validate(&file, check_all, check_version); let mut lock_errors: Vec<String> = vec![]; - let composer = self.create_composer_instance(input, io_box.clone(), None, false, None)?; + let composer = self.create_composer_instance(input, io.clone(), None, false, None)?; let mut composer = crate::command::composer_full_mut(&composer); let check_lock = (check_lock && composer @@ -182,7 +180,7 @@ impl ValidateCommand { } self.output_result( - io, + io.clone(), &file, &mut errors, &mut warnings, @@ -229,7 +227,7 @@ impl ValidateCommand { validator.validate(&dep_file, check_all, check_version); self.output_result( - io, + io.clone(), &package.get_pretty_name(), &mut dep_errors, &mut dep_warnings, @@ -264,7 +262,7 @@ impl ValidateCommand { fn output_result( &self, - io: &dyn IOInterface, + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, name: &str, errors: &mut Vec<String>, warnings: &mut Vec<String>, diff --git a/crates/shirabe/src/config.rs b/crates/shirabe/src/config.rs index f39fc1c..b3460e8 100644 --- a/crates/shirabe/src/config.rs +++ b/crates/shirabe/src/config.rs @@ -21,6 +21,7 @@ use std::cell::RefCell; use crate::advisory::Auditor; use crate::downloader::TransportException; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::util::Platform; use crate::util::ProcessExecutor; @@ -1144,7 +1145,7 @@ impl Config { pub fn prohibit_url_by_config( &mut self, url: &str, - io: Option<&dyn IOInterface>, + io: Option<std::rc::Rc<std::cell::RefCell<dyn IOInterface>>>, repo_options: &IndexMap<String, PhpMixed>, ) -> Result<()> { // Return right away if the URL is malformed or custom (see issue #5173), but only for non-HTTP(S) URLs @@ -1206,7 +1207,7 @@ impl Config { ) .into()); } - if let Some(io) = io { + if let Some(ref io) = io { if let Some(ref hostname) = hostname { if !self.warned_hosts.contains_key(hostname) { io.write_error3( @@ -1224,7 +1225,7 @@ impl Config { } } - if let Some(io) = io { + if let Some(ref io) = io { if let Some(ref hostname) = hostname { if !self.ssl_verify_warned_hosts.contains_key(hostname) { let mut warning: Option<String> = None; diff --git a/crates/shirabe/src/downloader/fossil_downloader.rs b/crates/shirabe/src/downloader/fossil_downloader.rs index fae3bd4..7e80c4c 100644 --- a/crates/shirabe/src/downloader/fossil_downloader.rs +++ b/crates/shirabe/src/downloader/fossil_downloader.rs @@ -47,7 +47,7 @@ impl FossilDownloader { ) -> Result<Option<PhpMixed>> { self.inner.config.borrow_mut().prohibit_url_by_config( &url, - Some(&*self.inner.io.borrow()), + Some(self.inner.io.clone()), &indexmap::IndexMap::new(), )?; @@ -108,7 +108,7 @@ impl FossilDownloader { ) -> Result<Option<PhpMixed>> { self.inner.config.borrow_mut().prohibit_url_by_config( &url, - Some(&*self.inner.io.borrow()), + Some(self.inner.io.clone()), &indexmap::IndexMap::new(), )?; diff --git a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs index ef02660..237fad4 100644 --- a/crates/shirabe/src/event_dispatcher/event_dispatcher.rs +++ b/crates/shirabe/src/event_dispatcher/event_dispatcher.rs @@ -612,8 +612,6 @@ impl EventDispatcher { // TODO(phase-b): IOInterface needs an `as_any` shim before // `instanceof ConsoleIO` can be expressed; treat io as a // generic IOInterface for now. - let _io_ref_guard = self.io.borrow(); - let _io_ref: &dyn IOInterface = &*_io_ref_guard; let downcast: Option<&ConsoleIO> = None; let output: ConsoleOutput = if let Some(_console_io) = downcast { // TODO(plugin): \ReflectionProperty to read private `output` from ConsoleIO diff --git a/crates/shirabe/src/factory.rs b/crates/shirabe/src/factory.rs index f2fa99b..ce45306 100644 --- a/crates/shirabe/src/factory.rs +++ b/crates/shirabe/src/factory.rs @@ -44,6 +44,7 @@ use crate::installer::MetapackageInstaller; use crate::installer::PluginInstaller; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; +use crate::io::IOInterfaceMutable; use crate::json::JsonFile; use crate::json::JsonValidationException; use crate::package::Locker; @@ -592,8 +593,8 @@ impl Factory { 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())?; + io.borrow_mut() + .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 diff --git a/crates/shirabe/src/installer.rs b/crates/shirabe/src/installer.rs index f0c07bf..f7bcde3 100644 --- a/crates/shirabe/src/installer.rs +++ b/crates/shirabe/src/installer.rs @@ -321,7 +321,7 @@ impl Installer { { self.installation_manager .borrow_mut() - .notify_installs(&*self.io.borrow()); + .notify_installs(self.io.clone()); } return Err(e); } @@ -339,7 +339,7 @@ impl Installer { { self.installation_manager .borrow_mut() - .notify_installs(&*self.io.borrow()); + .notify_installs(self.io.clone()); } if self.update { diff --git a/crates/shirabe/src/installer/installation_manager.rs b/crates/shirabe/src/installer/installation_manager.rs index 95a1870..26fe84f 100644 --- a/crates/shirabe/src/installer/installation_manager.rs +++ b/crates/shirabe/src/installer/installation_manager.rs @@ -635,7 +635,7 @@ impl InstallationManager { self.output_progress = output_progress; } - pub fn notify_installs(&mut self, _io: &dyn IOInterface) { + pub fn notify_installs(&mut self, _io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>) { // TODO(phase-c-promise): PHP collects every http_downloader.add() promise and runs them via // Loop::wait; the single-threaded sync bridge block_on's each notification serially instead. let result: Result<()> = (|| -> Result<()> { diff --git a/crates/shirabe/src/package/version/version_selector.rs b/crates/shirabe/src/package/version/version_selector.rs index 99b459e..d2a551f 100644 --- a/crates/shirabe/src/package/version/version_selector.rs +++ b/crates/shirabe/src/package/version/version_selector.rs @@ -16,6 +16,7 @@ use crate::filter::platform_requirement_filter::IgnoreListPlatformRequirementFil use crate::filter::platform_requirement_filter::PlatformRequirementFilterFactory; use crate::filter::platform_requirement_filter::PlatformRequirementFilterInterface; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::package::PackageInterfaceHandle; use crate::package::base_package; use crate::package::dumper::ArrayDumper; @@ -66,7 +67,7 @@ impl VersionSelector { preferred_stability: &str, platform_requirement_filter: Option<Box<dyn PlatformRequirementFilterInterface>>, repo_set_flags: i64, - io: Option<&dyn IOInterface>, + io: Option<std::rc::Rc<std::cell::RefCell<dyn IOInterface>>>, show_warnings: shirabe_php_shim::PhpMixed, ) -> anyhow::Result<Option<crate::package::PackageInterfaceHandle>> { if !base_package::STABILITIES.contains_key(preferred_stability) { @@ -178,7 +179,7 @@ impl VersionSelector { let is_latest_version = !already_seen_names.contains_key(&pkg.get_name()); already_seen_names.insert(pkg.get_name().to_string(), true); - if let Some(io) = io { + if let Some(ref io) = io { let should_warn = match &show_warnings { shirabe_php_shim::PhpMixed::Bool(b) => *b, _ => true, diff --git a/crates/shirabe/src/plugin/plugin_interface.rs b/crates/shirabe/src/plugin/plugin_interface.rs index ae5e3b6..c0212de 100644 --- a/crates/shirabe/src/plugin/plugin_interface.rs +++ b/crates/shirabe/src/plugin/plugin_interface.rs @@ -3,15 +3,17 @@ use crate::composer::ComposerHandle; use crate::io::IOInterface; use crate::plugin::Capable; +use std::cell::RefCell; +use std::rc::Rc; 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: &ComposerHandle, io: Rc<RefCell<dyn IOInterface>>); - fn deactivate(&mut self, composer: &ComposerHandle, io: &dyn IOInterface); + fn deactivate(&mut self, composer: &ComposerHandle, io: Rc<RefCell<dyn IOInterface>>); - fn uninstall(&mut self, composer: &ComposerHandle, io: &dyn IOInterface); + fn uninstall(&mut self, composer: &ComposerHandle, io: Rc<RefCell<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 611ddfa..c917e99 100644 --- a/crates/shirabe/src/plugin/plugin_manager.rs +++ b/crates/shirabe/src/plugin/plugin_manager.rs @@ -453,7 +453,7 @@ impl PluginManager { String::new() } )); - plugin.activate(&self.composer_full(), &*self.io.borrow()); + plugin.activate(&self.composer_full(), self.io.clone()); // TODO(plugin): if plugin is EventSubscriberInterface, hook into the event dispatcher // The PHP code calls $this->composer->getEventDispatcher()->addSubscriber($plugin); @@ -480,7 +480,7 @@ impl PluginManager { self.io .write_error(&format!("Unloading plugin {}", get_class_obj(plugin))); let mut removed = self.plugins.remove(index); - removed.deactivate(&self.composer_full(), &*self.io.borrow()); + removed.deactivate(&self.composer_full(), self.io.clone()); // TODO(plugin): remove_listener accepts any callable/object in PHP; here we have // a plugin instance and need to translate to a Callable, which is not portable @@ -493,7 +493,7 @@ impl PluginManager { // TODO(plugin): plugin uninstall hook self.io .write_error(&format!("Uninstalling plugin {}", get_class_obj(plugin))); - plugin.uninstall(&self.composer_full(), &*self.io.borrow()); + plugin.uninstall(&self.composer_full(), self.io.clone()); } fn load_repository( diff --git a/crates/shirabe/src/repository/composer_repository.rs b/crates/shirabe/src/repository/composer_repository.rs index 9931a73..d39fd82 100644 --- a/crates/shirabe/src/repository/composer_repository.rs +++ b/crates/shirabe/src/repository/composer_repository.rs @@ -264,11 +264,12 @@ impl ComposerRepository { let base_url = base_url_trimmed.trim_end_matches('/').to_string(); assert!(!base_url.is_empty()); - // TODO(phase-b): Cache::new expects std::rc::Rc<std::cell::RefCell<dyn IOInterface>> but io is also stored in self.io; - // need shared ownership (Rc) for IOInterface. Using todo!() placeholder. - let cache: Cache = todo!( - "Cache::new requires std::rc::Rc<std::cell::RefCell<dyn IOInterface>> but io is also moved into self.io" + let cache_dir = format!( + "{}/{}", + config.get("cache-repo-dir").as_string().unwrap_or(""), + Preg::replace(r"{[^a-z0-9.]}i", "-", &Url::sanitize(url.clone()))?, ); + let cache = Cache::new(io.clone(), &cache_dir, Some("a-z0-9.$~"), None, false); let version_parser = VersionParser::new(); let loader = ArrayLoader::new(Some(version_parser.clone()), true); @@ -2963,7 +2964,7 @@ impl ComposerRepository { .as_array() .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()) .unwrap_or_default(); - HttpDownloader::output_warnings(&*self.io.borrow(), &self.url, &data_local); + HttpDownloader::output_warnings(self.io.clone(), &self.url, &data_local); if let Some(ck) = cache_key_owned.as_ref() { if !ck.is_empty() && !self.cache.is_read_only() { @@ -3160,7 +3161,7 @@ impl ComposerRepository { .as_array() .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()) .unwrap_or_default(); - HttpDownloader::output_warnings(&*self.io.borrow(), &self.url, &data); + HttpDownloader::output_warnings(self.io.clone(), &self.url, &data); let last_modified_date = response.get_header("last-modified"); response.collect(); @@ -3338,7 +3339,7 @@ impl ComposerRepository { .as_array() .map(|a| a.iter().map(|(k, v)| (k.clone(), (**v).clone())).collect()) .unwrap_or_default(); - HttpDownloader::output_warnings(&*self.io.borrow(), &self.url, &data); + HttpDownloader::output_warnings(self.io.clone(), &self.url, &data); let last_modified_date = response.get_header("last-modified"); response.collect(); diff --git a/crates/shirabe/src/repository/repository_factory.rs b/crates/shirabe/src/repository/repository_factory.rs index 1159da1..89334a1 100644 --- a/crates/shirabe/src/repository/repository_factory.rs +++ b/crates/shirabe/src/repository/repository_factory.rs @@ -10,6 +10,7 @@ use crate::config::Config; use crate::event_dispatcher::EventDispatcher; use crate::factory::Factory; use crate::io::IOInterface; +use crate::io::IOInterfaceMutable; use crate::json::JsonFile; use crate::repository::FilesystemRepository; use crate::repository::RepositoryInterfaceHandle; @@ -150,9 +151,9 @@ impl RepositoryFactory { Some(c) => c, None => std::rc::Rc::new(std::cell::RefCell::new(Factory::create_config(None, None)?)), }; - if let Some(_io) = &io { - // TODO(phase-b): IOInterface::load_configuration requires &mut self, but this - // function takes &dyn IOInterface. Wider refactor needed; skip for now. + if let Some(io) = &io { + io.borrow_mut() + .load_configuration(&mut *config.borrow_mut())?; } let mut owned_rm; diff --git a/crates/shirabe/src/repository/vcs/forgejo_driver.rs b/crates/shirabe/src/repository/vcs/forgejo_driver.rs index ccd0c16..d5c4a89 100644 --- a/crates/shirabe/src/repository/vcs/forgejo_driver.rs +++ b/crates/shirabe/src/repository/vcs/forgejo_driver.rs @@ -487,7 +487,12 @@ impl ForgejoDriver { } } - pub fn supports(io: &dyn IOInterface, config: &Config, url: &str, _deep: bool) -> bool { + pub fn supports( + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, + config: &Config, + url: &str, + _deep: bool, + ) -> bool { let forgejo_url = ForgejoUrl::try_from(Some(url)); if forgejo_url.is_none() { return false; diff --git a/crates/shirabe/src/repository/vcs/fossil_driver.rs b/crates/shirabe/src/repository/vcs/fossil_driver.rs index 207a138..1e34f21 100644 --- a/crates/shirabe/src/repository/vcs/fossil_driver.rs +++ b/crates/shirabe/src/repository/vcs/fossil_driver.rs @@ -32,7 +32,7 @@ impl FossilDriver { // Ensure we are allowed to use this URL by config. self.inner.config.borrow_mut().prohibit_url_by_config( &self.inner.url, - Some(&*self.inner.io.borrow()), + Some(self.inner.io.clone()), &indexmap::IndexMap::new(), )?; diff --git a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs index 53e49fc..8a0dffd 100644 --- a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs +++ b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs @@ -857,7 +857,12 @@ impl GitBitbucketDriver { } /// @inheritDoc - pub fn supports(io: &dyn IOInterface, _config: &Config, url: &str, _deep: bool) -> bool { + pub fn supports( + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, + _config: &Config, + url: &str, + _deep: bool, + ) -> bool { if !Preg::is_match( r"#^https?://bitbucket\.org/([^/]+)/([^/]+?)(\.git|/?)?$#i", url, diff --git a/crates/shirabe/src/repository/vcs/git_driver.rs b/crates/shirabe/src/repository/vcs/git_driver.rs index 665e2fb..01aa759 100644 --- a/crates/shirabe/src/repository/vcs/git_driver.rs +++ b/crates/shirabe/src/repository/vcs/git_driver.rs @@ -536,7 +536,12 @@ impl crate::repository::vcs::VcsDriverInterface for GitDriver { Ok(()) } - fn supports(_io: &dyn IOInterface, _config: &Config, _url: &str, _deep: bool) -> bool { + fn supports( + _io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, + _config: &Config, + _url: &str, + _deep: bool, + ) -> bool { todo!() } } diff --git a/crates/shirabe/src/repository/vcs/github_driver.rs b/crates/shirabe/src/repository/vcs/github_driver.rs index 5f8266c..0b9066b 100644 --- a/crates/shirabe/src/repository/vcs/github_driver.rs +++ b/crates/shirabe/src/repository/vcs/github_driver.rs @@ -934,7 +934,12 @@ impl GitHubDriver { Ok(self.branches.clone().unwrap_or_default()) } - pub fn supports(io: &dyn IOInterface, config: &Config, url: &str, _deep: bool) -> bool { + pub fn supports( + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, + config: &Config, + url: &str, + _deep: bool, + ) -> bool { let mut matches: IndexMap<CaptureKey, String> = IndexMap::new(); if !Preg::is_match_strict_groups3( r"#^((?:https?|git)://([^/]+)/|git@([^:]+):/?)([^/]+)/([^/]+?)(?:\.git|/)?$#", diff --git a/crates/shirabe/src/repository/vcs/gitlab_driver.rs b/crates/shirabe/src/repository/vcs/gitlab_driver.rs index e31eb67..e8701bf 100644 --- a/crates/shirabe/src/repository/vcs/gitlab_driver.rs +++ b/crates/shirabe/src/repository/vcs/gitlab_driver.rs @@ -979,7 +979,12 @@ impl GitLabDriver { /// Uses the config `gitlab-domains` to see if the driver supports the url for the /// repository given. - pub fn supports(io: &dyn IOInterface, config: &Config, url: &str, _deep: bool) -> bool { + pub fn supports( + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, + config: &Config, + url: &str, + _deep: bool, + ) -> bool { let mut match_: IndexMap<CaptureKey, String> = IndexMap::new(); if !Preg::is_match_strict_groups3(Self::URL_REGEX, url, Some(&mut match_)).unwrap_or(false) { diff --git a/crates/shirabe/src/repository/vcs/hg_driver.rs b/crates/shirabe/src/repository/vcs/hg_driver.rs index ab3bd0c..9079d71 100644 --- a/crates/shirabe/src/repository/vcs/hg_driver.rs +++ b/crates/shirabe/src/repository/vcs/hg_driver.rs @@ -62,7 +62,7 @@ impl HgDriver { self.inner.config.borrow_mut().prohibit_url_by_config( &self.inner.url, - Some(&*self.inner.io.borrow()), + Some(self.inner.io.clone()), &indexmap::IndexMap::new(), )?; diff --git a/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs b/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs index 7ace36a..c002dc5 100644 --- a/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs +++ b/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs @@ -5,6 +5,8 @@ use crate::io::IOInterface; use chrono::{DateTime, Utc}; use indexmap::IndexMap; use shirabe_php_shim::PhpMixed; +use std::cell::RefCell; +use std::rc::Rc; pub trait VcsDriverInterface: std::fmt::Debug { fn initialize(&mut self) -> anyhow::Result<()>; @@ -34,7 +36,7 @@ pub trait VcsDriverInterface: std::fmt::Debug { fn cleanup(&mut self) -> anyhow::Result<()>; - fn supports(io: &dyn IOInterface, config: &Config, url: &str, deep: bool) -> bool + fn supports(io: Rc<RefCell<dyn IOInterface>>, config: &Config, url: &str, deep: bool) -> bool where Self: Sized; } diff --git a/crates/shirabe/src/self_update/versions.rs b/crates/shirabe/src/self_update/versions.rs index c503007..88b0a45 100644 --- a/crates/shirabe/src/self_update/versions.rs +++ b/crates/shirabe/src/self_update/versions.rs @@ -2,6 +2,7 @@ use crate::config::Config; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::util::HttpDownloader; use indexmap::IndexMap; use shirabe_external_packages::composer::pcre::Preg; @@ -71,7 +72,7 @@ impl Versions { pub fn set_channel( &mut self, channel: String, - io: Option<&dyn IOInterface>, + io: Option<std::rc::Rc<std::cell::RefCell<dyn IOInterface>>>, ) -> anyhow::Result<Result<(), InvalidArgumentException>> { if !Self::CHANNELS.contains(&channel.as_str()) { return Ok(Err(InvalidArgumentException { diff --git a/crates/shirabe/src/util/config_validator.rs b/crates/shirabe/src/util/config_validator.rs index 47b4968..5621841 100644 --- a/crates/shirabe/src/util/config_validator.rs +++ b/crates/shirabe/src/util/config_validator.rs @@ -39,9 +39,8 @@ impl ConfigValidator { let mut lax_valid = false; let mut manifest: Option<IndexMap<String, PhpMixed>> = None; - // TODO(phase-b): io type mismatch (&dyn IOInterface vs std::rc::Rc<std::cell::RefCell<dyn IOInterface>>) - let mut json = - JsonFile::new(file.to_string(), None, None).expect("config file path is always local"); + let mut json = JsonFile::new(file.to_string(), None, Some(self.io.clone())) + .expect("config file path is always local"); let schema_result: anyhow::Result<()> = (|| -> anyhow::Result<()> { manifest = Some(match json.read()? { PhpMixed::Array(m) => m.into_iter().map(|(k, v)| (k, *v)).collect(), diff --git a/crates/shirabe/src/util/git.rs b/crates/shirabe/src/util/git.rs index 1f6fd0a..b2438c7 100644 --- a/crates/shirabe/src/util/git.rs +++ b/crates/shirabe/src/util/git.rs @@ -150,7 +150,7 @@ impl Git { // Ensure we are allowed to use this URL by config self.config.borrow_mut().prohibit_url_by_config( url, - Some(&*self.io.borrow()), + Some(self.io.clone()), &IndexMap::new(), )?; diff --git a/crates/shirabe/src/util/hg.rs b/crates/shirabe/src/util/hg.rs index 47e80e2..f5ee256 100644 --- a/crates/shirabe/src/util/hg.rs +++ b/crates/shirabe/src/util/hg.rs @@ -36,7 +36,7 @@ impl Hg { ) -> Result<()> { self.config.borrow_mut().prohibit_url_by_config( &url, - Some(&*self.io.borrow()), + Some(self.io.clone()), &indexmap::IndexMap::new(), )?; diff --git a/crates/shirabe/src/util/http/curl_downloader.rs b/crates/shirabe/src/util/http/curl_downloader.rs index 71c0b5a..b86564f 100644 --- a/crates/shirabe/src/util/http/curl_downloader.rs +++ b/crates/shirabe/src/util/http/curl_downloader.rs @@ -341,7 +341,7 @@ impl CurlDownloader { { self.config.borrow_mut().prohibit_url_by_config( url, - Some(&*self.io.borrow()), + Some(self.io.clone()), &options, )?; } @@ -1187,7 +1187,7 @@ impl CurlDownloader { == Some("application/json") { HttpDownloader::output_warnings( - &*self.io.borrow(), + self.io.clone(), job.get("origin").and_then(|v| v.as_string()).unwrap_or(""), &match json_decode(response_ref.inner.get_body().unwrap_or(""), true)? { PhpMixed::Array(a) => a.into_iter().map(|(k, v)| (k, *v)).collect(), diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs index 610bd3a..166f1f8 100644 --- a/crates/shirabe/src/util/http_downloader.rs +++ b/crates/shirabe/src/util/http_downloader.rs @@ -18,6 +18,7 @@ use crate::composer::ComposerHandle; use crate::config::Config; use crate::downloader::TransportException; use crate::io::IOInterface; +use crate::io::IOInterfaceImmutable; use crate::package::version::VersionParser; use crate::util::GetResult; use crate::util::Platform; @@ -689,7 +690,7 @@ impl HttpDownloader { /// /// @param array{warning?: string, info?: string, warning-versions?: string, info-versions?: string, warnings?: array<array{versions: string, message: string}>, infos?: array<array{versions: string, message: string}>} $data pub fn output_warnings( - io: &dyn IOInterface, + io: std::rc::Rc<std::cell::RefCell<dyn IOInterface>>, url: &str, data: &IndexMap<String, PhpMixed>, ) -> Result<()> { diff --git a/crates/shirabe/src/util/remote_filesystem.rs b/crates/shirabe/src/util/remote_filesystem.rs index 9aa40bd..22f5ea2 100644 --- a/crates/shirabe/src/util/remote_filesystem.rs +++ b/crates/shirabe/src/util/remote_filesystem.rs @@ -292,7 +292,7 @@ impl RemoteFilesystem { { let _ = self.config.borrow_mut().prohibit_url_by_config( &file_url, - Some(&*self.io.borrow()), + Some(self.io.clone()), &indexmap::IndexMap::new(), ); } @@ -338,7 +338,7 @@ impl RemoteFilesystem { _ => IndexMap::new(), }; let _ = HttpDownloader::output_warnings( - &*self.io.borrow(), + self.io.clone(), origin_url, &parsed_map, ); diff --git a/crates/shirabe/src/util/svn.rs b/crates/shirabe/src/util/svn.rs index 737e75d..7634b62 100644 --- a/crates/shirabe/src/util/svn.rs +++ b/crates/shirabe/src/util/svn.rs @@ -98,7 +98,7 @@ impl Svn { // Ensure we are allowed to use this URL by config self.config.borrow_mut().prohibit_url_by_config( url, - Some(&*self.io.borrow()), + Some(self.io.clone()), &indexmap::IndexMap::new(), )?; |
