@@ -317,8 +317,7 @@ pub struct Package {
317
317
name : String ,
318
318
vers : String ,
319
319
deps : Vec < Dependency > ,
320
- files : Vec < ( String , String ) > ,
321
- extra_files : Vec < ( String , String ) > ,
320
+ files : Vec < PackageFile > ,
322
321
yanked : bool ,
323
322
features : HashMap < String , Vec < String > > ,
324
323
local : bool ,
@@ -342,6 +341,20 @@ pub struct Dependency {
342
341
optional : bool ,
343
342
}
344
343
344
+ /// A file to be created in a package.
345
+ struct PackageFile {
346
+ path : String ,
347
+ contents : String ,
348
+ /// The Unix mode for the file. Note that when extracted on Windows, this
349
+ /// is mostly ignored since it doesn't have the same style of permissions.
350
+ mode : u32 ,
351
+ /// If `true`, the file is created in the root of the tarfile, used for
352
+ /// testing invalid packages.
353
+ extra : bool ,
354
+ }
355
+
356
+ const DEFAULT_MODE : u32 = 0o644 ;
357
+
345
358
/// Initializes the on-disk registry and sets up the config so that crates.io
346
359
/// is replaced with the one on disk.
347
360
pub fn init ( ) {
@@ -379,7 +392,6 @@ impl Package {
379
392
vers : vers. to_string ( ) ,
380
393
deps : Vec :: new ( ) ,
381
394
files : Vec :: new ( ) ,
382
- extra_files : Vec :: new ( ) ,
383
395
yanked : false ,
384
396
features : HashMap :: new ( ) ,
385
397
local : false ,
@@ -416,7 +428,17 @@ impl Package {
416
428
417
429
/// Adds a file to the package.
418
430
pub fn file ( & mut self , name : & str , contents : & str ) -> & mut Package {
419
- self . files . push ( ( name. to_string ( ) , contents. to_string ( ) ) ) ;
431
+ self . file_with_mode ( name, DEFAULT_MODE , contents)
432
+ }
433
+
434
+ /// Adds a file with a specific Unix mode.
435
+ pub fn file_with_mode ( & mut self , path : & str , mode : u32 , contents : & str ) -> & mut Package {
436
+ self . files . push ( PackageFile {
437
+ path : path. to_string ( ) ,
438
+ contents : contents. to_string ( ) ,
439
+ mode,
440
+ extra : false ,
441
+ } ) ;
420
442
self
421
443
}
422
444
@@ -425,9 +447,13 @@ impl Package {
425
447
/// Normal files are automatically placed within a directory named
426
448
/// `$PACKAGE-$VERSION`. This allows you to override that behavior,
427
449
/// typically for testing invalid behavior.
428
- pub fn extra_file ( & mut self , name : & str , contents : & str ) -> & mut Package {
429
- self . extra_files
430
- . push ( ( name. to_string ( ) , contents. to_string ( ) ) ) ;
450
+ pub fn extra_file ( & mut self , path : & str , contents : & str ) -> & mut Package {
451
+ self . files . push ( PackageFile {
452
+ path : path. to_string ( ) ,
453
+ contents : contents. to_string ( ) ,
454
+ mode : DEFAULT_MODE ,
455
+ extra : true ,
456
+ } ) ;
431
457
self
432
458
}
433
459
@@ -639,19 +665,30 @@ impl Package {
639
665
let f = t ! ( File :: create( & dst) ) ;
640
666
let mut a = Builder :: new ( GzEncoder :: new ( f, Compression :: default ( ) ) ) ;
641
667
642
- if !self . files . iter ( ) . any ( |( name, _) | name == "Cargo.toml" ) {
668
+ if !self
669
+ . files
670
+ . iter ( )
671
+ . any ( |PackageFile { path, .. } | path == "Cargo.toml" )
672
+ {
643
673
self . append_manifest ( & mut a) ;
644
674
}
645
675
if self . files . is_empty ( ) {
646
- self . append ( & mut a, "src/lib.rs" , "" ) ;
676
+ self . append ( & mut a, "src/lib.rs" , DEFAULT_MODE , "" ) ;
647
677
} else {
648
- for & ( ref name, ref contents) in self . files . iter ( ) {
649
- self . append ( & mut a, name, contents) ;
678
+ for PackageFile {
679
+ path,
680
+ contents,
681
+ mode,
682
+ extra,
683
+ } in & self . files
684
+ {
685
+ if * extra {
686
+ self . append_raw ( & mut a, path, * mode, contents) ;
687
+ } else {
688
+ self . append ( & mut a, path, * mode, contents) ;
689
+ }
650
690
}
651
691
}
652
- for & ( ref name, ref contents) in self . extra_files . iter ( ) {
653
- self . append_extra ( & mut a, name, contents) ;
654
- }
655
692
}
656
693
657
694
fn append_manifest < W : Write > ( & self , ar : & mut Builder < W > ) {
@@ -704,21 +741,23 @@ impl Package {
704
741
manifest. push_str ( "[lib]\n proc-macro = true\n " ) ;
705
742
}
706
743
707
- self . append ( ar, "Cargo.toml" , & manifest) ;
744
+ self . append ( ar, "Cargo.toml" , DEFAULT_MODE , & manifest) ;
708
745
}
709
746
710
- fn append < W : Write > ( & self , ar : & mut Builder < W > , file : & str , contents : & str ) {
711
- self . append_extra (
747
+ fn append < W : Write > ( & self , ar : & mut Builder < W > , file : & str , mode : u32 , contents : & str ) {
748
+ self . append_raw (
712
749
ar,
713
750
& format ! ( "{}-{}/{}" , self . name, self . vers, file) ,
751
+ mode,
714
752
contents,
715
753
) ;
716
754
}
717
755
718
- fn append_extra < W : Write > ( & self , ar : & mut Builder < W > , path : & str , contents : & str ) {
756
+ fn append_raw < W : Write > ( & self , ar : & mut Builder < W > , path : & str , mode : u32 , contents : & str ) {
719
757
let mut header = Header :: new_ustar ( ) ;
720
758
header. set_size ( contents. len ( ) as u64 ) ;
721
759
t ! ( header. set_path( path) ) ;
760
+ header. set_mode ( mode) ;
722
761
header. set_cksum ( ) ;
723
762
t ! ( ar. append( & header, contents. as_bytes( ) ) ) ;
724
763
}
0 commit comments