sentry-cli 3.3.3__tar.gz → 3.3.5__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 (179) hide show
  1. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/Cargo.lock +3 -3
  2. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/Cargo.toml +1 -1
  3. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/PKG-INFO +1 -1
  4. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/sentry_cli.egg-info/PKG-INFO +1 -1
  5. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/sentry_cli.egg-info/SOURCES.txt +4 -0
  6. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/build.rs +7 -0
  7. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/mod.rs +1 -1
  8. sentry_cli-3.3.5/src/api/data_types/code_mappings.rs +37 -0
  9. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/mod.rs +2 -0
  10. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/snapshots.rs +2 -14
  11. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/mod.rs +31 -1
  12. sentry_cli-3.3.5/src/commands/build/download.rs +106 -0
  13. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/build/mod.rs +2 -0
  14. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/build/snapshots.rs +49 -18
  15. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/build/upload.rs +15 -0
  16. sentry_cli-3.3.5/src/commands/code_mappings/mod.rs +45 -0
  17. sentry_cli-3.3.5/src/commands/code_mappings/upload.rs +452 -0
  18. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/mod.rs +2 -0
  19. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/progress.rs +1 -8
  20. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/sourcemaps.rs +6 -1
  21. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/vcs.rs +19 -7
  22. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/LICENSE +0 -0
  23. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/MANIFEST.in +0 -0
  24. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/README.md +0 -0
  25. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/AGENTS.md +0 -0
  26. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/CLAUDE.md +0 -0
  27. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/Cargo.toml +0 -0
  28. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/build.rs +0 -0
  29. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
  30. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
  31. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
  32. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
  33. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
  34. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Info.plist +0 -0
  35. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Products/Applications/DemoApp.app/Assets.car +0 -0
  36. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
  37. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/apple-catalog-parsing/src/lib.rs +0 -0
  38. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/build.rs +0 -0
  39. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/pyproject.toml +0 -0
  40. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/sentry_cli.egg-info/dependency_links.txt +0 -0
  41. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/sentry_cli.egg-info/top_level.txt +0 -0
  42. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/setup.cfg +0 -0
  43. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/setup.py +0 -0
  44. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/AGENTS.md +0 -0
  45. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/CLAUDE.md +0 -0
  46. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/connection_manager.rs +0 -0
  47. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/artifact.rs +0 -0
  48. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/compression.rs +0 -0
  49. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/dif.rs +0 -0
  50. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/file_state.rs +0 -0
  51. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
  52. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/upload/mod.rs +0 -0
  53. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/chunking/upload/options.rs +0 -0
  54. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/data_types/deploy.rs +0 -0
  55. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/encoding.rs +0 -0
  56. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/envelopes_api.rs +0 -0
  57. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/errors/api_error.rs +0 -0
  58. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/errors/mod.rs +0 -0
  59. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/errors/sentry_error.rs +0 -0
  60. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/pagination.rs +0 -0
  61. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/api/serialization.rs +0 -0
  62. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/bashsupport.sh +0 -0
  63. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/bash_hook.rs +0 -0
  64. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/dart_symbol_map/mod.rs +0 -0
  65. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/dart_symbol_map/upload.rs +0 -0
  66. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/debug_files/bundle_jvm.rs +0 -0
  67. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/debug_files/bundle_sources.rs +0 -0
  68. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/debug_files/check.rs +0 -0
  69. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/debug_files/find.rs +0 -0
  70. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/debug_files/mod.rs +0 -0
  71. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/debug_files/print_sources.rs +0 -0
  72. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/debug_files/upload.rs +0 -0
  73. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/deploys/list.rs +0 -0
  74. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/deploys/mod.rs +0 -0
  75. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/deploys/new.rs +0 -0
  76. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/derive_parser.rs +0 -0
  77. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/events/list.rs +0 -0
  78. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/events/mod.rs +0 -0
  79. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/info.rs +0 -0
  80. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/issues/list.rs +0 -0
  81. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/issues/mod.rs +0 -0
  82. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/issues/mute.rs +0 -0
  83. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/issues/resolve.rs +0 -0
  84. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/issues/unresolve.rs +0 -0
  85. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/login.rs +0 -0
  86. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/logs/list.rs +0 -0
  87. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/logs/mod.rs +0 -0
  88. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/monitors/list.rs +0 -0
  89. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/monitors/mod.rs +0 -0
  90. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/monitors/run.rs +0 -0
  91. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/organizations/list.rs +0 -0
  92. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/organizations/mod.rs +0 -0
  93. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/proguard/mod.rs +0 -0
  94. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/proguard/upload.rs +0 -0
  95. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/proguard/uuid.rs +0 -0
  96. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/projects/list.rs +0 -0
  97. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/projects/mod.rs +0 -0
  98. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/react_native/gradle.rs +0 -0
  99. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/react_native/mod.rs +0 -0
  100. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/react_native/xcode.rs +0 -0
  101. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/archive.rs +0 -0
  102. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/delete.rs +0 -0
  103. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/finalize.rs +0 -0
  104. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/info.rs +0 -0
  105. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/list.rs +0 -0
  106. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/mod.rs +0 -0
  107. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/new.rs +0 -0
  108. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/propose_version.rs +0 -0
  109. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/restore.rs +0 -0
  110. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/releases/set_commits.rs +0 -0
  111. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/repos/list.rs +0 -0
  112. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/repos/mod.rs +0 -0
  113. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/send_envelope.rs +0 -0
  114. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/send_event.rs +0 -0
  115. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/send_metric/common_args.rs +0 -0
  116. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/send_metric/increment.rs +0 -0
  117. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/send_metric/mod.rs +0 -0
  118. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/send_metric/set.rs +0 -0
  119. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/sourcemaps/inject.rs +0 -0
  120. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/sourcemaps/mod.rs +0 -0
  121. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/sourcemaps/resolve.rs +0 -0
  122. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/sourcemaps/upload.rs +0 -0
  123. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/uninstall.rs +0 -0
  124. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/update.rs +0 -0
  125. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/upload_dif.rs +0 -0
  126. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/upload_dsym.rs +0 -0
  127. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/commands/upload_proguard.rs +0 -0
  128. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/config.rs +0 -0
  129. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/constants.rs +0 -0
  130. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/main.rs +0 -0
  131. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/android.rs +0 -0
  132. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/args.rs +0 -0
  133. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/auth_token/auth_token_impl.rs +0 -0
  134. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/auth_token/error.rs +0 -0
  135. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/auth_token/mod.rs +0 -0
  136. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/auth_token/org_auth_token.rs +0 -0
  137. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/auth_token/redacting.rs +0 -0
  138. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/auth_token/test.rs +0 -0
  139. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/auth_token/user_auth_token.rs +0 -0
  140. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/build/apple.rs +0 -0
  141. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/build/mod.rs +0 -0
  142. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/build/normalize.rs +0 -0
  143. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/build/validation.rs +0 -0
  144. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/build_vcs.rs +0 -0
  145. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/chunks/mod.rs +0 -0
  146. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/chunks/options.rs +0 -0
  147. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/chunks/types.rs +0 -0
  148. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/chunks/upload.rs +0 -0
  149. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/ci.rs +0 -0
  150. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/cordova.rs +0 -0
  151. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/dif.rs +0 -0
  152. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/dif_upload/error.rs +0 -0
  153. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/dif_upload/mod.rs +0 -0
  154. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/event.rs +0 -0
  155. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/file_search.rs +0 -0
  156. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/file_upload.rs +0 -0
  157. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/formatting.rs +0 -0
  158. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/fs.rs +0 -0
  159. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/http.rs +0 -0
  160. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/logging.rs +0 -0
  161. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/mod.rs +0 -0
  162. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/non_empty.rs +0 -0
  163. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/proguard/mapping.rs +0 -0
  164. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/proguard/mod.rs +0 -0
  165. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/proguard/upload.rs +0 -0
  166. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/releases.rs +0 -0
  167. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/retry.rs +0 -0
  168. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_default_twenty.snap +0 -0
  169. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_ignore_missing.snap +0 -0
  170. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_base.snap +0 -0
  171. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_previous_commit.snap +0 -0
  172. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/snapshots/sentry_cli__utils__vcs__tests__get_commits_from_git.snap +0 -0
  173. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/source_bundle.rs +0 -0
  174. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/sourcemaps/inject.rs +0 -0
  175. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/system.rs +0 -0
  176. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/ui.rs +0 -0
  177. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/update.rs +0 -0
  178. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/value_parsers.rs +0 -0
  179. {sentry_cli-3.3.3 → sentry_cli-3.3.5}/src/utils/xcode.rs +0 -0
@@ -3230,9 +3230,9 @@ dependencies = [
3230
3230
 
3231
3231
  [[package]]
3232
3232
  name = "rustls-webpki"
3233
- version = "0.103.8"
3233
+ version = "0.103.10"
3234
3234
  source = "registry+https://github.com/rust-lang/crates.io-index"
3235
- checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52"
3235
+ checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
3236
3236
  dependencies = [
3237
3237
  "ring",
3238
3238
  "rustls-pki-types",
@@ -3414,7 +3414,7 @@ dependencies = [
3414
3414
 
3415
3415
  [[package]]
3416
3416
  name = "sentry-cli"
3417
- version = "3.3.3"
3417
+ version = "3.3.5"
3418
3418
  dependencies = [
3419
3419
  "anyhow",
3420
3420
  "anylog",
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  build = "build.rs"
3
3
  name = "sentry-cli"
4
- version = "3.3.3"
4
+ version = "3.3.5"
5
5
  edition = "2021"
6
6
  rust-version = "1.91"
7
7
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.3.3
3
+ Version: 3.3.5
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: 3.3.3
3
+ Version: 3.3.5
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
@@ -36,6 +36,7 @@ src/api/envelopes_api.rs
36
36
  src/api/mod.rs
37
37
  src/api/pagination.rs
38
38
  src/api/serialization.rs
39
+ src/api/data_types/code_mappings.rs
39
40
  src/api/data_types/deploy.rs
40
41
  src/api/data_types/mod.rs
41
42
  src/api/data_types/snapshots.rs
@@ -63,9 +64,12 @@ src/commands/update.rs
63
64
  src/commands/upload_dif.rs
64
65
  src/commands/upload_dsym.rs
65
66
  src/commands/upload_proguard.rs
67
+ src/commands/build/download.rs
66
68
  src/commands/build/mod.rs
67
69
  src/commands/build/snapshots.rs
68
70
  src/commands/build/upload.rs
71
+ src/commands/code_mappings/mod.rs
72
+ src/commands/code_mappings/upload.rs
69
73
  src/commands/dart_symbol_map/mod.rs
70
74
  src/commands/dart_symbol_map/upload.rs
71
75
  src/commands/debug_files/bundle_jvm.rs
@@ -28,6 +28,13 @@ pub struct AssembleBuildResponse {
28
28
  pub artifact_url: Option<String>,
29
29
  }
30
30
 
31
+ #[derive(Debug, Deserialize)]
32
+ #[serde(rename_all = "camelCase")]
33
+ pub struct BuildInstallDetails {
34
+ pub is_installable: bool,
35
+ pub install_url: Option<String>,
36
+ }
37
+
31
38
  /// VCS information for build app uploads
32
39
  #[derive(Debug, Serialize)]
33
40
  pub struct VcsInfo<'a> {
@@ -10,7 +10,7 @@ mod hash_algorithm;
10
10
  mod upload;
11
11
 
12
12
  pub use self::artifact::{AssembleArtifactsResponse, ChunkedArtifactRequest};
13
- pub use self::build::{AssembleBuildResponse, ChunkedBuildRequest, VcsInfo};
13
+ pub use self::build::{AssembleBuildResponse, BuildInstallDetails, ChunkedBuildRequest, VcsInfo};
14
14
  pub use self::compression::ChunkCompression;
15
15
  pub use self::dif::{AssembleDifsRequest, AssembleDifsResponse, ChunkedDifRequest};
16
16
  pub use self::file_state::ChunkedFileState;
@@ -0,0 +1,37 @@
1
+ //! Data types for the bulk code mappings API.
2
+
3
+ use serde::{Deserialize, Serialize};
4
+
5
+ #[derive(Debug, Serialize)]
6
+ #[serde(rename_all = "camelCase")]
7
+ pub struct BulkCodeMappingsRequest<'a> {
8
+ pub project: &'a str,
9
+ pub repository: &'a str,
10
+ pub default_branch: &'a str,
11
+ pub mappings: &'a [BulkCodeMapping],
12
+ }
13
+
14
+ #[derive(Debug, Deserialize, Serialize)]
15
+ #[serde(rename_all = "camelCase")]
16
+ pub struct BulkCodeMapping {
17
+ pub stack_root: String,
18
+ pub source_root: String,
19
+ }
20
+
21
+ #[derive(Debug, Deserialize)]
22
+ pub struct BulkCodeMappingsResponse {
23
+ pub created: u64,
24
+ pub updated: u64,
25
+ pub errors: u64,
26
+ pub mappings: Vec<BulkCodeMappingResult>,
27
+ }
28
+
29
+ #[derive(Debug, Deserialize)]
30
+ #[serde(rename_all = "camelCase")]
31
+ pub struct BulkCodeMappingResult {
32
+ pub stack_root: String,
33
+ pub source_root: String,
34
+ pub status: String,
35
+ #[serde(default)]
36
+ pub detail: Option<String>,
37
+ }
@@ -1,9 +1,11 @@
1
1
  //! Data types used in the api module
2
2
 
3
3
  mod chunking;
4
+ mod code_mappings;
4
5
  mod deploy;
5
6
  mod snapshots;
6
7
 
7
8
  pub use self::chunking::*;
9
+ pub use self::code_mappings::*;
8
10
  pub use self::deploy::*;
9
11
  pub use self::snapshots::*;
@@ -7,7 +7,6 @@ use serde_json::Value;
7
7
 
8
8
  use super::VcsInfo;
9
9
 
10
- const IMAGE_FILE_NAME_FIELD: &str = "image_file_name";
11
10
  const WIDTH_FIELD: &str = "width";
12
11
  const HEIGHT_FIELD: &str = "height";
13
12
 
@@ -42,16 +41,7 @@ pub struct ImageMetadata {
42
41
  }
43
42
 
44
43
  impl ImageMetadata {
45
- pub fn new(
46
- image_file_name: String,
47
- width: u32,
48
- height: u32,
49
- mut extra: HashMap<String, Value>,
50
- ) -> Self {
51
- extra.insert(
52
- IMAGE_FILE_NAME_FIELD.to_owned(),
53
- Value::String(image_file_name),
54
- );
44
+ pub fn new(width: u32, height: u32, mut extra: HashMap<String, Value>) -> Self {
55
45
  extra.insert(WIDTH_FIELD.to_owned(), Value::from(width));
56
46
  extra.insert(HEIGHT_FIELD.to_owned(), Value::from(height));
57
47
 
@@ -68,18 +58,16 @@ mod tests {
68
58
  #[test]
69
59
  fn cli_managed_fields_override_sidecar_fields() {
70
60
  let extra = serde_json::from_value(json!({
71
- (IMAGE_FILE_NAME_FIELD): "from-sidecar.png",
72
61
  (WIDTH_FIELD): 1,
73
62
  (HEIGHT_FIELD): 2,
74
63
  "custom": "keep-me"
75
64
  }))
76
65
  .unwrap();
77
66
 
78
- let metadata = ImageMetadata::new("from-cli.png".to_owned(), 100, 200, extra);
67
+ let metadata = ImageMetadata::new(100, 200, extra);
79
68
  let serialized = serde_json::to_value(metadata).unwrap();
80
69
 
81
70
  let expected = json!({
82
- (IMAGE_FILE_NAME_FIELD): "from-cli.png",
83
71
  (WIDTH_FIELD): 100,
84
72
  (HEIGHT_FIELD): 200,
85
73
  "custom": "keep-me"
@@ -16,7 +16,6 @@ use std::borrow::Cow;
16
16
  use std::cell::RefCell;
17
17
  use std::collections::HashMap;
18
18
  use std::error::Error as _;
19
- #[cfg(any(target_os = "macos", not(feature = "managed")))]
20
19
  use std::fs::File;
21
20
  use std::io::{self, Read as _, Write};
22
21
  use std::rc::Rc;
@@ -724,6 +723,26 @@ impl AuthenticatedApi<'_> {
724
723
  .convert_rnf(ApiErrorKind::ProjectNotFound)
725
724
  }
726
725
 
726
+ pub fn get_build_install_details(
727
+ &self,
728
+ org: &str,
729
+ build_id: &str,
730
+ ) -> ApiResult<BuildInstallDetails> {
731
+ let url = format!(
732
+ "/organizations/{}/preprodartifacts/{}/install-details/",
733
+ PathArg(org),
734
+ PathArg(build_id)
735
+ );
736
+
737
+ self.get(&url)?.convert()
738
+ }
739
+
740
+ pub fn download_installable_build(&self, url: &str, dst: &mut File) -> ApiResult<ApiResponse> {
741
+ self.request(Method::Get, url)?
742
+ .progress_bar_mode(ProgressBarMode::Response)
743
+ .send_into(dst)
744
+ }
745
+
727
746
  /// List all organizations associated with the authenticated token
728
747
  /// in the given `Region`. If no `Region` is provided, we assume
729
748
  /// we're issuing a request to a monolith deployment.
@@ -978,6 +997,17 @@ impl AuthenticatedApi<'_> {
978
997
  Ok(rv)
979
998
  }
980
999
 
1000
+ /// Bulk uploads code mappings for an organization.
1001
+ pub fn bulk_upload_code_mappings(
1002
+ &self,
1003
+ org: &str,
1004
+ body: &BulkCodeMappingsRequest,
1005
+ ) -> ApiResult<BulkCodeMappingsResponse> {
1006
+ let path = format!("/organizations/{}/code-mappings/bulk/", PathArg(org));
1007
+ self.post(&path, body)?
1008
+ .convert_rnf(ApiErrorKind::OrganizationNotFound)
1009
+ }
1010
+
981
1011
  /// Creates a preprod snapshot artifact for the given project.
982
1012
  pub fn create_preprod_snapshot<S: Serialize>(
983
1013
  &self,
@@ -0,0 +1,106 @@
1
+ use std::fs;
2
+ use std::path::PathBuf;
3
+
4
+ use anyhow::{bail, Result};
5
+ use clap::{Arg, ArgMatches, Command};
6
+ use log::info;
7
+
8
+ use crate::api::Api;
9
+ use crate::config::Config;
10
+ use crate::utils::args::ArgExt as _;
11
+ use crate::utils::fs::TempFile;
12
+
13
+ const EXPERIMENTAL_WARNING: &str =
14
+ "[EXPERIMENTAL] The \"build download\" command is experimental. \
15
+ The command is subject to breaking changes, including removal, in any Sentry CLI release.";
16
+
17
+ pub fn make_command(command: Command) -> Command {
18
+ command
19
+ .about("[EXPERIMENTAL] Download a build artifact.")
20
+ .long_about(format!(
21
+ "Download a build artifact.\n\n{EXPERIMENTAL_WARNING}"
22
+ ))
23
+ .org_arg()
24
+ .arg(
25
+ Arg::new("build_id")
26
+ .long("build-id")
27
+ .short('b')
28
+ .required(true)
29
+ .help("The ID of the build to download."),
30
+ )
31
+ .arg(Arg::new("output").long("output").help(
32
+ "The output file path. Defaults to \
33
+ 'preprod_artifact_<build_id>.<ext>' in the current directory, \
34
+ where ext is ipa or apk depending on the platform.",
35
+ ))
36
+ }
37
+
38
+ /// For iOS builds, the install URL points to a plist manifest.
39
+ /// Replace the response_format to download the actual IPA binary instead.
40
+ fn ensure_binary_format(url: &str) -> String {
41
+ url.replace("response_format=plist", "response_format=ipa")
42
+ }
43
+
44
+ /// Extract the file extension from the response_format query parameter.
45
+ fn extension_from_url(url: &str) -> Result<&str> {
46
+ if url.contains("response_format=ipa") {
47
+ Ok("ipa")
48
+ } else if url.contains("response_format=apk") {
49
+ Ok("apk")
50
+ } else {
51
+ bail!("Unsupported build format in download URL.")
52
+ }
53
+ }
54
+
55
+ pub fn execute(matches: &ArgMatches) -> Result<()> {
56
+ eprintln!("{EXPERIMENTAL_WARNING}");
57
+ let config = Config::current();
58
+ let org = config.get_org(matches)?;
59
+ let build_id = matches
60
+ .get_one::<String>("build_id")
61
+ .expect("build_id is required");
62
+
63
+ let api = Api::current();
64
+ let authenticated_api = api.authenticated()?;
65
+
66
+ info!("Fetching install details for build {build_id}");
67
+ let details = authenticated_api.get_build_install_details(&org, build_id)?;
68
+
69
+ if !details.is_installable {
70
+ bail!("Build {build_id} is not installable.");
71
+ }
72
+
73
+ let install_url = details
74
+ .install_url
75
+ .ok_or_else(|| anyhow::anyhow!("Build {build_id} has no install URL."))?;
76
+
77
+ let download_url = ensure_binary_format(&install_url);
78
+
79
+ let output_path = match matches.get_one::<String>("output") {
80
+ Some(path) => PathBuf::from(path),
81
+ None => {
82
+ let ext = extension_from_url(&download_url)?;
83
+ PathBuf::from(format!("preprod_artifact_{build_id}.{ext}"))
84
+ }
85
+ };
86
+
87
+ info!("Downloading build {build_id} to {}", output_path.display());
88
+
89
+ let tmp = TempFile::create()?;
90
+ let mut file = tmp.open()?;
91
+ let response = authenticated_api.download_installable_build(&download_url, &mut file)?;
92
+
93
+ if response.failed() {
94
+ bail!(
95
+ "Failed to download build (server returned status {}).",
96
+ response.status()
97
+ );
98
+ }
99
+
100
+ drop(file);
101
+ fs::copy(tmp.path(), &output_path)?;
102
+
103
+ println!("Successfully downloaded build to {}", output_path.display());
104
+
105
+ Ok(())
106
+ }
@@ -3,11 +3,13 @@ use clap::{ArgMatches, Command};
3
3
 
4
4
  use crate::utils::args::ArgExt as _;
5
5
 
6
+ pub mod download;
6
7
  pub mod snapshots;
7
8
  pub mod upload;
8
9
 
9
10
  macro_rules! each_subcommand {
10
11
  ($mac:ident) => {
12
+ $mac!(download);
11
13
  $mac!(snapshots);
12
14
  $mac!(upload);
13
15
  };
@@ -11,6 +11,7 @@ use console::style;
11
11
  use itertools::Itertools as _;
12
12
  use log::{debug, info, warn};
13
13
  use objectstore_client::{ClientBuilder, ExpirationPolicy, Usecase};
14
+ use rayon::prelude::*;
14
15
  use secrecy::ExposeSecret as _;
15
16
  use serde_json::Value;
16
17
  use sha2::{Digest as _, Sha256};
@@ -230,7 +231,7 @@ fn compute_sha256_hash(path: &Path) -> Result<String> {
230
231
  let mut file = std::fs::File::open(path)
231
232
  .with_context(|| format!("Failed to open image for hashing: {}", path.display()))?;
232
233
  let mut hasher = Sha256::new();
233
- let mut buffer = [0u8; 8192];
234
+ let mut buffer = [0u8; 65536];
234
235
  loop {
235
236
  let bytes_read = file
236
237
  .read(&mut buffer)
@@ -331,12 +332,35 @@ fn upload_images(
331
332
 
332
333
  let mut many_builder = session.many();
333
334
  let mut manifest_entries = HashMap::new();
334
- let image_count = images.len();
335
+ let mut collisions: HashMap<String, Vec<String>> = HashMap::new();
336
+ let mut kept_paths = HashMap::new();
337
+
338
+ let hashed_images: Vec<_> = images
339
+ .into_par_iter()
340
+ .map(|image| {
341
+ let hash = compute_sha256_hash(&image.path)?;
342
+ Ok((image, hash))
343
+ })
344
+ .collect::<Result<Vec<_>>>()?;
335
345
 
336
- for image in images {
337
- debug!("Processing image: {}", image.path.display());
346
+ for (image, hash) in hashed_images {
347
+ let image_file_name = image
348
+ .relative_path
349
+ .file_name()
350
+ .unwrap_or_default()
351
+ .to_string_lossy()
352
+ .into_owned();
353
+
354
+ let relative_path = crate::utils::fs::path_as_url(&image.relative_path);
355
+
356
+ if manifest_entries.contains_key(&image_file_name) {
357
+ collisions
358
+ .entry(image_file_name)
359
+ .or_default()
360
+ .push(relative_path);
361
+ continue;
362
+ }
338
363
 
339
- let hash = compute_sha256_hash(&image.path)?;
340
364
  let file = runtime
341
365
  .block_on(tokio::fs::File::open(&image.path))
342
366
  .with_context(|| {
@@ -353,33 +377,40 @@ fn upload_images(
353
377
  .expiration_policy(expiration),
354
378
  );
355
379
 
356
- let image_file_name = image
357
- .relative_path
358
- .file_name()
359
- .unwrap_or_default()
360
- .to_string_lossy()
361
- .into_owned();
362
-
363
- let extra = read_sidecar_metadata(&image.path).unwrap_or_else(|err| {
380
+ let mut extra = read_sidecar_metadata(&image.path).unwrap_or_else(|err| {
364
381
  warn!("Error reading sidecar metadata, ignoring it instead: {err:#}");
365
382
  HashMap::new()
366
383
  });
384
+ extra.insert("content_hash".to_owned(), serde_json::Value::String(hash));
367
385
 
386
+ kept_paths.insert(image_file_name.clone(), relative_path);
368
387
  manifest_entries.insert(
369
- hash,
370
- ImageMetadata::new(image_file_name, image.width, image.height, extra),
388
+ image_file_name,
389
+ ImageMetadata::new(image.width, image.height, extra),
371
390
  );
372
391
  }
373
392
 
393
+ if !collisions.is_empty() {
394
+ let mut details = String::new();
395
+ for (name, excluded_paths) in &collisions {
396
+ let mut all_paths = vec![kept_paths[name].as_str()];
397
+ all_paths.extend(excluded_paths.iter().map(|s| s.as_str()));
398
+ details.push_str(&format!("\n {name}: {}", all_paths.join(", ")));
399
+ }
400
+ warn!("Some images share identical file names. Only the first occurrence of each is included:{details}");
401
+ }
402
+
374
403
  let result = runtime.block_on(async { many_builder.send().error_for_failures().await });
375
404
 
405
+ let uploaded_count = manifest_entries.len();
406
+
376
407
  match result {
377
408
  Ok(()) => {
378
409
  println!(
379
410
  "{} Uploaded {} image {}",
380
411
  style(">").dim(),
381
- style(image_count).yellow(),
382
- if image_count == 1 { "file" } else { "files" }
412
+ style(uploaded_count).yellow(),
413
+ if uploaded_count == 1 { "file" } else { "files" }
383
414
  );
384
415
  Ok(manifest_entries)
385
416
  }
@@ -391,7 +422,7 @@ fn upload_images(
391
422
  eprintln!(" {}", style(format!("{error:#}")).red());
392
423
  error_count += 1;
393
424
  }
394
- anyhow::bail!("Failed to upload {error_count} out of {image_count} images")
425
+ anyhow::bail!("Failed to upload {error_count} out of {uploaded_count} images")
395
426
  }
396
427
  }
397
428
  }
@@ -143,6 +143,20 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
143
143
  return Err(anyhow!("Path does not exist: {}", path.display()));
144
144
  }
145
145
 
146
+ // On non-Apple Silicon, reject xcarchive/IPA early before trying to
147
+ // open the path as a file (xcarchive is a directory, so ByteView::open
148
+ // would fail with a confusing I/O error).
149
+ #[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
150
+ {
151
+ let ext = path.extension().and_then(|e| e.to_str()).unwrap_or("");
152
+ if ext.eq_ignore_ascii_case("xcarchive") || ext.eq_ignore_ascii_case("ipa") {
153
+ return Err(anyhow!(
154
+ "Uploading XCArchive and IPA files requires an Apple Silicon Mac: {}",
155
+ path.display()
156
+ ));
157
+ }
158
+ }
159
+
146
160
  let byteview = ByteView::open(path)?;
147
161
  debug!("Loaded file with {} bytes", byteview.len());
148
162
 
@@ -301,6 +315,7 @@ fn validate_is_supported_build(path: &Path, bytes: &[u8]) -> Result<()> {
301
315
  }
302
316
 
303
317
  debug!("File format validation failed");
318
+
304
319
  #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
305
320
  let format_list = "APK, AAB, XCArchive, or IPA";
306
321
  #[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
@@ -0,0 +1,45 @@
1
+ use anyhow::Result;
2
+ use clap::{ArgMatches, Command};
3
+
4
+ use crate::utils::args::ArgExt as _;
5
+
6
+ pub mod upload;
7
+
8
+ macro_rules! each_subcommand {
9
+ ($mac:ident) => {
10
+ $mac!(upload);
11
+ };
12
+ }
13
+
14
+ pub fn make_command(mut command: Command) -> Command {
15
+ macro_rules! add_subcommand {
16
+ ($name:ident) => {{
17
+ command = command.subcommand(crate::commands::code_mappings::$name::make_command(
18
+ Command::new(stringify!($name).replace('_', "-")),
19
+ ));
20
+ }};
21
+ }
22
+
23
+ command = command
24
+ .about("Manage code mappings for Sentry. Code mappings link stack trace paths to source code paths in your repository, enabling source context and code linking in Sentry.")
25
+ .subcommand_required(true)
26
+ .arg_required_else_help(true)
27
+ .org_arg()
28
+ .project_arg(false);
29
+ each_subcommand!(add_subcommand);
30
+ command
31
+ }
32
+
33
+ pub fn execute(matches: &ArgMatches) -> Result<()> {
34
+ macro_rules! execute_subcommand {
35
+ ($name:ident) => {{
36
+ if let Some(sub_matches) =
37
+ matches.subcommand_matches(&stringify!($name).replace('_', "-"))
38
+ {
39
+ return crate::commands::code_mappings::$name::execute(&sub_matches);
40
+ }
41
+ }};
42
+ }
43
+ each_subcommand!(execute_subcommand);
44
+ unreachable!();
45
+ }