@@ -6,14 +6,15 @@ mod config;
6
6
mod curl_helper;
7
7
mod discourse;
8
8
mod github;
9
+ mod recompress;
9
10
mod sign;
10
11
mod smoke_test;
11
12
12
13
use std:: fs:: { self , File , OpenOptions } ;
13
- use std:: io:: { self , Read } ;
14
+ use std:: io:: Read ;
14
15
use std:: path:: { Path , PathBuf } ;
15
16
use std:: process:: Command ;
16
- use std:: time:: { Duration , Instant } ;
17
+ use std:: time:: Duration ;
17
18
use std:: { collections:: HashSet , env} ;
18
19
19
20
use crate :: build_manifest:: BuildManifest ;
@@ -24,8 +25,6 @@ use chrono::Utc;
24
25
use curl:: easy:: Easy ;
25
26
use fs2:: FileExt ;
26
27
use github:: { CreateTag , Github } ;
27
- use rayon:: prelude:: * ;
28
- use xz2:: read:: XzDecoder ;
29
28
30
29
use crate :: config:: { Channel , Config } ;
31
30
@@ -376,115 +375,23 @@ impl Context {
376
375
let file = file?;
377
376
let path = file. path ( ) ;
378
377
match path. extension ( ) . and_then ( |s| s. to_str ( ) ) {
379
- // Delete signature/hash files...
380
- Some ( "asc" ) | Some ( "sha256" ) => {
381
- fs:: remove_file ( & path) ?;
382
- }
383
378
// Store off the input files for potential recompression.
384
379
Some ( "xz" ) => {
385
380
to_recompress. push ( path. to_path_buf ( ) ) ;
386
381
}
382
+ // Delete signature/hash files...
383
+ Some ( "asc" ) | Some ( "sha256" ) => {
384
+ fs:: remove_file ( & path) ?;
385
+ }
387
386
Some ( "gz" ) if self . config . recompress_gz => {
388
387
fs:: remove_file ( & path) ?;
389
388
}
390
389
_ => { }
391
390
}
392
391
}
393
392
394
- // Also, generate *.gz from *.xz if the former is missing. Since the gz
395
- // and xz tarballs have the same content, we did not deploy the gz files
396
- // from the CI. But rustup users may still expect to get gz files, so we
397
- // are recompressing the xz files as gz here.
398
- if !to_recompress. is_empty ( ) {
399
- println ! (
400
- "starting to recompress {} files across {} threads" ,
401
- to_recompress. len( ) ,
402
- to_recompress. len( ) . min( rayon:: current_num_threads( ) ) ,
403
- ) ;
404
- println ! (
405
- "gz recompression enabled: {} (note: may occur anyway for missing gz artifacts)" ,
406
- self . config. recompress_gz
407
- ) ;
408
- println ! ( "xz recompression enabled: {}" , self . config. recompress_xz) ;
409
- let recompress_start = Instant :: now ( ) ;
410
-
411
- let recompress_gz = self . config . recompress_gz ;
412
- let recompress_xz = self . config . recompress_xz ;
413
- let compression_level = flate2:: Compression :: new ( self . config . gzip_compression_level ) ;
414
- to_recompress
415
- . par_iter ( )
416
- . map ( |xz_path| {
417
- println ! ( "recompressing {}..." , xz_path. display( ) ) ;
418
- let gz_path = xz_path. with_extension ( "gz" ) ;
419
-
420
- // Produce gzip if explicitly enabled or the destination file doesn't exist.
421
- if recompress_gz || !gz_path. is_file ( ) {
422
- let mut xz_orig = XzDecoder :: new ( File :: open ( xz_path) ?) ;
423
- let gz = File :: create ( gz_path) ?;
424
- let mut gz = flate2:: write:: GzEncoder :: new ( gz, compression_level) ;
425
- io:: copy ( & mut xz_orig, & mut gz) ?;
426
- }
427
-
428
- // xz recompression with more aggressive settings than we want to take the time
429
- // for in rust-lang/rust CI. This cuts 5-15% off of the produced tarballs.
430
- //
431
- // Note that this is using a single-threaded compressor as we're parallelizing
432
- // via rayon already. In rust-lang/rust we were trying to use parallel
433
- // compression, but the default block size for that is 3*dict_size so we
434
- // weren't actually using more than one core in most of the builders with
435
- // <192MB uncompressed tarballs. In promote-release since we're recompressing
436
- // 100s of tarballs there's no need for each individual compression to be
437
- // parallel.
438
- if recompress_xz {
439
- let mut filters = xz2:: stream:: Filters :: new ( ) ;
440
- let mut lzma_ops = xz2:: stream:: LzmaOptions :: new_preset ( 9 ) . unwrap ( ) ;
441
- // This sets the overall dictionary size, which is also how much memory (baseline)
442
- // is needed for decompression.
443
- lzma_ops. dict_size ( 64 * 1024 * 1024 ) ;
444
- // Use the best match finder for compression ratio.
445
- lzma_ops. match_finder ( xz2:: stream:: MatchFinder :: BinaryTree4 ) ;
446
- lzma_ops. mode ( xz2:: stream:: Mode :: Normal ) ;
447
- // Set nice len to the maximum for best compression ratio
448
- lzma_ops. nice_len ( 273 ) ;
449
- // Set depth to a reasonable value, 0 means auto, 1000 is somwhat high but gives
450
- // good results.
451
- lzma_ops. depth ( 1000 ) ;
452
- // 2 is the default and does well for most files
453
- lzma_ops. position_bits ( 2 ) ;
454
- // 0 is the default and does well for most files
455
- lzma_ops. literal_position_bits ( 0 ) ;
456
- // 3 is the default and does well for most files
457
- lzma_ops. literal_context_bits ( 3 ) ;
458
-
459
- filters. lzma2 ( & lzma_ops) ;
460
-
461
- // FIXME: Do we want a checksum as part of compression?
462
- let stream = xz2:: stream:: Stream :: new_stream_encoder (
463
- & filters,
464
- xz2:: stream:: Check :: None ,
465
- )
466
- . unwrap ( ) ;
467
- let xz_recompressed = xz_path. with_extension ( "xz_recompressed" ) ;
468
- let xz_out = File :: create ( & xz_recompressed) ?;
469
- let mut xz_out = xz2:: write:: XzEncoder :: new_stream (
470
- std:: io:: BufWriter :: new ( xz_out) ,
471
- stream,
472
- ) ;
473
- let mut xz_orig = XzDecoder :: new ( File :: open ( xz_path) ?) ;
474
- io:: copy ( & mut xz_orig, & mut xz_out) ?;
475
- fs:: rename ( & xz_recompressed, xz_path) ?;
476
- }
477
-
478
- Ok :: < ( ) , Error > ( ( ) )
479
- } )
480
- . collect :: < Result < Vec < ( ) > , Error > > ( ) ?;
481
-
482
- println ! (
483
- "finished recompressing {} files in {:.2?}" ,
484
- to_recompress. len( ) ,
485
- recompress_start. elapsed( ) ,
486
- ) ;
487
- }
393
+ // Generate recompressed artifacts from the input set.
394
+ self . recompress ( & to_recompress) ?;
488
395
489
396
Ok ( ( ) )
490
397
}
0 commit comments