1
1
#![ feature( rustc_private) ]
2
2
#![ feature( uniform_paths) ]
3
+ #![ feature( set_stdio) ]
3
4
4
5
extern crate getopts;
6
+ extern crate serde_json;
5
7
8
+ use cargo:: core:: { Package , PackageId , PackageSet , Source , SourceId , SourceMap , Workspace } ;
6
9
use log:: debug;
10
+ use serde_json:: Value ;
7
11
use std:: {
8
- io:: Write ,
9
12
env,
13
+ io:: BufReader ,
14
+ io:: Write ,
15
+ fs:: File ,
10
16
path:: { Path , PathBuf } ,
11
17
process:: { Command , Stdio } ,
12
18
} ;
13
- use cargo:: core:: { Package , PackageId , PackageSet , Source , SourceId , SourceMap , Workspace } ;
14
19
15
20
pub type Result < T > = cargo:: util:: CargoResult < T > ;
16
21
@@ -106,6 +111,9 @@ fn run(config: &cargo::Config, matches: &getopts::Matches, explain: bool) -> Res
106
111
let ( current_rlib, current_deps_output) = current. rlib_and_dep_output ( config, & name, true ) ?;
107
112
let ( stable_rlib, stable_deps_output) = stable. rlib_and_dep_output ( config, & name, false ) ?;
108
113
114
+ println ! ( "current_rlib: {:?}" , current_rlib) ;
115
+ println ! ( "stable_rlib: {:?}" , stable_rlib) ;
116
+
109
117
if matches. opt_present ( "d" ) {
110
118
println ! (
111
119
"--extern old={} -L{} --extern new={} -L{}" ,
@@ -335,7 +343,7 @@ impl<'a> WorkInfo<'a> {
335
343
) -> Result < WorkInfo < ' a > > {
336
344
// TODO: fall back to locally cached package instance, or better yet, search for it
337
345
// first.
338
- let package_ids = [ PackageId :: new ( name, version, source. id ) ?] ;
346
+ let package_ids = [ PackageId :: new ( name, version, & source. id ) ?] ;
339
347
debug ! ( "(remote) package id: {:?}" , package_ids[ 0 ] ) ;
340
348
let sources = {
341
349
let mut s = SourceMap :: new ( ) ;
@@ -344,7 +352,7 @@ impl<'a> WorkInfo<'a> {
344
352
} ;
345
353
346
354
let package_set = PackageSet :: new ( & package_ids, sources, config) ?;
347
- let package = package_set. get_one ( package_ids[ 0 ] ) ?;
355
+ let package = package_set. get_one ( & package_ids[ 0 ] ) ?;
348
356
let workspace = Workspace :: ephemeral ( package. clone ( ) , config, None , false ) ?;
349
357
350
358
Ok ( Self {
@@ -360,21 +368,55 @@ impl<'a> WorkInfo<'a> {
360
368
name : & str ,
361
369
current : bool ,
362
370
) -> Result < ( PathBuf , PathBuf ) > {
363
- let opts =
364
- cargo:: ops:: CompileOptions :: new ( config, cargo:: core:: compiler:: CompileMode :: Build )
365
- . unwrap ( ) ;
371
+ let mut opts =
372
+ cargo:: ops:: CompileOptions :: new ( config, cargo:: core:: compiler:: CompileMode :: Build ) ?;
373
+ // we need the build plan to find our build artifacts
374
+ opts. build_config . build_plan = true ;
375
+ // TODO: this is where we could insert feature flag builds (or using the CLI mechanisms)
376
+
377
+ env:: set_var ( "RUSTFLAGS" ,
378
+ format ! ( "-C metadata={}" , if current { "new" } else { "old" } ) ) ;
379
+
380
+ let mut outdir = env:: temp_dir ( ) ;
381
+ outdir. push ( & format ! ( "cargo_semver_{}_{}" , name, current) ) ;
382
+
383
+ // redirection gang
384
+ let outfile = File :: create ( & outdir) ?;
385
+ let old_stdio = std:: io:: set_print ( Some ( Box :: new ( outfile) ) ) ;
386
+
387
+ let _ = cargo:: ops:: compile ( & self . workspace , & opts) ?;
388
+
389
+ std:: io:: set_print ( old_stdio) ;
390
+
391
+ // actually compile things now
392
+ opts. build_config . build_plan = false ;
366
393
367
- env:: set_var ( "RUSTFLAGS" , format ! ( "-C metadata={}" , if current { "new" } else { "old" } ) ) ;
368
394
let compilation = cargo:: ops:: compile ( & self . workspace , & opts) ?;
369
395
env:: remove_var ( "RUSTFLAGS" ) ;
370
396
371
- // TODO: use cargo metadata to fetch the rlib path here:
372
- let rlib = compilation. libraries [ & self . package . package_id ( ) ]
373
- . iter ( )
374
- . find ( |t| t. 0 . name ( ) == name)
375
- . ok_or_else ( || failure:: err_msg ( "lost a build artifact" . to_owned ( ) ) ) ?;
397
+ let build_plan: Value =
398
+ serde_json:: from_reader ( BufReader :: new ( File :: open ( & outdir) ?) ) ?;
399
+
400
+ // FIXME: yuck drilling
401
+ if let Value :: Object ( m) = build_plan {
402
+ if let Some ( Value :: Array ( v) ) = m. get ( "invocations" ) {
403
+ for s in v {
404
+ if let Value :: Object ( m2) = s {
405
+ if let Some ( Value :: String ( s2) ) = m2. get ( "package_name" ) {
406
+ if s2 != name { continue ; }
407
+ }
408
+
409
+ if let Some ( Value :: Array ( v2) ) = m2. get ( "outputs" ) {
410
+ if let Some ( Value :: String ( s) ) = v2. get ( 0 ) {
411
+ return Ok ( ( PathBuf :: from ( s) , compilation. deps_output ) ) ;
412
+ }
413
+ }
414
+ }
415
+ }
416
+ }
417
+ }
376
418
377
- Ok ( ( rlib . 1 . clone ( ) , compilation . deps_output ) )
419
+ Err ( failure :: err_msg ( "lost build artifact" . to_owned ( ) ) )
378
420
}
379
421
}
380
422
0 commit comments