From efec43b3b8827820cf35fe1b73d8e33f5fe84eb4 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 20 Jun 2026 01:16:50 +0900 Subject: refactor: auto-fix clippy warnings --- crates/shirabe/src/util/auth_helper.rs | 61 +++--- crates/shirabe/src/util/bitbucket.rs | 2 +- crates/shirabe/src/util/config_validator.rs | 56 +++--- crates/shirabe/src/util/filesystem.rs | 18 +- crates/shirabe/src/util/git.rs | 150 +++++++-------- crates/shirabe/src/util/github.rs | 2 +- crates/shirabe/src/util/gitlab.rs | 20 +- crates/shirabe/src/util/hg.rs | 105 +++++----- crates/shirabe/src/util/http/curl_downloader.rs | 225 +++++++++++----------- crates/shirabe/src/util/http/proxy_manager.rs | 8 +- crates/shirabe/src/util/http/response.rs | 9 +- crates/shirabe/src/util/http_downloader.rs | 60 +++--- crates/shirabe/src/util/ini_helper.rs | 2 +- crates/shirabe/src/util/loop.rs | 11 +- crates/shirabe/src/util/no_proxy_pattern.rs | 6 +- crates/shirabe/src/util/package_info.rs | 8 +- crates/shirabe/src/util/perforce.rs | 14 +- crates/shirabe/src/util/platform.rs | 52 +++-- crates/shirabe/src/util/process_executor.rs | 138 +++++++------ crates/shirabe/src/util/remote_filesystem.rs | 147 +++++++------- crates/shirabe/src/util/stream_context_factory.rs | 134 ++++++------- crates/shirabe/src/util/svn.rs | 36 ++-- crates/shirabe/src/util/tar.rs | 8 +- crates/shirabe/src/util/url.rs | 6 +- crates/shirabe/src/util/zip.rs | 16 +- 25 files changed, 612 insertions(+), 682 deletions(-) (limited to 'crates/shirabe/src/util') diff --git a/crates/shirabe/src/util/auth_helper.rs b/crates/shirabe/src/util/auth_helper.rs index d520270..5952429 100644 --- a/crates/shirabe/src/util/auth_helper.rs +++ b/crates/shirabe/src/util/auth_helper.rs @@ -114,13 +114,7 @@ impl AuthHelper { Ok(()) } - /// @param int $statusCode HTTP status code that triggered this call - /// @param string|null $reason a message/description explaining why this was called - /// @param string[] $headers - /// @param int $retryCount the amount of retries already done on this URL - /// @return array containing retry (bool) and storeAuth (string|bool) keys, if retry is true the request should be - /// retried, if storeAuth is true then on a successful retry the authentication should be persisted to auth.json - /// @phpstan-return array{retry: bool, storeAuth: 'prompt'|bool} + #[allow(clippy::too_many_arguments, reason = "to keep PHP signature")] pub fn prompt_auth_if_needed( &mut self, url: &str, @@ -194,28 +188,23 @@ impl AuthHelper { } message = format!( - "{}\n", - format!( - "GitHub API limit ({} calls/hr) is exhausted, could not fetch {}. {} You can also wait until {} for the rate limit to reset.", - rate_limit.get("limit").cloned().unwrap_or(PhpMixed::Null), - url, - message, - rate_limit.get("reset").cloned().unwrap_or(PhpMixed::Null), - ), + "GitHub API limit ({} calls/hr) is exhausted, could not fetch {}. {} You can also wait until {} for the rate limit to reset.\n", + rate_limit.get("limit").cloned().unwrap_or(PhpMixed::Null), + url, + message, + rate_limit.get("reset").cloned().unwrap_or(PhpMixed::Null), ); } else { // Try to extract a more specific error message from GitHub's API response let mut git_hub_api_message: Option = None; if let Some(body) = response_body { let decoded = json_decode(body, true)?; - if is_array(&decoded) { - if let Some(arr) = decoded.as_array() { - if let Some(msg) = arr.get("message") { - if is_string(msg) { - git_hub_api_message = msg.as_string().map(|s| s.to_string()); - } - } - } + if is_array(&decoded) + && let Some(arr) = decoded.as_array() + && let Some(msg) = arr.get("message") + && is_string(msg) + { + git_hub_api_message = msg.as_string().map(|s| s.to_string()); } } @@ -297,16 +286,16 @@ impl AuthHelper { .into()); } - if let Some(prev_auth) = auth { - if self.io.has_authentication(origin) { - let current_auth = self.io.get_authentication(origin); - if prev_auth == current_auth { - return Err(TransportException::new( - format!("Invalid credentials for '{}', aborting.", url), - status_code, - ) - .into()); - } + if let Some(prev_auth) = auth + && self.io.has_authentication(origin) + { + let current_auth = self.io.get_authentication(origin); + if prev_auth == current_auth { + return Err(TransportException::new( + format!("Invalid credentials for '{}', aborting.", url), + status_code, + ) + .into()); } } } else if origin == "bitbucket.org" || origin == "api.bitbucket.org" { @@ -473,10 +462,8 @@ impl AuthHelper { } else { false }; - if !http_has_header { - if let Some(PhpMixed::Array(http)) = options.get_mut("http") { - http.insert("header".to_string(), Box::new(PhpMixed::List(vec![]))); - } + if !http_has_header && let Some(PhpMixed::Array(http)) = options.get_mut("http") { + http.insert("header".to_string(), Box::new(PhpMixed::List(vec![]))); } } diff --git a/crates/shirabe/src/util/bitbucket.rs b/crates/shirabe/src/util/bitbucket.rs index 67ae575..0584308 100644 --- a/crates/shirabe/src/util/bitbucket.rs +++ b/crates/shirabe/src/util/bitbucket.rs @@ -382,7 +382,7 @@ impl Bitbucket { .remove_config_setting(&format!("bitbucket-oauth.{}", origin_url))?; let token = self.token.as_ref().ok_or_else(|| LogicException { - message: format!("Expected a token configured with expires_in present, got null",), + message: "Expected a token configured with expires_in present, got null".to_string(), code: 0, })?; let expires_in = token diff --git a/crates/shirabe/src/util/config_validator.rs b/crates/shirabe/src/util/config_validator.rs index 90195e7..a3f6ef7 100644 --- a/crates/shirabe/src/util/config_validator.rs +++ b/crates/shirabe/src/util/config_validator.rs @@ -97,7 +97,7 @@ impl ConfigValidator { // validate actual data if manifest .get("license") - .map_or(true, |v| matches!(v, PhpMixed::Null)) + .is_none_or(|v| matches!(v, PhpMixed::Null)) || !manifest.contains_key("license") { warnings.push("No license specified, it is recommended to do so. For closed-source software you may use \"proprietary\" as license.".to_string()); @@ -160,26 +160,28 @@ impl ConfigValidator { warnings.push("The version field is present, it is recommended to leave it out if the package is published on Packagist.".to_string()); } - if let Some(PhpMixed::String(name)) = manifest.get("name") { - if !name.is_empty() && Preg::is_match(r"{[A-Z]}", name) { - let suggest_name = Preg::replace( - r"{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}", - r"\1\3-\2\4", - name, - ); - let suggest_name = suggest_name.to_lowercase(); + if let Some(PhpMixed::String(name)) = manifest.get("name") + && !name.is_empty() + && Preg::is_match(r"{[A-Z]}", name) + { + let suggest_name = Preg::replace( + r"{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}", + r"\1\3-\2\4", + name, + ); + let suggest_name = suggest_name.to_lowercase(); - publish_errors.push(format!( + publish_errors.push(format!( "Name \"{}\" does not match the best practice (e.g. lower-cased/with-dashes). We suggest using \"{}\" instead. As such you will not be able to submit it to Packagist.", name, suggest_name )); - } } - if let Some(PhpMixed::String(t)) = manifest.get("type") { - if !t.is_empty() && t == "composer-installer" { - warnings.push("The package type 'composer-installer' is deprecated. Please distribute your custom installers as plugins from now on. See https://getcomposer.org/doc/articles/plugins.md for plugin documentation.".to_string()); - } + if let Some(PhpMixed::String(t)) = manifest.get("type") + && !t.is_empty() + && t == "composer-installer" + { + warnings.push("The package type 'composer-installer' is deprecated. Please distribute your custom installers as plugins from now on. See https://getcomposer.org/doc/articles/plugins.md for plugin documentation.".to_string()); } // check for require-dev overrides @@ -236,13 +238,13 @@ impl ConfigValidator { let mut packages: IndexMap> = require; packages.extend(require_dev); for (package, version) in &packages { - if let PhpMixed::String(version_str) = version.as_ref() { - if Preg::is_match(r"{#}", version_str) { - warnings.push(format!( + if let PhpMixed::String(version_str) = version.as_ref() + && Preg::is_match(r"{#}", version_str) + { + warnings.push(format!( "The package \"{}\" is pointing to a commit-ref, this is bad practice and can cause unforeseen issues.", package )); - } } } @@ -280,15 +282,15 @@ impl ConfigValidator { // check for empty psr-0/psr-4 namespace prefixes if let Some(PhpMixed::Array(autoload)) = manifest.get("autoload") { - if let Some(PhpMixed::Array(psr0)) = autoload.get("psr-0").map(|v| v.as_ref()) { - if psr0.contains_key("") { - warnings.push("Defining autoload.psr-0 with an empty namespace prefix is a bad idea for performance".to_string()); - } + if let Some(PhpMixed::Array(psr0)) = autoload.get("psr-0").map(|v| v.as_ref()) + && psr0.contains_key("") + { + warnings.push("Defining autoload.psr-0 with an empty namespace prefix is a bad idea for performance".to_string()); } - if let Some(PhpMixed::Array(psr4)) = autoload.get("psr-4").map(|v| v.as_ref()) { - if psr4.contains_key("") { - warnings.push("Defining autoload.psr-4 with an empty namespace prefix is a bad idea for performance".to_string()); - } + if let Some(PhpMixed::Array(psr4)) = autoload.get("psr-4").map(|v| v.as_ref()) + && psr4.contains_key("") + { + warnings.push("Defining autoload.psr-4 with an empty namespace prefix is a bad idea for performance".to_string()); } } diff --git a/crates/shirabe/src/util/filesystem.rs b/crates/shirabe/src/util/filesystem.rs index cb0e4a5..50112ea 100644 --- a/crates/shirabe/src/util/filesystem.rs +++ b/crates/shirabe/src/util/filesystem.rs @@ -51,7 +51,7 @@ impl Filesystem { .depth(0) .r#in(dir); - finder.len() == 0 + finder.is_empty() } pub fn empty_directory( @@ -519,11 +519,7 @@ impl Filesystem { // Returning early-formatted Result is not possible without changing signature; panic to surface in tests. panic!( "{}", - format!( - "$from ({}) and $to ({}) must be absolute paths.", - from.to_string(), - to.to_string() - ) + format!("$from ({}) and $to ({}) must be absolute paths.", from, to) ); } @@ -584,11 +580,7 @@ impl Filesystem { if !self.is_absolute_path(from) || !self.is_absolute_path(to) { panic!( "{}", - format!( - "$from ({}) and $to ({}) must be absolute paths.", - from.to_string(), - to.to_string() - ) + format!("$from ({}) and $to ({}) must be absolute paths.", from, to) ); } @@ -722,8 +714,8 @@ impl Filesystem { for chunk in explode("/", &path) { if ".." == chunk && (strlen(&absolute) > 0 || up) { array_pop(&mut parts); - up = !(parts.len() == 0 || ".." == end(&parts).unwrap_or_default()); - } else if "." != chunk && "" != chunk { + up = !(parts.is_empty() || ".." == end(&parts).unwrap_or_default()); + } else if "." != chunk && !chunk.is_empty() { parts.push(chunk.clone()); up = ".." != chunk; } diff --git a/crates/shirabe/src/util/git.rs b/crates/shirabe/src/util/git.rs index 5916f9b..1467a29 100644 --- a/crates/shirabe/src/util/git.rs +++ b/crates/shirabe/src/util/git.rs @@ -118,7 +118,7 @@ impl Git { map.insert("%url%".to_string(), url.to_string()); map.insert( "%sanitizedUrl%".to_string(), - Preg::replace(r"{://([^@]+?):(.+?)@}", "://", &url), + Preg::replace(r"{://([^@]+?):(.+?)@}", "://", url), ); array_map( @@ -198,10 +198,8 @@ impl Git { counter += 1; } - if collect_outputs { - if let Some(out) = command_output { - *out = PhpMixed::String(implode("", &outputs)); - } + if collect_outputs && let Some(out) = command_output { + *out = PhpMixed::String(implode("", &outputs)); } status @@ -222,7 +220,7 @@ impl Git { // capture username/password from URL if there is one and we have no auth configured yet let mut output = String::new(); self.process.borrow_mut().execute_args( - &vec!["git".to_string(), "remote".to_string(), "-v".to_string()], + &["git".to_string(), "remote".to_string(), "-v".to_string()], &mut output, cwd.map(|s| s.to_string()), ); @@ -252,7 +250,7 @@ impl Git { if Preg::is_match3( &format!( "{{^(?:https?|git)://{}/(.*)}}", - Self::get_github_domains_regex(&*self.config.borrow()) + Self::get_github_domains_regex(&self.config.borrow()) ), url, Some(&mut m), @@ -276,7 +274,7 @@ impl Git { if run_commands_inline( &proto_url, - &mut *self.process.borrow_mut(), + &mut self.process.borrow_mut(), &mut last_command, command_output.as_deref_mut(), ) == 0 @@ -286,17 +284,11 @@ impl Git { messages.push(format!( "- {}\n{}", proto_url, - Preg::replace( - r"#^#m", - " ", - &self.process.borrow().get_error_output().to_string() - ) + Preg::replace(r"#^#m", " ", self.process.borrow().get_error_output()) )); - if initial_clone { - if let Some(ref orig) = orig_cwd { - self.filesystem.borrow_mut().remove_directory(orig); - } + if initial_clone && let Some(ref orig) = orig_cwd { + self.filesystem.borrow_mut().remove_directory(orig); } } @@ -326,7 +318,7 @@ impl Git { let bypass_ssh_for_github = Preg::is_match( &format!( "{{^git@{}:(.+?)\\.git$}}i", - Self::get_github_domains_regex(&*self.config.borrow()) + Self::get_github_domains_regex(&self.config.borrow()) ), url, ) && !in_array( @@ -345,7 +337,7 @@ impl Git { if bypass_ssh_for_github || 0 != run_commands_inline( url, - &mut *self.process.borrow_mut(), + &mut self.process.borrow_mut(), &mut last_command, command_output.as_deref_mut(), ) @@ -357,14 +349,14 @@ impl Git { let github_matched = Preg::is_match3( &format!( "{{^git@{}:(.+?)\\.git$}}i", - Self::get_github_domains_regex(&*self.config.borrow()) + Self::get_github_domains_regex(&self.config.borrow()) ), url, Some(&mut m), ) || Preg::is_match3( &format!( "{{^https?://{}/(.*?)(?:\\.git)?$}}i", - Self::get_github_domains_regex(&*self.config.borrow()) + Self::get_github_domains_regex(&self.config.borrow()) ), url, Some(&mut m), @@ -408,7 +400,7 @@ impl Git { ); if run_commands_inline( &auth_url, - &mut *self.process.borrow_mut(), + &mut self.process.borrow_mut(), &mut last_command, command_output.as_deref_mut(), ) == 0 @@ -419,18 +411,15 @@ impl Git { credentials = vec![rawurlencode(&username), rawurlencode(&password)]; error_msg = self.process.borrow().get_error_output().to_string(); } - } else if { - let bb_matched = Preg::is_match3( - r"{^(https?)://(bitbucket\.org)/(.*?)(?:\.git)?$}i", - url, - Some(&mut m), - ) || Preg::is_match3( - r"{^(git)@(bitbucket\.org):(.+?\.git)$}i", - url, - Some(&mut m), - ); - bb_matched - } { + } else if Preg::is_match3( + r"{^(https?)://(bitbucket\.org)/(.*?)(?:\.git)?$}i", + url, + Some(&mut m), + ) || Preg::is_match3( + r"{^(git)@(bitbucket\.org):(.+?\.git)$}i", + url, + Some(&mut m), + ) { // bitbucket either through oauth or app password, with fallback to ssh. let mut bitbucket_util = Bitbucket::new( self.io.clone(), @@ -493,7 +482,7 @@ impl Git { if run_commands_inline( &auth_url, - &mut *self.process.borrow_mut(), + &mut self.process.borrow_mut(), &mut last_command, command_output.as_deref_mut(), ) == 0 @@ -540,7 +529,7 @@ impl Git { ); if run_commands_inline( &auth_url, - &mut *self.process.borrow_mut(), + &mut self.process.borrow_mut(), &mut last_command, command_output.as_deref_mut(), ) == 0 @@ -559,7 +548,7 @@ impl Git { ); if run_commands_inline( &ssh_url, - &mut *self.process.borrow_mut(), + &mut self.process.borrow_mut(), &mut last_command, command_output.as_deref_mut(), ) == 0 @@ -568,24 +557,21 @@ impl Git { } error_msg = self.process.borrow().get_error_output().to_string(); - } else if { - let gl_matched = Preg::is_match3( - &format!( - "{{^(git)@{}:(.+?\\.git)$}}i", - Self::get_gitlab_domains_regex(&*self.config.borrow()) - ), - url, - Some(&mut m), - ) || Preg::is_match3( - &format!( - "{{^(https?)://{}/(.*)}}i", - Self::get_gitlab_domains_regex(&*self.config.borrow()) - ), - url, - Some(&mut m), - ); - gl_matched - } { + } else if Preg::is_match3( + &format!( + "{{^(git)@{}:(.+?\\.git)$}}i", + Self::get_gitlab_domains_regex(&self.config.borrow()) + ), + url, + Some(&mut m), + ) || Preg::is_match3( + &format!( + "{{^(https?)://{}/(.*)}}i", + Self::get_gitlab_domains_regex(&self.config.borrow()) + ), + url, + Some(&mut m), + ) { let mut m1 = m.get(&CaptureKey::ByIndex(1)).cloned().unwrap_or_default(); let m2 = m.get(&CaptureKey::ByIndex(2)).cloned().unwrap_or_default(); let m3 = m.get(&CaptureKey::ByIndex(3)).cloned().unwrap_or_default(); @@ -649,7 +635,7 @@ impl Git { if run_commands_inline( &auth_url, - &mut *self.process.borrow_mut(), + &mut self.process.borrow_mut(), &mut last_command, command_output.as_deref_mut(), ) == 0 @@ -668,7 +654,7 @@ impl Git { let mut auth_parts: Option = None; if str_contains(&m2, "@") { let parts = explode("@", &m2); - auth_parts = parts.get(0).cloned(); + auth_parts = parts.first().cloned(); m2 = parts.get(1).cloned().unwrap_or_default(); } @@ -677,14 +663,14 @@ impl Git { auth = Some(self.io.get_authentication(&m2)); } else if self.io.is_interactive() { let mut default_username: Option = None; - if let Some(ref parts) = auth_parts { - if !parts.is_empty() { - if str_contains(parts, ":") { - let split = explode(":", parts); - default_username = split.get(0).cloned(); - } else { - default_username = Some(parts.clone()); - } + if let Some(ref parts) = auth_parts + && !parts.is_empty() + { + if str_contains(parts, ":") { + let split = explode(":", parts); + default_username = split.first().cloned(); + } else { + default_username = Some(parts.clone()); } } @@ -742,9 +728,9 @@ impl Git { if run_commands_inline( &auth_url, - &mut *self.process.borrow_mut(), + &mut self.process.borrow_mut(), &mut last_command, - command_output.as_deref_mut(), + command_output, ) == 0 { self.io.borrow_mut().set_authentication( @@ -768,10 +754,8 @@ impl Git { } } - if initial_clone { - if let Some(ref orig) = orig_cwd { - self.filesystem.borrow_mut().remove_directory(orig); - } + if initial_clone && let Some(ref orig) = orig_cwd { + self.filesystem.borrow_mut().remove_directory(orig); } let mut last_command_str = match &last_command { @@ -822,7 +806,7 @@ impl Git { let mut output = String::new(); if is_dir(dir) && self.process.borrow_mut().execute_args( - &vec![ + &[ "git".to_string(), "rev-parse".to_string(), "--git-dir".to_string(), @@ -933,12 +917,12 @@ impl Git { if self.check_ref_is_in_mirror(dir, r#ref)? { if Preg::is_match(r"{^[a-f0-9]{40}$}", r#ref) && pretty_version.is_some() { let branch = - Preg::replace(r"{(?:^dev-|(?:\.x)?-dev$)}i", "", &pretty_version.unwrap()); + Preg::replace(r"{(?:^dev-|(?:\.x)?-dev$)}i", "", pretty_version.unwrap()); let mut branches: Option = None; let mut tags: Option = None; let mut output = String::new(); if self.process.borrow_mut().execute_args( - &vec!["git".to_string(), "branch".to_string()], + &["git".to_string(), "branch".to_string()], &mut output, Some(dir.to_string()), ) == 0 @@ -947,7 +931,7 @@ impl Git { } let mut output = String::new(); if self.process.borrow_mut().execute_args( - &vec!["git".to_string(), "tag".to_string()], + &["git".to_string(), "tag".to_string()], &mut output, Some(dir.to_string()), ) == 0 @@ -988,10 +972,10 @@ impl Git { process: &std::rc::Rc>, ) -> String { let git_version = Self::get_version(process); - if let Some(v) = git_version { - if version_compare(&v, "2.10.0-rc0", ">=") { - return " --no-show-signature".to_string(); - } + if let Some(v) = git_version + && version_compare(&v, "2.10.0-rc0", ">=") + { + return " --no-show-signature".to_string(); } String::new() @@ -1063,7 +1047,7 @@ impl Git { let mut output = String::new(); if is_dir(dir) && self.process.borrow_mut().execute_args( - &vec![ + &[ "git".to_string(), "rev-parse".to_string(), "--git-dir".to_string(), @@ -1075,7 +1059,7 @@ impl Git { { let mut ignored_output = String::new(); let exit_code = self.process.borrow_mut().execute_args( - &vec![ + &[ "git".to_string(), "rev-parse".to_string(), "--quiet".to_string(), @@ -1137,7 +1121,7 @@ impl Git { if is_local_path_repository { let mut output = String::new(); self.process.borrow_mut().execute_args( - &vec![ + &[ "git".to_string(), "remote".to_string(), "show".to_string(), @@ -1279,7 +1263,7 @@ impl Git { let mut ignored_output = String::new(); if self.process.borrow_mut().execute_args( - &vec!["git".to_string(), "--version".to_string()], + &["git".to_string(), "--version".to_string()], &mut ignored_output, Option::<&str>::None, ) != 0 diff --git a/crates/shirabe/src/util/github.rs b/crates/shirabe/src/util/github.rs index 766d75b..204d95e 100644 --- a/crates/shirabe/src/util/github.rs +++ b/crates/shirabe/src/util/github.rs @@ -257,7 +257,7 @@ impl GitHub { ); return Ok(false); } - return Err(te.into()); + return Err(te); } } diff --git a/crates/shirabe/src/util/gitlab.rs b/crates/shirabe/src/util/gitlab.rs index 3938a07..86b7620 100644 --- a/crates/shirabe/src/util/gitlab.rs +++ b/crates/shirabe/src/util/gitlab.rs @@ -478,18 +478,14 @@ impl GitLab { pub fn is_oauth_expired(&self, origin_url: &str) -> bool { let auth_tokens = self.config.borrow_mut().get("gitlab-oauth"); - if let Some(map) = auth_tokens.as_array() { - if let Some(token_info) = map.get(origin_url) { - if let Some(token_map) = token_info.as_array() { - if let Some(expires_at) = token_map.get("expires-at") { - if let Some(expires_at_int) = expires_at.as_int() { - if expires_at_int < time() { - return true; - } - } - } - } - } + if let Some(map) = auth_tokens.as_array() + && let Some(token_info) = map.get(origin_url) + && let Some(token_map) = token_info.as_array() + && let Some(expires_at) = token_map.get("expires-at") + && let Some(expires_at_int) = expires_at.as_int() + && expires_at_int < time() + { + return true; } false diff --git a/crates/shirabe/src/util/hg.rs b/crates/shirabe/src/util/hg.rs index c8f5489..d20cf16 100644 --- a/crates/shirabe/src/util/hg.rs +++ b/crates/shirabe/src/util/hg.rs @@ -60,61 +60,59 @@ impl Hg { &mut matches, ); - if matched { - if self + if matched + && self .io .has_authentication(matches.get("host").map(|s| s.as_str()).unwrap_or("")) - { - let authenticated_url = if matches.get("proto").map(|s| s.as_str()) == Some("ssh") { - let user = if let Some(u) = matches.get("user") { - format!("{}@", rawurlencode(u)) - } else { - String::new() - }; - format!( - "{}://{}{}{}", - matches.get("proto").unwrap_or(&String::new()), - user, - matches.get("host").unwrap_or(&String::new()), - matches.get("path").unwrap_or(&String::new()), - ) + { + let authenticated_url = if matches.get("proto").map(|s| s.as_str()) == Some("ssh") { + let user = if let Some(u) = matches.get("user") { + format!("{}@", rawurlencode(u)) } else { - let auth = self - .io - .get_authentication(matches.get("host").map(|s| s.as_str()).unwrap_or("")); - format!( - "{}://{}:{}@{}{}", - matches.get("proto").unwrap_or(&String::new()), - rawurlencode( - auth.get("username") - .and_then(|s| s.as_deref()) - .unwrap_or("") - ), - rawurlencode( - auth.get("password") - .and_then(|s| s.as_deref()) - .unwrap_or("") - ), - matches.get("host").unwrap_or(&String::new()), - matches.get("path").unwrap_or(&String::new()), - ) + String::new() }; + format!( + "{}://{}{}{}", + matches.get("proto").unwrap_or(&String::new()), + user, + matches.get("host").unwrap_or(&String::new()), + matches.get("path").unwrap_or(&String::new()), + ) + } else { + let auth = self + .io + .get_authentication(matches.get("host").map(|s| s.as_str()).unwrap_or("")); + format!( + "{}://{}:{}@{}{}", + matches.get("proto").unwrap_or(&String::new()), + rawurlencode( + auth.get("username") + .and_then(|s| s.as_deref()) + .unwrap_or("") + ), + rawurlencode( + auth.get("password") + .and_then(|s| s.as_deref()) + .unwrap_or("") + ), + matches.get("host").unwrap_or(&String::new()), + matches.get("path").unwrap_or(&String::new()), + ) + }; - let command = command_callable(authenticated_url); - let mut ignored_output = String::new(); - if self - .process - .borrow_mut() - .execute_args(&command, &mut ignored_output, cwd) - == 0 - { - return Ok(()); - } - - let error = self.process.borrow().get_error_output().to_string(); - return self - .throw_exception(&format!("Failed to clone {}, \n\n{}", url, error), &url); + let command = command_callable(authenticated_url); + let mut ignored_output = String::new(); + if self + .process + .borrow_mut() + .execute_args(&command, &mut ignored_output, cwd) + == 0 + { + return Ok(()); } + + let error = self.process.borrow().get_error_output().to_string(); + return self.throw_exception(&format!("Failed to clone {}, \n\n{}", url, error), &url); } let error = format!( @@ -150,13 +148,12 @@ impl Hg { &mut output, (), ) == 0 - { - if let Some(matches) = Preg::is_match_with_indexed_captures( + && let Some(matches) = Preg::is_match_with_indexed_captures( r"/^.+? (\d+(?:\.\d+)+)(?:\+.*?)?\)?\r?\n/", &output, - ) { - return matches.into_iter().nth(1); - } + ) + { + return matches.into_iter().nth(1); } None }) diff --git a/crates/shirabe/src/util/http/curl_downloader.rs b/crates/shirabe/src/util/http/curl_downloader.rs index 3a47d4f..c03da7a 100644 --- a/crates/shirabe/src/util/http/curl_downloader.rs +++ b/crates/shirabe/src/util/http/curl_downloader.rs @@ -270,12 +270,7 @@ impl CurlDownloader { self.init_download(resolve, reject, origin, url, options, copy_to, attributes) } - /// @param mixed[] $options - /// - /// @param array{retryAuthFailure?: bool, redirects?: int<0, max>, retries?: int<0, max>, storeAuth?: 'prompt'|bool, ipResolve?: 4|6|null} $attributes - /// @param non-empty-string $url - /// - /// @return int internal job id + #[allow(clippy::too_many_arguments, reason = "to keep PHP signature")] fn init_download( &mut self, resolve: Box, @@ -444,27 +439,26 @@ impl CurlDownloader { // $options['http']['header'] = array_diff($options['http']['header'], ['Connection: close']); // $options['http']['header'][] = 'Connection: keep-alive'; - if let Some(PhpMixed::Array(http)) = options.get_mut("http") { - if let Some(boxed) = http.get_mut("header") { - if let PhpMixed::List(list) = boxed.as_mut() { - let headers: Vec = list - .iter() - .filter_map(|b| match b.as_ref() { - PhpMixed::String(s) => Some(s.clone()), - _ => None, - }) - .collect(); - let diffed = array_diff(&headers, &["Connection: close".to_string()]); - let mut new_list: Vec> = diffed - .into_iter() - .map(|s| Box::new(PhpMixed::String(s))) - .collect(); - new_list.push(Box::new(PhpMixed::String( - "Connection: keep-alive".to_string(), - ))); - *list = new_list; - } - } + if let Some(PhpMixed::Array(http)) = options.get_mut("http") + && let Some(boxed) = http.get_mut("header") + && let PhpMixed::List(list) = boxed.as_mut() + { + let headers: Vec = list + .iter() + .filter_map(|b| match b.as_ref() { + PhpMixed::String(s) => Some(s.clone()), + _ => None, + }) + .collect(); + let diffed = array_diff(&headers, &["Connection: close".to_string()]); + let mut new_list: Vec> = diffed + .into_iter() + .map(|s| Box::new(PhpMixed::String(s))) + .collect(); + new_list.push(Box::new(PhpMixed::String( + "Connection: keep-alive".to_string(), + ))); + *list = new_list; } let version = curl_version(); @@ -1085,9 +1079,10 @@ impl CurlDownloader { ); // Gzipped responses with missing Content-Length header cannot be detected during the file download // because $progress['size_download'] refers to the gzipped size downloaded, not the actual file size - if let Some(c_str) = c.as_deref() { - if Platform::strlen(c_str) >= max_file_size { - anyhow::bail!( + if let Some(c_str) = c.as_deref() + && Platform::strlen(c_str) >= max_file_size + { + anyhow::bail!( MaxFileSizeExceededException(TransportException::new( format!( "Maximum allowed download size reached. Downloaded {} of allowed {} bytes", @@ -1099,7 +1094,6 @@ impl CurlDownloader { .0 .message ); - } } contents = PhpMixed::String(c.unwrap_or_default()); } else { @@ -1193,8 +1187,7 @@ impl CurlDownloader { // handle 3xx redirects, 304 Not Modified is excluded let sc = status_code.unwrap_or(0); - if sc >= 300 - && sc <= 399 + if (300..=399).contains(&sc) && sc != 304 && job .get("attributes") @@ -1228,7 +1221,7 @@ impl CurlDownloader { } // fail 4xx and 5xx responses and capture the response - if sc >= 400 && sc <= 599 { + if (400..=599).contains(&sc) { let method_is_get = !job .get("options") .and_then(|v| v.as_array()) @@ -1480,48 +1473,48 @@ impl CurlDownloader { .and_then(|v| v.as_string()) .unwrap_or("") .to_string(); - if let Some(primary_ip) = primary_ip { - if primary_ip.as_string() != Some(&prev_primary_ip) { - let prevent_ip_access_callable = self - .jobs - .get(&i) - .and_then(|j| j.get("options")) - .and_then(|v| v.as_array()) - .and_then(|a| a.get("prevent_ip_access_callable")) - .is_some(); - // PHP: is_callable($cb = $job['options']['prevent_ip_access_callable']) && $cb($primaryIp) - // TODO(phase-c): prevent_ip_access_callable is a caller-supplied callable - // carried inside the options array as PhpMixed; invoking it needs a typed - // callable model (options would have to hold an Rc), which the - // PhpMixed-keyed options map cannot express yet. - let blocked = prevent_ip_access_callable && false; - if blocked { - let job = self.jobs.get(&i).cloned().unwrap_or_default(); - self.reject_job( - &job, - anyhow::anyhow!( - TransportException::new( - format!( - "IP \"{}\" is blocked for \"{}\".", - primary_ip.clone(), - progress_now - .get("url") - .cloned() - .unwrap_or(PhpMixed::Null), - ), - 0, - ) - .message - ), - ); - } + if let Some(primary_ip) = primary_ip + && primary_ip.as_string() != Some(&prev_primary_ip) + { + let prevent_ip_access_callable = self + .jobs + .get(&i) + .and_then(|j| j.get("options")) + .and_then(|v| v.as_array()) + .and_then(|a| a.get("prevent_ip_access_callable")) + .is_some(); + // PHP: is_callable($cb = $job['options']['prevent_ip_access_callable']) && $cb($primaryIp) + // TODO(phase-c): prevent_ip_access_callable is a caller-supplied callable + // carried inside the options array as PhpMixed; invoking it needs a typed + // callable model (options would have to hold an Rc), which the + // PhpMixed-keyed options map cannot express yet. + // The callable that would actually decide blocking cannot be invoked yet + // (see TODO above), so no IP is treated as blocked for now. + let _ = prevent_ip_access_callable; + let blocked = false; + if blocked { + let job = self.jobs.get(&i).cloned().unwrap_or_default(); + self.reject_job( + &job, + anyhow::anyhow!( + TransportException::new( + format!( + "IP \"{}\" is blocked for \"{}\".", + primary_ip.clone(), + progress_now.get("url").cloned().unwrap_or(PhpMixed::Null), + ), + 0, + ) + .message + ), + ); + } - if let Some(job) = self.jobs.get_mut(&i) { - job.insert( - "primaryIp".to_string(), - PhpMixed::String(primary_ip.as_string().unwrap_or("").to_string()), - ); - } + if let Some(job) = self.jobs.get_mut(&i) { + job.insert( + "primaryIp".to_string(), + PhpMixed::String(primary_ip.as_string().unwrap_or("").to_string()), + ); } } @@ -1538,46 +1531,46 @@ impl CurlDownloader { response: &CurlResponse, ) -> anyhow::Result> { let mut target_url = String::new(); - if let Some(location_header) = response.inner.get_header("location") { - if !location_header.is_empty() { - if !parse_url(&location_header, shirabe_php_shim::PHP_URL_SCHEME).is_null() { - // Absolute URL; e.g. https://example.com/composer - target_url = location_header.clone(); - } else if !parse_url(&location_header, shirabe_php_shim::PHP_URL_HOST).is_null() { - // Scheme relative; e.g. //example.com/foo - let job_url = job.get("url").and_then(|v| v.as_string()).unwrap_or(""); - target_url = format!( - "{}:{}", - parse_url(job_url, shirabe_php_shim::PHP_URL_SCHEME) - .as_string() - .unwrap_or(""), - location_header - ); - } else if location_header.starts_with('/') { - // Absolute path; e.g. /foo - let job_url = job.get("url").and_then(|v| v.as_string()).unwrap_or(""); - let url_host = parse_url(job_url, shirabe_php_shim::PHP_URL_HOST); - let url_host_str = url_host.as_string().unwrap_or(""); - - // Replace path using hostname as an anchor. - target_url = Preg::replace( - &format!( - r"{{^(.+(?://|@){}(?::\d+)?)(?:[/\?].*)?$}}", - preg_quote(url_host_str, None) - ), - &format!("\\1{}", location_header), - job_url, - ); - } else { - // Relative path; e.g. foo - // This actually differs from PHP which seems to add duplicate slashes. - let job_url = job.get("url").and_then(|v| v.as_string()).unwrap_or(""); - target_url = Preg::replace( - r"{^(.+/)[^/?]*(?:\?.*)?$}", - &format!("\\1{}", location_header), - job_url, - ); - } + if let Some(location_header) = response.inner.get_header("location") + && !location_header.is_empty() + { + if !parse_url(&location_header, shirabe_php_shim::PHP_URL_SCHEME).is_null() { + // Absolute URL; e.g. https://example.com/composer + target_url = location_header.clone(); + } else if !parse_url(&location_header, shirabe_php_shim::PHP_URL_HOST).is_null() { + // Scheme relative; e.g. //example.com/foo + let job_url = job.get("url").and_then(|v| v.as_string()).unwrap_or(""); + target_url = format!( + "{}:{}", + parse_url(job_url, shirabe_php_shim::PHP_URL_SCHEME) + .as_string() + .unwrap_or(""), + location_header + ); + } else if location_header.starts_with('/') { + // Absolute path; e.g. /foo + let job_url = job.get("url").and_then(|v| v.as_string()).unwrap_or(""); + let url_host = parse_url(job_url, shirabe_php_shim::PHP_URL_HOST); + let url_host_str = url_host.as_string().unwrap_or(""); + + // Replace path using hostname as an anchor. + target_url = Preg::replace( + &format!( + r"{{^(.+(?://|@){}(?::\d+)?)(?:[/\?].*)?$}}", + preg_quote(url_host_str, None) + ), + &format!("\\1{}", location_header), + job_url, + ); + } else { + // Relative path; e.g. foo + // This actually differs from PHP which seems to add duplicate slashes. + let job_url = job.get("url").and_then(|v| v.as_string()).unwrap_or(""); + target_url = Preg::replace( + r"{^(.+/)[^/?]*(?:\?.*)?$}", + &format!("\\1{}", location_header), + job_url, + ); } } @@ -1772,7 +1765,7 @@ impl CurlDownloader { PhpMixed::Array(a) => a.into_iter().map(|(k, v)| (k, *v)).collect(), _ => IndexMap::new(), }; - let origin = Url::get_origin(&*self.config.borrow(), url); + let origin = Url::get_origin(&self.config.borrow(), url); let copy_to = job .get("filename") diff --git a/crates/shirabe/src/util/http/proxy_manager.rs b/crates/shirabe/src/util/http/proxy_manager.rs index eac3cb2..37d73c0 100644 --- a/crates/shirabe/src/util/http/proxy_manager.rs +++ b/crates/shirabe/src/util/http/proxy_manager.rs @@ -110,10 +110,10 @@ impl ProxyManager { fn get_proxy_env(env_name: &str) -> (Option, String) { for name in [env_name.to_lowercase(), env_name.to_uppercase()] { - if let Ok(val) = std::env::var(&name) { - if !val.is_empty() { - return (Some(val), name); - } + if let Ok(val) = std::env::var(&name) + && !val.is_empty() + { + return (Some(val), name); } } (None, String::new()) diff --git a/crates/shirabe/src/util/http/response.rs b/crates/shirabe/src/util/http/response.rs index ad55fa2..e1da15d 100644 --- a/crates/shirabe/src/util/http/response.rs +++ b/crates/shirabe/src/util/http/response.rs @@ -69,12 +69,11 @@ impl Response { shirabe_external_packages::composer::pcre::CaptureKey, String, > = indexmap::IndexMap::new(); - if Preg::match3(&pattern, header, Some(&mut matches)) { - if let Some(s) = + if Preg::match3(&pattern, header, Some(&mut matches)) + && let Some(s) = matches.get(&shirabe_external_packages::composer::pcre::CaptureKey::ByIndex(1)) - { - value = Some(s.clone()); - } + { + value = Some(s.clone()); } } value diff --git a/crates/shirabe/src/util/http_downloader.rs b/crates/shirabe/src/util/http_downloader.rs index 9279518..929dd67 100644 --- a/crates/shirabe/src/util/http_downloader.rs +++ b/crates/shirabe/src/util/http_downloader.rs @@ -110,12 +110,12 @@ impl HttpDownloader { disable_tls: bool, ) -> Self { let disabled = Platform::get_env("COMPOSER_DISABLE_NETWORK") - .map_or(false, |s| !s.is_empty() && s != "0"); + .is_some_and(|s| !s.is_empty() && s != "0"); // Setup TLS options // The cafile option can be set via config.json let mut self_options: IndexMap = IndexMap::new(); - if disable_tls == false { + if !disable_tls { self_options = StreamContextFactory::get_tls_defaults(&options, ()).unwrap_or_default(); } @@ -174,7 +174,7 @@ impl HttpDownloader { /// Download a file synchronously pub fn get(&mut self, url: &str, options: IndexMap) -> Result { - if "" == url { + if url.is_empty() { return Err(InvalidArgumentException { message: "$url must not be an empty string".to_string(), code: 0, @@ -202,7 +202,7 @@ impl HttpDownloader { url: &str, options: IndexMap, ) -> Result { - if "" == url { + if url.is_empty() { return Err(InvalidArgumentException { message: "$url must not be an empty string".to_string(), code: 0, @@ -229,7 +229,7 @@ impl HttpDownloader { to: &str, options: IndexMap, ) -> Result { - if "" == url { + if url.is_empty() { return Err(InvalidArgumentException { message: "$url must not be an empty string".to_string(), code: 0, @@ -256,7 +256,7 @@ impl HttpDownloader { to: &str, options: IndexMap, ) -> Result { - if "" == url { + if url.is_empty() { return Err(InvalidArgumentException { message: "$url must not be an empty string".to_string(), code: 0, @@ -296,7 +296,7 @@ impl HttpDownloader { let id = self.id_gen; self.id_gen += 1; - let origin = Url::get_origin(&*self.config.borrow(), &request.url); + let origin = Url::get_origin(&self.config.borrow(), &request.url); if !sync && !self.allow_async { return Err(LogicException { @@ -680,21 +680,21 @@ impl HttpDownloader { } let versions_key = format!("{}-versions", r#type); - if let Some(versions_value) = data.get(&versions_key) { - if !shirabe_php_shim::empty(versions_value) { - let version_parser: VersionParser = VersionParser::new(); - let constraint = version_parser - .parse_constraints(versions_value.as_string().unwrap_or(""))?; - let composer_constraint = SimpleConstraint::new( - "==".to_string(), - version_parser - .normalize(&composer::get_version(), None)? - .to_string(), - None, - ); - if !constraint.matches(&composer_constraint.into()) { - continue; - } + if let Some(versions_value) = data.get(&versions_key) + && !shirabe_php_shim::empty(versions_value) + { + let version_parser: VersionParser = VersionParser::new(); + let constraint = + version_parser.parse_constraints(versions_value.as_string().unwrap_or(""))?; + let composer_constraint = SimpleConstraint::new( + "==".to_string(), + version_parser + .normalize(&composer::get_version(), None)? + .to_string(), + None, + ); + if !constraint.matches(&composer_constraint.into()) { + continue; } } @@ -761,13 +761,11 @@ impl HttpDownloader { /// @return ?string[] pub fn get_exception_hints(e: &anyhow::Error) -> Option> { let e_as_transport: Option<&TransportException> = e.downcast_ref::(); - if e_as_transport.is_none() { - return None; - } + e_as_transport?; let e_as_transport = e_as_transport.unwrap(); - if false != strpos(e_as_transport.get_message(), "Resolving timed out").is_some() - || false != strpos(e_as_transport.get_message(), "Could not resolve host").is_some() + if strpos(e_as_transport.get_message(), "Resolving timed out").is_some() + || strpos(e_as_transport.get_message(), "Could not resolve host").is_some() { Silencer::suppress(None); let mut ctx_options: IndexMap = IndexMap::new(); @@ -814,10 +812,10 @@ impl HttpDownloader { PhpMixed::Array(m) => m.get("allow_self_signed").cloned(), _ => None, }); - if let Some(v) = allow_self_signed { - if !shirabe_php_shim::empty(&v) { - return false; - } + if let Some(v) = allow_self_signed + && !shirabe_php_shim::empty(&v) + { + return false; } true diff --git a/crates/shirabe/src/util/ini_helper.rs b/crates/shirabe/src/util/ini_helper.rs index a0f3fd5..5789411 100644 --- a/crates/shirabe/src/util/ini_helper.rs +++ b/crates/shirabe/src/util/ini_helper.rs @@ -14,7 +14,7 @@ impl IniHelper { pub fn get_message() -> String { let mut paths = Self::get_all(); - if paths.first().map_or(false, |s| s.is_empty()) { + if paths.first().is_some_and(|s| s.is_empty()) { paths.remove(0); } diff --git a/crates/shirabe/src/util/loop.rs b/crates/shirabe/src/util/loop.rs index 8cbd49d..2a0e6d3 100644 --- a/crates/shirabe/src/util/loop.rs +++ b/crates/shirabe/src/util/loop.rs @@ -18,9 +18,8 @@ impl Loop { ) -> Self { http_downloader.borrow_mut().enable_async(); - let process_executor = process_executor.map(|pe| { + let process_executor = process_executor.inspect(|pe| { pe.borrow_mut().enable_async(); - pe }); Self { @@ -51,10 +50,10 @@ impl Loop { // on a multi-thread runtime these futures should be driven concurrently instead of in order. // The PHP progress bar is tied to the worker active-job count and is also deferred until then. for promise in promises { - if let Err(e) = promise.await { - if uncaught.is_none() { - uncaught = Some(e); - } + if let Err(e) = promise.await + && uncaught.is_none() + { + uncaught = Some(e); } } diff --git a/crates/shirabe/src/util/no_proxy_pattern.rs b/crates/shirabe/src/util/no_proxy_pattern.rs index 512b881..34491ba 100644 --- a/crates/shirabe/src/util/no_proxy_pattern.rs +++ b/crates/shirabe/src/util/no_proxy_pattern.rs @@ -135,7 +135,7 @@ impl NoProxyPattern { matched = rule_ipdata.ip == url_ipdata.ip; } else { // Match host and port - let haystack = substr(&url.name, -(strlen(&rule.name) as i64), None); + let haystack = substr(&url.name, -strlen(&rule.name), None); matched = stripos(&haystack, &rule.name) == Some(0); } @@ -260,7 +260,7 @@ impl NoProxyPattern { // Check for a CIDR prefix-length if strpos(&host, "/").is_some() { let parts = explode("/", &host); - host = parts.get(0).cloned().unwrap_or_default(); + host = parts.first().cloned().unwrap_or_default(); let prefix_str = parts.get(1).cloned().unwrap_or_default(); if !allow_prefix || !self.validate_int(&prefix_str, 0, 128) { @@ -446,7 +446,7 @@ impl NoProxyPattern { // Check for square-bracket notation // PHP: if ($hostName[0] === '[') - if host_name.chars().next() == Some('[') { + if host_name.starts_with('[') { let index = strpos(&host_name, "]"); // The smallest ip6 address is :: diff --git a/crates/shirabe/src/util/package_info.rs b/crates/shirabe/src/util/package_info.rs index df34951..4e02dab 100644 --- a/crates/shirabe/src/util/package_info.rs +++ b/crates/shirabe/src/util/package_info.rs @@ -8,10 +8,10 @@ impl PackageInfo { pub fn get_view_source_url(package: PackageInterfaceHandle) -> Option { if let Some(complete) = package.as_complete() { let support = complete.get_support(); - if let Some(source) = support.get("source") { - if source != "" { - return Some(source.clone()); - } + if let Some(source) = support.get("source") + && !source.is_empty() + { + return Some(source.clone()); } } diff --git a/crates/shirabe/src/util/perforce.rs b/crates/shirabe/src/util/perforce.rs index 937e305..3f73f7d 100644 --- a/crates/shirabe/src/util/perforce.rs +++ b/crates/shirabe/src/util/perforce.rs @@ -85,7 +85,7 @@ impl Perforce { pub fn check_server_exists(url: &str, process_executor: &mut ProcessExecutor) -> bool { let mut ignored_output = String::new(); process_executor.execute_args( - &vec![ + &[ "p4".to_string(), "-p".to_string(), url.to_string(), @@ -208,10 +208,10 @@ impl Perforce { self.p4_stream = Some(stream.to_string()); let index = strrpos(stream, "/"); // Stream format is //depot/stream, while non-streaming depot is //depot - if let Some(i) = index { - if (i as i64) > 2 { - self.p4_depot_type = Some("stream".to_string()); - } + if let Some(i) = index + && (i as i64) > 2 + { + self.p4_depot_type = Some("stream".to_string()); } } @@ -295,7 +295,7 @@ impl Perforce { let res_array = explode(PHP_EOL, &result); for line in &res_array { let fields = explode("=", line); - if strcmp(name, fields.get(0).map(|s| s.as_str()).unwrap_or("")) == 0 { + if strcmp(name, fields.first().map(|s| s.as_str()).unwrap_or("")) == 0 { let field1 = fields.get(1).cloned().unwrap_or_default(); let index = strpos(&field1, " "); let value = match index { @@ -705,7 +705,7 @@ impl Perforce { )); let result = self.command_result.clone(); let res_array = explode(PHP_EOL, &result); - let last_commit = res_array.get(0).cloned().unwrap_or_default(); + let last_commit = res_array.first().cloned().unwrap_or_default(); let last_commit_arr = explode(" ", &last_commit); let last_commit_num = last_commit_arr.get(1).cloned().unwrap_or_default(); diff --git a/crates/shirabe/src/util/platform.rs b/crates/shirabe/src/util/platform.rs index 7c9f569..7560072 100644 --- a/crates/shirabe/src/util/platform.rs +++ b/crates/shirabe/src/util/platform.rs @@ -151,23 +151,21 @@ impl Platform { return Ok(home); } - if Self::is_windows() { - if let Some(home) = Self::get_env("USERPROFILE") { - return Ok(home); - } + if Self::is_windows() + && let Some(home) = Self::get_env("USERPROFILE") + { + return Ok(home); } if function_exists("posix_getuid") && function_exists("posix_getpwuid") { let info = posix_getpwuid(posix_getuid()); - if is_array(&info) { - if let Some(arr) = info.as_array() { - if let Some(dir) = arr.get("dir") { - if let Some(s) = dir.as_string() { - return Ok(s.to_string()); - } - } - } + if is_array(&info) + && let Some(arr) = info.as_array() + && let Some(dir) = arr.get("dir") + && let Some(s) = dir.as_string() + { + return Ok(s.to_string()); } } @@ -335,10 +333,10 @@ impl Platform { } // Check if formatted mode is S_IFCHR - if let Some(arr) = stat.as_array() { - if let Some(mode) = arr.get("mode").and_then(|v| v.as_int()) { - return 0o020000 == (mode & 0o170000); - } + if let Some(arr) = stat.as_array() + && let Some(mode) = arr.get("mode").and_then(|v| v.as_int()) + { + return 0o020000 == (mode & 0o170000); } false @@ -368,18 +366,16 @@ impl Platform { if function_exists("posix_getpwuid") && function_exists("posix_geteuid") { let process_user = posix_getpwuid(posix_geteuid()); - if is_array(&process_user) { - if let Some(arr) = process_user.as_array() { - if arr - .get("name") - .and_then(|v| v.as_string()) - .map(|s| s == "vagrant") - .unwrap_or(false) - { - *cached = Some(true); - return true; - } - } + if is_array(&process_user) + && let Some(arr) = process_user.as_array() + && arr + .get("name") + .and_then(|v| v.as_string()) + .map(|s| s == "vagrant") + .unwrap_or(false) + { + *cached = Some(true); + return true; } } diff --git a/crates/shirabe/src/util/process_executor.rs b/crates/shirabe/src/util/process_executor.rs index 42bd0c8..ca31290 100644 --- a/crates/shirabe/src/util/process_executor.rs +++ b/crates/shirabe/src/util/process_executor.rs @@ -251,16 +251,16 @@ impl ProcessExecutor { if !Platform::is_windows() && tty { // PHP: try { $process->setTty(true); } catch (RuntimeException $e) { /* ignore */ } - if let Err(e) = process.set_tty(true) { - if e.downcast_ref::().is_none() { - return Err(e); - } - // ignore TTY enabling errors + if let Err(e) = process.set_tty(true) + && e.downcast_ref::().is_none() + { + return Err(e); } + // ignore TTY enabling errors } // PHP: $callback = is_callable($output) ? $output : fn($type, $buffer) => $this->outputHandler($type, $buffer); - let output_is_callable = output.as_deref().map(|o| is_callable(o)).unwrap_or(false); + let output_is_callable = output.as_deref().map(is_callable).unwrap_or(false); let _callback: Box = if output_is_callable { // TODO(phase-c): the user-supplied $output is a PhpMixed callable that cannot be // invoked without a typed callable model (Rc); deferred with the callable model. @@ -291,20 +291,20 @@ impl ProcessExecutor { }), ); - let result: Result<()> = (|| -> Result<()> { + let result: Result<()> = { let _ = process.run(/* callback */ Some(Box::new(|_t: &str, _b: &str| {}))); - let output_is_callable_inner = - output.as_deref().map(|o| is_callable(o)).unwrap_or(false); - if self.capture_output && !output_is_callable_inner { - if let Some(out) = output.as_mut() { - **out = PhpMixed::String(process.get_output()); - } + let output_is_callable_inner = output.as_deref().map(is_callable).unwrap_or(false); + if self.capture_output + && !output_is_callable_inner + && let Some(out) = output.as_mut() + { + **out = PhpMixed::String(process.get_output()); } self.error_output = process.get_error_output(); Ok(()) - })(); + }; let final_result: Result<()> = match result { Ok(()) => Ok(()), Err(e) => { @@ -369,7 +369,7 @@ impl ProcessExecutor { } Ok(self - .run_process(command, cwd, env, tty, output.as_deref_mut())? + .run_process(command, cwd, env, tty, output)? .unwrap_or(0)) } @@ -466,33 +466,31 @@ impl ProcessExecutor { self.output_command_run(&command, cwd.as_deref(), true); - let process_result: Result = (|| -> Result { - if is_string(&command) { - Ok(Process::from_shell_commandline( - command.as_string().unwrap_or(""), - cwd.as_deref(), - None, - None, - Some(Self::get_timeout() as f64), - )) - } else if let PhpMixed::List(ref list) = command { - Ok(Process::new( - list.iter() - .map(|v| v.as_string().unwrap_or("").to_string()) - .collect(), - cwd.clone(), - None, - None, - Some(Self::get_timeout() as f64), - )) - } else { - Err(LogicException { - message: "Invalid command type".to_string(), - code: 0, - } - .into()) + let process_result: Result = (if is_string(&command) { + Ok(Process::from_shell_commandline( + command.as_string().unwrap_or(""), + cwd.as_deref(), + None, + None, + Some(Self::get_timeout() as f64), + )) + } else if let PhpMixed::List(ref list) = command { + Ok(Process::new( + list.iter() + .map(|v| v.as_string().unwrap_or("").to_string()) + .collect(), + cwd.clone(), + None, + None, + Some(Self::get_timeout() as f64), + )) + } else { + Err(LogicException { + message: "Invalid command type".to_string(), + code: 0, } - })(); + .into()) + }); let process = match process_result { Ok(p) => p, Err(e) => { @@ -511,10 +509,10 @@ impl ProcessExecutor { } // PHP: $process->start($callback); — we operate on the stored job.process directly - if let Some(job) = self.jobs.get_mut(&id) { - if let Some(p) = job.process.as_mut() { - p.start(None); - } + if let Some(job) = self.jobs.get_mut(&id) + && let Some(p) = job.process.as_mut() + { + p.start(None); } } @@ -570,36 +568,34 @@ impl ProcessExecutor { let j = self.jobs.get(id).unwrap(); (j.status, j.process.is_some()) }; - if status == Self::STATUS_STARTED { - if has_process { - let is_running = self + if status == Self::STATUS_STARTED && has_process { + let is_running = self + .jobs + .get(id) + .and_then(|j| j.process.as_ref()) + .map(|p| p.is_running()) + .unwrap_or(false); + if !is_running { + // PHP: call_user_func($job['resolve'], $job['process']) — the .then handler + // marks the job completed/failed based on the process exit status. + let successful = self .jobs .get(id) .and_then(|j| j.process.as_ref()) - .map(|p| p.is_running()) + .map(|p| p.is_successful()) .unwrap_or(false); - if !is_running { - // PHP: call_user_func($job['resolve'], $job['process']) — the .then handler - // marks the job completed/failed based on the process exit status. - let successful = self - .jobs - .get(id) - .and_then(|j| j.process.as_ref()) - .map(|p| p.is_successful()) - .unwrap_or(false); - if let Some(job) = self.jobs.get_mut(id) { - job.status = if successful { - Self::STATUS_COMPLETED - } else { - Self::STATUS_FAILED - }; - } - self.mark_job_done(); + if let Some(job) = self.jobs.get_mut(id) { + job.status = if successful { + Self::STATUS_COMPLETED + } else { + Self::STATUS_FAILED + }; } + self.mark_job_done(); + } - if let Some(p) = self.jobs.get(id).and_then(|j| j.process.as_ref()) { - p.check_timeout()?; - } + if let Some(p) = self.jobs.get(id).and_then(|j| j.process.as_ref()) { + p.check_timeout()?; } } @@ -725,7 +721,7 @@ impl ProcessExecutor { /// Escapes a string to be used as a shell argument for Symfony Process. fn escape_argument(argument: &str) -> String { let mut argument = argument.to_string(); - if "" == argument { + if argument.is_empty() { return escapeshellarg(&argument); } @@ -792,7 +788,7 @@ impl ProcessExecutor { _ => vec![], } }; - if cmd.get(0).map(|s| s.as_str()) != Some("git") { + if cmd.first().map(|s| s.as_str()) != Some("git") { return false; } diff --git a/crates/shirabe/src/util/remote_filesystem.rs b/crates/shirabe/src/util/remote_filesystem.rs index 80b2617..1890a95 100644 --- a/crates/shirabe/src/util/remote_filesystem.rs +++ b/crates/shirabe/src/util/remote_filesystem.rs @@ -231,10 +231,10 @@ impl RemoteFilesystem { options.shift_remove("gitlab-token"); } - if let Some(http_opts) = options.get_mut("http") { - if let PhpMixed::Array(m) = http_opts { - m.insert("ignore_errors".to_string(), Box::new(PhpMixed::Bool(true))); - } + if let Some(http_opts) = options.get_mut("http") + && let PhpMixed::Array(m) = http_opts + { + m.insert("ignore_errors".to_string(), Box::new(PhpMixed::Bool(true))); } let mut degraded_packagist = false; @@ -399,12 +399,11 @@ impl RemoteFilesystem { te.set_headers(http_response_header.clone()); te.set_status_code(Self::find_status_code(&http_response_header)); } - if result.is_some() { - if let Ok(decoded) = + if result.is_some() + && let Ok(decoded) = self.decode_result(result.as_deref(), &http_response_header) - { - te.set_response(decoded); - } + { + te.set_response(decoded); } } caught_e = Some(e); @@ -421,13 +420,14 @@ impl RemoteFilesystem { error_message ); } - if let Some(e) = caught_e { - if !self.retry { - let msg_owned = format!("{}", e); - if !self.degraded_mode && strpos(&msg_owned, "Operation timed out").is_some() { - self.degraded_mode = true; - self.io.write_error3("", true, crate::io::NORMAL); - self.io.write_error3( + if let Some(e) = caught_e + && !self.retry + { + let msg_owned = format!("{}", e); + if !self.degraded_mode && strpos(&msg_owned, "Operation timed out").is_some() { + self.degraded_mode = true; + self.io.write_error3("", true, crate::io::NORMAL); + self.io.write_error3( &format!( "{}\nRetrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info", msg_owned, @@ -436,17 +436,16 @@ impl RemoteFilesystem { crate::io::NORMAL, ); - return self.get( - &self.origin_url.clone(), - &self.file_url.clone(), - additional_options, - self.file_name.clone(), - self.progress, - ); - } - - return Err(e); + return self.get( + &self.origin_url.clone(), + &self.file_url.clone(), + additional_options, + self.file_name.clone(), + self.progress, + ); } + + return Err(e); } let mut status_code: Option = None; @@ -465,10 +464,9 @@ impl RemoteFilesystem { && substr(&self.file_url, -4, None) == ".zip" && (location_header.is_none() || substr( - &parse_url(location_header.as_deref().unwrap_or(""), PHP_URL_PATH) + parse_url(location_header.as_deref().unwrap_or(""), PHP_URL_PATH) .as_string() - .unwrap_or("") - .to_string(), + .unwrap_or(""), -4, None, ) != ".zip") @@ -501,46 +499,48 @@ impl RemoteFilesystem { } let mut has_followed_redirect = false; - if let Some(code) = status_code { - if code >= 300 && code <= 399 && code != 304 && self.redirects < self.max_redirects { - has_followed_redirect = true; - result = self.handle_redirect( - &http_response_header, - additional_options.clone(), - result.clone(), - )?; - } + if let Some(code) = status_code + && (300..=399).contains(&code) + && code != 304 + && self.redirects < self.max_redirects + { + has_followed_redirect = true; + result = self.handle_redirect( + &http_response_header, + additional_options.clone(), + result.clone(), + )?; } - if let Some(code) = status_code { - if code >= 400 && code <= 599 { - if !self.retry { - if self.progress && !is_redirect { - self.io.overwrite_error4( - "Downloading (failed)", - false, - None, - crate::io::NORMAL, - ); - } - - let mut e = TransportException::new_with_code( - format!( - "The \"{}\" file could not be downloaded ({})", - self.file_url, http_response_header[0] - ), - code, + if let Some(code) = status_code + && (400..=599).contains(&code) + { + if !self.retry { + if self.progress && !is_redirect { + self.io.overwrite_error4( + "Downloading (failed)", + false, + None, + crate::io::NORMAL, ); - e.set_headers(http_response_header.clone()); - let decoded = self - .decode_result(result.as_deref(), &http_response_header) - .unwrap_or(None); - e.set_response(decoded); - e.set_status_code(Some(code)); - return Err(anyhow::anyhow!(e)); } - result = None; + + let mut e = TransportException::new_with_code( + format!( + "The \"{}\" file could not be downloaded ({})", + self.file_url, http_response_header[0] + ), + code, + ); + e.set_headers(http_response_header.clone()); + let decoded = self + .decode_result(result.as_deref(), &http_response_header) + .unwrap_or(None); + e.set_response(decoded); + e.set_status_code(Some(code)); + return Err(anyhow::anyhow!(e)); } + result = None; } if self.progress && !self.retry && !is_redirect { @@ -724,16 +724,15 @@ impl RemoteFilesystem { Err(e) => caught_e = Some(e), } - if let Some(ref r) = result { - if let Some(max) = max_file_size { - if Platform::strlen(r) >= max { - return Err(anyhow::anyhow!(MaxFileSizeExceededException::new(format!( - "Maximum allowed download size reached. Downloaded {} of allowed {} bytes", - Platform::strlen(r), - max - )))); - } - } + if let Some(ref r) = result + && let Some(max) = max_file_size + && Platform::strlen(r) >= max + { + return Err(anyhow::anyhow!(MaxFileSizeExceededException::new(format!( + "Maximum allowed download size reached. Downloaded {} of allowed {} bytes", + Platform::strlen(r), + max + )))); } if PHP_VERSION_ID >= 80400 { diff --git a/crates/shirabe/src/util/stream_context_factory.rs b/crates/shirabe/src/util/stream_context_factory.rs index 7d8ab3f..d73f3b4 100644 --- a/crates/shirabe/src/util/stream_context_factory.rs +++ b/crates/shirabe/src/util/stream_context_factory.rs @@ -51,19 +51,19 @@ impl StreamContextFactory { }; options = array_replace_recursive(options, default_options); - if let Some(PhpMixed::Array(http)) = options.get_mut("http") { - if let Some(header) = http.get("header").cloned() { - let fixed = Self::fix_http_header_field(&*header); - http.insert( - "header".to_string(), - Box::new(PhpMixed::List( - fixed - .into_iter() - .map(|s| Box::new(PhpMixed::String(s))) - .collect(), - )), - ); - } + if let Some(PhpMixed::Array(http)) = options.get_mut("http") + && let Some(header) = http.get("header").cloned() + { + let fixed = Self::fix_http_header_field(&header); + http.insert( + "header".to_string(), + Box::new(PhpMixed::List( + fixed + .into_iter() + .map(|s| Box::new(PhpMixed::String(s))) + .collect(), + )), + ); } Ok(stream_context_create(&options, Some(&default_params))) @@ -80,10 +80,8 @@ impl StreamContextFactory { .and_then(|v| v.as_array()) .map(|a| a.contains_key("header")) .unwrap_or(false); - if !has_header { - if let Some(PhpMixed::Array(http)) = options.get_mut("http") { - http.insert("header".to_string(), Box::new(PhpMixed::List(vec![]))); - } + if !has_header && let Some(PhpMixed::Array(http)) = options.get_mut("http") { + http.insert("header".to_string(), Box::new(PhpMixed::List(vec![]))); } // Convert string header to array let header_is_string = options @@ -92,16 +90,15 @@ impl StreamContextFactory { .and_then(|a| a.get("header")) .map(|v| matches!(**v, PhpMixed::String(_))) .unwrap_or(false); - if header_is_string { - if let Some(PhpMixed::Array(http)) = options.get_mut("http") { - if let Some(PhpMixed::String(header_str)) = http.get("header").map(|v| *v.clone()) { - let parts: Vec> = header_str - .split("\r\n") - .map(|s| Box::new(PhpMixed::String(s.to_string()))) - .collect(); - http.insert("header".to_string(), Box::new(PhpMixed::List(parts))); - } - } + if header_is_string + && let Some(PhpMixed::Array(http)) = options.get_mut("http") + && let Some(PhpMixed::String(header_str)) = http.get("header").map(|v| *v.clone()) + { + let parts: Vec> = header_str + .split("\r\n") + .map(|s| Box::new(PhpMixed::String(s.to_string()))) + .collect(); + http.insert("header".to_string(), Box::new(PhpMixed::List(parts))); } // Add stream proxy options if there is a proxy @@ -136,14 +133,11 @@ impl StreamContextFactory { // Header will be a Proxy-Authorization string or not set let proxy_http = proxy_options.get("http"); - if let Some(proxy_header) = proxy_http.and_then(|h| h.get("header")) { - if let Some(PhpMixed::Array(http)) = options.get_mut("http") { - if let Some(PhpMixed::List(headers)) = - http.get_mut("header").map(|v| &mut **v) - { - headers.push(Box::new(proxy_header.clone())); - } - } + if let Some(proxy_header) = proxy_http.and_then(|h| h.get("header")) + && let Some(PhpMixed::Array(http)) = options.get_mut("http") + && let Some(PhpMixed::List(headers)) = http.get_mut("header").map(|v| &mut **v) + { + headers.push(Box::new(proxy_header.clone())); } let proxy_options_flat: IndexMap = proxy_options @@ -226,10 +220,10 @@ impl StreamContextFactory { "" }, ); - if let Some(PhpMixed::Array(http)) = options.get_mut("http") { - if let Some(PhpMixed::List(headers)) = http.get_mut("header").map(|v| &mut **v) { - headers.push(Box::new(PhpMixed::String(user_agent))); - } + if let Some(PhpMixed::Array(http)) = options.get_mut("http") + && let Some(PhpMixed::List(headers)) = http.get_mut("header").map(|v| &mut **v) + { + headers.push(Box::new(PhpMixed::String(user_agent))); } } @@ -315,23 +309,23 @@ impl StreamContextFactory { d }; - if let Some(ssl_options) = options.get("ssl") { - if let Some(ssl_defaults_mixed) = defaults.get("ssl").cloned() { - let merged = array_replace_recursive( - match ssl_defaults_mixed { - PhpMixed::Array(a) => a.into_iter().map(|(k, v)| (k, *v)).collect(), - _ => IndexMap::new(), - }, - match ssl_options.clone() { - PhpMixed::Array(a) => a.into_iter().map(|(k, v)| (k, *v)).collect(), - _ => IndexMap::new(), - }, - ); - defaults.insert( - "ssl".to_string(), - PhpMixed::Array(merged.into_iter().map(|(k, v)| (k, Box::new(v))).collect()), - ); - } + if let Some(ssl_options) = options.get("ssl") + && let Some(ssl_defaults_mixed) = defaults.get("ssl").cloned() + { + let merged = array_replace_recursive( + match ssl_defaults_mixed { + PhpMixed::Array(a) => a.into_iter().map(|(k, v)| (k, *v)).collect(), + _ => IndexMap::new(), + }, + match ssl_options.clone() { + PhpMixed::Array(a) => a.into_iter().map(|(k, v)| (k, *v)).collect(), + _ => IndexMap::new(), + }, + ); + defaults.insert( + "ssl".to_string(), + PhpMixed::Array(merged.into_iter().map(|(k, v)| (k, Box::new(v))).collect()), + ); } // Attempt to find a local cafile or throw an exception if none pre-set. @@ -358,13 +352,13 @@ impl StreamContextFactory { .and_then(|a| a.get("cafile")) .and_then(|v| v.as_string()) .map(|s| s.to_string()); - if let Some(ref cafile) = cafile { - if !Filesystem::is_readable(cafile) || !CaBundle::validate_ca_file(cafile, logger) { - return Err(TransportException::new( - "The configured cafile was not valid or could not be read.".to_string(), - 0, - )); - } + if let Some(ref cafile) = cafile + && (!Filesystem::is_readable(cafile) || !CaBundle::validate_ca_file(cafile, logger)) + { + return Err(TransportException::new( + "The configured cafile was not valid or could not be read.".to_string(), + 0, + )); } let capath = defaults @@ -373,13 +367,13 @@ impl StreamContextFactory { .and_then(|a| a.get("capath")) .and_then(|v| v.as_string()) .map(|s| s.to_string()); - if let Some(ref capath) = capath { - if !shirabe_php_shim::is_dir(capath) || !Filesystem::is_readable(capath) { - return Err(TransportException::new( - "The configured capath was not valid or could not be read.".to_string(), - 0, - )); - } + if let Some(ref capath) = capath + && (!shirabe_php_shim::is_dir(capath) || !Filesystem::is_readable(capath)) + { + return Err(TransportException::new( + "The configured capath was not valid or could not be read.".to_string(), + 0, + )); } // Disable TLS compression to prevent CRIME attacks where supported. diff --git a/crates/shirabe/src/util/svn.rs b/crates/shirabe/src/util/svn.rs index 181fccf..269cb5d 100644 --- a/crates/shirabe/src/util/svn.rs +++ b/crates/shirabe/src/util/svn.rs @@ -372,24 +372,24 @@ impl Svn { .as_array() .and_then(|m| m.get(host_str)) .map(|v| (**v).clone()); - if let Some(entry) = auth_for_host { - if let Some(entry_arr) = entry.as_array() { - self.credentials = Some(SvnCredentials { - username: entry_arr - .get("username") - .and_then(|v| v.as_string()) - .unwrap_or("") - .to_string(), - password: entry_arr - .get("password") - .and_then(|v| v.as_string()) - .unwrap_or("") - .to_string(), - }); - - self.has_auth = Some(true); - return true; - } + if let Some(entry) = auth_for_host + && let Some(entry_arr) = entry.as_array() + { + self.credentials = Some(SvnCredentials { + username: entry_arr + .get("username") + .and_then(|v| v.as_string()) + .unwrap_or("") + .to_string(), + password: entry_arr + .get("password") + .and_then(|v| v.as_string()) + .unwrap_or("") + .to_string(), + }); + + self.has_auth = Some(true); + return true; } self.has_auth = Some(false); diff --git a/crates/shirabe/src/util/tar.rs b/crates/shirabe/src/util/tar.rs index 2d44392..95a6fde 100644 --- a/crates/shirabe/src/util/tar.rs +++ b/crates/shirabe/src/util/tar.rs @@ -47,10 +47,10 @@ impl Tar { "{}/composer.json", top_level_paths.keys().next().cloned().unwrap_or_default() ); - if !top_level_paths.is_empty() { - if let Some(file) = phar.get(&composer_json_path) { - return Ok(file.get_content()); - } + if !top_level_paths.is_empty() + && let Some(file) = phar.get(&composer_json_path) + { + return Ok(file.get_content()); } Err(anyhow::anyhow!(RuntimeException { diff --git a/crates/shirabe/src/util/url.rs b/crates/shirabe/src/util/url.rs index 064c850..534e318 100644 --- a/crates/shirabe/src/util/url.rs +++ b/crates/shirabe/src/util/url.rs @@ -166,7 +166,7 @@ impl Url { // e.g. https://api.github.com/repositories/9999999999?access_token=github_token let url = Preg::replace(r"([&?]access_token=)[^&]+", "$1***", &url); - let url = Preg::replace_callback( + Preg::replace_callback( r"(?i)^(?P[a-z0-9]+://)?(?P[^:/\s@]+):(?P[^@\s/]+)@", |m| { let user = m @@ -185,8 +185,6 @@ impl Url { } }, &url, - ); - - url + ) } } diff --git a/crates/shirabe/src/util/zip.rs b/crates/shirabe/src/util/zip.rs index d76d805..4231db4 100644 --- a/crates/shirabe/src/util/zip.rs +++ b/crates/shirabe/src/util/zip.rs @@ -45,10 +45,10 @@ impl Zip { fn locate_file(zip: &ZipArchive, filename: &str) -> Result { // return root composer.json if it is there and is a file - if let Some(index) = zip.locate_name(filename) { - if zip.get_from_index(index).is_some() { - return Ok(index); - } + if let Some(index) = zip.locate_name(filename) + && zip.get_from_index(index).is_some() + { + return Ok(index); } let mut top_level_paths: IndexMap = IndexMap::new(); @@ -95,10 +95,10 @@ impl Zip { if !top_level_paths.is_empty() { let first_key = top_level_paths.keys().next().unwrap().clone(); - if let Some(index) = zip.locate_name(&format!("{}{}", first_key, filename)) { - if zip.get_from_index(index).is_some() { - return Ok(index); - } + if let Some(index) = zip.locate_name(&format!("{}{}", first_key, filename)) + && zip.get_from_index(index).is_some() + { + return Ok(index); } } -- cgit v1.3.1