1
+ use crate :: core:: package:: MANIFEST_PREAMBLE ;
1
2
use crate :: core:: shell:: Verbosity ;
2
- use crate :: core:: { GitReference , Workspace } ;
3
+ use crate :: core:: { GitReference , Package , Workspace } ;
3
4
use crate :: ops;
4
5
use crate :: sources:: path:: PathSource ;
5
6
use crate :: sources:: CRATES_IO_REGISTRY ;
@@ -9,6 +10,7 @@ use cargo_util::{paths, Sha256};
9
10
use serde:: Serialize ;
10
11
use std:: collections:: HashSet ;
11
12
use std:: collections:: { BTreeMap , BTreeSet , HashMap } ;
13
+ use std:: ffi:: OsStr ;
12
14
use std:: fs:: { self , File , OpenOptions } ;
13
15
use std:: io:: { Read , Write } ;
14
16
use std:: path:: { Path , PathBuf } ;
@@ -225,7 +227,7 @@ fn sync(
225
227
let pathsource = PathSource :: new ( src, id. source_id ( ) , config) ;
226
228
let paths = pathsource. list_files ( pkg) ?;
227
229
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)
229
231
. with_context ( || format ! ( "failed to copy over vendored sources for: {}" , id) ) ?;
230
232
231
233
// Finally, emit the metadata about this package
@@ -315,6 +317,7 @@ fn sync(
315
317
}
316
318
317
319
fn cp_sources (
320
+ pkg : & Package ,
318
321
src : & Path ,
319
322
paths : & [ PathBuf ] ,
320
323
dst : & Path ,
@@ -354,35 +357,65 @@ fn cp_sources(
354
357
. fold ( dst. to_owned ( ) , |acc, component| acc. join ( & component) ) ;
355
358
356
359
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
+ } ;
357
396
358
- let cksum = copy_and_checksum ( p, & dst, tmp_buf) ?;
359
397
cksums. insert ( relative. to_str ( ) . unwrap ( ) . replace ( "\\ " , "/" ) , cksum) ;
360
398
}
361
399
Ok ( ( ) )
362
400
}
363
401
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 > {
376
409
let mut dst = dst_opts
377
410
. open ( dst_path)
378
411
. with_context ( || format ! ( "failed to create {:?}" , dst_path) ) ?;
379
412
// Not going to bother setting mode on pre-existing files, since there
380
413
// shouldn't be any under normal conditions.
381
414
let mut cksum = Sha256 :: new ( ) ;
382
415
loop {
383
- let n = src
416
+ let n = contents
384
417
. read ( buf)
385
- . with_context ( || format ! ( "failed to read from {:?}" , src_path ) ) ?;
418
+ . with_context ( || format ! ( "failed to read from {:?}" , contents_path ) ) ?;
386
419
if n == 0 {
387
420
break Ok ( cksum. finish_hex ( ) ) ;
388
421
}
0 commit comments