diff --git a/src/commands/debug_files/upload.rs b/src/commands/debug_files/upload.rs index 1d62cf463e..70d325d4d1 100644 --- a/src/commands/debug_files/upload.rs +++ b/src/commands/debug_files/upload.rs @@ -16,7 +16,7 @@ use crate::utils::args::ArgExt; use crate::utils::dif::{DifType, ObjectDifFeatures}; use crate::utils::dif_upload::{DifFormat, DifUpload}; use crate::utils::system::QuietExit; -use crate::utils::xcode::{InfoPlist, MayDetach}; +use crate::utils::xcode::InfoPlist; static DERIVED_DATA_FOLDER: &str = "Library/Developer/Xcode/DerivedData"; @@ -152,15 +152,12 @@ pub fn make_command(command: Command) -> Command { ) .arg( Arg::new("force_foreground") + .hide(true) .long("force-foreground") .action(ArgAction::SetTrue) .help( - "Wait for the process to finish.{n}\ - By default, the upload process will detach and continue in the \ - background when triggered from Xcode. When an error happens, \ - a dialog is shown. If this parameter is passed Xcode will wait \ - for the process to finish before the build finishes and output \ - will be shown in the Xcode build output.", + "DEPRECATED: Foreground uploads are now the default behavior.{n}\ + This flag has no effect and will be removed in a future version.", ), ) .arg( @@ -306,45 +303,38 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { return Ok(()); } - MayDetach::wrap("Debug symbol upload", |handle| { - // Optionally detach if run from Xcode - if !matches.get_flag("force_foreground") { - handle.may_detach()?; - } - - // Execute the upload - let (uploaded, has_processing_errors) = upload.upload()?; - - // Did we miss explicitly requested symbols? - if matches.get_flag("require_all") { - let required_ids: BTreeSet = matches - .get_many::("ids") - .unwrap_or_default() - .cloned() - .collect(); + // Execute the upload + let (uploaded, has_processing_errors) = upload.upload()?; - let found_ids = uploaded.into_iter().map(|dif| dif.id()).collect(); - let missing_ids: Vec<_> = required_ids.difference(&found_ids).collect(); + // Did we miss explicitly requested symbols? + if matches.get_flag("require_all") { + let required_ids: BTreeSet = matches + .get_many::("ids") + .unwrap_or_default() + .cloned() + .collect(); - if !missing_ids.is_empty() { - eprintln!(); - eprintln!("{}", style("Error: Some symbols could not be found!").red()); - eprintln!("The following symbols are still missing:"); - for id in missing_ids { - println!(" {id}"); - } + let found_ids = uploaded.into_iter().map(|dif| dif.id()).collect(); + let missing_ids: Vec<_> = required_ids.difference(&found_ids).collect(); - return Err(QuietExit(1).into()); + if !missing_ids.is_empty() { + eprintln!(); + eprintln!("{}", style("Error: Some symbols could not be found!").red()); + eprintln!("The following symbols are still missing:"); + for id in missing_ids { + println!(" {id}"); } - } - // report a non 0 status code if the server encountered issues. - if has_processing_errors { - eprintln!(); - eprintln!("{}", style("Error: some symbols did not process correctly")); return Err(QuietExit(1).into()); } + } + + // report a non 0 status code if the server encountered issues. + if has_processing_errors { + eprintln!(); + eprintln!("{}", style("Error: some symbols did not process correctly")); + return Err(QuietExit(1).into()); + } - Ok(()) - }) + Ok(()) } diff --git a/src/commands/react_native/xcode.rs b/src/commands/react_native/xcode.rs index 118ea1f06f..8545abffff 100644 --- a/src/commands/react_native/xcode.rs +++ b/src/commands/react_native/xcode.rs @@ -22,7 +22,7 @@ use crate::utils::file_upload::UploadContext; use crate::utils::fs::TempFile; use crate::utils::sourcemaps::SourceMapProcessor; use crate::utils::system::propagate_exit_status; -use crate::utils::xcode::{InfoPlist, MayDetach}; +use crate::utils::xcode::InfoPlist; #[derive(Serialize, Deserialize, Default, Debug)] struct SourceMapReport { @@ -207,197 +207,197 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { let hermesc = find_hermesc(); info!("Using hermesc interpreter '{}'", &hermesc); - MayDetach::wrap("React native symbol handling", |md| { - let bundle_path; - let sourcemap_path; - let bundle_url; - let sourcemap_url; - let bundle_file; - let sourcemap_file; - - // If we have a fetch URL we need to fetch them from there now. In that - // case we do indeed fetch it right from the running packager and then - // store it in temporary files for later consumption. - if let Some(url) = fetch_url { - if !matches.get_flag("force_foreground") { - md.may_detach()?; - } - let api = Api::current(); - let url = url.trim_end_matches('/'); - bundle_file = TempFile::create()?; - bundle_path = bundle_file.path().to_path_buf(); - bundle_url = "~/index.ios.bundle".to_string(); - sourcemap_file = TempFile::create()?; - sourcemap_path = sourcemap_file.path().to_path_buf(); - sourcemap_url = "~/index.ios.map".to_string(); - - // wait up to 10 seconds for the server to be up. - if !api.wait_until_available(url, Duration::seconds(10))? { - bail!("Error: react-native packager did not respond in time"); - } - - api.download( - &format!("{url}/index.ios.bundle?platform=ios&dev=true"), - &mut bundle_file.open()?, - )?; - api.download( - &format!("{url}/index.ios.map?platform=ios&dev=true"), - &mut sourcemap_file.open()?, - )?; - - // This is the case where we need to hook into the release process to - // collect sourcemaps when they are generated. - // - // this invokes via an indirection of sentry-cli our wrap_call() below. - // What is happening behind the scenes is that we switch out NODE_BINARY - // for ourselves which is what the react-native build script normally - // invokes. Because we export __SENTRY_RN_WRAP_XCODE_CALL=1, the main - // sentry-cli script will invoke our wrap_call() function below. - // - // That will then attempt to figure out that a react-native bundle is - // happening to the build script, parse out the arguments, add additional - // arguments if needed and then report the parsed arguments to a temporary - // JSON file we load back below. - // - // We do the same for Hermes Compiler to retrieve the bundle file and - // the same for the combine source maps for the final Hermes source map. - // - // With that we we then have all the information we need to invoke the - // upload process. - } else { - let mut command = process::Command::new(&script); - command - .env("NODE_BINARY", env::current_exe()?.to_str().unwrap()) - .env("SENTRY_RN_REAL_NODE_BINARY", &node) - .env( - "SENTRY_RN_SOURCEMAP_REPORT", - report_file.path().to_str().unwrap(), - ) - .env("__SENTRY_RN_WRAP_XCODE_CALL", "1"); - - if is_hermes_enabled(&hermesc) { - command - .env("HERMES_CLI_PATH", env::current_exe()?.to_str().unwrap()) - .env("SENTRY_RN_REAL_HERMES_CLI_PATH", &hermesc); - } - - let rv = command.spawn()?.wait()?; - propagate_exit_status(rv); - - if !matches.get_flag("force_foreground") { - md.may_detach()?; - } - let mut f = fs::File::open(report_file.path())?; - let report: SourceMapReport = serde_json::from_reader(&mut f).unwrap_or_else(|_| { - let format_err = format!( - "File {} doesn't contain a valid JSON data.", - report_file.path().display() - ); - panic!("{}", format_err); - }); - let (Some(packager_bundle_path), Some(packager_sourcemap_path)) = - (report.packager_bundle_path, report.packager_sourcemap_path) - else { - println!("Warning: build produced no packager sourcemaps."); - return Ok(()); - }; - - // If Hermes emitted source map we have to use it - if let (Some(hermes_bundle_path), Some(hermes_sourcemap_path)) = - (report.hermes_bundle_path, report.hermes_sourcemap_path) - { - bundle_path = hermes_bundle_path.clone(); - sourcemap_path = hermes_sourcemap_path.clone(); - println!("Using Hermes bundle and combined source map."); - - // If Hermes emitted only bundle or Hermes was disabled use packager bundle and source map - } else { - bundle_path = packager_bundle_path; - sourcemap_path = packager_sourcemap_path; - println!("Using React Native Packager bundle and source map."); - } - bundle_url = format!("~/{}", bundle_path.file_name().unwrap().to_string_lossy()); - sourcemap_url = format!( - "~/{}", - sourcemap_path.file_name().unwrap().to_string_lossy() - ); + let bundle_path; + let sourcemap_path; + let bundle_url; + let sourcemap_url; + let bundle_file; + let sourcemap_file; + + // If we have a fetch URL we need to fetch them from there now. In that + // case we do indeed fetch it right from the running packager and then + // store it in temporary files for later consumption. + if let Some(url) = fetch_url { + let api = Api::current(); + let url = url.trim_end_matches('/'); + bundle_file = TempFile::create()?; + bundle_path = bundle_file.path().to_path_buf(); + bundle_url = "~/index.ios.bundle".to_string(); + sourcemap_file = TempFile::create()?; + sourcemap_path = sourcemap_file.path().to_path_buf(); + sourcemap_url = "~/index.ios.map".to_string(); + + // wait up to 10 seconds for the server to be up. + if !api.wait_until_available(url, Duration::seconds(10))? { + bail!("Error: react-native packager did not respond in time"); } - // now that we have all the data, we can now process and upload the - // sourcemaps. - println!("Processing react-native sourcemaps for Sentry upload."); - info!(" bundle path: {}", bundle_path.display()); - info!(" sourcemap path: {}", sourcemap_path.display()); - - let mut processor = SourceMapProcessor::new(); - processor.add(&bundle_url, ReleaseFileSearch::collect_file(bundle_path)?)?; - processor.add( - &sourcemap_url, - ReleaseFileSearch::collect_file(sourcemap_path)?, + api.download( + &format!("{url}/index.ios.bundle?platform=ios&dev=true"), + &mut bundle_file.open()?, + )?; + api.download( + &format!("{url}/index.ios.map?platform=ios&dev=true"), + &mut sourcemap_file.open()?, )?; - processor.rewrite(&[base.parent().unwrap().to_str().unwrap()])?; - processor.add_sourcemap_references()?; - processor.add_debug_id_references()?; - let api = Api::current(); - let chunk_upload_options = api.authenticated()?.get_chunk_upload_options(&org)?; + // This is the case where we need to hook into the release process to + // collect sourcemaps when they are generated. + // + // this invokes via an indirection of sentry-cli our wrap_call() below. + // What is happening behind the scenes is that we switch out NODE_BINARY + // for ourselves which is what the react-native build script normally + // invokes. Because we export __SENTRY_RN_WRAP_XCODE_CALL=1, the main + // sentry-cli script will invoke our wrap_call() function below. + // + // That will then attempt to figure out that a react-native bundle is + // happening to the build script, parse out the arguments, add additional + // arguments if needed and then report the parsed arguments to a temporary + // JSON file we load back below. + // + // We do the same for Hermes Compiler to retrieve the bundle file and + // the same for the combine source maps for the final Hermes source map. + // + // With that we we then have all the information we need to invoke the + // upload process. + } else { + let mut command = process::Command::new(&script); + command + .env("NODE_BINARY", env::current_exe()?.to_str().unwrap()) + .env("SENTRY_RN_REAL_NODE_BINARY", &node) + .env( + "SENTRY_RN_SOURCEMAP_REPORT", + report_file.path().to_str().unwrap(), + ) + .env("__SENTRY_RN_WRAP_XCODE_CALL", "1"); + + if is_hermes_enabled(&hermesc) { + command + .env("HERMES_CLI_PATH", env::current_exe()?.to_str().unwrap()) + .env("SENTRY_RN_REAL_HERMES_CLI_PATH", &hermesc); + } - let dist_from_env = env::var("SENTRY_DIST"); - let release_from_env = env::var("SENTRY_RELEASE"); + let rv = command.spawn()?.wait()?; + propagate_exit_status(rv); - let wait_for_secs = matches.get_one::("wait_for").copied(); - let wait = matches.get_flag("wait") || wait_for_secs.is_some(); - let max_wait = wait_for_secs.map_or(DEFAULT_MAX_WAIT, std::time::Duration::from_secs); + let mut f = fs::File::open(report_file.path())?; + let report: SourceMapReport = serde_json::from_reader(&mut f).unwrap_or_else(|_| { + let format_err = format!( + "File {} doesn't contain a valid JSON data.", + report_file.path().display() + ); + panic!("{}", format_err); + }); + let (Some(packager_bundle_path), Some(packager_sourcemap_path)) = + (report.packager_bundle_path, report.packager_sourcemap_path) + else { + println!("Warning: build produced no packager sourcemaps."); + return Ok(()); + }; - if dist_from_env.is_err() - && release_from_env.is_err() - && matches.get_flag("no_auto_release") + // If Hermes emitted source map we have to use it + if let (Some(hermes_bundle_path), Some(hermes_sourcemap_path)) = + (report.hermes_bundle_path, report.hermes_sourcemap_path) { - processor.upload(&UploadContext { - org: &org, - project: Some(&project), - release: None, - dist: None, - note: None, - wait, - max_wait, - dedupe: false, - chunk_upload_options: chunk_upload_options.as_ref(), - })?; + bundle_path = hermes_bundle_path.clone(); + sourcemap_path = hermes_sourcemap_path.clone(); + println!("Using Hermes bundle and combined source map."); + + // If Hermes emitted only bundle or Hermes was disabled use packager bundle and source map } else { - let (dist, release_name) = match (&dist_from_env, &release_from_env) { - (Err(_), Err(_)) => { - // Neither environment variable is present, attempt to parse Info.plist - info!("Parsing Info.plist"); - match InfoPlist::discover_from_env() { - Ok(Some(plist)) => { - // Successfully discovered and parsed Info.plist - let dist_string = plist.build().to_string(); - let release_string = format!( - "{}@{}+{}", - plist.bundle_id(), - plist.version(), - dist_string - ); - info!("Parse result from Info.plist: {:?}", &plist); - (Some(dist_string), Some(release_string)) - } - _ => { - bail!("Info.plist was not found or an parsing error occurred"); - } + bundle_path = packager_bundle_path; + sourcemap_path = packager_sourcemap_path; + println!("Using React Native Packager bundle and source map."); + } + bundle_url = format!("~/{}", bundle_path.file_name().unwrap().to_string_lossy()); + sourcemap_url = format!( + "~/{}", + sourcemap_path.file_name().unwrap().to_string_lossy() + ); + } + + // now that we have all the data, we can now process and upload the + // sourcemaps. + println!("Processing react-native sourcemaps for Sentry upload."); + info!(" bundle path: {}", bundle_path.display()); + info!(" sourcemap path: {}", sourcemap_path.display()); + + let mut processor = SourceMapProcessor::new(); + processor.add(&bundle_url, ReleaseFileSearch::collect_file(bundle_path)?)?; + processor.add( + &sourcemap_url, + ReleaseFileSearch::collect_file(sourcemap_path)?, + )?; + processor.rewrite(&[base.parent().unwrap().to_str().unwrap()])?; + processor.add_sourcemap_references()?; + processor.add_debug_id_references()?; + + let api = Api::current(); + let chunk_upload_options = api.authenticated()?.get_chunk_upload_options(&org)?; + + let dist_from_env = env::var("SENTRY_DIST"); + let release_from_env = env::var("SENTRY_RELEASE"); + + let wait_for_secs = matches.get_one::("wait_for").copied(); + let wait = matches.get_flag("wait") || wait_for_secs.is_some(); + let max_wait = wait_for_secs.map_or(DEFAULT_MAX_WAIT, std::time::Duration::from_secs); + + if dist_from_env.is_err() && release_from_env.is_err() && matches.get_flag("no_auto_release") { + processor.upload(&UploadContext { + org: &org, + project: Some(&project), + release: None, + dist: None, + note: None, + wait, + max_wait, + dedupe: false, + chunk_upload_options: chunk_upload_options.as_ref(), + })?; + } else { + let (dist, release_name) = match (&dist_from_env, &release_from_env) { + (Err(_), Err(_)) => { + // Neither environment variable is present, attempt to parse Info.plist + info!("Parsing Info.plist"); + match InfoPlist::discover_from_env() { + Ok(Some(plist)) => { + // Successfully discovered and parsed Info.plist + let dist_string = plist.build().to_string(); + let release_string = + format!("{}@{}+{}", plist.bundle_id(), plist.version(), dist_string); + info!("Parse result from Info.plist: {:?}", &plist); + (Some(dist_string), Some(release_string)) + } + _ => { + bail!("Info.plist was not found or an parsing error occurred"); } } - // At least one environment variable is present, use the values from the environment - _ => (dist_from_env.ok(), release_from_env.ok()), - }; + } + // At least one environment variable is present, use the values from the environment + _ => (dist_from_env.ok(), release_from_env.ok()), + }; - match matches.get_many::("dist") { - None => { + match matches.get_many::("dist") { + None => { + processor.upload(&UploadContext { + org: &org, + project: Some(&project), + release: release_name.as_deref(), + dist: dist.as_deref(), + note: None, + wait, + max_wait, + dedupe: false, + chunk_upload_options: chunk_upload_options.as_ref(), + })?; + } + Some(dists) => { + for dist in dists { processor.upload(&UploadContext { org: &org, project: Some(&project), release: release_name.as_deref(), - dist: dist.as_deref(), + dist: Some(dist), note: None, wait, max_wait, @@ -405,26 +405,11 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { chunk_upload_options: chunk_upload_options.as_ref(), })?; } - Some(dists) => { - for dist in dists { - processor.upload(&UploadContext { - org: &org, - project: Some(&project), - release: release_name.as_deref(), - dist: Some(dist), - note: None, - wait, - max_wait, - dedupe: false, - chunk_upload_options: chunk_upload_options.as_ref(), - })?; - } - } } } + } - Ok(()) - }) + Ok(()) } pub fn wrap_call() -> Result<()> { diff --git a/src/config.rs b/src/config.rs index 54bf8a5625..1a8be2c11c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -439,17 +439,6 @@ impl Config { ) } - /// 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 - .get_from(Some("ui"), "show_notifications") - .map(|x| x == "true") - .unwrap_or(true)) - } - /// Returns the maximum DIF upload size pub fn get_max_dif_archive_size(&self) -> u64 { let key = "max_upload_size"; diff --git a/src/utils/xcode.rs b/src/utils/xcode.rs index 802a191572..33d303ac56 100644 --- a/src/utils/xcode.rs +++ b/src/utils/xcode.rs @@ -15,15 +15,9 @@ use regex::Regex; use serde::Deserialize; #[cfg(target_os = "macos")] -use { - libc::getpid, - mac_process_info, osascript, - unix_daemonize::{daemonize_redirect, ChdirMode}, -}; +use {libc::getpid, mac_process_info}; use crate::utils::fs::SeekRead; -#[cfg(target_os = "macos")] -use crate::utils::fs::TempFile; use crate::utils::system::expand_vars; #[derive(Deserialize, Debug)] @@ -375,121 +369,6 @@ impl InfoPlist { } } -/// Helper struct that allows the current execution to detach from -/// 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, -} - -impl<'a> MayDetach<'a> { - fn new(task_name: &'a str) -> MayDetach<'a> { - #[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. - #[cfg(target_os = "macos")] - pub fn is_detached(&self) -> bool { - self.output_file.is_some() - } - - /// If we are launched from xcode this detaches us from the xcode console - /// and continues execution in the background. From this moment on output - /// is captured and the user is notified with notifications. - #[cfg(target_os = "macos")] - pub fn may_detach(&mut self) -> Result { - if !launched_from_xcode() { - return Ok(false); - } - - let output_file = TempFile::create()?; - - println!("Continuing in background."); - println!("Output is redirected to {}", output_file.path().display()); - show_notification("Sentry", &format!("{} starting", self.task_name))?; - - daemonize_redirect( - Some(output_file.path()), - Some(output_file.path()), - ChdirMode::NoChdir, - ) - .unwrap(); - self.output_file = Some(output_file); - Ok(true) - } - - /// For non mac platforms this just never detaches. - #[cfg(not(target_os = "macos"))] - pub fn may_detach(&mut self) -> Result { - Ok(false) - } - - /// Wraps the execution of a code block. Does not detach until someone - /// calls into `may_detach`. - #[cfg(target_os = "macos")] - pub fn wrap) -> Result>( - task_name: &'a str, - f: F, - ) -> Result { - use std::time::Duration; - - let mut md = MayDetach::new(task_name); - match f(&mut md) { - Ok(x) => { - md.show_done()?; - Ok(x) - } - Err(err) => { - if let Some(ref output_file) = md.output_file { - crate::utils::system::print_error(&err); - if md.show_critical_info()? { - open::that(output_file.path())?; - std::thread::sleep(Duration::from_millis(5000)); - } - } - Err(err) - } - } - } - - /// Dummy wrap call that never detaches for non mac platforms. - #[cfg(not(target_os = "macos"))] - pub fn wrap Result>(task_name: &'a str, f: F) -> Result { - f(&mut MayDetach::new(task_name)) - } - - #[cfg(target_os = "macos")] - fn show_critical_info(&self) -> Result { - show_critical_info( - &format!("{} failed", self.task_name), - "The Sentry build step failed while running in the background. \ - You can ignore this error or view details to attempt to resolve \ - it. Ignoring it might cause your crashes not to be handled \ - properly.", - ) - } - - #[cfg(target_os = "macos")] - fn show_done(&self) -> Result<()> { - if self.is_detached() { - show_notification("Sentry", &format!("{} finished", self.task_name))?; - } - Ok(()) - } -} - /// Returns true if we were invoked from xcode #[cfg(target_os = "macos")] pub fn launched_from_xcode() -> bool { @@ -513,82 +392,6 @@ 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. -#[cfg(target_os = "macos")] -pub fn show_critical_info(title: &str, message: &str) -> Result { - use serde::Serialize; - - lazy_static! { - static ref SCRIPT: osascript::JavaScript = osascript::JavaScript::new( - " - var App = Application('XCode'); - App.includeStandardAdditions = true; - return App.displayAlert($params.title, { - message: $params.message, - as: \"critical\", - buttons: [\"Show details\", \"Ignore\"] - }); - " - ); - } - - #[derive(Serialize)] - struct AlertParams<'a> { - title: &'a str, - message: &'a str, - } - - #[derive(Debug, Deserialize)] - struct AlertResult { - #[serde(rename = "buttonReturned")] - button: String, - } - - let rv: AlertResult = SCRIPT - .execute_with_params(AlertParams { title, message }) - .context("Failed to display Xcode dialog")?; - - Ok(&rv.button != "Ignore") -} - -/// Shows a notification in xcode -#[cfg(target_os = "macos")] -pub fn show_notification(title: &str, message: &str) -> Result<()> { - use crate::config::Config; - use serde::Serialize; - - lazy_static! { - static ref SCRIPT: osascript::JavaScript = osascript::JavaScript::new( - " - var App = Application.currentApplication(); - App.includeStandardAdditions = true; - App.displayNotification($params.message, { - withTitle: $params.title - }); - " - ); - } - - let config = Config::current(); - if !config.show_notifications()? { - return Ok(()); - } - - #[derive(Serialize)] - struct NotificationParams<'a> { - title: &'a str, - message: &'a str, - } - - SCRIPT - .execute_with_params::<_, ()>(NotificationParams { title, message }) - .context("Failed to display Xcode notification")?; - - Ok(()) -} - #[test] fn test_expansion() { let mut vars = HashMap::new(); diff --git a/tests/integration/_cases/debug_files/debug_files-upload-help.trycmd b/tests/integration/_cases/debug_files/debug_files-upload-help.trycmd index b7f7fe405e..03cde26869 100644 --- a/tests/integration/_cases/debug_files/debug_files-upload-help.trycmd +++ b/tests/integration/_cases/debug_files/debug_files-upload-help.trycmd @@ -52,12 +52,6 @@ Options: This runs all steps for the processing but does not trigger the upload. This is useful if you just want to verify the setup or skip the upload in tests. - --force-foreground Wait for the process to finish. - By default, the upload process will detach and continue in the - background when triggered from Xcode. When an error happens, a - dialog is shown. If this parameter is passed Xcode will wait for - the process to finish before the build finishes and output will be - shown in the Xcode build output. --include-sources Include sources from the local file system and upload them as source bundles. --wait Wait for the server to fully process uploaded files. Errors can diff --git a/tests/integration/_cases/upload_dif/upload_dif-help.trycmd b/tests/integration/_cases/upload_dif/upload_dif-help.trycmd index 2775f2ae28..be378c8e03 100644 --- a/tests/integration/_cases/upload_dif/upload_dif-help.trycmd +++ b/tests/integration/_cases/upload_dif/upload_dif-help.trycmd @@ -52,12 +52,6 @@ Options: This runs all steps for the processing but does not trigger the upload. This is useful if you just want to verify the setup or skip the upload in tests. - --force-foreground Wait for the process to finish. - By default, the upload process will detach and continue in the - background when triggered from Xcode. When an error happens, a - dialog is shown. If this parameter is passed Xcode will wait for - the process to finish before the build finishes and output will be - shown in the Xcode build output. --include-sources Include sources from the local file system and upload them as source bundles. --wait Wait for the server to fully process uploaded files. Errors can diff --git a/tests/integration/_cases/upload_dsym/upload_dsym-help.trycmd b/tests/integration/_cases/upload_dsym/upload_dsym-help.trycmd index fc07d840c5..53045a3197 100644 --- a/tests/integration/_cases/upload_dsym/upload_dsym-help.trycmd +++ b/tests/integration/_cases/upload_dsym/upload_dsym-help.trycmd @@ -52,12 +52,6 @@ Options: This runs all steps for the processing but does not trigger the upload. This is useful if you just want to verify the setup or skip the upload in tests. - --force-foreground Wait for the process to finish. - By default, the upload process will detach and continue in the - background when triggered from Xcode. When an error happens, a - dialog is shown. If this parameter is passed Xcode will wait for - the process to finish before the build finishes and output will be - shown in the Xcode build output. --include-sources Include sources from the local file system and upload them as source bundles. --wait Wait for the server to fully process uploaded files. Errors can