@@ -8,17 +8,15 @@ use cargo::core::{Package, PackageId, Source, SourceId, Workspace};
8
8
use cargo:: sources:: RegistrySource ;
9
9
use curl:: easy:: Easy ;
10
10
use log:: debug;
11
- use rand:: Rng ;
12
11
use rustc_session:: getopts;
13
12
use serde:: Deserialize ;
14
13
use std:: collections:: HashSet ;
15
14
use std:: {
16
- env,
17
- fs:: File ,
18
- io:: BufReader ,
15
+ env, io,
19
16
io:: Write ,
20
17
path:: { Path , PathBuf } ,
21
18
process:: { Command , Stdio } ,
19
+ sync:: { Arc , RwLock } ,
22
20
} ;
23
21
24
22
pub type Result < T > = cargo:: util:: CargoResult < T > ;
@@ -503,33 +501,27 @@ impl<'a> WorkInfo<'a> {
503
501
format ! ( "-C metadata={}" , if current { "new" } else { "old" } ) ,
504
502
) ;
505
503
506
- let mut outdir = env:: temp_dir ( ) ;
507
- // The filename is randomized to avoid clashes when multiple cargo-semver instances are running.
508
- outdir. push ( & format ! (
509
- "cargo_semver_{}_{}_{}" ,
510
- name,
511
- current,
512
- rand:: thread_rng( ) . gen :: <u32 >( )
513
- ) ) ;
514
-
515
- // redirection gang
516
- let outfile = File :: create ( & outdir) ?;
504
+ // Capture build plan from a separate Cargo invocation
505
+ let output = VecWrite ( Arc :: new ( RwLock :: new ( Vec :: new ( ) ) ) ) ;
517
506
518
- let mut file_write = cargo:: core:: Shell :: from_write ( Box :: new ( outfile ) ) ;
507
+ let mut file_write = cargo:: core:: Shell :: from_write ( Box :: new ( output . clone ( ) ) ) ;
519
508
file_write. set_verbosity ( cargo:: core:: Verbosity :: Quiet ) ;
509
+
520
510
let old_shell = std:: mem:: replace ( & mut * config. shell ( ) , file_write) ;
521
511
522
512
cargo:: ops:: compile ( & self . workspace , & opts) ?;
523
513
524
514
let _ = std:: mem:: replace ( & mut * config. shell ( ) , old_shell) ;
515
+ let plan_output = output. read ( ) ?;
525
516
526
517
// actually compile things now
527
518
opts. build_config . build_plan = false ;
528
519
529
520
let compilation = cargo:: ops:: compile ( & self . workspace , & opts) ?;
530
521
env:: remove_var ( "RUSTFLAGS" ) ;
531
522
532
- let build_plan: BuildPlan = serde_json:: from_reader ( BufReader :: new ( File :: open ( & outdir) ?) ) ?;
523
+ let build_plan: BuildPlan = serde_json:: from_slice ( & plan_output)
524
+ . map_err ( |_| anyhow:: anyhow!( "Can't read build plan" ) ) ?;
533
525
534
526
// TODO: handle multiple outputs gracefully
535
527
for i in & build_plan. invocations {
@@ -572,3 +564,30 @@ pub fn find_on_crates_io(crate_name: &str) -> Result<crates_io::Crate> {
572
564
} )
573
565
} )
574
566
}
567
+
568
+ /// Thread-safe byte buffer that implements `io::Write`.
569
+ #[ derive( Clone ) ]
570
+ struct VecWrite ( Arc < RwLock < Vec < u8 > > > ) ;
571
+
572
+ impl VecWrite {
573
+ pub fn read ( & self ) -> io:: Result < std:: sync:: RwLockReadGuard < ' _ , Vec < u8 > > > {
574
+ self . 0
575
+ . read ( )
576
+ . map_err ( |_| io:: Error :: new ( io:: ErrorKind :: Other , "lock poison" ) )
577
+ }
578
+ pub fn write ( & self ) -> io:: Result < std:: sync:: RwLockWriteGuard < ' _ , Vec < u8 > > > {
579
+ self . 0
580
+ . write ( )
581
+ . map_err ( |_| io:: Error :: new ( io:: ErrorKind :: Other , "lock poison" ) )
582
+ }
583
+ }
584
+
585
+ impl io:: Write for VecWrite {
586
+ fn write ( & mut self , data : & [ u8 ] ) -> io:: Result < usize > {
587
+ let mut lock = Self :: write ( self ) ?;
588
+ io:: Write :: write ( & mut * lock, data)
589
+ }
590
+ fn flush ( & mut self ) -> io:: Result < ( ) > {
591
+ Ok ( ( ) )
592
+ }
593
+ }
0 commit comments