diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-19 21:46:01 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-19 21:46:08 +0900 |
| commit | 5e31fa33c3b5cf726a57a063b8e7a070869250fe (patch) | |
| tree | 98522466966fa7df483cad174ab5fc03db39bc09 /crates/shirabe/src/util/bitbucket.rs | |
| parent | c839244d8d09f3036ebfee8eef7eb6b147e593ab (diff) | |
| download | php-shirabe-5e31fa33c3b5cf726a57a063b8e7a070869250fe.tar.gz php-shirabe-5e31fa33c3b5cf726a57a063b8e7a070869250fe.tar.zst php-shirabe-5e31fa33c3b5cf726a57a063b8e7a070869250fe.zip | |
fix(compile): fix more random compile errors
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe/src/util/bitbucket.rs')
| -rw-r--r-- | crates/shirabe/src/util/bitbucket.rs | 230 |
1 files changed, 116 insertions, 114 deletions
diff --git a/crates/shirabe/src/util/bitbucket.rs b/crates/shirabe/src/util/bitbucket.rs index ca9aabd..cd4a9fa 100644 --- a/crates/shirabe/src/util/bitbucket.rs +++ b/crates/shirabe/src/util/bitbucket.rs @@ -12,12 +12,16 @@ use crate::io::io_interface::IOInterface; use crate::util::http_downloader::HttpDownloader; use crate::util::process_executor::ProcessExecutor; +fn transport_error_code(err: &anyhow::Error) -> Option<i64> { + err.downcast_ref::<TransportException>().map(|te| te.code) +} + #[derive(Debug)] pub struct Bitbucket { io: Box<dyn IOInterface>, - config: Config, - process: ProcessExecutor, - http_downloader: HttpDownloader, + config: std::rc::Rc<std::cell::RefCell<Config>>, + process: std::rc::Rc<std::cell::RefCell<ProcessExecutor>>, + http_downloader: std::rc::Rc<std::cell::RefCell<HttpDownloader>>, token: Option<IndexMap<String, PhpMixed>>, time: Option<i64>, } @@ -28,15 +32,23 @@ impl Bitbucket { pub fn new( io: Box<dyn IOInterface>, - config: Config, - process: Option<ProcessExecutor>, - http_downloader: Option<HttpDownloader>, + config: std::rc::Rc<std::cell::RefCell<Config>>, + process: Option<std::rc::Rc<std::cell::RefCell<ProcessExecutor>>>, + http_downloader: Option<std::rc::Rc<std::cell::RefCell<HttpDownloader>>>, time: Option<i64>, ) -> anyhow::Result<Self> { - let process = process.unwrap_or_else(|| ProcessExecutor::new(&*io)); + let process = process.unwrap_or_else(|| { + std::rc::Rc::new(std::cell::RefCell::new(ProcessExecutor::new(Some( + io.clone_box(), + )))) + }); let http_downloader = match http_downloader { Some(h) => h, - None => Factory::create_http_downloader(&*io, &config, IndexMap::new())?, + None => std::rc::Rc::new(std::cell::RefCell::new(Factory::create_http_downloader( + &*io, + &config, + IndexMap::new(), + )?)), }; Ok(Self { io, @@ -64,21 +76,23 @@ impl Bitbucket { return false; } - let mut output = String::new(); - if self.process.execute( - &[ - "git".to_string(), - "config".to_string(), - "bitbucket.accesstoken".to_string(), - ], - &mut output, - None, - ) == 0 + let mut output = PhpMixed::Null; + if self + .process + .borrow_mut() + .execute( + PhpMixed::from(vec!["git", "config", "bitbucket.accesstoken"]), + Some(&mut output), + None, + ) + .unwrap_or(1) + == 0 { + let output_str = output.as_string().unwrap_or("").trim().to_string(); self.io.set_authentication( origin_url.to_string(), "x-token-auth".to_string(), - Some(output.trim().to_string()), + Some(output_str), ); return true; } @@ -104,68 +118,59 @@ impl Bitbucket { Box::new(PhpMixed::Bool(false)), ); options.insert("http".to_string(), Box::new(PhpMixed::Array(http))); - let options = PhpMixed::Array(options); + let options: IndexMap<String, PhpMixed> = + options.into_iter().map(|(k, v)| (k, *v)).collect(); let response = match self .http_downloader - .get(Self::OAUTH2_ACCESS_TOKEN_URL, &options) + .borrow_mut() + .get(Self::OAUTH2_ACCESS_TOKEN_URL, options) { Ok(r) => r, Err(te) => { - if te.code == 400 { - self.io.write_error( - PhpMixed::String( - "<error>Invalid OAuth consumer provided.</error>".to_string(), - ), + let code = transport_error_code(&te).unwrap_or(0); + if code == 400 { + self.io.write_error3( + "<error>Invalid OAuth consumer provided.</error>", + true, + io_interface::NORMAL, + ); + self.io.write_error3( + "This can have three reasons:", + true, + io_interface::NORMAL, + ); + self.io.write_error3( + "1. You are authenticating with a bitbucket username/password combination", true, io_interface::NORMAL, ); - self.io.write_error( - PhpMixed::String("This can have three reasons:".to_string()), + self.io.write_error3( + "2. You are using an OAuth consumer, but didn't configure a (dummy) callback url", + true, + io_interface::NORMAL, + ); + self.io.write_error3( + "3. You are using an OAuth consumer, but didn't configure it as private consumer", true, io_interface::NORMAL, ); - self.io.write_error( - PhpMixed::String( - "1. You are authenticating with a bitbucket username/password combination".to_string(), - ), - true, - io_interface::NORMAL, - ); - self.io.write_error( - PhpMixed::String( - "2. You are using an OAuth consumer, but didn't configure a (dummy) callback url".to_string(), - ), - true, - io_interface::NORMAL, - ); - self.io.write_error( - PhpMixed::String( - "3. You are using an OAuth consumer, but didn't configure it as private consumer".to_string(), - ), - true, - io_interface::NORMAL, - ); return Ok(false); } - if te.code == 403 || te.code == 401 { - self.io.write_error( - PhpMixed::String( - "<error>Invalid OAuth consumer provided.</error>".to_string(), - ), + if code == 403 || code == 401 { + self.io.write_error3( + "<error>Invalid OAuth consumer provided.</error>", + true, + io_interface::NORMAL, + ); + self.io.write_error3( + "You can also add it manually later by using \"composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>\"", true, io_interface::NORMAL, ); - self.io.write_error( - PhpMixed::String( - "You can also add it manually later by using \"composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>\"".to_string(), - ), - true, - io_interface::NORMAL, - ); return Ok(false); } - return Err(te.into()); + return Err(te); } }; @@ -204,43 +209,31 @@ impl Bitbucket { message: Option<&str>, ) -> anyhow::Result<bool> { if let Some(msg) = message { - self.io.write_error( - PhpMixed::String(msg.to_string()), - true, - io_interface::NORMAL, - ); + self.io.write_error3(msg, true, io_interface::NORMAL); } - let local_auth_config = self.config.get_local_auth_config_source(); + let config_ref = self.config.borrow(); + let local_auth_config = config_ref.get_local_auth_config_source(); let url = "https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/"; - self.io.write_error( - PhpMixed::String("Follow the instructions here:".to_string()), - true, - io_interface::NORMAL, - ); - self.io.write_error( - PhpMixed::String(url.to_string()), - true, - io_interface::NORMAL, - ); - let auth_config_source_name = self.config.get_auth_config_source().get_name(); + self.io + .write_error3("Follow the instructions here:", true, io_interface::NORMAL); + self.io.write_error3(url, true, io_interface::NORMAL); + let auth_config_source_name = config_ref.get_auth_config_source().get_name(); let local_name_prefix = local_auth_config .as_ref() .map(|c| format!("{} OR ", c.get_name())) .unwrap_or_default(); - self.io.write_error( - PhpMixed::String(format!( + self.io.write_error3( + &format!( "to create a consumer. It will be stored in \"{}\" for future use by Composer.", local_name_prefix + &auth_config_source_name - )), + ), true, io_interface::NORMAL, ); - self.io.write_error( - PhpMixed::String( - "Ensure you enter a \"Callback URL\" (http://example.com is fine) or it will not be possible to create an Access Token (this callback url will not be used by composer)".to_string(), - ), + self.io.write_error3( + "Ensure you enter a \"Callback URL\" (http://example.com is fine) or it will not be possible to create an Access Token (this callback url will not be used by composer)", true, io_interface::NORMAL, ); @@ -262,15 +255,13 @@ impl Bitbucket { .to_string(); if consumer_key.is_empty() { - self.io.write_error( - PhpMixed::String("<warning>No consumer key given, aborting.</warning>".to_string()), + self.io.write_error3( + "<warning>No consumer key given, aborting.</warning>", true, io_interface::NORMAL, ); - self.io.write_error( - PhpMixed::String( - "You can also add it manually later by using \"composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>\"".to_string(), - ), + self.io.write_error3( + "You can also add it manually later by using \"composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>\"", true, io_interface::NORMAL, ); @@ -285,17 +276,13 @@ impl Bitbucket { .to_string(); if consumer_secret.is_empty() { - self.io.write_error( - PhpMixed::String( - "<warning>No consumer secret given, aborting.</warning>".to_string(), - ), + self.io.write_error3( + "<warning>No consumer secret given, aborting.</warning>", true, io_interface::NORMAL, ); - self.io.write_error( - PhpMixed::String( - "You can also add it manually later by using \"composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>\"".to_string(), - ), + self.io.write_error3( + "You can also add it manually later by using \"composer config --global --auth bitbucket-oauth.bitbucket.org <consumer-key> <consumer-secret>\"", true, io_interface::NORMAL, ); @@ -312,10 +299,15 @@ impl Bitbucket { return Ok(false); } - let use_local = - store_in_local_auth_config && self.config.get_local_auth_config_source().is_some(); + let use_local = store_in_local_auth_config + && self + .config + .borrow() + .get_local_auth_config_source() + .is_some(); if use_local { - let mut auth_config_source = self.config.get_local_auth_config_source().unwrap(); + let mut auth_config_source = + self.config.borrow().get_local_auth_config_source().unwrap(); self.store_in_auth_config( &mut *auth_config_source, origin_url, @@ -323,7 +315,7 @@ impl Bitbucket { &consumer_secret, )?; } else { - let mut auth_config_source = self.config.get_auth_config_source(); + let mut auth_config_source = self.config.borrow().get_auth_config_source(); self.store_in_auth_config( &mut *auth_config_source, origin_url, @@ -333,11 +325,12 @@ impl Bitbucket { } self.config + .borrow() .get_auth_config_source() .remove_config_setting(&format!("http-basic.{}", origin_url))?; - self.io.write_error( - PhpMixed::String("<info>Consumer stored successfully.</info>".to_string()), + self.io.write_error3( + "<info>Consumer stored successfully.</info>", true, io_interface::NORMAL, ); @@ -371,9 +364,14 @@ impl Bitbucket { return Ok(String::new()); } - let use_local = self.config.get_local_auth_config_source().is_some(); + let use_local = self + .config + .borrow() + .get_local_auth_config_source() + .is_some(); if use_local { - let mut auth_config_source = self.config.get_local_auth_config_source().unwrap(); + let mut auth_config_source = + self.config.borrow().get_local_auth_config_source().unwrap(); self.store_in_auth_config( &mut *auth_config_source, origin_url, @@ -381,7 +379,7 @@ impl Bitbucket { consumer_secret, )?; } else { - let mut auth_config_source = self.config.get_auth_config_source(); + let mut auth_config_source = self.config.borrow().get_auth_config_source(); self.store_in_auth_config( &mut *auth_config_source, origin_url, @@ -415,6 +413,7 @@ impl Bitbucket { consumer_secret: &str, ) -> anyhow::Result<()> { self.config + .borrow() .get_config_source() .remove_config_setting(&format!("bitbucket-oauth.{}", origin_url))?; @@ -460,16 +459,19 @@ impl Bitbucket { Box::new(PhpMixed::Int(t + expires_in)), ); - self.config.get_auth_config_source().add_config_setting( - &format!("bitbucket-oauth.{}", origin_url), - PhpMixed::Array(consumer), - )?; + self.config + .borrow() + .get_auth_config_source() + .add_config_setting( + &format!("bitbucket-oauth.{}", origin_url), + PhpMixed::Array(consumer), + )?; Ok(()) } fn get_token_from_config(&mut self, origin_url: &str) -> bool { - let auth_config = self.config.get("bitbucket-oauth"); + let auth_config = self.config.borrow_mut().get("bitbucket-oauth"); let auth_map = match auth_config.as_array() { Some(m) => m.clone(), |
