sentry-cli 3.3.0__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.3.0 → sentry_cli-3.3.1}/Cargo.lock +1 -1
  2. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/Cargo.toml +1 -1
  3. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/PKG-INFO +2 -2
  4. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/README.md +1 -1
  5. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/sentry_cli.egg-info/PKG-INFO +2 -2
  6. sentry_cli-3.3.1/src/api/data_types/snapshots.rs +86 -0
  7. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/build/snapshots.rs +135 -17
  8. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/proguard/upload.rs +1 -4
  9. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/proguard/uuid.rs +1 -2
  10. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/dif.rs +11 -13
  11. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/proguard/mapping.rs +4 -29
  12. sentry_cli-3.3.0/src/api/data_types/snapshots.rs +0 -31
  13. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/LICENSE +0 -0
  14. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/MANIFEST.in +0 -0
  15. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/AGENTS.md +0 -0
  16. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/CLAUDE.md +0 -0
  17. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/Cargo.toml +0 -0
  18. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/build.rs +0 -0
  19. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
  20. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
  21. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
  22. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
  23. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
  24. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Info.plist +0 -0
  25. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Products/Applications/DemoApp.app/Assets.car +0 -0
  26. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
  27. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/src/lib.rs +0 -0
  28. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/build.rs +0 -0
  29. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/pyproject.toml +0 -0
  30. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/sentry_cli.egg-info/SOURCES.txt +0 -0
  31. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/sentry_cli.egg-info/dependency_links.txt +0 -0
  32. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/sentry_cli.egg-info/top_level.txt +0 -0
  33. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/setup.cfg +0 -0
  34. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/setup.py +0 -0
  35. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/AGENTS.md +0 -0
  36. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/CLAUDE.md +0 -0
  37. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/connection_manager.rs +0 -0
  38. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/artifact.rs +0 -0
  39. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/build.rs +0 -0
  40. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/compression.rs +0 -0
  41. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/dif.rs +0 -0
  42. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/file_state.rs +0 -0
  43. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
  44. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/mod.rs +0 -0
  45. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/upload/mod.rs +0 -0
  46. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/upload/options.rs +0 -0
  47. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/deploy.rs +0 -0
  48. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/mod.rs +0 -0
  49. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/encoding.rs +0 -0
  50. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/envelopes_api.rs +0 -0
  51. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/errors/api_error.rs +0 -0
  52. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/errors/mod.rs +0 -0
  53. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/errors/sentry_error.rs +0 -0
  54. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/mod.rs +0 -0
  55. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/pagination.rs +0 -0
  56. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/serialization.rs +0 -0
  57. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/bashsupport.sh +0 -0
  58. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/bash_hook.rs +0 -0
  59. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/build/mod.rs +0 -0
  60. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/build/upload.rs +0 -0
  61. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/dart_symbol_map/mod.rs +0 -0
  62. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/dart_symbol_map/upload.rs +0 -0
  63. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/bundle_jvm.rs +0 -0
  64. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/bundle_sources.rs +0 -0
  65. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/check.rs +0 -0
  66. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/find.rs +0 -0
  67. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/mod.rs +0 -0
  68. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/print_sources.rs +0 -0
  69. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/upload.rs +0 -0
  70. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/deploys/list.rs +0 -0
  71. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/deploys/mod.rs +0 -0
  72. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/deploys/new.rs +0 -0
  73. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/derive_parser.rs +0 -0
  74. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/events/list.rs +0 -0
  75. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/events/mod.rs +0 -0
  76. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/info.rs +0 -0
  77. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/list.rs +0 -0
  78. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/mod.rs +0 -0
  79. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/mute.rs +0 -0
  80. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/resolve.rs +0 -0
  81. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/unresolve.rs +0 -0
  82. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/login.rs +0 -0
  83. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/logs/list.rs +0 -0
  84. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/logs/mod.rs +0 -0
  85. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/mod.rs +0 -0
  86. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/monitors/list.rs +0 -0
  87. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/monitors/mod.rs +0 -0
  88. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/monitors/run.rs +0 -0
  89. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/organizations/list.rs +0 -0
  90. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/organizations/mod.rs +0 -0
  91. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/proguard/mod.rs +0 -0
  92. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/projects/list.rs +0 -0
  93. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/projects/mod.rs +0 -0
  94. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/react_native/gradle.rs +0 -0
  95. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/react_native/mod.rs +0 -0
  96. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/react_native/xcode.rs +0 -0
  97. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/archive.rs +0 -0
  98. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/delete.rs +0 -0
  99. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/finalize.rs +0 -0
  100. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/info.rs +0 -0
  101. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/list.rs +0 -0
  102. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/mod.rs +0 -0
  103. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/new.rs +0 -0
  104. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/propose_version.rs +0 -0
  105. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/restore.rs +0 -0
  106. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/set_commits.rs +0 -0
  107. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/repos/list.rs +0 -0
  108. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/repos/mod.rs +0 -0
  109. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_envelope.rs +0 -0
  110. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_event.rs +0 -0
  111. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_metric/common_args.rs +0 -0
  112. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_metric/increment.rs +0 -0
  113. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_metric/mod.rs +0 -0
  114. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_metric/set.rs +0 -0
  115. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/sourcemaps/inject.rs +0 -0
  116. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/sourcemaps/mod.rs +0 -0
  117. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/sourcemaps/resolve.rs +0 -0
  118. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/sourcemaps/upload.rs +0 -0
  119. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/uninstall.rs +0 -0
  120. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/update.rs +0 -0
  121. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/upload_dif.rs +0 -0
  122. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/upload_dsym.rs +0 -0
  123. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/upload_proguard.rs +0 -0
  124. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/config.rs +0 -0
  125. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/constants.rs +0 -0
  126. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/main.rs +0 -0
  127. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/android.rs +0 -0
  128. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/args.rs +0 -0
  129. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/auth_token_impl.rs +0 -0
  130. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/error.rs +0 -0
  131. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/mod.rs +0 -0
  132. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/org_auth_token.rs +0 -0
  133. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/redacting.rs +0 -0
  134. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/test.rs +0 -0
  135. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/user_auth_token.rs +0 -0
  136. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/build/apple.rs +0 -0
  137. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/build/mod.rs +0 -0
  138. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/build/normalize.rs +0 -0
  139. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/build/validation.rs +0 -0
  140. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/chunks/mod.rs +0 -0
  141. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/chunks/options.rs +0 -0
  142. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/chunks/types.rs +0 -0
  143. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/chunks/upload.rs +0 -0
  144. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/ci.rs +0 -0
  145. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/cordova.rs +0 -0
  146. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/dif_upload/error.rs +0 -0
  147. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/dif_upload/mod.rs +0 -0
  148. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/event.rs +0 -0
  149. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/file_search.rs +0 -0
  150. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/file_upload.rs +0 -0
  151. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/formatting.rs +0 -0
  152. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/fs.rs +0 -0
  153. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/http.rs +0 -0
  154. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/logging.rs +0 -0
  155. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/mod.rs +0 -0
  156. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/non_empty.rs +0 -0
  157. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/progress.rs +0 -0
  158. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/proguard/mod.rs +0 -0
  159. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/proguard/upload.rs +0 -0
  160. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/releases.rs +0 -0
  161. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/retry.rs +0 -0
  162. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_default_twenty.snap +0 -0
  163. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_ignore_missing.snap +0 -0
  164. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_base.snap +0 -0
  165. {sentry_cli-3.3.0 → 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.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__get_commits_from_git.snap +0 -0
  167. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/source_bundle.rs +0 -0
  168. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/sourcemaps/inject.rs +0 -0
  169. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/sourcemaps.rs +0 -0
  170. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/system.rs +0 -0
  171. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/ui.rs +0 -0
  172. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/update.rs +0 -0
  173. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/value_parsers.rs +0 -0
  174. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/vcs.rs +0 -0
  175. {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/xcode.rs +0 -0
@@ -3414,7 +3414,7 @@ dependencies = [
3414
3414
 
3415
3415
  [[package]]
3416
3416
  name = "sentry-cli"
3417
- version = "3.3.0"
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.3.0"
4
+ version = "3.3.1"
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.0
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.3.0
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
 
@@ -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
@@ -174,11 +187,49 @@ fn collect_image_info(dir: &Path, path: &Path) -> Option<ImageInfo> {
174
187
  })
175
188
  }
176
189
 
177
- 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()))?;
178
220
  let mut hasher = Sha256::new();
179
- 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
+ }
180
231
  let result = hasher.finalize();
181
- format!("{result:x}")
232
+ Ok(format!("{result:x}"))
182
233
  }
183
234
 
184
235
  fn is_hidden(root: &Path, path: &Path) -> bool {
@@ -196,6 +247,29 @@ fn is_image_file(path: &Path) -> bool {
196
247
  .unwrap_or(false)
197
248
  }
198
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
+
199
273
  fn upload_images(
200
274
  images: Vec<ImageInfo>,
201
275
  org: &str,
@@ -219,9 +293,22 @@ fn upload_images(
219
293
  .build()?;
220
294
 
221
295
  let mut scope = Usecase::new("preprod").scope();
222
- for (key, value) in &options.objectstore.scopes {
223
- 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
+ }
224
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
+
225
312
  let session = scope.session(&client)?;
226
313
 
227
314
  let runtime = tokio::runtime::Builder::new_current_thread()
@@ -236,16 +323,20 @@ fn upload_images(
236
323
  for image in images {
237
324
  debug!("Processing image: {}", image.path.display());
238
325
 
239
- let contents = fs::read(&image.path)
240
- .with_context(|| format!("Failed to read image: {}", image.path.display()))?;
241
- 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
+ })?;
242
332
 
243
- 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());
244
335
 
245
336
  many_builder = many_builder.push(
246
337
  session
247
- .put(contents)
248
- .key(&hash)
338
+ .put_file(file)
339
+ .key(&key)
249
340
  .expiration_policy(expiration),
250
341
  );
251
342
 
@@ -255,13 +346,15 @@ fn upload_images(
255
346
  .unwrap_or_default()
256
347
  .to_string_lossy()
257
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
+
258
355
  manifest_entries.insert(
259
356
  hash,
260
- ImageMetadata {
261
- image_file_name,
262
- width: image.width,
263
- height: image.height,
264
- },
357
+ ImageMetadata::new(image_file_name, image.width, image.height, extra),
265
358
  );
266
359
  }
267
360
 
@@ -288,3 +381,28 @@ fn upload_images(
288
381
  }
289
382
  }
290
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
+ }
@@ -95,10 +95,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
95
95
  // them all up.
96
96
  for path in &paths {
97
97
  match ByteView::open(path) {
98
- Ok(byteview) => match ProguardMapping::try_from(byteview) {
99
- Ok(mapping) => mappings.push(mapping),
100
- Err(e) => eprintln!("warning: ignoring proguard mapping '{path}': {e}"),
101
- },
98
+ Ok(byteview) => mappings.push(ProguardMapping::from(byteview)),
102
99
  Err(ref err) if err.kind() == io::ErrorKind::NotFound => {
103
100
  eprintln!(
104
101
  "warning: proguard mapping '{path}' does not exist. This \
@@ -29,8 +29,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
29
29
 
30
30
  let byteview = ByteView::open(path)
31
31
  .with_context(|| format!("failed to open proguard mapping '{path}'"))?;
32
- let mapping = ProguardMapping::try_from(byteview)
33
- .with_context(|| format!("failed to parse proguard mapping '{path}'"))?;
32
+ let mapping = ProguardMapping::from(byteview);
34
33
 
35
34
  println!("{}", mapping.uuid());
36
35
  Ok(())
@@ -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
 
@@ -2,23 +2,16 @@ use std::borrow::Cow;
2
2
  use std::fmt::{Display, Formatter, Result as FmtResult};
3
3
 
4
4
  use symbolic::common::{ByteView, DebugId};
5
- use thiserror::Error;
6
5
  use uuid::Uuid;
7
6
 
8
7
  use crate::utils::chunks::Assemblable;
9
8
 
10
- #[derive(Debug, Error)]
11
- pub enum ProguardMappingError {
12
- #[error("Proguard mapping does not contain line information")]
13
- MissingLineInfo,
14
- }
15
-
16
9
  pub struct ProguardMapping<'a> {
17
10
  bytes: ByteView<'a>,
18
11
  uuid: Uuid,
19
12
  }
20
13
 
21
- impl<'a> ProguardMapping<'a> {
14
+ impl ProguardMapping<'_> {
22
15
  /// Get the UUID of the mapping.
23
16
  pub fn uuid(&self) -> Uuid {
24
17
  self.uuid
@@ -29,31 +22,13 @@ impl<'a> ProguardMapping<'a> {
29
22
  pub fn force_uuid(&mut self, uuid: Uuid) {
30
23
  self.uuid = uuid;
31
24
  }
32
-
33
- /// Create a new `ProguardMapping` from a `ByteView`.
34
- /// Not public because we want to ensure that the `ByteView` contains line
35
- /// information, and this method does not check for that. To create a
36
- /// `ProguardMapping` externally, use the `TryFrom<ByteView>` implementation.
37
- fn new(bytes: ByteView<'a>, uuid: Uuid) -> Self {
38
- Self { bytes, uuid }
39
- }
40
25
  }
41
26
 
42
- impl<'a> TryFrom<ByteView<'a>> for ProguardMapping<'a> {
43
- type Error = ProguardMappingError;
44
-
45
- /// Try to create a `ProguardMapping` from a `ByteView`.
46
- /// The method returns an error if the mapping does not contain
47
- /// line information.
48
- fn try_from(value: ByteView<'a>) -> Result<Self, Self::Error> {
27
+ impl<'a> From<ByteView<'a>> for ProguardMapping<'a> {
28
+ fn from(value: ByteView<'a>) -> Self {
49
29
  let mapping = ::proguard::ProguardMapping::new(&value);
50
-
51
- if !mapping.has_line_info() {
52
- return Err(ProguardMappingError::MissingLineInfo);
53
- }
54
-
55
30
  let uuid = mapping.uuid();
56
- Ok(ProguardMapping::new(value, uuid))
31
+ Self { bytes: value, uuid }
57
32
  }
58
33
  }
59
34
 
@@ -1,31 +0,0 @@
1
- //! Data types for the snapshots API.
2
-
3
- use std::collections::HashMap;
4
-
5
- use serde::{Deserialize, Serialize};
6
-
7
- /// Response from the create snapshot endpoint.
8
- #[derive(Debug, Deserialize)]
9
- #[serde(rename_all = "camelCase")]
10
- pub struct CreateSnapshotResponse {
11
- pub artifact_id: String,
12
- pub image_count: u64,
13
- pub snapshot_url: Option<String>,
14
- }
15
-
16
- // Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
17
- /// Manifest describing a set of snapshot images for an app.
18
- #[derive(Debug, Serialize)]
19
- pub struct SnapshotsManifest {
20
- pub app_id: String,
21
- pub images: HashMap<String, ImageMetadata>,
22
- }
23
-
24
- // Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
25
- /// Metadata for a single image in a snapshot manifest.
26
- #[derive(Debug, Serialize)]
27
- pub struct ImageMetadata {
28
- pub image_file_name: String,
29
- pub width: u32,
30
- pub height: u32,
31
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes