@@ -14,7 +14,6 @@ use std::fs::{self, File};
1414use std:: io:: { BufReader , BufWriter , Read as _, Seek as _, Write as _} ;
1515use std:: iter:: IntoIterator ;
1616use std:: mem:: transmute;
17- use std:: ops:: Deref ;
1817use std:: path:: { Component , Path , PathBuf } ;
1918use std:: process:: Command ;
2019use std:: str;
@@ -23,7 +22,6 @@ use std::time::Duration;
2322use anyhow:: { bail, format_err, Error , Result } ;
2423use console:: style;
2524use log:: { debug, info, warn} ;
26- use sha1_smol:: Digest ;
2725use symbolic:: common:: { Arch , AsSelf , ByteView , DebugId , SelfCell , Uuid } ;
2826use symbolic:: debuginfo:: macho:: { BcSymbolMap , UuidMapping } ;
2927use symbolic:: debuginfo:: pe:: PeObject ;
@@ -33,26 +31,21 @@ use symbolic::il2cpp::ObjectLineMapping;
3331use walkdir:: WalkDir ;
3432use which:: which;
3533use zip:: result:: ZipError ;
36- use zip:: write:: SimpleFileOptions ;
37- use zip:: { ZipArchive , ZipWriter } ;
34+ use zip:: ZipArchive ;
3835
3936use self :: error:: ValidationError ;
4037use crate :: api:: { Api , ChunkServerOptions , ChunkUploadCapability } ;
4138use crate :: config:: Config ;
4239use crate :: constants:: { DEFAULT_MAX_DIF_SIZE , DEFAULT_MAX_WAIT } ;
4340use crate :: utils:: chunks;
44- use crate :: utils:: chunks:: { Assemblable , BatchedSliceExt as _ , ChunkOptions , Chunked , ItemSize } ;
41+ use crate :: utils:: chunks:: { Assemblable , ChunkOptions , Chunked } ;
4542use crate :: utils:: dif:: ObjectDifFeatures ;
46- use crate :: utils:: fs:: { get_sha1_checksum , TempDir , TempFile } ;
43+ use crate :: utils:: fs:: { TempDir , TempFile } ;
4744use crate :: utils:: progress:: { ProgressBar , ProgressStyle } ;
48- use crate :: utils:: ui:: { copy_with_progress, make_byte_progress_bar} ;
4945
5046/// A debug info file on the server.
5147pub use crate :: api:: DebugInfoFile ;
5248
53- /// Fallback maximum number of chunks in a batch for the legacy upload.
54- static MAX_CHUNKS : u64 = 64 ;
55-
5649/// A Debug Information File.
5750///
5851/// This is primarily used to store inside the [`DifMatch`] so does not contain any
@@ -212,11 +205,6 @@ impl<'data> DifMatch<'data> {
212205 }
213206 }
214207
215- /// Returns the size of of this DIF in bytes.
216- pub fn size ( & self ) -> u64 {
217- self . data ( ) . len ( ) as u64
218- }
219-
220208 /// Returns the path of this DIF relative to the search origin.
221209 pub fn path ( & self ) -> & str {
222210 & self . name
@@ -315,40 +303,6 @@ impl Assemblable for DifMatch<'_> {
315303 }
316304}
317305
318- /// A `DifMatch` with computed SHA1 checksum.
319- #[ derive( Debug ) ]
320- struct HashedDifMatch < ' data > {
321- inner : DifMatch < ' data > ,
322- checksum : Digest ,
323- }
324-
325- impl < ' data > HashedDifMatch < ' data > {
326- /// Calculates the SHA1 checksum for the given DIF.
327- fn from ( inner : DifMatch < ' data > ) -> Result < Self > {
328- let checksum = get_sha1_checksum ( inner. data ( ) ) ?;
329- Ok ( HashedDifMatch { inner, checksum } )
330- }
331-
332- /// Returns the SHA1 checksum of this DIF.
333- fn checksum ( & self ) -> Digest {
334- self . checksum
335- }
336- }
337-
338- impl < ' data > Deref for HashedDifMatch < ' data > {
339- type Target = DifMatch < ' data > ;
340-
341- fn deref ( & self ) -> & Self :: Target {
342- & self . inner
343- }
344- }
345-
346- impl ItemSize for HashedDifMatch < ' _ > {
347- fn size ( & self ) -> u64 {
348- self . deref ( ) . size ( )
349- }
350- }
351-
352306type ZipFileArchive = ZipArchive < BufReader < File > > ;
353307
354308/// A handle to the source of a potential `DifMatch` used inside `search_difs`.
@@ -1250,130 +1204,6 @@ fn upload_difs_chunked(
12501204 chunks:: upload_chunked_objects ( & chunked, options)
12511205}
12521206
1253- /// Returns debug files missing on the server.
1254- fn get_missing_difs < ' data > (
1255- objects : Vec < HashedDifMatch < ' data > > ,
1256- options : & DifUpload ,
1257- ) -> Result < Vec < HashedDifMatch < ' data > > > {
1258- info ! (
1259- "Checking for missing debug information files: {:#?}" ,
1260- & objects
1261- ) ;
1262-
1263- let api = Api :: current ( ) ;
1264- let missing_checksums = {
1265- let checksums = objects. iter ( ) . map ( HashedDifMatch :: checksum) ;
1266- api. authenticated ( ) ?
1267- . find_missing_dif_checksums ( options. org , options. project , checksums) ?
1268- } ;
1269-
1270- let missing = objects
1271- . into_iter ( )
1272- . filter ( |sym| missing_checksums. contains ( & sym. checksum ( ) ) )
1273- . collect ( ) ;
1274-
1275- info ! ( "Missing debug information files: {:#?}" , & missing) ;
1276- Ok ( missing)
1277- }
1278-
1279- /// Compresses the given batch into a ZIP archive.
1280- fn create_batch_archive ( difs : & [ HashedDifMatch < ' _ > ] ) -> Result < TempFile > {
1281- let total_bytes = difs. iter ( ) . map ( ItemSize :: size) . sum ( ) ;
1282- let pb = make_byte_progress_bar ( total_bytes) ;
1283- let tf = TempFile :: create ( ) ?;
1284-
1285- {
1286- let mut zip = ZipWriter :: new ( tf. open ( ) ?) ;
1287-
1288- for symbol in difs {
1289- zip. start_file ( symbol. file_name ( ) , SimpleFileOptions :: default ( ) ) ?;
1290- copy_with_progress ( & pb, & mut symbol. data ( ) , & mut zip) ?;
1291- }
1292- }
1293-
1294- pb. finish_and_clear ( ) ;
1295- Ok ( tf)
1296- }
1297-
1298- /// Uploads the given DIFs to the server in batched ZIP archives.
1299- fn upload_in_batches (
1300- objects : & [ HashedDifMatch < ' _ > ] ,
1301- options : & DifUpload ,
1302- ) -> Result < Vec < DebugInfoFile > > {
1303- let api = Api :: current ( ) ;
1304- let max_size = Config :: current ( ) . get_max_dif_archive_size ( ) ;
1305- let mut dsyms = Vec :: new ( ) ;
1306-
1307- for ( i, ( batch, _) ) in objects. batches ( max_size, MAX_CHUNKS ) . enumerate ( ) {
1308- println ! ( "\n {}" , style( format!( "Batch {}" , i + 1 ) ) . bold( ) ) ;
1309-
1310- println ! (
1311- "{} Compressing {} debug symbol files" ,
1312- style( ">" ) . dim( ) ,
1313- style( batch. len( ) ) . yellow( )
1314- ) ;
1315- let archive = create_batch_archive ( batch) ?;
1316-
1317- println ! ( "{} Uploading debug symbol files" , style( ">" ) . dim( ) ) ;
1318- dsyms. extend (
1319- api. authenticated ( ) ?
1320- . region_specific ( options. org )
1321- . upload_dif_archive ( options. project , archive. path ( ) ) ?,
1322- ) ;
1323- }
1324-
1325- Ok ( dsyms)
1326- }
1327-
1328- /// Uploads debug info files using the legacy endpoint.
1329- #[ deprecated = "this non-chunked upload mechanism is deprecated in favor of upload_difs_chunked" ]
1330- fn upload_difs_batched ( options : & DifUpload ) -> Result < Vec < DebugInfoFile > > {
1331- // Search for debug files in the file system and ZIPs
1332- let found = search_difs ( options) ?;
1333- if found. is_empty ( ) {
1334- println ! ( "{} No debug information files found" , style( ">" ) . dim( ) ) ;
1335- return Ok ( Default :: default ( ) ) ;
1336- }
1337-
1338- // Try to resolve BCSymbolMaps
1339- let symbol_map = options. symbol_map . as_deref ( ) ;
1340- let processed = process_symbol_maps ( found, symbol_map) ?;
1341-
1342- // Calculate checksums
1343- let hashed = prepare_difs ( processed, HashedDifMatch :: from) ?;
1344-
1345- // Check which files are missing on the server
1346- let missing = get_missing_difs ( hashed, options) ?;
1347- if missing. is_empty ( ) {
1348- println ! (
1349- "{} Nothing to upload, all files are on the server" ,
1350- style( ">" ) . dim( )
1351- ) ;
1352- println ! ( "{} Nothing to upload" , style( ">" ) . dim( ) ) ;
1353- return Ok ( Default :: default ( ) ) ;
1354- }
1355- if options. no_upload {
1356- println ! ( "{} skipping upload." , style( ">" ) . dim( ) ) ;
1357- return Ok ( Default :: default ( ) ) ;
1358- }
1359-
1360- // Upload missing DIFs in batches
1361- let uploaded = upload_in_batches ( & missing, options) ?;
1362- if !uploaded. is_empty ( ) {
1363- println ! ( "{} File upload complete:\n " , style( ">" ) . dim( ) ) ;
1364- for dif in & uploaded {
1365- println ! (
1366- " {} ({}; {})" ,
1367- style( & dif. id( ) ) . dim( ) ,
1368- & dif. object_name,
1369- dif. cpu_name
1370- ) ;
1371- }
1372- }
1373-
1374- Ok ( uploaded)
1375- }
1376-
13771207/// The format of a Debug Information File (DIF).
13781208///
13791209/// Most DIFs are also object files, but we also know of some auxiliary DIF formats.
@@ -1641,23 +1471,16 @@ impl<'a> DifUpload<'a> {
16411471 self . bcsymbolmaps_allowed = chunk_options. supports ( ChunkUploadCapability :: BcSymbolmap ) ;
16421472 self . il2cpp_mappings_allowed = chunk_options. supports ( ChunkUploadCapability :: Il2Cpp ) ;
16431473
1644- if chunk_options. supports ( ChunkUploadCapability :: DebugFiles ) {
1645- self . validate_capabilities ( ) ;
1646- return upload_difs_chunked ( self , chunk_options) ;
1474+ if !chunk_options. supports ( ChunkUploadCapability :: DebugFiles ) {
1475+ anyhow:: bail!(
1476+ "Your Sentry server does not support chunked uploads for debug files. Please upgrade \
1477+ your Sentry server, or if you cannot upgrade your server, downgrade your Sentry \
1478+ CLI version to 2.x."
1479+ ) ;
16471480 }
16481481
16491482 self . validate_capabilities ( ) ;
1650-
1651- log:: warn!(
1652- "[DEPRECATION NOTICE] Your Sentry server does not support chunked uploads for debug \
1653- files. Falling back to deprecated upload method. Support for this deprecated upload \
1654- method will be removed in Sentry CLI 3.0.0. Please upgrade your Sentry server, or if \
1655- you cannot upgrade, pin your Sentry CLI version to 2.x, so you don't get upgraded \
1656- to 3.x when it is released."
1657- ) ;
1658-
1659- #[ expect( deprecated, reason = "fallback to legacy upload" ) ]
1660- Ok ( ( upload_difs_batched ( & self ) ?, false ) )
1483+ upload_difs_chunked ( self , chunk_options)
16611484 }
16621485
16631486 /// Validate that the server supports all requested capabilities.
0 commit comments