1+ use crate :: core:: package:: MANIFEST_PREAMBLE ;
12use crate :: core:: shell:: Verbosity ;
2- use crate :: core:: { GitReference , Workspace } ;
3+ use crate :: core:: { GitReference , Package , Workspace } ;
34use crate :: ops;
45use crate :: sources:: path:: PathSource ;
56use crate :: sources:: CRATES_IO_REGISTRY ;
@@ -9,6 +10,7 @@ use cargo_util::{paths, Sha256};
910use serde:: Serialize ;
1011use std:: collections:: HashSet ;
1112use std:: collections:: { BTreeMap , BTreeSet , HashMap } ;
13+ use std:: ffi:: OsStr ;
1214use std:: fs:: { self , File , OpenOptions } ;
1315use std:: io:: { Read , Write } ;
1416use std:: path:: { Path , PathBuf } ;
@@ -225,7 +227,7 @@ fn sync(
225227 let pathsource = PathSource :: new ( src, id. source_id ( ) , config) ;
226228 let paths = pathsource. list_files ( pkg) ?;
227229 let mut map = BTreeMap :: new ( ) ;
228- cp_sources ( src, & paths, & dst, & mut map, & mut tmp_buf)
230+ cp_sources ( pkg , src, & paths, & dst, & mut map, & mut tmp_buf)
229231 . with_context ( || format ! ( "failed to copy over vendored sources for: {}" , id) ) ?;
230232
231233 // Finally, emit the metadata about this package
@@ -315,6 +317,7 @@ fn sync(
315317}
316318
317319fn cp_sources (
320+ pkg : & Package ,
318321 src : & Path ,
319322 paths : & [ PathBuf ] ,
320323 dst : & Path ,
@@ -354,35 +357,65 @@ fn cp_sources(
354357 . fold ( dst. to_owned ( ) , |acc, component| acc. join ( & component) ) ;
355358
356359 paths:: create_dir_all ( dst. parent ( ) . unwrap ( ) ) ?;
360+ let mut dst_opts = OpenOptions :: new ( ) ;
361+ dst_opts. write ( true ) . create ( true ) . truncate ( true ) ;
362+ // When vendoring git dependencies, the manifest has not been normalized like it would be
363+ // when published. This causes issue when the manifest is using workspace inheritance.
364+ // To get around this issue we use the "original" manifest after `{}.workspace = true`
365+ // has been resolved for git dependencies.
366+ let cksum = if dst. file_name ( ) == Some ( OsStr :: new ( "Cargo.toml" ) )
367+ && pkg. package_id ( ) . source_id ( ) . is_git ( )
368+ {
369+ let original_toml = toml:: to_string_pretty ( pkg. manifest ( ) . original ( ) ) ?;
370+ let contents = format ! ( "{}\n {}" , MANIFEST_PREAMBLE , original_toml) ;
371+ copy_and_checksum (
372+ & dst,
373+ & mut dst_opts,
374+ & mut contents. as_bytes ( ) ,
375+ "Generated Cargo.toml" ,
376+ tmp_buf,
377+ ) ?
378+ } else {
379+ let mut src = File :: open ( & p) . with_context ( || format ! ( "failed to open {:?}" , & p) ) ?;
380+ #[ cfg( unix) ]
381+ {
382+ use std:: os:: unix:: fs:: { MetadataExt , OpenOptionsExt } ;
383+ let src_metadata = src
384+ . metadata ( )
385+ . with_context ( || format ! ( "failed to stat {:?}" , p) ) ?;
386+ dst_opts. mode ( src_metadata. mode ( ) ) ;
387+ }
388+ copy_and_checksum (
389+ & dst,
390+ & mut dst_opts,
391+ & mut src,
392+ & p. display ( ) . to_string ( ) ,
393+ tmp_buf,
394+ ) ?
395+ } ;
357396
358- let cksum = copy_and_checksum ( p, & dst, tmp_buf) ?;
359397 cksums. insert ( relative. to_str ( ) . unwrap ( ) . replace ( "\\ " , "/" ) , cksum) ;
360398 }
361399 Ok ( ( ) )
362400}
363401
364- fn copy_and_checksum ( src_path : & Path , dst_path : & Path , buf : & mut [ u8 ] ) -> CargoResult < String > {
365- let mut src = File :: open ( src_path) . with_context ( || format ! ( "failed to open {:?}" , src_path) ) ?;
366- let mut dst_opts = OpenOptions :: new ( ) ;
367- dst_opts. write ( true ) . create ( true ) . truncate ( true ) ;
368- #[ cfg( unix) ]
369- {
370- use std:: os:: unix:: fs:: { MetadataExt , OpenOptionsExt } ;
371- let src_metadata = src
372- . metadata ( )
373- . with_context ( || format ! ( "failed to stat {:?}" , src_path) ) ?;
374- dst_opts. mode ( src_metadata. mode ( ) ) ;
375- }
402+ fn copy_and_checksum < T : Read > (
403+ dst_path : & Path ,
404+ dst_opts : & mut OpenOptions ,
405+ contents : & mut T ,
406+ contents_path : & str ,
407+ buf : & mut [ u8 ] ,
408+ ) -> CargoResult < String > {
376409 let mut dst = dst_opts
377410 . open ( dst_path)
378411 . with_context ( || format ! ( "failed to create {:?}" , dst_path) ) ?;
379412 // Not going to bother setting mode on pre-existing files, since there
380413 // shouldn't be any under normal conditions.
381414 let mut cksum = Sha256 :: new ( ) ;
382415 loop {
383- let n = src
416+ let n = contents
384417 . read ( buf)
385- . with_context ( || format ! ( "failed to read from {:?}" , src_path ) ) ?;
418+ . with_context ( || format ! ( "failed to read from {:?}" , contents_path ) ) ?;
386419 if n == 0 {
387420 break Ok ( cksum. finish_hex ( ) ) ;
388421 }
0 commit comments