sentry-cli 2.45.0__tar.gz → 2.46.0a0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/Cargo.lock +1 -1
  2. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/Cargo.toml +1 -1
  3. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/PKG-INFO +1 -1
  4. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/sentry_cli.egg-info/PKG-INFO +1 -1
  5. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/errors/api_error.rs +0 -2
  6. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/mod.rs +11 -67
  7. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/debug_files/bundle_sources.rs +8 -3
  8. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/files/delete.rs +2 -1
  9. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/files/list.rs +2 -1
  10. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/files/mod.rs +6 -1
  11. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/files/upload.rs +2 -1
  12. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/react_native/gradle.rs +6 -6
  13. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/finalize.rs +9 -2
  14. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/sourcemaps/explain.rs +2 -1
  15. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/sourcemaps/upload.rs +8 -6
  16. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/config.rs +56 -8
  17. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/file_upload.rs +73 -0
  18. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/sourcemaps.rs +45 -138
  19. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/system.rs +24 -17
  20. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/LICENSE +0 -0
  21. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/MANIFEST.in +0 -0
  22. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/README.md +0 -0
  23. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/build.rs +0 -0
  24. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/pyproject.toml +0 -0
  25. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/sentry_cli.egg-info/SOURCES.txt +0 -0
  26. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/sentry_cli.egg-info/dependency_links.txt +0 -0
  27. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/sentry_cli.egg-info/top_level.txt +0 -0
  28. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/setup.cfg +0 -0
  29. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/setup.py +0 -0
  30. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/connection_manager.rs +0 -0
  31. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/artifact.rs +0 -0
  32. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/compression.rs +0 -0
  33. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/dif.rs +0 -0
  34. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/file_state.rs +0 -0
  35. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
  36. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/mod.rs +0 -0
  37. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/upload/capability.rs +0 -0
  38. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/upload/mod.rs +0 -0
  39. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/chunking/upload/options.rs +0 -0
  40. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/deploy.rs +0 -0
  41. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/data_types/mod.rs +0 -0
  42. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/encoding.rs +0 -0
  43. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/envelopes_api.rs +0 -0
  44. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/errors/mod.rs +0 -0
  45. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/errors/sentry_error.rs +0 -0
  46. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/api/pagination.rs +0 -0
  47. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/bashsupport.sh +0 -0
  48. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/bash_hook.rs +0 -0
  49. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/debug_files/bundle_jvm.rs +0 -0
  50. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/debug_files/check.rs +0 -0
  51. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/debug_files/find.rs +0 -0
  52. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/debug_files/mod.rs +0 -0
  53. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/debug_files/print_sources.rs +0 -0
  54. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/debug_files/upload.rs +0 -0
  55. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/deploys/list.rs +0 -0
  56. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/deploys/mod.rs +0 -0
  57. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/deploys/new.rs +0 -0
  58. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/derive_parser.rs +0 -0
  59. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/events/list.rs +0 -0
  60. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/events/mod.rs +0 -0
  61. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/info.rs +0 -0
  62. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/issues/list.rs +0 -0
  63. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/issues/mod.rs +0 -0
  64. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/issues/mute.rs +0 -0
  65. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/issues/resolve.rs +0 -0
  66. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/issues/unresolve.rs +0 -0
  67. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/login.rs +0 -0
  68. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/mod.rs +0 -0
  69. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/monitors/list.rs +0 -0
  70. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/monitors/mod.rs +0 -0
  71. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/monitors/run.rs +0 -0
  72. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/organizations/list.rs +0 -0
  73. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/organizations/mod.rs +0 -0
  74. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/projects/list.rs +0 -0
  75. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/projects/mod.rs +0 -0
  76. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/react_native/appcenter.rs +0 -0
  77. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/react_native/mod.rs +0 -0
  78. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/react_native/xcode.rs +0 -0
  79. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/archive.rs +0 -0
  80. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/delete.rs +0 -0
  81. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/info.rs +0 -0
  82. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/list.rs +0 -0
  83. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/mod.rs +0 -0
  84. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/new.rs +0 -0
  85. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/propose_version.rs +0 -0
  86. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/restore.rs +0 -0
  87. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/releases/set_commits.rs +0 -0
  88. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/repos/list.rs +0 -0
  89. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/repos/mod.rs +0 -0
  90. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/send_envelope.rs +0 -0
  91. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/send_event.rs +0 -0
  92. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/send_metric/common_args.rs +0 -0
  93. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/send_metric/distribution.rs +0 -0
  94. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/send_metric/gauge.rs +0 -0
  95. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/send_metric/increment.rs +0 -0
  96. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/send_metric/mod.rs +0 -0
  97. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/send_metric/set.rs +0 -0
  98. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/sourcemaps/inject.rs +0 -0
  99. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/sourcemaps/mod.rs +0 -0
  100. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/sourcemaps/resolve.rs +0 -0
  101. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/uninstall.rs +0 -0
  102. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/update.rs +0 -0
  103. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/upload_dif.rs +0 -0
  104. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/upload_dsym.rs +0 -0
  105. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/commands/upload_proguard.rs +0 -0
  106. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/constants.rs +0 -0
  107. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/main.rs +0 -0
  108. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/android.rs +0 -0
  109. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/appcenter.rs +0 -0
  110. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/args.rs +0 -0
  111. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/auth_token/auth_token_impl.rs +0 -0
  112. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/auth_token/error.rs +0 -0
  113. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/auth_token/mod.rs +0 -0
  114. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/auth_token/org_auth_token.rs +0 -0
  115. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/auth_token/redacting.rs +0 -0
  116. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/auth_token/test.rs +0 -0
  117. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/auth_token/user_auth_token.rs +0 -0
  118. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/chunks/mod.rs +0 -0
  119. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/chunks/options.rs +0 -0
  120. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/chunks/types.rs +0 -0
  121. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/chunks/upload.rs +0 -0
  122. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/cordova.rs +0 -0
  123. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/dif.rs +0 -0
  124. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/dif_upload/error.rs +0 -0
  125. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/dif_upload/mod.rs +0 -0
  126. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/event.rs +0 -0
  127. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/file_search.rs +0 -0
  128. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/formatting.rs +0 -0
  129. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/fs.rs +0 -0
  130. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/http.rs +0 -0
  131. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/logging.rs +0 -0
  132. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/metrics.rs +0 -0
  133. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/mod.rs +0 -0
  134. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/progress.rs +0 -0
  135. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/proguard/mapping.rs +0 -0
  136. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/proguard/mod.rs +0 -0
  137. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/proguard/upload.rs +0 -0
  138. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/releases.rs +0 -0
  139. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/retry.rs +0 -0
  140. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/snapshots/sentry_cli__utils__vcs__generate_patch_default_twenty.snap +0 -0
  141. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/snapshots/sentry_cli__utils__vcs__generate_patch_ignore_missing.snap +0 -0
  142. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/snapshots/sentry_cli__utils__vcs__generate_patch_set_base.snap +0 -0
  143. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/snapshots/sentry_cli__utils__vcs__generate_patch_set_previous_commit.snap +0 -0
  144. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/snapshots/sentry_cli__utils__vcs__get_commits_from_git.snap +0 -0
  145. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/sourcemaps/inject.rs +0 -0
  146. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/ui.rs +0 -0
  147. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/update.rs +0 -0
  148. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/value_parsers.rs +0 -0
  149. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/vcs.rs +0 -0
  150. {sentry_cli-2.45.0 → sentry_cli-2.46.0a0}/src/utils/xcode.rs +0 -0
@@ -2685,7 +2685,7 @@ dependencies = [
2685
2685
 
2686
2686
  [[package]]
2687
2687
  name = "sentry-cli"
2688
- version = "2.45.0"
2688
+ version = "2.46.0-alpha"
2689
2689
  dependencies = [
2690
2690
  "anyhow",
2691
2691
  "anylog",
@@ -2,7 +2,7 @@
2
2
  authors = ["Armin Ronacher <armin.ronacher@active-4.com>"]
3
3
  build = "build.rs"
4
4
  name = "sentry-cli"
5
- version = "2.45.0"
5
+ version = "2.46.0-alpha"
6
6
  edition = "2021"
7
7
  rust-version = "1.80"
8
8
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 2.45.0
3
+ Version: 2.46.0a0
4
4
  Summary: A command line utility to work with Sentry.
5
5
  Home-page: https://github.com/getsentry/sentry-cli
6
6
  Author: Sentry
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 2.45.0
3
+ Version: 2.46.0a0
4
4
  Summary: A command line utility to work with Sentry.
5
5
  Home-page: https://github.com/getsentry/sentry-cli
6
6
  Author: Sentry
@@ -44,8 +44,6 @@ pub(in crate::api) enum ApiErrorKind {
44
44
  "DSN missing. Please set the `SENTRY_DSN` environment variable to your project's DSN."
45
45
  )]
46
46
  DsnMissing,
47
- #[error("Error preparing request")]
48
- ErrorPreparingRequest,
49
47
  }
50
48
 
51
49
  impl fmt::Display for ApiError {
@@ -65,6 +65,13 @@ lazy_static! {
65
65
  static ref API: Mutex<Option<Arc<Api>>> = Mutex::new(None);
66
66
  }
67
67
 
68
+ const RETRY_STATUS_CODES: &[u32] = &[
69
+ http::HTTP_STATUS_502_BAD_GATEWAY,
70
+ http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
71
+ http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
72
+ http::HTTP_STATUS_507_INSUFFICIENT_STORAGE,
73
+ ];
74
+
68
75
  /// Helper for the API access.
69
76
  /// Implements the low-level API access methods, and provides high-level implementations for interacting
70
77
  /// with portions of the API that do not require authentication via an auth token.
@@ -113,8 +120,6 @@ pub struct ApiRequest {
113
120
  is_authenticated: bool,
114
121
  body: Option<Vec<u8>>,
115
122
  progress_bar_mode: ProgressBarMode,
116
- max_retries: u32,
117
- retry_on_statuses: &'static [u32],
118
123
  }
119
124
 
120
125
  /// Represents an API response.
@@ -395,14 +400,6 @@ impl Api {
395
400
  let request = self
396
401
  .request(Method::Post, url, None)?
397
402
  .with_form_data(form)?
398
- .with_retry(
399
- self.config.get_max_retry_count().unwrap(),
400
- &[
401
- http::HTTP_STATUS_502_BAD_GATEWAY,
402
- http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
403
- http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
404
- ],
405
- )
406
403
  .progress_bar_mode(progress_bar_mode);
407
404
 
408
405
  // The request is performed to an absolute URL. Thus, `Self::request()` will
@@ -967,14 +964,6 @@ impl<'a> AuthenticatedApi<'a> {
967
964
 
968
965
  self.request(Method::Post, &url)?
969
966
  .with_json_body(request)?
970
- .with_retry(
971
- self.api.config.get_max_retry_count().unwrap(),
972
- &[
973
- http::HTTP_STATUS_502_BAD_GATEWAY,
974
- http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
975
- http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
976
- ],
977
- )
978
967
  .send()?
979
968
  .convert_rnf(ApiErrorKind::ProjectNotFound)
980
969
  }
@@ -1000,14 +989,6 @@ impl<'a> AuthenticatedApi<'a> {
1000
989
  version: None,
1001
990
  dist: None,
1002
991
  })?
1003
- .with_retry(
1004
- self.api.config.get_max_retry_count().unwrap(),
1005
- &[
1006
- http::HTTP_STATUS_502_BAD_GATEWAY,
1007
- http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
1008
- http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
1009
- ],
1010
- )
1011
992
  .send()?
1012
993
  .convert_rnf(ApiErrorKind::ReleaseNotFound)
1013
994
  }
@@ -1031,14 +1012,6 @@ impl<'a> AuthenticatedApi<'a> {
1031
1012
  version,
1032
1013
  dist,
1033
1014
  })?
1034
- .with_retry(
1035
- self.api.config.get_max_retry_count().unwrap(),
1036
- &[
1037
- http::HTTP_STATUS_502_BAD_GATEWAY,
1038
- http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
1039
- http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
1040
- ],
1041
- )
1042
1015
  .send()?
1043
1016
  .convert_rnf(ApiErrorKind::ReleaseNotFound)
1044
1017
  }
@@ -1407,15 +1380,6 @@ impl RegionSpecificApi<'_> {
1407
1380
  form.part("file").file(file).add()?;
1408
1381
  self.request(Method::Post, &path)?
1409
1382
  .with_form_data(form)?
1410
- .with_retry(
1411
- self.api.api.config.get_max_retry_count().map_err(|e| {
1412
- ApiError::with_source(
1413
- ApiErrorKind::ErrorPreparingRequest,
1414
- e.context("Could not parse retry count"),
1415
- )
1416
- })?,
1417
- &[http::HTTP_STATUS_507_INSUFFICIENT_STORAGE],
1418
- )
1419
1383
  .progress_bar_mode(ProgressBarMode::Request)
1420
1384
  .send()?
1421
1385
  .convert()
@@ -1471,14 +1435,6 @@ impl RegionSpecificApi<'_> {
1471
1435
  let resp = self
1472
1436
  .request(Method::Post, &path)?
1473
1437
  .with_form_data(form)?
1474
- .with_retry(
1475
- self.api.api.config.get_max_retry_count().unwrap(),
1476
- &[
1477
- http::HTTP_STATUS_502_BAD_GATEWAY,
1478
- http::HTTP_STATUS_503_SERVICE_UNAVAILABLE,
1479
- http::HTTP_STATUS_504_GATEWAY_TIMEOUT,
1480
- ],
1481
- )
1482
1438
  .progress_bar_mode(progress_bar_mode)
1483
1439
  .send()?;
1484
1440
  if resp.status() == 409 {
@@ -1666,8 +1622,6 @@ impl ApiRequest {
1666
1622
  is_authenticated: false,
1667
1623
  body: None,
1668
1624
  progress_bar_mode: ProgressBarMode::Disabled,
1669
- max_retries: 0,
1670
- retry_on_statuses: &[],
1671
1625
  };
1672
1626
 
1673
1627
  let request = match auth {
@@ -1741,13 +1695,6 @@ impl ApiRequest {
1741
1695
  self
1742
1696
  }
1743
1697
 
1744
- pub fn with_retry(mut self, max_retries: u32, retry_on_statuses: &'static [u32]) -> Self {
1745
- self.max_retries = max_retries;
1746
- self.retry_on_statuses = retry_on_statuses;
1747
-
1748
- self
1749
- }
1750
-
1751
1698
  /// Get a copy of the header list
1752
1699
  fn get_headers(&self) -> curl::easy::List {
1753
1700
  let mut result = curl::easy::List::new();
@@ -1776,18 +1723,17 @@ impl ApiRequest {
1776
1723
 
1777
1724
  /// Sends the request and reads the response body into the response object.
1778
1725
  pub fn send(mut self) -> ApiResult<ApiResponse> {
1726
+ let max_retries = Config::current().max_retries();
1727
+
1779
1728
  let mut backoff = get_default_backoff();
1780
1729
  let mut retry_number = 0;
1781
1730
 
1782
1731
  loop {
1783
1732
  let mut out = vec![];
1784
- debug!(
1785
- "retry number {}, max retries: {}",
1786
- retry_number, self.max_retries,
1787
- );
1733
+ debug!("retry number {retry_number}, max retries: {max_retries}",);
1788
1734
 
1789
1735
  let mut rv = self.send_into(&mut out)?;
1790
- if retry_number >= self.max_retries || !self.retry_on_statuses.contains(&rv.status) {
1736
+ if retry_number >= max_retries || !RETRY_STATUS_CODES.contains(&rv.status) {
1791
1737
  rv.body = Some(out);
1792
1738
  return Ok(rv);
1793
1739
  }
@@ -2054,8 +2000,6 @@ pub struct UpdatedRelease {
2054
2000
  pub projects: Option<Vec<String>>,
2055
2001
  #[serde(skip_serializing_if = "Option::is_none")]
2056
2002
  pub url: Option<String>,
2057
- #[serde(rename = "dateStarted", skip_serializing_if = "Option::is_none")]
2058
- pub date_started: Option<DateTime<Utc>>,
2059
2003
  #[serde(rename = "dateReleased", skip_serializing_if = "Option::is_none")]
2060
2004
  pub date_released: Option<DateTime<Utc>>,
2061
2005
  #[serde(skip_serializing_if = "Option::is_none")]
@@ -71,12 +71,13 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
71
71
  let output_path = matches.get_one::<String>("output").map(Path::new);
72
72
 
73
73
  for orig_path in matches.get_many::<String>("paths").unwrap() {
74
+ let orig_path: &Path = orig_path.as_ref();
74
75
  let canonical_path = get_canonical_path(orig_path)?;
75
76
 
76
77
  let archive = match DifFile::open_path(&canonical_path, None)? {
77
78
  DifFile::Archive(archive) => archive,
78
79
  _ => {
79
- warn!("Cannot build source bundles from {}", orig_path);
80
+ warn!("Cannot build source bundles from {}", orig_path.display());
80
81
  continue;
81
82
  }
82
83
  };
@@ -88,7 +89,11 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
88
89
  for (index, object) in archive.get().objects().enumerate() {
89
90
  let object = object?;
90
91
 
91
- let mut out = output_path.unwrap_or(parent_path).join(filename);
92
+ let mut out = output_path.unwrap_or(parent_path).join(
93
+ orig_path
94
+ .file_name()
95
+ .expect("orig_path should have a file name"),
96
+ );
92
97
  match index {
93
98
  0 => out.set_extension("src.zip"),
94
99
  index => out.set_extension(format!("{index}.src.zip")),
@@ -109,7 +114,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
109
114
  )?;
110
115
 
111
116
  if !written {
112
- eprintln!("skipped {orig_path} (no files found)");
117
+ eprintln!("skipped {} (no files found)", orig_path.display());
113
118
  fs::remove_file(&out)?;
114
119
  continue;
115
120
  } else {
@@ -8,7 +8,8 @@ use crate::config::Config;
8
8
 
9
9
  pub fn make_command(command: Command) -> Command {
10
10
  command
11
- .about("Delete a release file.")
11
+ .about("[DEPRECATED] Delete a release file.")
12
+ .hide(true)
12
13
  // Backward compatibility with `releases files <VERSION>` commands.
13
14
  .arg(Arg::new("version").long("version").hide(true))
14
15
  .arg(
@@ -6,7 +6,8 @@ use crate::{api::Api, config::Config, utils::formatting::Table};
6
6
 
7
7
  pub fn make_command(command: Command) -> Command {
8
8
  command
9
- .about("List all release files.")
9
+ .about("[DEPRECATED] List all release files.")
10
+ .hide(true)
10
11
  // Backward compatibility with `releases files <VERSION>` commands.
11
12
  .arg(Arg::new("version").long("version").hide(true))
12
13
  }
@@ -1,5 +1,6 @@
1
1
  use anyhow::Result;
2
2
  use clap::{ArgMatches, Command};
3
+ use console::style;
3
4
 
4
5
  use crate::utils::args::ArgExt;
5
6
 
@@ -25,7 +26,8 @@ pub fn make_command(mut command: Command) -> Command {
25
26
  }
26
27
 
27
28
  command = command
28
- .about("Manage release artifacts.")
29
+ .about("[DEPRECATED] Manage release artifacts.")
30
+ .hide(true)
29
31
  .subcommand_required(true)
30
32
  .arg_required_else_help(true)
31
33
  .org_arg()
@@ -42,6 +44,9 @@ pub fn make_command(mut command: Command) -> Command {
42
44
  }
43
45
 
44
46
  pub fn execute(matches: &ArgMatches) -> Result<()> {
47
+ eprintln!("{}", style("⚠ DEPRECATION NOTICE: This functionality will be removed in a future version of `sentry-cli`. \
48
+ Use the `sourcemaps` command instead.").yellow());
49
+
45
50
  macro_rules! execute_subcommand {
46
51
  ($name:ident) => {{
47
52
  if let Some(sub_matches) =
@@ -24,7 +24,8 @@ use crate::utils::progress::ProgressBarMode;
24
24
 
25
25
  pub fn make_command(command: Command) -> Command {
26
26
  command
27
- .about("Upload files for a release.")
27
+ .about("[DEPRECATED] Upload files for a release.")
28
+ .hide(true)
28
29
  // Backward compatibility with `releases files <VERSION>` commands.
29
30
  .arg(Arg::new("version").long("version").hide(true))
30
31
  .arg(
@@ -12,7 +12,7 @@ use crate::config::Config;
12
12
  use crate::constants::DEFAULT_MAX_WAIT;
13
13
  use crate::utils::args::{validate_distribution, ArgExt};
14
14
  use crate::utils::file_search::ReleaseFileSearch;
15
- use crate::utils::file_upload::UploadContext;
15
+ use crate::utils::file_upload::{SourceFile, UploadContext};
16
16
  use crate::utils::sourcemaps::SourceMapProcessor;
17
17
 
18
18
  pub fn make_command(command: Command) -> Command {
@@ -92,16 +92,16 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
92
92
  &bundle_url,
93
93
  ReleaseFileSearch::collect_file(bundle_path.clone())?,
94
94
  );
95
- processor.add(
96
- &sourcemap_url,
97
- ReleaseFileSearch::collect_file(sourcemap_path)?,
98
- );
95
+
96
+ let sourcemap_match = ReleaseFileSearch::collect_file(sourcemap_path.clone())?;
99
97
 
100
98
  if let Ok(ram_bundle) = RamBundle::parse_unbundle_from_path(&bundle_path) {
101
99
  debug!("File RAM bundle found, extracting its contents...");
102
- processor.unpack_ram_bundle(&ram_bundle, &bundle_url)?;
100
+ let sourcemap_source = SourceFile::from_release_file_match(&sourcemap_url, sourcemap_match);
101
+ processor.unpack_ram_bundle(&ram_bundle, &bundle_url, &sourcemap_source)?;
103
102
  } else {
104
103
  debug!("Non-file bundle found");
104
+ processor.add(&sourcemap_url, sourcemap_match);
105
105
  }
106
106
 
107
107
  processor.rewrite(&[base.to_str().unwrap()])?;
@@ -20,9 +20,10 @@ pub fn make_command(command: Command) -> Command {
20
20
  .arg(
21
21
  Arg::new("started")
22
22
  .long("started")
23
+ .hide(true)
23
24
  .value_parser(get_timestamp)
24
25
  .value_name("TIMESTAMP")
25
- .help("Set the release start date."),
26
+ .help("[DEPRECATED] This value is ignored."),
26
27
  )
27
28
  .arg(
28
29
  Arg::new("released")
@@ -38,13 +39,19 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
38
39
  let api = Api::current();
39
40
  let version = matches.get_one::<String>("version").unwrap();
40
41
 
42
+ if matches.get_one::<DateTime<Utc>>("started").is_some() {
43
+ log::warn!(
44
+ "The --started flag is deprecated. Its value is ignored, \
45
+ and the argument will be completely removed in a future version."
46
+ );
47
+ }
48
+
41
49
  api.authenticated()?.update_release(
42
50
  &config.get_org(matches)?,
43
51
  version,
44
52
  &UpdatedRelease {
45
53
  projects: config.get_projects(matches).ok(),
46
54
  url: matches.get_one::<String>("url").cloned(),
47
- date_started: matches.get_one::<DateTime<Utc>>("started").copied(),
48
55
  date_released: Some(
49
56
  matches
50
57
  .get_one::<DateTime<Utc>>("released")
@@ -16,7 +16,8 @@ use super::resolve::print_source;
16
16
 
17
17
  pub fn make_command(command: Command) -> Command {
18
18
  command
19
- .about("Explain why sourcemaps are not working for a given event.")
19
+ .about("[DEPRECATED] Explain why sourcemaps are not working for a given event.")
20
+ .hide(true)
20
21
  .alias("why")
21
22
  .arg(
22
23
  Arg::new("event")
@@ -13,7 +13,7 @@ use crate::config::Config;
13
13
  use crate::constants::DEFAULT_MAX_WAIT;
14
14
  use crate::utils::args::validate_distribution;
15
15
  use crate::utils::file_search::ReleaseFileSearch;
16
- use crate::utils::file_upload::UploadContext;
16
+ use crate::utils::file_upload::{SourceFile, UploadContext};
17
17
  use crate::utils::fs::path_as_url;
18
18
  use crate::utils::sourcemaps::SourceMapProcessor;
19
19
 
@@ -303,21 +303,23 @@ fn process_sources_from_bundle(
303
303
  &bundle_url,
304
304
  ReleaseFileSearch::collect_file(bundle_path.clone())?,
305
305
  );
306
- processor.add(
307
- &sourcemap_url,
308
- ReleaseFileSearch::collect_file(sourcemap_path)?,
309
- );
306
+ let sourcemap_match = ReleaseFileSearch::collect_file(sourcemap_path)?;
310
307
 
311
308
  if let Ok(ram_bundle) = sourcemap::ram_bundle::RamBundle::parse_unbundle_from_path(&bundle_path)
312
309
  {
313
310
  debug!("File RAM bundle found, extracting its contents...");
314
311
  // For file ("unbundle") RAM bundles we need to explicitly unpack it, otherwise we cannot detect it
315
312
  // reliably inside "processor.rewrite()"
316
- processor.unpack_ram_bundle(&ram_bundle, &bundle_url)?;
313
+
314
+ let sourcemap_source = SourceFile::from_release_file_match(&sourcemap_url, sourcemap_match);
315
+ processor.unpack_ram_bundle(&ram_bundle, &bundle_url, &sourcemap_source)?;
317
316
  } else if sourcemap::ram_bundle::RamBundle::parse_indexed_from_path(&bundle_path).is_ok() {
318
317
  debug!("Indexed RAM bundle found");
318
+ let sourcemap_source = SourceFile::from_release_file_match(&sourcemap_url, sourcemap_match);
319
+ processor.unpack_indexed_ram_bundles(&sourcemap_source)?;
319
320
  } else {
320
321
  warn!("Regular bundle found");
322
+ processor.add(&sourcemap_url, sourcemap_match);
321
323
  }
322
324
 
323
325
  let mut prefixes = get_prefixes_from_args(matches);
@@ -1,8 +1,10 @@
1
1
  //! This module implements config access.
2
2
  use std::env;
3
+ use std::env::VarError;
3
4
  use std::fs;
4
5
  use std::fs::OpenOptions;
5
6
  use std::io;
7
+ use std::num::ParseIntError;
6
8
  use std::path::{Path, PathBuf};
7
9
  use std::sync::Arc;
8
10
 
@@ -26,6 +28,9 @@ use crate::utils::http::is_absolute_url;
26
28
  #[cfg(target_os = "macos")]
27
29
  use crate::utils::xcode;
28
30
 
31
+ const MAX_RETRIES_ENV_VAR: &str = "SENTRY_HTTP_MAX_RETRIES";
32
+ const MAX_RETRIES_INI_KEY: &str = "max_retries";
33
+
29
34
  /// Represents the auth information
30
35
  #[derive(Debug, Clone)]
31
36
  pub enum Auth {
@@ -48,6 +53,7 @@ pub struct Config {
48
53
  cached_log_level: log::LevelFilter,
49
54
  cached_vcs_remote: String,
50
55
  cached_token_data: Option<AuthTokenPayload>,
56
+ max_retries: u32,
51
57
  }
52
58
 
53
59
  impl Config {
@@ -86,6 +92,7 @@ impl Config {
86
92
  cached_headers: get_default_headers(&ini),
87
93
  cached_log_level: get_default_log_level(&ini),
88
94
  cached_vcs_remote: get_default_vcs_remote(&ini),
95
+ max_retries: get_max_retries(&ini),
89
96
  ini,
90
97
  cached_token_data: token_embedded_data,
91
98
  }
@@ -462,14 +469,9 @@ impl Config {
462
469
  .unwrap_or(DEFAULT_MAX_DIF_ITEM_SIZE)
463
470
  }
464
471
 
465
- pub fn get_max_retry_count(&self) -> Result<u32> {
466
- if env::var_os("SENTRY_HTTP_MAX_RETRIES").is_some() {
467
- Ok(env::var("SENTRY_HTTP_MAX_RETRIES")?.parse()?)
468
- } else if let Some(val) = self.ini.get_from(Some("http"), "max_retries") {
469
- Ok(val.parse()?)
470
- } else {
471
- Ok(DEFAULT_RETRIES)
472
- }
472
+ /// Returns the configured maximum number of retries for failed HTTP requests.
473
+ pub fn max_retries(&self) -> u32 {
474
+ self.max_retries
473
475
  }
474
476
 
475
477
  /// Return the DSN
@@ -520,6 +522,50 @@ impl Config {
520
522
  }
521
523
  }
522
524
 
525
+ /// Obtains the maximum number of retries from the environment or the ini file.
526
+ /// Environment variable takes precedence over the ini file. If neither is set,
527
+ /// the default value is returned.
528
+ fn get_max_retries(ini: &Ini) -> u32 {
529
+ match max_retries_from_env() {
530
+ Ok(Some(val)) => return val,
531
+ Ok(None) => (),
532
+ Err(e) => {
533
+ warn!(
534
+ "Ignoring invalid {MAX_RETRIES_ENV_VAR} environment variable: {}",
535
+ e
536
+ );
537
+ }
538
+ };
539
+
540
+ match max_retries_from_ini(ini) {
541
+ Ok(Some(val)) => return val,
542
+ Ok(None) => (),
543
+ Err(e) => {
544
+ warn!("Ignoring invalid {MAX_RETRIES_INI_KEY} ini key: {}", e);
545
+ }
546
+ };
547
+
548
+ DEFAULT_RETRIES
549
+ }
550
+
551
+ /// Computes the maximum number of retries from the `SENTRY_HTTP_MAX_RETRIES` environment variable.
552
+ /// Returns `Ok(None)` if the environment variable is not set, other errors are returned as is.
553
+ fn max_retries_from_env() -> Result<Option<u32>> {
554
+ match env::var(MAX_RETRIES_ENV_VAR) {
555
+ Ok(val) => Ok(Some(val.parse()?)),
556
+ Err(VarError::NotPresent) => Ok(None),
557
+ Err(e) => Err(e.into()),
558
+ }
559
+ }
560
+
561
+ /// Computes the maximum number of retries from the `max_retries` ini key.
562
+ /// Returns `Ok(None)` if the key is not set, other errors are returned as is.
563
+ fn max_retries_from_ini(ini: &Ini) -> Result<Option<u32>, ParseIntError> {
564
+ ini.get_from(Some("http"), MAX_RETRIES_INI_KEY)
565
+ .map(|val| val.parse())
566
+ .transpose()
567
+ }
568
+
523
569
  fn warn_about_conflicting_urls(token_url: &str, manually_configured_url: Option<&str>) {
524
570
  if let Some(manually_configured_url) = manually_configured_url {
525
571
  if manually_configured_url != token_url {
@@ -672,6 +718,7 @@ impl Clone for Config {
672
718
  cached_log_level: self.cached_log_level,
673
719
  cached_vcs_remote: self.cached_vcs_remote.clone(),
674
720
  cached_token_data: self.cached_token_data.clone(),
721
+ max_retries: self.max_retries,
675
722
  }
676
723
  }
677
724
  }
@@ -757,6 +804,7 @@ mod tests {
757
804
  cached_log_level: LevelFilter::Off,
758
805
  cached_vcs_remote: String::new(),
759
806
  cached_token_data: None,
807
+ max_retries: 0,
760
808
  };
761
809
 
762
810
  assert_eq!(
@@ -1,5 +1,6 @@
1
1
  //! Searches, processes and uploads release files.
2
2
  use std::collections::{BTreeMap, HashMap};
3
+ use std::ffi::OsStr;
3
4
  use std::fmt::{self, Display};
4
5
  use std::io::BufWriter;
5
6
  use std::path::PathBuf;
@@ -16,6 +17,7 @@ use rayon::ThreadPoolBuilder;
16
17
  use sentry::types::DebugId;
17
18
  use sha1_smol::Digest;
18
19
  use symbolic::common::ByteView;
20
+ use symbolic::debuginfo::js;
19
21
  use symbolic::debuginfo::sourcebundle::{
20
22
  SourceBundleErrorKind, SourceBundleWriter, SourceFileInfo, SourceFileType,
21
23
  };
@@ -29,6 +31,8 @@ use crate::utils::chunks::{upload_chunks, Chunk, ASSEMBLE_POLL_INTERVAL};
29
31
  use crate::utils::fs::{get_sha1_checksum, get_sha1_checksums, TempFile};
30
32
  use crate::utils::progress::{ProgressBar, ProgressBarMode, ProgressStyle};
31
33
 
34
+ use super::file_search::ReleaseFileMatch;
35
+
32
36
  /// Fallback concurrency for release file uploads.
33
37
  static DEFAULT_CONCURRENCY: usize = 4;
34
38
 
@@ -239,6 +243,68 @@ pub struct SourceFile {
239
243
  }
240
244
 
241
245
  impl SourceFile {
246
+ pub fn from_release_file_match(url: &str, mut file: ReleaseFileMatch) -> SourceFile {
247
+ let (ty, debug_id) = if sourcemap::is_sourcemap_slice(&file.contents) {
248
+ (
249
+ SourceFileType::SourceMap,
250
+ std::str::from_utf8(&file.contents)
251
+ .ok()
252
+ .and_then(js::discover_sourcemap_embedded_debug_id),
253
+ )
254
+ } else if file
255
+ .path
256
+ .file_name()
257
+ .and_then(OsStr::to_str)
258
+ .map(|x| x.ends_with("bundle"))
259
+ .unwrap_or(false)
260
+ && sourcemap::ram_bundle::is_ram_bundle_slice(&file.contents)
261
+ {
262
+ (SourceFileType::IndexedRamBundle, None)
263
+ } else if is_hermes_bytecode(&file.contents) {
264
+ // This is actually a big hack:
265
+ // For the react-native Hermes case, we skip uploading the bytecode bundle,
266
+ // and rather flag it as an empty "minified source". That way, it
267
+ // will get a SourceMap reference, and the server side processor
268
+ // should deal with it accordingly.
269
+ file.contents.clear();
270
+ (SourceFileType::MinifiedSource, None)
271
+ } else {
272
+ // Here, we use MinifiedSource for historical reasons. We used to guess whether
273
+ // a JS file was a minified file or a source file, and we would treat these files
274
+ // differently when uploading or injecting them. However, the desired behavior is
275
+ // and has always been to treat all JS files the same, since users should be
276
+ // responsible for providing the file paths for only files they would like to have
277
+ // uploaded or injected. The minified file guessing furthermore was not reliable,
278
+ // since minification is not a necessary step in the JS build process.
279
+ //
280
+ // We use MinifiedSource here rather than Source because we want to treat all JS
281
+ // files the way we used to treat minified files only. To use Source, we would need
282
+ // to analyze all possible code paths that check this value, and update those as
283
+ // well. To keep the change minimal, we use MinifiedSource here.
284
+ (
285
+ SourceFileType::MinifiedSource,
286
+ std::str::from_utf8(&file.contents)
287
+ .ok()
288
+ .and_then(js::discover_debug_id),
289
+ )
290
+ };
291
+
292
+ let mut source_file = SourceFile {
293
+ url: url.into(),
294
+ path: file.path,
295
+ contents: file.contents.into(),
296
+ ty,
297
+ headers: BTreeMap::new(),
298
+ messages: vec![],
299
+ already_uploaded: false,
300
+ };
301
+
302
+ if let Some(debug_id) = debug_id {
303
+ source_file.set_debug_id(debug_id.to_string());
304
+ }
305
+ source_file
306
+ }
307
+
242
308
  /// Calculates and returns the SHA1 checksum of the file.
243
309
  pub fn checksum(&self) -> Result<Digest> {
244
310
  get_sha1_checksum(&**self.contents)
@@ -753,6 +819,13 @@ fn print_upload_context_details(context: &UploadContext) {
753
819
  );
754
820
  }
755
821
 
822
+ fn is_hermes_bytecode(slice: &[u8]) -> bool {
823
+ // The hermes bytecode format magic is defined here:
824
+ // https://github.com/facebook/hermes/blob/5243222ef1d92b7393d00599fc5cff01d189a88a/include/hermes/BCGen/HBC/BytecodeFileFormat.h#L24-L25
825
+ const HERMES_MAGIC: [u8; 8] = [0xC6, 0x1F, 0xBC, 0x03, 0xC1, 0x03, 0x19, 0x1F];
826
+ slice.starts_with(&HERMES_MAGIC)
827
+ }
828
+
756
829
  #[cfg(test)]
757
830
  mod tests {
758
831
  use sha1_smol::Sha1;