sentry-cli 3.3.5__tar.gz → 3.4.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 (180) hide show
  1. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/Cargo.lock +7 -28
  2. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/Cargo.toml +3 -3
  3. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/PKG-INFO +1 -1
  4. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/sentry_cli.egg-info/PKG-INFO +1 -1
  5. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/snapshots.rs +49 -2
  6. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/mod.rs +2 -1
  7. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/build/snapshots.rs +110 -84
  8. sentry_cli-3.4.1/src/commands/debug_files/bundle_jvm.rs +535 -0
  9. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/file_search.rs +26 -5
  10. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/logging.rs +4 -8
  11. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/progress.rs +1 -1
  12. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/source_bundle.rs +58 -32
  13. sentry_cli-3.3.5/src/commands/debug_files/bundle_jvm.rs +0 -102
  14. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/LICENSE +0 -0
  15. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/MANIFEST.in +0 -0
  16. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/README.md +0 -0
  17. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/AGENTS.md +0 -0
  18. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/CLAUDE.md +0 -0
  19. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/Cargo.toml +0 -0
  20. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/build.rs +0 -0
  21. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
  22. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
  23. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
  24. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
  25. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
  26. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Info.plist +0 -0
  27. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Products/Applications/DemoApp.app/Assets.car +0 -0
  28. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
  29. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/apple-catalog-parsing/src/lib.rs +0 -0
  30. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/build.rs +0 -0
  31. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/pyproject.toml +0 -0
  32. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/sentry_cli.egg-info/SOURCES.txt +0 -0
  33. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/sentry_cli.egg-info/dependency_links.txt +0 -0
  34. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/sentry_cli.egg-info/top_level.txt +0 -0
  35. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/setup.cfg +0 -0
  36. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/setup.py +0 -0
  37. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/AGENTS.md +0 -0
  38. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/CLAUDE.md +0 -0
  39. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/connection_manager.rs +0 -0
  40. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/artifact.rs +0 -0
  41. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/build.rs +0 -0
  42. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/compression.rs +0 -0
  43. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/dif.rs +0 -0
  44. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/file_state.rs +0 -0
  45. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
  46. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/mod.rs +0 -0
  47. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/upload/mod.rs +0 -0
  48. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/chunking/upload/options.rs +0 -0
  49. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/code_mappings.rs +0 -0
  50. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/deploy.rs +0 -0
  51. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/data_types/mod.rs +0 -0
  52. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/encoding.rs +0 -0
  53. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/envelopes_api.rs +0 -0
  54. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/errors/api_error.rs +0 -0
  55. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/errors/mod.rs +0 -0
  56. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/errors/sentry_error.rs +0 -0
  57. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/pagination.rs +0 -0
  58. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/api/serialization.rs +0 -0
  59. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/bashsupport.sh +0 -0
  60. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/bash_hook.rs +0 -0
  61. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/build/download.rs +0 -0
  62. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/build/mod.rs +0 -0
  63. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/build/upload.rs +0 -0
  64. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/code_mappings/mod.rs +0 -0
  65. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/code_mappings/upload.rs +0 -0
  66. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/dart_symbol_map/mod.rs +0 -0
  67. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/dart_symbol_map/upload.rs +0 -0
  68. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/debug_files/bundle_sources.rs +0 -0
  69. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/debug_files/check.rs +0 -0
  70. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/debug_files/find.rs +0 -0
  71. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/debug_files/mod.rs +0 -0
  72. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/debug_files/print_sources.rs +0 -0
  73. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/debug_files/upload.rs +0 -0
  74. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/deploys/list.rs +0 -0
  75. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/deploys/mod.rs +0 -0
  76. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/deploys/new.rs +0 -0
  77. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/derive_parser.rs +0 -0
  78. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/events/list.rs +0 -0
  79. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/events/mod.rs +0 -0
  80. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/info.rs +0 -0
  81. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/issues/list.rs +0 -0
  82. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/issues/mod.rs +0 -0
  83. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/issues/mute.rs +0 -0
  84. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/issues/resolve.rs +0 -0
  85. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/issues/unresolve.rs +0 -0
  86. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/login.rs +0 -0
  87. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/logs/list.rs +0 -0
  88. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/logs/mod.rs +0 -0
  89. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/mod.rs +0 -0
  90. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/monitors/list.rs +0 -0
  91. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/monitors/mod.rs +0 -0
  92. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/monitors/run.rs +0 -0
  93. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/organizations/list.rs +0 -0
  94. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/organizations/mod.rs +0 -0
  95. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/proguard/mod.rs +0 -0
  96. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/proguard/upload.rs +0 -0
  97. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/proguard/uuid.rs +0 -0
  98. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/projects/list.rs +0 -0
  99. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/projects/mod.rs +0 -0
  100. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/react_native/gradle.rs +0 -0
  101. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/react_native/mod.rs +0 -0
  102. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/react_native/xcode.rs +0 -0
  103. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/archive.rs +0 -0
  104. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/delete.rs +0 -0
  105. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/finalize.rs +0 -0
  106. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/info.rs +0 -0
  107. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/list.rs +0 -0
  108. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/mod.rs +0 -0
  109. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/new.rs +0 -0
  110. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/propose_version.rs +0 -0
  111. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/restore.rs +0 -0
  112. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/releases/set_commits.rs +0 -0
  113. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/repos/list.rs +0 -0
  114. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/repos/mod.rs +0 -0
  115. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/send_envelope.rs +0 -0
  116. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/send_event.rs +0 -0
  117. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/send_metric/common_args.rs +0 -0
  118. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/send_metric/increment.rs +0 -0
  119. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/send_metric/mod.rs +0 -0
  120. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/send_metric/set.rs +0 -0
  121. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/sourcemaps/inject.rs +0 -0
  122. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/sourcemaps/mod.rs +0 -0
  123. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/sourcemaps/resolve.rs +0 -0
  124. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/sourcemaps/upload.rs +0 -0
  125. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/uninstall.rs +0 -0
  126. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/update.rs +0 -0
  127. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/upload_dif.rs +0 -0
  128. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/upload_dsym.rs +0 -0
  129. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/commands/upload_proguard.rs +0 -0
  130. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/config.rs +0 -0
  131. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/constants.rs +0 -0
  132. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/main.rs +0 -0
  133. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/android.rs +0 -0
  134. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/args.rs +0 -0
  135. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/auth_token/auth_token_impl.rs +0 -0
  136. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/auth_token/error.rs +0 -0
  137. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/auth_token/mod.rs +0 -0
  138. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/auth_token/org_auth_token.rs +0 -0
  139. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/auth_token/redacting.rs +0 -0
  140. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/auth_token/test.rs +0 -0
  141. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/auth_token/user_auth_token.rs +0 -0
  142. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/build/apple.rs +0 -0
  143. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/build/mod.rs +0 -0
  144. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/build/normalize.rs +0 -0
  145. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/build/validation.rs +0 -0
  146. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/build_vcs.rs +0 -0
  147. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/chunks/mod.rs +0 -0
  148. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/chunks/options.rs +0 -0
  149. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/chunks/types.rs +0 -0
  150. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/chunks/upload.rs +0 -0
  151. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/ci.rs +0 -0
  152. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/cordova.rs +0 -0
  153. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/dif.rs +0 -0
  154. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/dif_upload/error.rs +0 -0
  155. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/dif_upload/mod.rs +0 -0
  156. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/event.rs +0 -0
  157. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/file_upload.rs +0 -0
  158. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/formatting.rs +0 -0
  159. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/fs.rs +0 -0
  160. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/http.rs +0 -0
  161. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/mod.rs +0 -0
  162. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/non_empty.rs +0 -0
  163. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/proguard/mapping.rs +0 -0
  164. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/proguard/mod.rs +0 -0
  165. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/proguard/upload.rs +0 -0
  166. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/releases.rs +0 -0
  167. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/retry.rs +0 -0
  168. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_default_twenty.snap +0 -0
  169. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_ignore_missing.snap +0 -0
  170. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_base.snap +0 -0
  171. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_previous_commit.snap +0 -0
  172. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__get_commits_from_git.snap +0 -0
  173. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/sourcemaps/inject.rs +0 -0
  174. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/sourcemaps.rs +0 -0
  175. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/system.rs +0 -0
  176. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/ui.rs +0 -0
  177. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/update.rs +0 -0
  178. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/value_parsers.rs +0 -0
  179. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/vcs.rs +0 -0
  180. {sentry_cli-3.3.5 → sentry_cli-3.4.1}/src/utils/xcode.rs +0 -0
@@ -206,28 +206,6 @@ dependencies = [
206
206
  "tokio",
207
207
  ]
208
208
 
209
- [[package]]
210
- name = "async-stream"
211
- version = "0.3.6"
212
- source = "registry+https://github.com/rust-lang/crates.io-index"
213
- checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476"
214
- dependencies = [
215
- "async-stream-impl",
216
- "futures-core",
217
- "pin-project-lite",
218
- ]
219
-
220
- [[package]]
221
- name = "async-stream-impl"
222
- version = "0.3.6"
223
- source = "registry+https://github.com/rust-lang/crates.io-index"
224
- checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
225
- dependencies = [
226
- "proc-macro2",
227
- "quote",
228
- "syn",
229
- ]
230
-
231
209
  [[package]]
232
210
  name = "atomic-waker"
233
211
  version = "1.1.2"
@@ -2322,12 +2300,11 @@ dependencies = [
2322
2300
 
2323
2301
  [[package]]
2324
2302
  name = "objectstore-client"
2325
- version = "0.1.2"
2303
+ version = "0.1.6"
2326
2304
  source = "registry+https://github.com/rust-lang/crates.io-index"
2327
- checksum = "033eedf125e31b30962c0172842e964fc9983bbccd99d9ff033e7e413946861c"
2305
+ checksum = "f99caa869461b61decd1985c029d7e1462d1bde8e2448040db27d567165fcc1e"
2328
2306
  dependencies = [
2329
2307
  "async-compression",
2330
- "async-stream",
2331
2308
  "bytes",
2332
2309
  "futures-util",
2333
2310
  "infer",
@@ -2346,9 +2323,9 @@ dependencies = [
2346
2323
 
2347
2324
  [[package]]
2348
2325
  name = "objectstore-types"
2349
- version = "0.1.2"
2326
+ version = "0.1.6"
2350
2327
  source = "registry+https://github.com/rust-lang/crates.io-index"
2351
- checksum = "956cbdef3971ea108a15e5248625d6229870da3a3c637b6e7aada213526f8014"
2328
+ checksum = "c375bccef8773d1739eabb7e2b1bbd7e9a9071c8f9557e3b50dce7220e8c8736"
2352
2329
  dependencies = [
2353
2330
  "http",
2354
2331
  "humantime",
@@ -3345,6 +3322,7 @@ version = "0.8.0"
3345
3322
  source = "registry+https://github.com/rust-lang/crates.io-index"
3346
3323
  checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e"
3347
3324
  dependencies = [
3325
+ "serde",
3348
3326
  "zeroize",
3349
3327
  ]
3350
3328
 
@@ -3414,7 +3392,7 @@ dependencies = [
3414
3392
 
3415
3393
  [[package]]
3416
3394
  name = "sentry-cli"
3417
- version = "3.3.5"
3395
+ version = "3.4.1"
3418
3396
  dependencies = [
3419
3397
  "anyhow",
3420
3398
  "anylog",
@@ -4142,6 +4120,7 @@ dependencies = [
4142
4120
  "bytes",
4143
4121
  "futures-core",
4144
4122
  "futures-sink",
4123
+ "futures-util",
4145
4124
  "pin-project-lite",
4146
4125
  "tokio",
4147
4126
  ]
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  build = "build.rs"
3
3
  name = "sentry-cli"
4
- version = "3.3.5"
4
+ version = "3.4.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.1.2" , default-features = false, features = ["native-tls"] }
47
+ objectstore-client = { version = "0.1.6" , 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"
@@ -79,7 +79,7 @@ zip = "2.4.2"
79
79
  data-encoding = "2.3.3"
80
80
  magic_string = "0.3.4"
81
81
  chrono-tz = "0.8.4"
82
- secrecy = "0.8.0"
82
+ secrecy = { version = "0.8.0", features = ["serde"] }
83
83
  lru = "0.16.3"
84
84
  backon = { version = "1.5.2", features = ["std", "std-blocking-sleep"] }
85
85
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.3.5
3
+ Version: 3.4.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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.3.5
3
+ Version: 3.4.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
@@ -25,6 +25,14 @@ pub struct CreateSnapshotResponse {
25
25
  pub struct SnapshotsManifest<'a> {
26
26
  pub app_id: String,
27
27
  pub images: HashMap<String, ImageMetadata>,
28
+ /// If set, Sentry will only report images as changed if their difference %
29
+ /// is greater than this value (e.g. 0.01 = only report changes >= 1%).
30
+ #[serde(skip_serializing_if = "Option::is_none")]
31
+ pub diff_threshold: Option<f64>,
32
+ /// When true, this upload contains only a subset of images.
33
+ /// Removals and renames will not be detected on PRs.
34
+ #[serde(skip_serializing_if = "std::ops::Not::not")]
35
+ pub selective: bool,
28
36
  #[serde(flatten)]
29
37
  pub vcs_info: VcsInfo<'a>,
30
38
  }
@@ -32,8 +40,8 @@ pub struct SnapshotsManifest<'a> {
32
40
  // Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
33
41
  /// Metadata for a single image in a snapshot manifest.
34
42
  ///
35
- /// CLI-managed fields (`image_file_name`, `width`, `height`) override any
36
- /// identically named fields provided by user sidecar metadata.
43
+ /// CLI-managed fields (`width`, `height`) override any identically named
44
+ /// fields provided by user sidecar metadata.
37
45
  #[derive(Debug, Serialize)]
38
46
  pub struct ImageMetadata {
39
47
  #[serde(flatten)]
@@ -55,6 +63,45 @@ mod tests {
55
63
 
56
64
  use serde_json::json;
57
65
 
66
+ fn empty_vcs_info() -> VcsInfo<'static> {
67
+ VcsInfo {
68
+ head_sha: None,
69
+ base_sha: None,
70
+ vcs_provider: "".into(),
71
+ head_repo_name: "".into(),
72
+ base_repo_name: "".into(),
73
+ head_ref: "".into(),
74
+ base_ref: "".into(),
75
+ pr_number: None,
76
+ }
77
+ }
78
+
79
+ #[test]
80
+ fn manifest_omits_selective_when_false() {
81
+ let manifest = SnapshotsManifest {
82
+ app_id: "app".into(),
83
+ images: HashMap::new(),
84
+ diff_threshold: None,
85
+ selective: false,
86
+ vcs_info: empty_vcs_info(),
87
+ };
88
+ let json = serde_json::to_value(&manifest).unwrap();
89
+ assert!(!json.as_object().unwrap().contains_key("selective"));
90
+ }
91
+
92
+ #[test]
93
+ fn manifest_includes_selective_when_true() {
94
+ let manifest = SnapshotsManifest {
95
+ app_id: "app".into(),
96
+ images: HashMap::new(),
97
+ diff_threshold: None,
98
+ selective: true,
99
+ vcs_info: empty_vcs_info(),
100
+ };
101
+ let json = serde_json::to_value(&manifest).unwrap();
102
+ assert_eq!(json["selective"], json!(true));
103
+ }
104
+
58
105
  #[test]
59
106
  fn cli_managed_fields_override_sidecar_fields() {
60
107
  let extra = serde_json::from_value(json!({
@@ -33,7 +33,7 @@ use lazy_static::lazy_static;
33
33
  use log::{debug, info, warn};
34
34
  use parking_lot::Mutex;
35
35
  use regex::{Captures, Regex};
36
- use secrecy::ExposeSecret as _;
36
+ use secrecy::{ExposeSecret as _, SecretString};
37
37
  use serde::de::DeserializeOwned;
38
38
  use serde::{Deserialize, Serialize};
39
39
  use sha1_smol::Digest;
@@ -2065,5 +2065,6 @@ pub struct SnapshotsUploadOptions {
2065
2065
  pub struct ObjectstoreUploadOptions {
2066
2066
  pub url: String,
2067
2067
  pub scopes: Vec<(String, String)>,
2068
+ pub auth_token: Option<SecretString>,
2068
2069
  pub expiration_policy: String,
2069
2070
  }
@@ -9,7 +9,7 @@ use anyhow::{Context as _, Result};
9
9
  use clap::{Arg, ArgMatches, Command};
10
10
  use console::style;
11
11
  use itertools::Itertools as _;
12
- use log::{debug, info, warn};
12
+ use log::{debug, warn};
13
13
  use objectstore_client::{ClientBuilder, ExpirationPolicy, Usecase};
14
14
  use rayon::prelude::*;
15
15
  use secrecy::ExposeSecret as _;
@@ -51,6 +51,32 @@ pub fn make_command(command: Command) -> Command {
51
51
  .help("The application identifier.")
52
52
  .required(true),
53
53
  )
54
+ .arg(
55
+ Arg::new("diff_threshold")
56
+ .long("diff-threshold")
57
+ .value_name("THRESHOLD")
58
+ .value_parser(|s: &str| {
59
+ let v: f64 = s.parse().map_err(|e| format!("invalid float: {e}"))?;
60
+ if !(0.0..=1.0).contains(&v) {
61
+ return Err("value must be between 0.0 and 1.0".to_owned());
62
+ }
63
+ Ok(v)
64
+ })
65
+ .help(
66
+ "If set, Sentry will only report images as changed if their \
67
+ difference % is greater than this value. \
68
+ Example: 0.01 = only report image changes >= 1%.",
69
+ ),
70
+ )
71
+ .arg(
72
+ Arg::new("selective")
73
+ .long("selective")
74
+ .action(clap::ArgAction::SetTrue)
75
+ .help(
76
+ "Indicates this upload contains only a subset of images. \
77
+ Removals and renames cannot be detected on PRs.",
78
+ ),
79
+ )
54
80
  .git_metadata_args()
55
81
  }
56
82
 
@@ -123,9 +149,15 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
123
149
  let manifest_entries = upload_images(images, &org, &project)?;
124
150
 
125
151
  // Build manifest from discovered images
152
+ let diff_threshold = matches.get_one::<f64>("diff_threshold").copied();
153
+
154
+ let selective = matches.get_flag("selective");
155
+
126
156
  let manifest = SnapshotsManifest {
127
157
  app_id: app_id.clone(),
128
158
  images: manifest_entries,
159
+ diff_threshold,
160
+ selective,
129
161
  vcs_info,
130
162
  };
131
163
 
@@ -283,6 +315,11 @@ fn read_sidecar_metadata(image_path: &Path) -> Result<HashMap<String, Value>> {
283
315
  })
284
316
  }
285
317
 
318
+ struct PreparedImage {
319
+ path: PathBuf,
320
+ key: String,
321
+ }
322
+
286
323
  fn upload_images(
287
324
  images: Vec<ImageInfo>,
288
325
  org: &str,
@@ -295,33 +332,43 @@ fn upload_images(
295
332
  let expiration = ExpirationPolicy::from_str(&options.objectstore.expiration_policy)
296
333
  .context("Failed to parse expiration policy from upload options")?;
297
334
 
298
- let client = ClientBuilder::new(options.objectstore.url)
299
- .token({
300
- // TODO: replace with auth from `ObjectstoreUploadOptions` when appropriate
301
- let auth = match authenticated_api.auth() {
302
- Auth::Token(token) => token.raw().expose_secret().to_owned(),
303
- };
304
- auth
335
+ let mut builder = ClientBuilder::new(options.objectstore.url);
336
+ if let Some(token) = options.objectstore.auth_token {
337
+ builder = builder.token(token.expose_secret().to_owned());
338
+ }
339
+ let builder = builder;
340
+
341
+ let sentry_token = match authenticated_api.auth() {
342
+ Auth::Token(token) => token.raw().expose_secret().to_owned(),
343
+ };
344
+ let sentry_token = format!("Bearer {sentry_token}")
345
+ .parse()
346
+ // Ignore original error to avoid leaking the token (even though it's invalid)
347
+ .map_err(|_| anyhow::anyhow!("Invalid auth token"))?;
348
+ let client = builder
349
+ .configure_reqwest(|r| {
350
+ let mut headers = http::HeaderMap::new();
351
+ headers.insert(http::header::AUTHORIZATION, sentry_token);
352
+ r.connect_timeout(Duration::from_secs(10))
353
+ .default_headers(headers)
305
354
  })
306
- .configure_reqwest(|r| r.connect_timeout(Duration::from_secs(10)))
307
355
  .build()?;
308
356
 
357
+ let scopes = options.objectstore.scopes;
358
+
359
+ let find_scope = |name: &str| {
360
+ scopes
361
+ .iter()
362
+ .find(|(k, _)| k == name)
363
+ .map(|(_, v)| v.clone())
364
+ };
365
+ let org_id = find_scope("org").context("Missing org in UploadOptions scope")?;
366
+ let project_id = find_scope("project").context("Missing project in UploadOptions scope")?;
367
+
309
368
  let mut scope = Usecase::new("preprod").scope();
310
- let (mut org_id, mut project_id): (Option<String>, Option<String>) = (None, None);
311
- for (key, value) in options.objectstore.scopes.into_iter() {
312
- scope = scope.push(&key, value.clone());
313
- if key == "org" {
314
- org_id = Some(value);
315
- } else if key == "project" {
316
- project_id = Some(value);
317
- }
369
+ for (key, value) in scopes {
370
+ scope = scope.push(&key, value);
318
371
  }
319
- let Some(org_id) = org_id else {
320
- anyhow::bail!("Missing org in UploadOptions scope");
321
- };
322
- let Some(project_id) = project_id else {
323
- anyhow::bail!("Missing project in UploadOptions scope");
324
- };
325
372
 
326
373
  let session = scope.session(&client)?;
327
374
 
@@ -330,10 +377,9 @@ fn upload_images(
330
377
  .build()
331
378
  .context("Failed to create tokio runtime")?;
332
379
 
333
- let mut many_builder = session.many();
334
380
  let mut manifest_entries = HashMap::new();
335
- let mut collisions: HashMap<String, Vec<String>> = HashMap::new();
336
- let mut kept_paths = HashMap::new();
381
+ let mut duplicates: Vec<String> = Vec::new();
382
+ let mut uploads = Vec::with_capacity(images.len());
337
383
 
338
384
  let hashed_images: Vec<_> = images
339
385
  .into_par_iter()
@@ -344,38 +390,14 @@ fn upload_images(
344
390
  .collect::<Result<Vec<_>>>()?;
345
391
 
346
392
  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);
393
+ let image_key = crate::utils::fs::path_as_url(&image.relative_path);
355
394
 
356
- if manifest_entries.contains_key(&image_file_name) {
357
- collisions
358
- .entry(image_file_name)
359
- .or_default()
360
- .push(relative_path);
395
+ if manifest_entries.contains_key(&image_key) {
396
+ duplicates.push(image_key);
361
397
  continue;
362
398
  }
363
399
 
364
- let file = runtime
365
- .block_on(tokio::fs::File::open(&image.path))
366
- .with_context(|| {
367
- format!("Failed to open image for upload: {}", image.path.display())
368
- })?;
369
-
370
400
  let key = format!("{org_id}/{project_id}/{hash}");
371
- info!("Queueing {} as {key}", image.relative_path.display());
372
-
373
- many_builder = many_builder.push(
374
- session
375
- .put_file(file)
376
- .key(&key)
377
- .expiration_policy(expiration),
378
- );
379
401
 
380
402
  let mut extra = read_sidecar_metadata(&image.path).unwrap_or_else(|err| {
381
403
  warn!("Error reading sidecar metadata, ignoring it instead: {err:#}");
@@ -383,48 +405,52 @@ fn upload_images(
383
405
  });
384
406
  extra.insert("content_hash".to_owned(), serde_json::Value::String(hash));
385
407
 
386
- kept_paths.insert(image_file_name.clone(), relative_path);
408
+ uploads.push(PreparedImage {
409
+ path: image.path,
410
+ key,
411
+ });
387
412
  manifest_entries.insert(
388
- image_file_name,
413
+ image_key,
389
414
  ImageMetadata::new(image.width, image.height, extra),
390
415
  );
391
416
  }
392
417
 
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}");
418
+ if !duplicates.is_empty() {
419
+ let paths = duplicates.join(", ");
420
+ warn!("Duplicate paths encountered, skipping: {paths}");
401
421
  }
402
422
 
403
- let result = runtime.block_on(async { many_builder.send().error_for_failures().await });
423
+ let total_count = uploads.len();
404
424
 
405
- let uploaded_count = manifest_entries.len();
425
+ let mut many_builder = session.many();
426
+ for prepared in uploads {
427
+ many_builder = many_builder.push(
428
+ session
429
+ .put_path(prepared.path.clone())
430
+ .key(&prepared.key)
431
+ .expiration_policy(expiration),
432
+ );
433
+ }
406
434
 
407
- match result {
408
- Ok(()) => {
409
- println!(
410
- "{} Uploaded {} image {}",
411
- style(">").dim(),
412
- style(uploaded_count).yellow(),
413
- if uploaded_count == 1 { "file" } else { "files" }
414
- );
415
- Ok(manifest_entries)
416
- }
417
- Err(errors) => {
418
- eprintln!("There were errors uploading images:");
419
- let mut error_count = 0;
420
- for error in errors {
421
- let error = anyhow::Error::new(error);
422
- eprintln!(" {}", style(format!("{error:#}")).red());
423
- error_count += 1;
424
- }
425
- anyhow::bail!("Failed to upload {error_count} out of {uploaded_count} images")
435
+ let result = runtime.block_on(async { many_builder.send().await.error_for_failures().await });
436
+ if let Err(errors) = result {
437
+ let errors: Vec<_> = errors.collect();
438
+ let error_count = errors.len();
439
+ eprintln!("There were errors uploading images:");
440
+ for error in errors {
441
+ let error = anyhow::Error::new(error);
442
+ eprintln!(" {}", style(format!("{error:#}")).red());
426
443
  }
444
+ anyhow::bail!("Failed to upload {error_count} images");
427
445
  }
446
+
447
+ println!(
448
+ "{} Uploaded {} image {}",
449
+ style(">").dim(),
450
+ style(total_count).yellow(),
451
+ if total_count == 1 { "file" } else { "files" }
452
+ );
453
+ Ok(manifest_entries)
428
454
  }
429
455
 
430
456
  #[cfg(test)]