sentry-cli 3.2.3__tar.gz → 3.3.1__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 (175) hide show
  1. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/Cargo.lock +5 -5
  2. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/Cargo.toml +2 -2
  3. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/PKG-INFO +2 -2
  4. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/README.md +1 -1
  5. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/sentry_cli.egg-info/PKG-INFO +2 -2
  6. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/sentry_cli.egg-info/SOURCES.txt +3 -0
  7. sentry_cli-3.3.1/src/api/data_types/snapshots.rs +86 -0
  8. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/build/snapshots.rs +143 -17
  9. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/mod.rs +2 -0
  10. sentry_cli-3.3.1/src/commands/proguard/mod.rs +45 -0
  11. sentry_cli-3.2.3/src/commands/upload_proguard.rs → sentry_cli-3.3.1/src/commands/proguard/upload.rs +9 -10
  12. sentry_cli-3.3.1/src/commands/proguard/uuid.rs +36 -0
  13. sentry_cli-3.3.1/src/commands/upload_proguard.rs +11 -0
  14. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/dif.rs +11 -13
  15. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/proguard/mapping.rs +4 -29
  16. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/releases.rs +7 -0
  17. sentry_cli-3.2.3/src/api/data_types/snapshots.rs +0 -30
  18. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/LICENSE +0 -0
  19. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/MANIFEST.in +0 -0
  20. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/AGENTS.md +0 -0
  21. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/CLAUDE.md +0 -0
  22. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/Cargo.toml +0 -0
  23. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/build.rs +0 -0
  24. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
  25. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
  26. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
  27. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
  28. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
  29. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Info.plist +0 -0
  30. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Products/Applications/DemoApp.app/Assets.car +0 -0
  31. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
  32. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/apple-catalog-parsing/src/lib.rs +0 -0
  33. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/build.rs +0 -0
  34. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/pyproject.toml +0 -0
  35. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/sentry_cli.egg-info/dependency_links.txt +0 -0
  36. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/sentry_cli.egg-info/top_level.txt +0 -0
  37. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/setup.cfg +0 -0
  38. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/setup.py +0 -0
  39. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/AGENTS.md +0 -0
  40. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/CLAUDE.md +0 -0
  41. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/connection_manager.rs +0 -0
  42. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/artifact.rs +0 -0
  43. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/build.rs +0 -0
  44. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/compression.rs +0 -0
  45. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/dif.rs +0 -0
  46. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/file_state.rs +0 -0
  47. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
  48. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/mod.rs +0 -0
  49. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/upload/mod.rs +0 -0
  50. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/chunking/upload/options.rs +0 -0
  51. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/deploy.rs +0 -0
  52. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/data_types/mod.rs +0 -0
  53. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/encoding.rs +0 -0
  54. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/envelopes_api.rs +0 -0
  55. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/errors/api_error.rs +0 -0
  56. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/errors/mod.rs +0 -0
  57. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/errors/sentry_error.rs +0 -0
  58. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/mod.rs +0 -0
  59. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/pagination.rs +0 -0
  60. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/api/serialization.rs +0 -0
  61. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/bashsupport.sh +0 -0
  62. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/bash_hook.rs +0 -0
  63. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/build/mod.rs +0 -0
  64. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/build/upload.rs +0 -0
  65. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/dart_symbol_map/mod.rs +0 -0
  66. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/dart_symbol_map/upload.rs +0 -0
  67. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/debug_files/bundle_jvm.rs +0 -0
  68. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/debug_files/bundle_sources.rs +0 -0
  69. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/debug_files/check.rs +0 -0
  70. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/debug_files/find.rs +0 -0
  71. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/debug_files/mod.rs +0 -0
  72. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/debug_files/print_sources.rs +0 -0
  73. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/debug_files/upload.rs +0 -0
  74. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/deploys/list.rs +0 -0
  75. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/deploys/mod.rs +0 -0
  76. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/deploys/new.rs +0 -0
  77. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/derive_parser.rs +0 -0
  78. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/events/list.rs +0 -0
  79. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/events/mod.rs +0 -0
  80. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/info.rs +0 -0
  81. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/issues/list.rs +0 -0
  82. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/issues/mod.rs +0 -0
  83. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/issues/mute.rs +0 -0
  84. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/issues/resolve.rs +0 -0
  85. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/issues/unresolve.rs +0 -0
  86. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/login.rs +0 -0
  87. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/logs/list.rs +0 -0
  88. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/logs/mod.rs +0 -0
  89. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/monitors/list.rs +0 -0
  90. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/monitors/mod.rs +0 -0
  91. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/monitors/run.rs +0 -0
  92. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/organizations/list.rs +0 -0
  93. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/organizations/mod.rs +0 -0
  94. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/projects/list.rs +0 -0
  95. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/projects/mod.rs +0 -0
  96. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/react_native/gradle.rs +0 -0
  97. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/react_native/mod.rs +0 -0
  98. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/react_native/xcode.rs +0 -0
  99. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/archive.rs +0 -0
  100. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/delete.rs +0 -0
  101. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/finalize.rs +0 -0
  102. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/info.rs +0 -0
  103. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/list.rs +0 -0
  104. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/mod.rs +0 -0
  105. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/new.rs +0 -0
  106. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/propose_version.rs +0 -0
  107. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/restore.rs +0 -0
  108. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/releases/set_commits.rs +0 -0
  109. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/repos/list.rs +0 -0
  110. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/repos/mod.rs +0 -0
  111. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/send_envelope.rs +0 -0
  112. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/send_event.rs +0 -0
  113. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/send_metric/common_args.rs +0 -0
  114. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/send_metric/increment.rs +0 -0
  115. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/send_metric/mod.rs +0 -0
  116. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/send_metric/set.rs +0 -0
  117. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/sourcemaps/inject.rs +0 -0
  118. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/sourcemaps/mod.rs +0 -0
  119. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/sourcemaps/resolve.rs +0 -0
  120. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/sourcemaps/upload.rs +0 -0
  121. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/uninstall.rs +0 -0
  122. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/update.rs +0 -0
  123. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/upload_dif.rs +0 -0
  124. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/commands/upload_dsym.rs +0 -0
  125. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/config.rs +0 -0
  126. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/constants.rs +0 -0
  127. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/main.rs +0 -0
  128. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/android.rs +0 -0
  129. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/args.rs +0 -0
  130. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/auth_token/auth_token_impl.rs +0 -0
  131. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/auth_token/error.rs +0 -0
  132. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/auth_token/mod.rs +0 -0
  133. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/auth_token/org_auth_token.rs +0 -0
  134. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/auth_token/redacting.rs +0 -0
  135. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/auth_token/test.rs +0 -0
  136. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/auth_token/user_auth_token.rs +0 -0
  137. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/build/apple.rs +0 -0
  138. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/build/mod.rs +0 -0
  139. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/build/normalize.rs +0 -0
  140. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/build/validation.rs +0 -0
  141. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/chunks/mod.rs +0 -0
  142. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/chunks/options.rs +0 -0
  143. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/chunks/types.rs +0 -0
  144. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/chunks/upload.rs +0 -0
  145. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/ci.rs +0 -0
  146. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/cordova.rs +0 -0
  147. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/dif_upload/error.rs +0 -0
  148. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/dif_upload/mod.rs +0 -0
  149. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/event.rs +0 -0
  150. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/file_search.rs +0 -0
  151. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/file_upload.rs +0 -0
  152. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/formatting.rs +0 -0
  153. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/fs.rs +0 -0
  154. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/http.rs +0 -0
  155. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/logging.rs +0 -0
  156. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/mod.rs +0 -0
  157. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/non_empty.rs +0 -0
  158. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/progress.rs +0 -0
  159. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/proguard/mod.rs +0 -0
  160. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/proguard/upload.rs +0 -0
  161. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/retry.rs +0 -0
  162. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_default_twenty.snap +0 -0
  163. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_ignore_missing.snap +0 -0
  164. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_base.snap +0 -0
  165. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_previous_commit.snap +0 -0
  166. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__get_commits_from_git.snap +0 -0
  167. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/source_bundle.rs +0 -0
  168. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/sourcemaps/inject.rs +0 -0
  169. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/sourcemaps.rs +0 -0
  170. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/system.rs +0 -0
  171. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/ui.rs +0 -0
  172. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/update.rs +0 -0
  173. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/value_parsers.rs +0 -0
  174. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/vcs.rs +0 -0
  175. {sentry_cli-3.2.3 → sentry_cli-3.3.1}/src/utils/xcode.rs +0 -0
@@ -2322,9 +2322,9 @@ dependencies = [
2322
2322
 
2323
2323
  [[package]]
2324
2324
  name = "objectstore-client"
2325
- version = "0.0.19"
2325
+ version = "0.1.2"
2326
2326
  source = "registry+https://github.com/rust-lang/crates.io-index"
2327
- checksum = "3bcaf8bc0ea7c50905631df108126c6a075ce5a9c16713ec4b68cc872a408e08"
2327
+ checksum = "033eedf125e31b30962c0172842e964fc9983bbccd99d9ff033e7e413946861c"
2328
2328
  dependencies = [
2329
2329
  "async-compression",
2330
2330
  "async-stream",
@@ -2346,9 +2346,9 @@ dependencies = [
2346
2346
 
2347
2347
  [[package]]
2348
2348
  name = "objectstore-types"
2349
- version = "0.0.19"
2349
+ version = "0.1.2"
2350
2350
  source = "registry+https://github.com/rust-lang/crates.io-index"
2351
- checksum = "f190038e8988112a4e593f1796612941117d88753574ef6476f99324d4605aae"
2351
+ checksum = "956cbdef3971ea108a15e5248625d6229870da3a3c637b6e7aada213526f8014"
2352
2352
  dependencies = [
2353
2353
  "http",
2354
2354
  "humantime",
@@ -3414,7 +3414,7 @@ dependencies = [
3414
3414
 
3415
3415
  [[package]]
3416
3416
  name = "sentry-cli"
3417
- version = "3.2.3"
3417
+ version = "3.3.1"
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.2.3"
4
+ version = "3.3.1"
5
5
  edition = "2021"
6
6
  rust-version = "1.91"
7
7
 
@@ -44,7 +44,7 @@ java-properties = "2.0.0"
44
44
  lazy_static = "1.4.0"
45
45
  libc = "0.2.139"
46
46
  log = { version = "0.4.17", features = ["std"] }
47
- objectstore-client = { version = "0.0.19" , default-features = false, features = ["native-tls"] }
47
+ objectstore-client = { version = "0.1.2" , default-features = false, features = ["native-tls"] }
48
48
  open = "3.2.0"
49
49
  parking_lot = "0.12.1"
50
50
  percent-encoding = "2.2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.2.3
3
+ Version: 3.3.1
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
@@ -50,7 +50,7 @@ Users who are using Sentry Self-Hosted versions older than 24.11.1 are encourage
50
50
  | **Sentry Self-Hosted Version** | **Newest Compatible Sentry CLI Version** |
51
51
  | ------------------------------ | --------------------------------------------------------------------- |
52
52
  | ≥ 24.11.1 | [latest](https://github.com/getsentry/sentry-cli/releases/latest) |
53
- | < 24.11.1 | [2.58.4](https://github.com/getsentry/sentry-cli/releases/tag/2.58.4) |
53
+ | < 24.11.1 | [2.58.5](https://github.com/getsentry/sentry-cli/releases/tag/2.58.5) |
54
54
 
55
55
  Note that we can only provide support for officially-supported Sentry Self-Hosted versions. We will not backport fixes for older Sentry CLI versions, even if they should be compatible with your self-hosted version.
56
56
 
@@ -33,7 +33,7 @@ Users who are using Sentry Self-Hosted versions older than 24.11.1 are encourage
33
33
  | **Sentry Self-Hosted Version** | **Newest Compatible Sentry CLI Version** |
34
34
  | ------------------------------ | --------------------------------------------------------------------- |
35
35
  | ≥ 24.11.1 | [latest](https://github.com/getsentry/sentry-cli/releases/latest) |
36
- | < 24.11.1 | [2.58.4](https://github.com/getsentry/sentry-cli/releases/tag/2.58.4) |
36
+ | < 24.11.1 | [2.58.5](https://github.com/getsentry/sentry-cli/releases/tag/2.58.5) |
37
37
 
38
38
  Note that we can only provide support for officially-supported Sentry Self-Hosted versions. We will not backport fixes for older Sentry CLI versions, even if they should be compatible with your self-hosted version.
39
39
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.2.3
3
+ Version: 3.3.1
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
@@ -50,7 +50,7 @@ Users who are using Sentry Self-Hosted versions older than 24.11.1 are encourage
50
50
  | **Sentry Self-Hosted Version** | **Newest Compatible Sentry CLI Version** |
51
51
  | ------------------------------ | --------------------------------------------------------------------- |
52
52
  | ≥ 24.11.1 | [latest](https://github.com/getsentry/sentry-cli/releases/latest) |
53
- | < 24.11.1 | [2.58.4](https://github.com/getsentry/sentry-cli/releases/tag/2.58.4) |
53
+ | < 24.11.1 | [2.58.5](https://github.com/getsentry/sentry-cli/releases/tag/2.58.5) |
54
54
 
55
55
  Note that we can only provide support for officially-supported Sentry Self-Hosted versions. We will not backport fixes for older Sentry CLI versions, even if they should be compatible with your self-hosted version.
56
56
 
@@ -92,6 +92,9 @@ src/commands/monitors/mod.rs
92
92
  src/commands/monitors/run.rs
93
93
  src/commands/organizations/list.rs
94
94
  src/commands/organizations/mod.rs
95
+ src/commands/proguard/mod.rs
96
+ src/commands/proguard/upload.rs
97
+ src/commands/proguard/uuid.rs
95
98
  src/commands/projects/list.rs
96
99
  src/commands/projects/mod.rs
97
100
  src/commands/react_native/gradle.rs
@@ -0,0 +1,86 @@
1
+ //! Data types for the snapshots API.
2
+
3
+ use std::collections::HashMap;
4
+
5
+ use serde::{Deserialize, Serialize};
6
+ use serde_json::Value;
7
+
8
+ const IMAGE_FILE_NAME_FIELD: &str = "image_file_name";
9
+ const WIDTH_FIELD: &str = "width";
10
+ const HEIGHT_FIELD: &str = "height";
11
+
12
+ /// Response from the create snapshot endpoint.
13
+ #[derive(Debug, Deserialize)]
14
+ #[serde(rename_all = "camelCase")]
15
+ pub struct CreateSnapshotResponse {
16
+ pub artifact_id: String,
17
+ pub image_count: u64,
18
+ pub snapshot_url: Option<String>,
19
+ }
20
+
21
+ // Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
22
+ /// Manifest describing a set of snapshot images for an app.
23
+ #[derive(Debug, Serialize)]
24
+ pub struct SnapshotsManifest {
25
+ pub app_id: String,
26
+ pub images: HashMap<String, ImageMetadata>,
27
+ }
28
+
29
+ // Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
30
+ /// Metadata for a single image in a snapshot manifest.
31
+ ///
32
+ /// CLI-managed fields (`image_file_name`, `width`, `height`) override any
33
+ /// identically named fields provided by user sidecar metadata.
34
+ #[derive(Debug, Serialize)]
35
+ pub struct ImageMetadata {
36
+ #[serde(flatten)]
37
+ data: HashMap<String, Value>,
38
+ }
39
+
40
+ impl ImageMetadata {
41
+ pub fn new(
42
+ image_file_name: String,
43
+ width: u32,
44
+ height: u32,
45
+ mut extra: HashMap<String, Value>,
46
+ ) -> Self {
47
+ extra.insert(
48
+ IMAGE_FILE_NAME_FIELD.to_owned(),
49
+ Value::String(image_file_name),
50
+ );
51
+ extra.insert(WIDTH_FIELD.to_owned(), Value::from(width));
52
+ extra.insert(HEIGHT_FIELD.to_owned(), Value::from(height));
53
+
54
+ Self { data: extra }
55
+ }
56
+ }
57
+
58
+ #[cfg(test)]
59
+ mod tests {
60
+ use super::*;
61
+
62
+ use serde_json::json;
63
+
64
+ #[test]
65
+ fn cli_managed_fields_override_sidecar_fields() {
66
+ let extra = serde_json::from_value(json!({
67
+ (IMAGE_FILE_NAME_FIELD): "from-sidecar.png",
68
+ (WIDTH_FIELD): 1,
69
+ (HEIGHT_FIELD): 2,
70
+ "custom": "keep-me"
71
+ }))
72
+ .unwrap();
73
+
74
+ let metadata = ImageMetadata::new("from-cli.png".to_owned(), 100, 200, extra);
75
+ let serialized = serde_json::to_value(metadata).unwrap();
76
+
77
+ let expected = json!({
78
+ (IMAGE_FILE_NAME_FIELD): "from-cli.png",
79
+ (WIDTH_FIELD): 100,
80
+ (HEIGHT_FIELD): 200,
81
+ "custom": "keep-me"
82
+ });
83
+
84
+ assert_eq!(serialized, expected);
85
+ }
86
+ }
@@ -1,14 +1,17 @@
1
1
  use std::collections::HashMap;
2
- use std::fs;
2
+ use std::fs::File;
3
+ use std::io::BufReader;
3
4
  use std::path::{Path, PathBuf};
4
5
  use std::str::FromStr as _;
5
6
 
6
7
  use anyhow::{Context as _, Result};
7
8
  use clap::{Arg, ArgMatches, Command};
8
9
  use console::style;
10
+ use itertools::Itertools as _;
9
11
  use log::{debug, info, warn};
10
12
  use objectstore_client::{ClientBuilder, ExpirationPolicy, Usecase};
11
13
  use secrecy::ExposeSecret as _;
14
+ use serde_json::Value;
12
15
  use sha2::{Digest as _, Sha256};
13
16
  use walkdir::WalkDir;
14
17
 
@@ -21,6 +24,7 @@ const EXPERIMENTAL_WARNING: &str =
21
24
  The command is subject to breaking changes, including removal, in any Sentry CLI release.";
22
25
 
23
26
  const IMAGE_EXTENSIONS: &[&str] = &["png", "jpg", "jpeg"];
27
+ const MAX_PIXELS_PER_IMAGE: u64 = 40_000_000;
24
28
 
25
29
  pub fn make_command(command: Command) -> Command {
26
30
  command
@@ -52,6 +56,12 @@ struct ImageInfo {
52
56
  height: u32,
53
57
  }
54
58
 
59
+ impl ImageInfo {
60
+ fn pixels(&self) -> u64 {
61
+ u64::from(self.width) * u64::from(self.height)
62
+ }
63
+ }
64
+
55
65
  pub fn execute(matches: &ArgMatches) -> Result<()> {
56
66
  eprintln!("{EXPERIMENTAL_WARNING}");
57
67
 
@@ -88,6 +98,8 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
88
98
  if images.len() == 1 { "file" } else { "files" }
89
99
  );
90
100
 
101
+ validate_image_sizes(&images)?;
102
+
91
103
  // Upload image files to objectstore
92
104
  println!(
93
105
  "{} Uploading {} image {}",
@@ -95,6 +107,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
95
107
  style(images.len()).yellow(),
96
108
  if images.len() == 1 { "file" } else { "files" }
97
109
  );
110
+
98
111
  let manifest_entries = upload_images(images, &org, &project)?;
99
112
 
100
113
  // Build manifest from discovered images
@@ -123,6 +136,14 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
123
136
  }
124
137
  );
125
138
 
139
+ if let Some(url) = &response.snapshot_url {
140
+ println!(
141
+ "{} View snapshots at {}",
142
+ style(">").dim(),
143
+ style(url).cyan()
144
+ );
145
+ }
146
+
126
147
  Ok(())
127
148
  }
128
149
 
@@ -166,11 +187,49 @@ fn collect_image_info(dir: &Path, path: &Path) -> Option<ImageInfo> {
166
187
  })
167
188
  }
168
189
 
169
- fn compute_sha256_hash(data: &[u8]) -> String {
190
+ fn validate_image_sizes(images: &[ImageInfo]) -> Result<()> {
191
+ let mut violations = images
192
+ .iter()
193
+ .filter(|img| img.pixels() > MAX_PIXELS_PER_IMAGE)
194
+ .map(|img| {
195
+ let path = img.relative_path.display();
196
+ let width = img.width;
197
+ let height = img.height;
198
+ let pixels = img.pixels();
199
+
200
+ format!(" {path} ({width}x{height} = {pixels} pixels)")
201
+ })
202
+ .peekable();
203
+
204
+ if violations.peek().is_some() {
205
+ let violation_messages = violations.join("\n");
206
+
207
+ anyhow::bail!(
208
+ "The following images exceed the maximum pixel limit of {MAX_PIXELS_PER_IMAGE}:\n{violation_messages}",
209
+ );
210
+ }
211
+
212
+ Ok(())
213
+ }
214
+
215
+ fn compute_sha256_hash(path: &Path) -> Result<String> {
216
+ use std::io::Read as _;
217
+
218
+ let mut file = std::fs::File::open(path)
219
+ .with_context(|| format!("Failed to open image for hashing: {}", path.display()))?;
170
220
  let mut hasher = Sha256::new();
171
- hasher.update(data);
221
+ let mut buffer = [0u8; 8192];
222
+ loop {
223
+ let bytes_read = file
224
+ .read(&mut buffer)
225
+ .with_context(|| format!("Failed to read image for hashing: {}", path.display()))?;
226
+ if bytes_read == 0 {
227
+ break;
228
+ }
229
+ hasher.update(&buffer[..bytes_read]);
230
+ }
172
231
  let result = hasher.finalize();
173
- format!("{result:x}")
232
+ Ok(format!("{result:x}"))
174
233
  }
175
234
 
176
235
  fn is_hidden(root: &Path, path: &Path) -> bool {
@@ -188,6 +247,29 @@ fn is_image_file(path: &Path) -> bool {
188
247
  .unwrap_or(false)
189
248
  }
190
249
 
250
+ /// Reads the companion JSON sidecar for an image, if it exists.
251
+ ///
252
+ /// For an image at `path/to/button.png`, looks for `path/to/button.json`.
253
+ /// Returns a map of all key-value pairs from the JSON file.
254
+ fn read_sidecar_metadata(image_path: &Path) -> Result<HashMap<String, Value>> {
255
+ let sidecar_path = image_path.with_extension("json");
256
+ if !sidecar_path.is_file() {
257
+ return Ok(HashMap::new());
258
+ }
259
+
260
+ debug!("Reading sidecar metadata: {}", sidecar_path.display());
261
+
262
+ let sidecar_file = File::open(&sidecar_path)
263
+ .with_context(|| format!("Failed to open sidecar file {}", sidecar_path.display()))?;
264
+
265
+ serde_json::from_reader(BufReader::new(sidecar_file)).with_context(|| {
266
+ format!(
267
+ "Failed to read sidecar file {} as JSON",
268
+ sidecar_path.display()
269
+ )
270
+ })
271
+ }
272
+
191
273
  fn upload_images(
192
274
  images: Vec<ImageInfo>,
193
275
  org: &str,
@@ -211,9 +293,22 @@ fn upload_images(
211
293
  .build()?;
212
294
 
213
295
  let mut scope = Usecase::new("preprod").scope();
214
- for (key, value) in &options.objectstore.scopes {
215
- scope = scope.push(key, value);
296
+ let (mut org_id, mut project_id): (Option<String>, Option<String>) = (None, None);
297
+ for (key, value) in options.objectstore.scopes.into_iter() {
298
+ scope = scope.push(&key, value.clone());
299
+ if key == "org" {
300
+ org_id = Some(value);
301
+ } else if key == "project" {
302
+ project_id = Some(value);
303
+ }
216
304
  }
305
+ let Some(org_id) = org_id else {
306
+ anyhow::bail!("Missing org in UploadOptions scope");
307
+ };
308
+ let Some(project_id) = project_id else {
309
+ anyhow::bail!("Missing project in UploadOptions scope");
310
+ };
311
+
217
312
  let session = scope.session(&client)?;
218
313
 
219
314
  let runtime = tokio::runtime::Builder::new_current_thread()
@@ -228,16 +323,20 @@ fn upload_images(
228
323
  for image in images {
229
324
  debug!("Processing image: {}", image.path.display());
230
325
 
231
- let contents = fs::read(&image.path)
232
- .with_context(|| format!("Failed to read image: {}", image.path.display()))?;
233
- let hash = compute_sha256_hash(&contents);
326
+ let hash = compute_sha256_hash(&image.path)?;
327
+ let file = runtime
328
+ .block_on(tokio::fs::File::open(&image.path))
329
+ .with_context(|| {
330
+ format!("Failed to open image for upload: {}", image.path.display())
331
+ })?;
234
332
 
235
- info!("Queueing {} as {hash}", image.relative_path.display());
333
+ let key = format!("{org_id}/{project_id}/{hash}");
334
+ info!("Queueing {} as {key}", image.relative_path.display());
236
335
 
237
336
  many_builder = many_builder.push(
238
337
  session
239
- .put(contents)
240
- .key(&hash)
338
+ .put_file(file)
339
+ .key(&key)
241
340
  .expiration_policy(expiration),
242
341
  );
243
342
 
@@ -247,13 +346,15 @@ fn upload_images(
247
346
  .unwrap_or_default()
248
347
  .to_string_lossy()
249
348
  .into_owned();
349
+
350
+ let extra = read_sidecar_metadata(&image.path).unwrap_or_else(|err| {
351
+ warn!("Error reading sidecar metadata, ignoring it instead: {err:#}");
352
+ HashMap::new()
353
+ });
354
+
250
355
  manifest_entries.insert(
251
356
  hash,
252
- ImageMetadata {
253
- image_file_name,
254
- width: image.width,
255
- height: image.height,
256
- },
357
+ ImageMetadata::new(image_file_name, image.width, image.height, extra),
257
358
  );
258
359
  }
259
360
 
@@ -280,3 +381,28 @@ fn upload_images(
280
381
  }
281
382
  }
282
383
  }
384
+
385
+ #[cfg(test)]
386
+ mod tests {
387
+ use super::*;
388
+
389
+ fn make_image(width: u32, height: u32) -> ImageInfo {
390
+ ImageInfo {
391
+ path: PathBuf::from("img.png"),
392
+ relative_path: PathBuf::from("img.png"),
393
+ width,
394
+ height,
395
+ }
396
+ }
397
+
398
+ #[test]
399
+ fn test_validate_image_sizes_at_limit_passes() {
400
+ assert!(validate_image_sizes(&[make_image(8000, 5000)]).is_ok());
401
+ }
402
+
403
+ #[test]
404
+ fn test_validate_image_sizes_over_limit_fails() {
405
+ let err = validate_image_sizes(&[make_image(8001, 5000)]).unwrap_err();
406
+ assert!(err.to_string().contains("exceed the maximum pixel limit"));
407
+ }
408
+ }
@@ -32,6 +32,7 @@ mod login;
32
32
  mod logs;
33
33
  mod monitors;
34
34
  mod organizations;
35
+ mod proguard;
35
36
  mod projects;
36
37
  mod react_native;
37
38
  mod releases;
@@ -60,6 +61,7 @@ macro_rules! each_subcommand {
60
61
  $mac!(logs);
61
62
  $mac!(monitors);
62
63
  $mac!(organizations);
64
+ $mac!(proguard);
63
65
  $mac!(projects);
64
66
  $mac!(react_native);
65
67
  $mac!(releases);
@@ -0,0 +1,45 @@
1
+ use anyhow::Result;
2
+ use clap::{ArgMatches, Command};
3
+
4
+ pub mod upload;
5
+ pub mod uuid;
6
+
7
+ macro_rules! each_subcommand {
8
+ ($mac:ident) => {
9
+ $mac!(upload);
10
+ $mac!(uuid);
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::proguard::$name::make_command(
18
+ Command::new(stringify!($name).replace('_', "-")),
19
+ ));
20
+ }};
21
+ }
22
+
23
+ command = command
24
+ .about("Manage ProGuard mapping files.")
25
+ .subcommand_required(true)
26
+ .arg_required_else_help(true);
27
+
28
+ each_subcommand!(add_subcommand);
29
+ command
30
+ }
31
+
32
+ pub fn execute(matches: &ArgMatches) -> Result<()> {
33
+ macro_rules! execute_subcommand {
34
+ ($name:ident) => {{
35
+ if let Some(sub_matches) =
36
+ matches.subcommand_matches(&stringify!($name).replace('_', "-"))
37
+ {
38
+ return crate::commands::proguard::$name::execute(&sub_matches);
39
+ }
40
+ }};
41
+ }
42
+
43
+ each_subcommand!(execute_subcommand);
44
+ unreachable!();
45
+ }
@@ -59,13 +59,15 @@ pub fn make_command(command: Command) -> Command {
59
59
  .short('u')
60
60
  .value_name("UUID")
61
61
  .value_parser(Uuid::parse_str)
62
+ .hide(true)
62
63
  .help(
63
- "Explicitly override the UUID of the mapping file with another one.{n}\
64
- This should be used with caution as it means that you can upload \
65
- multiple mapping files if you don't take care. This however can \
66
- be useful if you have a build process in which you need to know \
67
- the UUID of the proguard file before it was created. If you upload \
68
- a file with a forced UUID you can only upload a single proguard file.",
64
+ "[DEPRECATED] Manually override the UUID for the uploaded mapping.\n\
65
+ We no longer recommend using this option. \
66
+ If you use this option, you must use it consistently, and you must \
67
+ ensure the UUID is generated deterministically based on the ProGuard \
68
+ mapping. \n\
69
+ If you need to know the UUID before upload, we recommend using the \
70
+ `proguard uuid` command.",
69
71
  ),
70
72
  )
71
73
  }
@@ -93,10 +95,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
93
95
  // them all up.
94
96
  for path in &paths {
95
97
  match ByteView::open(path) {
96
- Ok(byteview) => match ProguardMapping::try_from(byteview) {
97
- Ok(mapping) => mappings.push(mapping),
98
- Err(e) => eprintln!("warning: ignoring proguard mapping '{path}': {e}"),
99
- },
98
+ Ok(byteview) => mappings.push(ProguardMapping::from(byteview)),
100
99
  Err(ref err) if err.kind() == io::ErrorKind::NotFound => {
101
100
  eprintln!(
102
101
  "warning: proguard mapping '{path}' does not exist. This \
@@ -0,0 +1,36 @@
1
+ use anyhow::{Context as _, Result};
2
+ use clap::{Arg, ArgMatches, Command};
3
+ use symbolic::common::ByteView;
4
+
5
+ use crate::utils::proguard::ProguardMapping;
6
+
7
+ pub fn make_command(command: Command) -> Command {
8
+ command
9
+ .about("Compute the UUID for a ProGuard mapping file.")
10
+ .long_about(
11
+ "Compute the UUID for a ProGuard mapping file.\n\n\
12
+ This command computes and prints to stdout the UUID of the ProGuard \
13
+ mapping at the specified path. This is the UUID that will be set by \
14
+ the `proguard upload` command. The UUID is deterministicly computed \
15
+ based on the file contents.",
16
+ )
17
+ .arg(
18
+ Arg::new("path")
19
+ .value_name("PATH")
20
+ .help("The path to the mapping file.")
21
+ .required(true),
22
+ )
23
+ }
24
+
25
+ pub fn execute(matches: &ArgMatches) -> Result<()> {
26
+ let path = matches
27
+ .get_one::<String>("path")
28
+ .expect("required argument");
29
+
30
+ let byteview = ByteView::open(path)
31
+ .with_context(|| format!("failed to open proguard mapping '{path}'"))?;
32
+ let mapping = ProguardMapping::from(byteview);
33
+
34
+ println!("{}", mapping.uuid());
35
+ Ok(())
36
+ }
@@ -0,0 +1,11 @@
1
+ use anyhow::Result;
2
+ use clap::{ArgMatches, Command};
3
+
4
+ pub fn make_command(command: Command) -> Command {
5
+ // Retained as a top-level command for backward compatibility.
6
+ crate::commands::proguard::upload::make_command(command)
7
+ }
8
+
9
+ pub fn execute(matches: &ArgMatches) -> Result<()> {
10
+ crate::commands::proguard::upload::execute(matches)
11
+ }
@@ -380,24 +380,22 @@ impl<'a> DifFile<'a> {
380
380
  pub fn is_usable(&self) -> bool {
381
381
  match self {
382
382
  DifFile::Archive(_) => self.has_ids() && self.features().has_some(),
383
- DifFile::Proguard(pg) => pg.get().has_line_info(),
383
+ DifFile::Proguard(..) => true,
384
384
  }
385
385
  }
386
386
 
387
387
  pub fn get_problem(&self) -> Option<&'static str> {
388
388
  if self.is_usable() {
389
- None
390
- } else {
391
- Some(match self {
392
- DifFile::Archive(..) => {
393
- if !self.has_ids() {
394
- "missing debug identifier, likely stripped"
395
- } else {
396
- "missing debug or unwind information"
397
- }
398
- }
399
- DifFile::Proguard(..) => "missing line information",
400
- })
389
+ return None;
390
+ }
391
+
392
+ match self {
393
+ DifFile::Archive(..) => Some(if !self.has_ids() {
394
+ "missing debug identifier, likely stripped"
395
+ } else {
396
+ "missing debug or unwind information"
397
+ }),
398
+ DifFile::Proguard(..) => None,
401
399
  }
402
400
  }
403
401