diff --git a/src/commands/react_native/xcode.rs b/src/commands/react_native/xcode.rs index db96a26726..2cd8322093 100644 --- a/src/commands/react_native/xcode.rs +++ b/src/commands/react_native/xcode.rs @@ -324,8 +324,14 @@ pub fn wrap_call() -> Result<()> { let mut args: Vec<_> = env::args().skip(1).collect(); let mut bundle_path = None; let mut sourcemap_path = None; + let bundle_command = env::var("SENTRY_RN_BUNDLE_COMMAND"); - if args.len() > 1 && (args[1] == "bundle" || args[1] == "ram-bundle") { + // bundle and ram-bundle are React Native CLI commands + // export:embed is an Expo CLI command (drop in replacement for bundle) + // if bundle_command is set, ignore the default values + if args.len() > 1 + && ((bundle_command.is_err() && (args[1] == "bundle" || args[1] == "ram-bundle" || args[1] == "export:embed")) + || (bundle_command.is_ok() && args[1] == bundle_command.unwrap())) { let mut iter = args.iter().fuse(); while let Some(item) = iter.next() { if item == "--sourcemap-output" { diff --git a/tests/integration/_cases/react_native/xcode-wrap-call-bundle.trycmd b/tests/integration/_cases/react_native/xcode-wrap-call-bundle.trycmd new file mode 100644 index 0000000000..edb81e5712 --- /dev/null +++ b/tests/integration/_cases/react_native/xcode-wrap-call-bundle.trycmd @@ -0,0 +1,6 @@ +``` +$ __SENTRY_RN_WRAP_XCODE_CALL=1 SENTRY_RN_REAL_NODE_BINARY=tests/integration/_fixtures/binary.sh SENTRY_RN_SOURCEMAP_REPORT=rn-sourcemap-report-bundle.json sentry-cli rn-cli.js bundle --sourcemap-output source.map.path --bundle-output source.path +? success +Binary executed with args: rn-cli.js bundle --sourcemap-output source.map.path --bundle-output source.path + +``` diff --git a/tests/integration/_cases/react_native/xcode-wrap-call-custom-bundle.trycmd b/tests/integration/_cases/react_native/xcode-wrap-call-custom-bundle.trycmd new file mode 100644 index 0000000000..bc815dd47c --- /dev/null +++ b/tests/integration/_cases/react_native/xcode-wrap-call-custom-bundle.trycmd @@ -0,0 +1,6 @@ +``` +$ __SENTRY_RN_WRAP_XCODE_CALL=1 SENTRY_RN_REAL_NODE_BINARY=tests/integration/_fixtures/binary.sh SENTRY_RN_SOURCEMAP_REPORT=rn-sourcemap-report-custom-bundle.json SENTRY_RN_BUNDLE_COMMAND=custom sentry-cli rn-cli.js custom --sourcemap-output source.map.path --bundle-output source.path +? success +Binary executed with args: rn-cli.js custom --sourcemap-output source.map.path --bundle-output source.path + +``` diff --git a/tests/integration/_cases/react_native/xcode-wrap-call-expo-export.trycmd b/tests/integration/_cases/react_native/xcode-wrap-call-expo-export.trycmd new file mode 100644 index 0000000000..ac5489bcfe --- /dev/null +++ b/tests/integration/_cases/react_native/xcode-wrap-call-expo-export.trycmd @@ -0,0 +1,6 @@ +``` +$ __SENTRY_RN_WRAP_XCODE_CALL=1 SENTRY_RN_REAL_NODE_BINARY=tests/integration/_fixtures/binary.sh SENTRY_RN_SOURCEMAP_REPORT=rn-sourcemap-report-expo-export.json sentry-cli expo-cli.js export:embed --sourcemap-output source.map.path --bundle-output source.path +? success +Binary executed with args: expo-cli.js export:embed --sourcemap-output source.map.path --bundle-output source.path + +``` diff --git a/tests/integration/_cases/react_native/xcode-wrap-call-minimum.trycmd b/tests/integration/_cases/react_native/xcode-wrap-call-minimum.trycmd new file mode 100644 index 0000000000..bbedf462b5 --- /dev/null +++ b/tests/integration/_cases/react_native/xcode-wrap-call-minimum.trycmd @@ -0,0 +1,6 @@ +``` +$ __SENTRY_RN_WRAP_XCODE_CALL=1 SENTRY_RN_REAL_NODE_BINARY=tests/integration/_fixtures/binary.sh SENTRY_RN_SOURCEMAP_REPORT=rn-sourcemap-report-minimum.json sentry-cli first second +? success +Binary executed with args: first second + +``` diff --git a/tests/integration/_fixtures/binary.sh b/tests/integration/_fixtures/binary.sh new file mode 100755 index 0000000000..89a2ba5f4f --- /dev/null +++ b/tests/integration/_fixtures/binary.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Binary executed with args: $@" diff --git a/tests/integration/_fixtures/react_native/empty-sourcemap-report.json.expected b/tests/integration/_fixtures/react_native/empty-sourcemap-report.json.expected new file mode 100644 index 0000000000..6206949459 --- /dev/null +++ b/tests/integration/_fixtures/react_native/empty-sourcemap-report.json.expected @@ -0,0 +1 @@ +{"bundle_path":null,"sourcemap_path":null} \ No newline at end of file diff --git a/tests/integration/_fixtures/react_native/full-sourcemap-report.json.expected b/tests/integration/_fixtures/react_native/full-sourcemap-report.json.expected new file mode 100644 index 0000000000..479fb5af84 --- /dev/null +++ b/tests/integration/_fixtures/react_native/full-sourcemap-report.json.expected @@ -0,0 +1 @@ +{"bundle_path":"source.path","sourcemap_path":"source.map.path"} \ No newline at end of file diff --git a/tests/integration/mod.rs b/tests/integration/mod.rs index 9eaa5c2386..d3a4196532 100644 --- a/tests/integration/mod.rs +++ b/tests/integration/mod.rs @@ -10,6 +10,7 @@ mod monitors; mod org_tokens; mod organizations; mod projects; +mod react_native; mod releases; mod send_envelope; mod send_event; diff --git a/tests/integration/react_native/mod.rs b/tests/integration/react_native/mod.rs new file mode 100644 index 0000000000..bc5650e1d9 --- /dev/null +++ b/tests/integration/react_native/mod.rs @@ -0,0 +1,61 @@ +#[cfg(target_os = "macos")] +use crate::integration::register_test; + +#[test] +#[cfg(target_os = "macos")] +fn xcode_wrap_call_minimum() { + register_test("react_native/xcode-wrap-call-minimum.trycmd"); + assert_empty_sourcemap_report("rn-sourcemap-report-minimum.json"); + clean_up("rn-sourcemap-report-minimum.json"); +} + +#[test] +#[cfg(target_os = "macos")] +fn xcode_wrap_call_bundle() { + register_test("react_native/xcode-wrap-call-bundle.trycmd"); + assert_full_sourcemap_report("rn-sourcemap-report-bundle.json"); + clean_up("rn-sourcemap-report-bundle.json"); +} + +#[test] +#[cfg(target_os = "macos")] +fn xcode_wrap_call_custom_bundle() { + register_test("react_native/xcode-wrap-call-custom-bundle.trycmd"); + assert_full_sourcemap_report("rn-sourcemap-report-custom-bundle.json"); + clean_up("rn-sourcemap-report-custom-bundle.json"); +} + +#[test] +#[cfg(target_os = "macos")] +fn xcode_wrap_call_expo_export() { + register_test("react_native/xcode-wrap-call-expo-export.trycmd"); + assert_full_sourcemap_report("rn-sourcemap-report-expo-export.json"); + clean_up("rn-sourcemap-report-expo-export.json"); +} + +#[cfg(target_os = "macos")] +fn clean_up(path: &str) { + std::fs::remove_file(path).unwrap(); +} + +#[cfg(target_os = "macos")] +fn assert_full_sourcemap_report(actual: &str) { + let actual_code = std::fs::read_to_string(actual).unwrap(); + let expected_code = std::fs::read_to_string( + "tests/integration/_fixtures/react_native/full-sourcemap-report.json.expected", + ) + .unwrap(); + + assert_eq!(actual_code, expected_code); +} + +#[cfg(target_os = "macos")] +fn assert_empty_sourcemap_report(actual: &str) { + let actual_code = std::fs::read_to_string(actual).unwrap(); + let expected_code = std::fs::read_to_string( + "tests/integration/_fixtures/react_native/empty-sourcemap-report.json.expected", + ) + .unwrap(); + + assert_eq!(actual_code, expected_code); +}