11//! Searches, processes and uploads release files.
22use std:: collections:: { BTreeMap , HashMap } ;
3+ use std:: ffi:: OsStr ;
34use std:: fmt:: { self , Display } ;
45use std:: io:: BufWriter ;
56use std:: path:: PathBuf ;
@@ -16,6 +17,7 @@ use rayon::ThreadPoolBuilder;
1617use sentry:: types:: DebugId ;
1718use sha1_smol:: Digest ;
1819use symbolic:: common:: ByteView ;
20+ use symbolic:: debuginfo:: js;
1921use symbolic:: debuginfo:: sourcebundle:: {
2022 SourceBundleErrorKind , SourceBundleWriter , SourceFileInfo , SourceFileType ,
2123} ;
@@ -29,6 +31,8 @@ use crate::utils::chunks::{upload_chunks, Chunk, ASSEMBLE_POLL_INTERVAL};
2931use crate :: utils:: fs:: { get_sha1_checksum, get_sha1_checksums, TempFile } ;
3032use crate :: utils:: progress:: { ProgressBar , ProgressBarMode , ProgressStyle } ;
3133
34+ use super :: file_search:: ReleaseFileMatch ;
35+
3236/// Fallback concurrency for release file uploads.
3337static DEFAULT_CONCURRENCY : usize = 4 ;
3438
@@ -239,6 +243,68 @@ pub struct SourceFile {
239243}
240244
241245impl SourceFile {
246+ pub fn from_release_file_match ( url : & str , mut file : ReleaseFileMatch ) -> SourceFile {
247+ let ( ty, debug_id) = if sourcemap:: is_sourcemap_slice ( & file. contents ) {
248+ (
249+ SourceFileType :: SourceMap ,
250+ std:: str:: from_utf8 ( & file. contents )
251+ . ok ( )
252+ . and_then ( js:: discover_sourcemap_embedded_debug_id) ,
253+ )
254+ } else if file
255+ . path
256+ . file_name ( )
257+ . and_then ( OsStr :: to_str)
258+ . map ( |x| x. ends_with ( "bundle" ) )
259+ . unwrap_or ( false )
260+ && sourcemap:: ram_bundle:: is_ram_bundle_slice ( & file. contents )
261+ {
262+ ( SourceFileType :: IndexedRamBundle , None )
263+ } else if is_hermes_bytecode ( & file. contents ) {
264+ // This is actually a big hack:
265+ // For the react-native Hermes case, we skip uploading the bytecode bundle,
266+ // and rather flag it as an empty "minified source". That way, it
267+ // will get a SourceMap reference, and the server side processor
268+ // should deal with it accordingly.
269+ file. contents . clear ( ) ;
270+ ( SourceFileType :: MinifiedSource , None )
271+ } else {
272+ // Here, we use MinifiedSource for historical reasons. We used to guess whether
273+ // a JS file was a minified file or a source file, and we would treat these files
274+ // differently when uploading or injecting them. However, the desired behavior is
275+ // and has always been to treat all JS files the same, since users should be
276+ // responsible for providing the file paths for only files they would like to have
277+ // uploaded or injected. The minified file guessing furthermore was not reliable,
278+ // since minification is not a necessary step in the JS build process.
279+ //
280+ // We use MinifiedSource here rather than Source because we want to treat all JS
281+ // files the way we used to treat minified files only. To use Source, we would need
282+ // to analyze all possible code paths that check this value, and update those as
283+ // well. To keep the change minimal, we use MinifiedSource here.
284+ (
285+ SourceFileType :: MinifiedSource ,
286+ std:: str:: from_utf8 ( & file. contents )
287+ . ok ( )
288+ . and_then ( js:: discover_debug_id) ,
289+ )
290+ } ;
291+
292+ let mut source_file = SourceFile {
293+ url : url. into ( ) ,
294+ path : file. path ,
295+ contents : file. contents . into ( ) ,
296+ ty,
297+ headers : BTreeMap :: new ( ) ,
298+ messages : vec ! [ ] ,
299+ already_uploaded : false ,
300+ } ;
301+
302+ if let Some ( debug_id) = debug_id {
303+ source_file. set_debug_id ( debug_id. to_string ( ) ) ;
304+ }
305+ source_file
306+ }
307+
242308 /// Calculates and returns the SHA1 checksum of the file.
243309 pub fn checksum ( & self ) -> Result < Digest > {
244310 get_sha1_checksum ( & * * self . contents )
@@ -753,6 +819,13 @@ fn print_upload_context_details(context: &UploadContext) {
753819 ) ;
754820}
755821
822+ fn is_hermes_bytecode ( slice : & [ u8 ] ) -> bool {
823+ // The hermes bytecode format magic is defined here:
824+ // https://github.com/facebook/hermes/blob/5243222ef1d92b7393d00599fc5cff01d189a88a/include/hermes/BCGen/HBC/BytecodeFileFormat.h#L24-L25
825+ const HERMES_MAGIC : [ u8 ; 8 ] = [ 0xC6 , 0x1F , 0xBC , 0x03 , 0xC1 , 0x03 , 0x19 , 0x1F ] ;
826+ slice. starts_with ( & HERMES_MAGIC )
827+ }
828+
756829#[ cfg( test) ]
757830mod tests {
758831 use sha1_smol:: Sha1 ;
0 commit comments