From 14ff75ab4b61eb7ca7a425ae10ba89f30b1745d1 Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Tue, 26 Mar 2024 10:10:07 +0100 Subject: [PATCH] ref: Privatize top-level modules and delete dead code (#1992) Since the CLI is only published as a binary, and not as a library, there is no reason for the top-level modules to be public. So, this PR makes them private. After making them private, the Rust compiler warned of several parts of the code that were unused. So, this PR removes all the dead code noticed by the compiler. The Rust compiler also warned of some code that was unused in Linux and Windows (but they are still used in the macOS binary), this PR adds #[cfg(target_os = "macos")] directives as needed to ensure this code is only compiled for the macOS platform --- src/api.rs | 29 ++------ src/config.rs | 4 +- src/main.rs | 10 +-- src/utils/codepush.rs | 140 --------------------------------------- src/utils/dif_upload.rs | 48 -------------- src/utils/enc.rs | 31 --------- src/utils/file_search.rs | 16 ----- src/utils/file_upload.rs | 5 -- src/utils/fs.rs | 7 +- src/utils/mod.rs | 2 - src/utils/progress.rs | 12 +--- src/utils/system.rs | 5 +- src/utils/xcode.rs | 27 +++++--- 13 files changed, 37 insertions(+), 299 deletions(-) delete mode 100644 src/utils/codepush.rs delete mode 100644 src/utils/enc.rs diff --git a/src/api.rs b/src/api.rs index 411ce9592b..f75ae993fd 100644 --- a/src/api.rs +++ b/src/api.rs @@ -18,7 +18,9 @@ use std::{env, fmt}; use anyhow::{Context, Result}; use backoff::backoff::Backoff; use brotli2::write::BrotliEncoder; -use chrono::{DateTime, Duration, FixedOffset, Utc}; +#[cfg(target_os = "macos")] +use chrono::Duration; +use chrono::{DateTime, FixedOffset, Utc}; use clap::ArgMatches; use flate2::write::GzEncoder; use if_chain::if_chain; @@ -158,7 +160,6 @@ pub enum ProgressBarMode { Disabled, Request, Response, - Both, Shared((Arc, u64, usize, Arc>>)), } @@ -170,12 +171,12 @@ impl ProgressBarMode { /// Returns whether a progress bar should be displayed during upload. pub fn request(&self) -> bool { - matches!(*self, ProgressBarMode::Request | ProgressBarMode::Both) + matches!(*self, ProgressBarMode::Request) } /// Returns whether a progress bar should be displayed during download. pub fn response(&self) -> bool { - matches!(*self, ProgressBarMode::Response | ProgressBarMode::Both) + matches!(*self, ProgressBarMode::Response) } } @@ -324,7 +325,6 @@ pub type ApiResult = Result; #[derive(Eq, PartialEq, Debug)] pub enum Method { Get, - Head, Post, Put, Delete, @@ -334,7 +334,6 @@ impl fmt::Display for Method { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Method::Get => write!(f, "GET"), - Method::Head => write!(f, "HEAD"), Method::Post => write!(f, "POST"), Method::Put => write!(f, "PUT"), Method::Delete => write!(f, "DELETE"), @@ -532,7 +531,8 @@ impl Api { } /// Convenience method that waits for a few seconds until a resource - /// becomes available. + /// becomes available. We only use this in the macOS binary. + #[cfg(target_os = "macos")] pub fn wait_until_available(&self, url: &str, duration: Duration) -> ApiResult { let started = Utc::now(); loop { @@ -1851,11 +1851,6 @@ impl ApiRequest { match method { Method::Get => handle.get(true)?, - Method::Head => { - handle.get(true)?; - handle.custom_request("HEAD")?; - handle.nobody(true)?; - } Method::Post => handle.custom_request("POST")?, Method::Put => handle.custom_request("PUT")?, Method::Delete => handle.custom_request("DELETE")?, @@ -2235,16 +2230,6 @@ pub struct Artifact { } impl Artifact { - pub fn get_header<'a>(&'a self, key: &str) -> Option<&'a str> { - let ikey = key.to_lowercase(); - for (k, v) in &self.headers { - if k.to_lowercase() == ikey { - return Some(v.as_str()); - } - } - None - } - pub fn get_sourcemap_reference(&self) -> Option<&str> { get_sourcemap_reference_from_headers(self.headers.iter()) } diff --git a/src/config.rs b/src/config.rs index f70d093a0d..5daa85f6b7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -431,7 +431,9 @@ impl Config { ) } - /// Returns true if notifications should be displayed + /// Returns true if notifications should be displayed. + /// We only use this function in the macOS binary. + #[cfg(target_os = "macos")] pub fn show_notifications(&self) -> Result { Ok(self .ini diff --git a/src/main.rs b/src/main.rs index 8deaa0cc05..735912283e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,11 @@ //! exported function is `main` which is directly invoked from the //! compiled binary that links against this library. -pub mod api; -pub mod commands; -pub mod config; -pub mod constants; -pub mod utils; +mod api; +mod commands; +mod config; +mod constants; +mod utils; /// Executes the command line application and exits the process. pub fn main() { diff --git a/src/utils/codepush.rs b/src/utils/codepush.rs deleted file mode 100644 index 1a5671d5d4..0000000000 --- a/src/utils/codepush.rs +++ /dev/null @@ -1,140 +0,0 @@ -use std::env; -use std::io; -use std::path::Path; -use std::process; -use std::str; - -use anyhow::{bail, format_err, Error, Result}; -use console::strip_ansi_codes; -use glob::{glob_with, MatchOptions}; -use if_chain::if_chain; -use serde::Deserialize; - -use crate::utils::releases::{get_xcode_release_name, infer_gradle_release_name}; -use crate::utils::xcode::{InfoPlist, XcodeProjectInfo}; - -#[cfg(not(windows))] -static CODEPUSH_BIN_PATH: &str = "code-push"; -#[cfg(not(windows))] -static CODEPUSH_NPM_PATH: &str = "node_modules/.bin/code-push"; - -#[cfg(windows)] -static CODEPUSH_BIN_PATH: &str = "code-push.cmd"; -#[cfg(windows)] -static CODEPUSH_NPM_PATH: &str = "node_modules/.bin/code-push.cmd"; - -#[derive(Debug, Deserialize)] -pub struct CodePushPackage { - pub label: String, -} - -#[derive(Debug, Deserialize)] -pub struct CodePushDeployment { - pub name: String, - pub package: Option, -} - -fn get_codepush_error(output: &process::Output) -> Error { - if let Ok(message) = str::from_utf8(&output.stderr) { - let stripped = strip_ansi_codes(message); - format_err!(if let Some(rest) = stripped.strip_prefix("[Error] ") { - rest - } else if let Some(rest) = stripped.strip_prefix("[Error] ") { - rest - } else { - &stripped - } - .to_string(),) - } else { - format_err!("Unknown Error") - } -} - -pub fn get_codepush_deployments(app: &str) -> Result> { - let codepush_bin = if Path::new(CODEPUSH_NPM_PATH).exists() { - CODEPUSH_NPM_PATH - } else { - CODEPUSH_BIN_PATH - }; - - let output = process::Command::new(codepush_bin) - .arg("deployment") - .arg("ls") - .arg(app) - .arg("--format") - .arg("json") - .output() - .map_err(|e| { - if e.kind() == io::ErrorKind::NotFound { - Error::msg("Codepush not found. Is it installed and configured on the PATH?") - } else { - Error::from(e).context("Failed to run codepush") - } - })?; - - if output.status.success() { - Ok(serde_json::from_slice(&output.stdout).unwrap_or_else(|_| { - let format_err = format!("Command `{codepush_bin} deployment ls {app} --format json` failed to produce a valid JSON output."); - panic!("{}", format_err); - })) - } else { - Err(get_codepush_error(&output).context("Failed to get codepush deployments")) - } -} - -pub fn get_codepush_package(app: &str, deployment: &str) -> Result { - let deployments = get_codepush_deployments(app)?; - for dep in deployments { - if_chain! { - if dep.name == deployment; - if let Some(pkg) = dep.package; - then { - return Ok(pkg); - } - } - } - - bail!("Could not find deployment {} for {}", deployment, app) -} - -pub fn get_react_native_codepush_release( - package: &CodePushPackage, - platform: &str, - bundle_id_override: Option<&str>, -) -> Result { - if let Some(bundle_id) = bundle_id_override { - return Ok(format!("{}+codepush:{}", bundle_id, package.label)); - } - - if platform == "ios" { - if !cfg!(target_os = "macos") { - bail!("Codepush releases for iOS require OS X if no bundle ID is specified"); - } - let mut opts = MatchOptions::new(); - opts.case_sensitive = false; - for entry in (glob_with("ios/*.xcodeproj", opts)?).flatten() { - let pi = XcodeProjectInfo::from_path(entry)?; - if let Some(ipl) = InfoPlist::from_project_info(&pi)? { - if let Some(release_name) = get_xcode_release_name(Some(ipl))? { - return Ok(format!("{}+codepush:{}", release_name, package.label)); - } - } - } - bail!("Could not find plist"); - } else if platform == "android" { - if_chain! { - if let Ok(here) = env::current_dir(); - if let Ok(android_folder) = here.join("android").metadata(); - if android_folder.is_dir(); - then { - if let Some(release_name) = infer_gradle_release_name(Some(here.join("android")))? { - return Ok(format!("{}+codepush:{}", release_name, package.label)); - } else { - bail!("Could not parse app id from build.gradle"); - } - } - } - bail!("Could not find AndroidManifest.xml"); - } - bail!("Unsupported platform '{}'", platform); -} diff --git a/src/utils/dif_upload.rs b/src/utils/dif_upload.rs index 950fab3f8c..5bbe99a7e0 100644 --- a/src/utils/dif_upload.rs +++ b/src/utils/dif_upload.rs @@ -1876,17 +1876,6 @@ impl DifUpload { self } - /// Add a `DebugId` to filter for. - /// - /// By default, all DebugIds will be included. - pub fn filter_id(&mut self, id: I) -> &mut Self - where - I: Into, - { - self.ids.insert(id.into()); - self - } - /// Add `DebugId`s to filter for. /// /// By default, all DebugIds will be included. If `ids` is empty, this will @@ -1910,18 +1899,6 @@ impl DifUpload { self } - /// Add `FileFormat`s to filter for. - /// - /// By default, all object formats will be included. If `formats` is empty, this - /// will not be changed. - pub fn filter_formats(&mut self, formats: I) -> &mut Self - where - I: IntoIterator, - { - self.formats.extend(formats); - self - } - /// Add an `ObjectFeature` to filter for. /// /// By default, all object features will be included. @@ -1930,31 +1907,6 @@ impl DifUpload { self } - /// Add a file extension to filter for. - /// - /// By default, all file extensions will be included. - pub fn filter_extension(&mut self, extension: S) -> &mut Self - where - S: Into, - { - self.extensions.insert(extension.into()); - self - } - - /// Add a file extension to filter for. - /// - /// By default, all file extensions will be included. - pub fn filter_extensions(&mut self, extensions: I) -> &mut Self - where - I: IntoIterator, - I::Item: Into, - { - for extension in extensions { - self.extensions.insert(extension.into()); - } - self - } - /// Set a path containing BCSymbolMaps to resolve hidden symbols in dSYMs /// obtained from iTunes Connect. This requires the `dsymutil` command. /// diff --git a/src/utils/enc.rs b/src/utils/enc.rs deleted file mode 100644 index 56c51d9e1b..0000000000 --- a/src/utils/enc.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::borrow::Cow; -use std::str; - -use anyhow::Result; -use chardet::detect; -use encoding::label::encoding_from_whatwg_label; -use encoding::DecoderTrap; -use if_chain::if_chain; - -#[derive(thiserror::Error, Debug)] -#[error("unknown encoding for string")] -pub struct UnknownEncodingError; - -// Decodes bytes from an unknown encoding -pub fn decode_unknown_string(bytes: &[u8]) -> Result> { - if let Ok(s) = str::from_utf8(bytes) { - Ok(Cow::Borrowed(s)) - } else { - let (label, confidence, _) = detect(bytes); - if_chain! { - if confidence >= 0.5; - if let Some(enc) = encoding_from_whatwg_label(&label); - if let Ok(s) = enc.decode(bytes, DecoderTrap::Replace); - then { - Ok(Cow::Owned(s)) - } else { - Err(UnknownEncodingError.into()) - } - } - } -} diff --git a/src/utils/file_search.rs b/src/utils/file_search.rs index 45d52f88d9..9d3d39acec 100644 --- a/src/utils/file_search.rs +++ b/src/utils/file_search.rs @@ -45,14 +45,6 @@ impl ReleaseFileSearch { self } - pub fn extension(&mut self, extension: E) -> &mut Self - where - E: Into, - { - self.extensions.insert(extension.into()); - self - } - pub fn extensions(&mut self, extensions: E) -> &mut Self where E: IntoIterator, @@ -64,14 +56,6 @@ impl ReleaseFileSearch { self } - pub fn ignore(&mut self, ignore: I) -> &mut Self - where - I: Into, - { - self.ignores.insert(ignore.into()); - self - } - pub fn ignores(&mut self, ignores: I) -> &mut Self where I: IntoIterator, diff --git a/src/utils/file_upload.rs b/src/utils/file_upload.rs index a2a22694c0..3b93fd2d03 100644 --- a/src/utils/file_upload.rs +++ b/src/utils/file_upload.rs @@ -144,11 +144,6 @@ impl SourceFile { self.headers.insert("debug-id".to_string(), debug_id); } - /// Returns the value of the "Sourcemap" header. - pub fn sourcemap_reference(&self) -> Option<&String> { - self.headers.get("Sourcemap") - } - /// Sets the value of the "Sourcemap" header. pub fn set_sourcemap_reference(&mut self, sourcemap: String) { self.headers.insert("Sourcemap".to_string(), sourcemap); diff --git a/src/utils/fs.rs b/src/utils/fs.rs index af69a5fcc9..b2cfe06ddd 100644 --- a/src/utils/fs.rs +++ b/src/utils/fs.rs @@ -1,7 +1,7 @@ use std::env; use std::fs; use std::io; -use std::io::{Read, Seek, SeekFrom}; +use std::io::{Read, Seek}; use std::path::{Path, PathBuf}; use anyhow::{bail, Result}; @@ -83,11 +83,6 @@ impl TempFile { pub fn path(&self) -> &Path { &self.path } - - /// Returns the size of the temp file. - pub fn size(&self) -> io::Result { - self.open()?.seek(SeekFrom::End(0)) - } } impl Drop for TempFile { diff --git a/src/utils/mod.rs b/src/utils/mod.rs index dc0d22c281..3f7704d273 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -4,11 +4,9 @@ pub mod appcenter; pub mod args; pub mod auth_token; pub mod chunks; -pub mod codepush; pub mod cordova; pub mod dif; pub mod dif_upload; -pub mod enc; pub mod event; pub mod file_search; pub mod file_upload; diff --git a/src/utils/progress.rs b/src/utils/progress.rs index 797fa8718e..493cc809f7 100644 --- a/src/utils/progress.rs +++ b/src/utils/progress.rs @@ -5,7 +5,7 @@ use std::time::Instant; use crate::utils::logging; -pub use indicatif::{ProgressDrawTarget, ProgressStyle}; +pub use indicatif::ProgressStyle; pub fn is_progress_bar_visible() -> bool { env::var("SENTRY_NO_PROGRESS_BAR") != Ok("1".into()) @@ -37,16 +37,6 @@ impl ProgressBar { indicatif::ProgressBar::hidden().into() } - pub fn finish(&self) { - self.inner.finish(); - logging::set_progress_bar(None); - } - - pub fn finish_with_message(&self, msg: &str) { - self.inner.finish_with_message(msg); - logging::set_progress_bar(None); - } - pub fn finish_with_duration(&self, op: &str) { let dur = self.start.elapsed(); // We could use `dur.as_secs_f64()`, but its unnecessarily precise (micros). Millis are enough for our purpose. diff --git a/src/utils/system.rs b/src/utils/system.rs index 96b0e32649..bc5730a7e3 100644 --- a/src/utils/system.rs +++ b/src/utils/system.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; use std::env; +#[cfg(target_os = "macos")] use std::process; use anyhow::{Error, Result}; @@ -10,7 +11,9 @@ use regex::{Captures, Regex}; use crate::config::Config; -/// Propagate an exit status outwarts +/// Propagate an exit status outwarts. +/// We only use this function in the macOS binary. +#[cfg(target_os = "macos")] pub fn propagate_exit_status(status: process::ExitStatus) { if !status.success() { if let Some(code) = status.code() { diff --git a/src/utils/xcode.rs b/src/utils/xcode.rs index 1eea36f027..cdc5cfab84 100644 --- a/src/utils/xcode.rs +++ b/src/utils/xcode.rs @@ -21,7 +21,9 @@ use { unix_daemonize::{daemonize_redirect, ChdirMode}, }; -use crate::utils::fs::{SeekRead, TempFile}; +use crate::utils::fs::SeekRead; +#[cfg(target_os = "macos")] +use crate::utils::fs::TempFile; use crate::utils::system::expand_vars; #[derive(Deserialize, Debug)] @@ -359,6 +361,7 @@ impl InfoPlist { &self.version } + #[cfg(target_os = "macos")] // only used in macOS binary pub fn build(&self) -> &str { &self.build } @@ -376,6 +379,7 @@ impl InfoPlist { /// the xcode console and continue in the background. This becomes /// a dummy shim for non xcode runs or platforms. pub struct MayDetach<'a> { + #[cfg(target_os = "macos")] // only used in macOS binary output_file: Option, #[allow(dead_code)] task_name: &'a str, @@ -383,13 +387,20 @@ pub struct MayDetach<'a> { impl<'a> MayDetach<'a> { fn new(task_name: &'a str) -> MayDetach<'a> { - MayDetach { - output_file: None, - task_name, + #[cfg(target_os = "macos")] + { + MayDetach { + output_file: None, + task_name, + } } + + #[cfg(not(target_os = "macos"))] + MayDetach { task_name } } - /// Returns true if we are deteached from xcode + /// Returns true if we are deteached from xcode. + #[cfg(target_os = "macos")] pub fn is_detached(&self) -> bool { self.output_file.is_some() } @@ -502,12 +513,6 @@ pub fn launched_from_xcode() -> bool { false } -/// Returns true if we were invoked from xcode -#[cfg(not(target_os = "macos"))] -pub fn launched_from_xcode() -> bool { - false -} - /// Shows a dialog in xcode and blocks. The dialog will have a title and a /// message as well as the buttons "Show details" and "Ignore". Returns /// `true` if the `show details` button has been pressed.