Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Commit ed055fe

Browse files
committed
Auto merge of #140 - Xanewok:deps, r=Manishearth
Bump Cargo to 0.48 The main change is in 8938495, which works around rust-lang/cargo#8236 that introduced different mechanism to output stdio/shell-based data. Everything now goes through cargo `Shell` type so `std::io::set_print` trick stopped working - instead, we create our custom shell and fetch the build plan through it. r? `@Manishearth` or `@ibabushkin`
2 parents 5ed300f + dd8c371 commit ed055fe

File tree

2 files changed

+54
-28
lines changed

2 files changed

+54
-28
lines changed

Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ license-file = "LICENSE"
1111
edition = "2018"
1212

1313
[dependencies]
14-
cargo = "0.44"
14+
cargo = "0.48"
1515
crates-io = "0.32"
1616
curl = "0.4.21"
1717
env_logger = "0.7"
1818
anyhow = "1.0.27"
1919
log = "0.4"
20-
rand = "0.7"
2120
semver = "0.9"
2221
serde = { version = "1.0.84", features = ["derive"] }
2322
serde_json = "1.0.34"
2423

2524
[dev-dependencies]
2625
quickcheck = "0.9"
26+
rand = "0.7"

src/bin/cargo-semver.rs

+52-26
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,15 @@ use cargo::core::{Package, PackageId, Source, SourceId, Workspace};
88
use cargo::sources::RegistrySource;
99
use curl::easy::Easy;
1010
use log::debug;
11-
use rand::Rng;
1211
use rustc_session::getopts;
1312
use serde::Deserialize;
1413
use std::collections::HashSet;
1514
use std::{
16-
env,
17-
fs::File,
18-
io::BufReader,
15+
env, io,
1916
io::Write,
2017
path::{Path, PathBuf},
2118
process::{Command, Stdio},
19+
sync::{Arc, RwLock},
2220
};
2321

2422
pub type Result<T> = cargo::util::CargoResult<T>;
@@ -481,13 +479,15 @@ impl<'a> WorkInfo<'a> {
481479
// we need the build plan to find our build artifacts
482480
opts.build_config.build_plan = true;
483481

484-
if let Some(target) = matches.opt_str("target") {
485-
let target = cargo::core::compiler::CompileTarget::new(&target);
486-
if let Ok(target) = target {
487-
let kind = cargo::core::compiler::CompileKind::Target(target);
488-
opts.build_config.requested_kind = kind;
489-
}
490-
}
482+
let compile_kind = if let Some(target) = matches.opt_str("target") {
483+
let target = cargo::core::compiler::CompileTarget::new(&target)?;
484+
485+
let kind = cargo::core::compiler::CompileKind::Target(target);
486+
opts.build_config.requested_kinds = vec![kind];
487+
kind
488+
} else {
489+
cargo::core::compiler::CompileKind::Host
490+
};
491491

492492
if let Some(s) = matches.opt_str("features") {
493493
opts.features = s.split(' ').map(str::to_owned).collect();
@@ -501,36 +501,35 @@ impl<'a> WorkInfo<'a> {
501501
format!("-C metadata={}", if current { "new" } else { "old" }),
502502
);
503503

504-
let mut outdir = env::temp_dir();
505-
// The filename is randomized to avoid clashes when multiple cargo-semver instances are running.
506-
outdir.push(&format!(
507-
"cargo_semver_{}_{}_{}",
508-
name,
509-
current,
510-
rand::thread_rng().gen::<u32>()
511-
));
504+
// Capture build plan from a separate Cargo invocation
505+
let output = VecWrite(Arc::new(RwLock::new(Vec::new())));
506+
507+
let mut file_write = cargo::core::Shell::from_write(Box::new(output.clone()));
508+
file_write.set_verbosity(cargo::core::Verbosity::Quiet);
512509

513-
// redirection gang
514-
let outfile = File::create(&outdir)?;
515-
let old_stdio = std::io::set_print(Some(Box::new(outfile)));
510+
let old_shell = std::mem::replace(&mut *config.shell(), file_write);
516511

517-
let _ = cargo::ops::compile(&self.workspace, &opts)?;
512+
cargo::ops::compile(&self.workspace, &opts)?;
518513

519-
std::io::set_print(old_stdio);
514+
let _ = std::mem::replace(&mut *config.shell(), old_shell);
515+
let plan_output = output.read()?;
520516

521517
// actually compile things now
522518
opts.build_config.build_plan = false;
523519

524520
let compilation = cargo::ops::compile(&self.workspace, &opts)?;
525521
env::remove_var("RUSTFLAGS");
526522

527-
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"))?;
528525

529526
// TODO: handle multiple outputs gracefully
530527
for i in &build_plan.invocations {
531528
if let Some(kind) = i.target_kind.get(0) {
532529
if kind.contains("lib") && i.package_name == name {
533-
return Ok((i.outputs[0].clone(), compilation.deps_output));
530+
let deps_output = &compilation.deps_output[&compile_kind];
531+
532+
return Ok((i.outputs[0].clone(), deps_output.clone()));
534533
}
535534
}
536535
}
@@ -565,3 +564,30 @@ pub fn find_on_crates_io(crate_name: &str) -> Result<crates_io::Crate> {
565564
})
566565
})
567566
}
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

Comments
 (0)