Replace std::sync::RwLock with parking_lot

The standard library version of an `RwLock` may get poisoned if a thread
panics that holds a write lock. The `RwLock` from parking_lot [1] does
not get poisoned it instead released the lock on a panic. This allows us
to simplify the `ProgressOutput` API since it no longer returns any
errors. No more panics can occur on `ProgressOutput::drop()`. The
`Error` enum can thus be simplified as well because there is no need to
convert `PoisonErrors` anymore.

[1] https://github.com/Amanieu/parking_lot
master
Michael Gerhaeuser 7 years ago
parent 1c50b12b8f
commit 62423e33d4
  1. 27
      Cargo.lock
  2. 1
      Cargo.toml
  3. 6
      src/bindgen.rs
  4. 4
      src/build.rs
  5. 6
      src/command/init.rs
  6. 2
      src/command/login.rs
  7. 2
      src/command/mod.rs
  8. 2
      src/command/pack.rs
  9. 2
      src/command/publish.rs
  10. 10
      src/error.rs
  11. 1
      src/lib.rs
  12. 10
      src/manifest.rs
  13. 53
      src/progressbar.rs
  14. 4
      src/readme.rs

27
Cargo.lock generated

@ -220,6 +220,15 @@ name = "libc"
version = "0.2.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lock_api"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.0.1"
@ -266,6 +275,15 @@ dependencies = [
"parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lock_api 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "parking_lot_core"
version = "0.2.14"
@ -375,6 +393,11 @@ name = "rustc-demangle"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scopeguard"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.63"
@ -653,6 +676,7 @@ dependencies = [
"human-panic 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indicatif 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
@ -727,12 +751,14 @@ dependencies = [
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
"checksum libc 0.2.41 (registry+https://github.com/rust-lang/crates.io-index)" = "ac8ebf8343a981e2fa97042b14768f02ed3e1d602eac06cae6166df3c8ced206"
"checksum lock_api 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0584737c452c08cb0869553519e150d5d4351195ad553ab9b125742f14237f13"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
"checksum num-integer 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac0ea58d64a89d9d6b7688031b3be9358d6c919badcf7fbb0527ccfd891ee45"
"checksum num-traits 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775393e285254d2f5004596d69bb8bc1149754570dcc08cf30cabeba67955e28"
"checksum os_type 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "081f0539f57611638feee0d72fe98ad0b685e99da117be6b254bd1dfd7421609"
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
"checksum parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4d05f1349491390b1730afba60bb20d55761bef489a954546b58b4b34e1e2ac"
"checksum parking_lot 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "59496464aa86ead2063b46eca52342bdf81d2a4bf7105f5c989ab53bfd305804"
"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa"
"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
@ -747,6 +773,7 @@ dependencies = [
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
"checksum serde 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4a07014dd9a6845448a9e62f6f27595847f09828caabf1b1d50bb6755fa4d2"
"checksum serde_derive 1.0.63 (registry+https://github.com/rust-lang/crates.io-index)" = "d68003d21ef20c5c48354638c2e5c0d4ce4a056fdbf973839e0e86054eae7794"
"checksum serde_json 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ee382a792fabc5d720630aeafe1a4c69abe3d32aaaa5dbba6762fd8246d1bbe3"

@ -14,6 +14,7 @@ failure = "0.1.1"
human-panic = "1.0.0"
indicatif = "0.9.0"
lazy_static = "1.0.0"
parking_lot = "0.6"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"

@ -6,7 +6,7 @@ use PBAR;
pub fn cargo_install_wasm_bindgen(step: &Step) -> Result<(), Error> {
let msg = format!("{}Installing WASM-bindgen...", emoji::DOWN_ARROW);
PBAR.step(step, &msg)?;
PBAR.step(step, &msg);
let output = Command::new("cargo")
.arg("install")
.arg("wasm-bindgen-cli")
@ -15,7 +15,7 @@ pub fn cargo_install_wasm_bindgen(step: &Step) -> Result<(), Error> {
if !output.status.success() {
let s = String::from_utf8_lossy(&output.stderr);
if s.contains("already exists") {
PBAR.info("wasm-bindgen already installed")?;
PBAR.info("wasm-bindgen already installed");
return Ok(());
}
Error::cli("Installing wasm-bindgen failed", s)
@ -33,7 +33,7 @@ pub fn wasm_bindgen_build(
step: &Step,
) -> Result<(), Error> {
let msg = format!("{}Running WASM-bindgen...", emoji::RUNNER);
PBAR.step(step, &msg)?;
PBAR.step(step, &msg);
let binary_name = name.replace("-", "_");
let release_or_debug = if debug { "debug" } else { "release" };
let wasm_path = format!(

@ -6,7 +6,7 @@ use PBAR;
pub fn rustup_add_wasm_target(step: &Step) -> Result<(), Error> {
let msg = format!("{}Adding WASM target...", emoji::TARGET);
PBAR.step(step, &msg)?;
PBAR.step(step, &msg);
ensure_nightly()?;
let output = Command::new("rustup")
.arg("target")
@ -41,7 +41,7 @@ fn ensure_nightly() -> Result<(), Error> {
pub fn cargo_build_wasm(path: &str, debug: bool, step: &Step) -> Result<(), Error> {
let msg = format!("{}Compiling to WASM...", emoji::CYCLONE);
PBAR.step(step, &msg)?;
PBAR.step(step, &msg);
let output = {
let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("+nightly").arg("build");

@ -17,7 +17,7 @@ use PBAR;
// the correct type here.
pub fn create_pkg_dir(path: &str, step: &Step) -> result::Result<(), Error> {
let msg = format!("{}Creating a pkg directory...", emoji::FOLDER);
PBAR.step(step, &msg)?;
PBAR.step(step, &msg);
let pkg_dir_path = format!("{}/pkg", path);
fs::create_dir_all(pkg_dir_path)?;
Ok(())
@ -103,13 +103,13 @@ impl Init {
"Your WASM pkg is ready to publish at {}/pkg.", &self.crate_path
);
PBAR.message(&format!("{} Done in {}", emoji::SPARKLE, &duration))?;
PBAR.message(&format!("{} Done in {}", emoji::SPARKLE, &duration));
PBAR.message(&format!(
"{} Your WASM pkg is ready to publish at {}/pkg.",
emoji::PACKAGE,
&self.crate_path
))?;
));
Ok(())
}

@ -26,6 +26,6 @@ pub fn login(
npm::npm_login(&registry, &scope, always_auth, &auth_type)?;
info!(&log, "Logged you in!");
PBAR.message(&format!("👋 logged you in!"))?;
PBAR.message(&format!("👋 logged you in!"));
Ok(())
}

@ -145,7 +145,7 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error
Ok(_) => {}
Err(ref e) => {
error!(&log, "{}", e);
PBAR.error(e.error_type())?;
PBAR.error(e.error_type());
}
}

@ -15,6 +15,6 @@ pub fn pack(path: Option<String>, log: &Logger) -> result::Result<(), Error> {
#[cfg(target_os = "windows")]
info!(&log, "Your package is located at {}\\pkg", &crate_path);
PBAR.message("🎒 packed up your package!")?;
PBAR.message("🎒 packed up your package!");
Ok(())
}

@ -13,6 +13,6 @@ pub fn publish(path: Option<String>, log: &Logger) -> result::Result<(), Error>
npm::npm_publish(&crate_path)?;
info!(&log, "Published your package!");
PBAR.message("💥 published your package!")?;
PBAR.message("💥 published your package!");
Ok(())
}

@ -2,7 +2,6 @@
use serde_json;
use std::borrow::Cow;
use std::io;
use std::sync::PoisonError;
use toml;
#[derive(Debug, Fail)]
@ -14,8 +13,6 @@ pub enum Error {
SerdeJson(#[cause] serde_json::Error),
#[fail(display = "{}", _0)]
SerdeToml(#[cause] toml::de::Error),
#[fail(display = "Acquiring lock failed")]
PoisonedLockError,
#[fail(display = "{}. stderr:\n\n{}", message, stderr)]
Cli { message: String, stderr: String },
#[fail(display = "{}", message)]
@ -41,7 +38,6 @@ impl Error {
Error::Io(_) => "There was an I/O error. Details:\n\n",
Error::SerdeJson(_) => "There was an JSON error. Details:\n\n",
Error::SerdeToml(_) => "There was an TOML error. Details:\n\n",
Error::PoisonedLockError => "There was an RwLock error. Details: \n\n",
Error::Cli {
message: _,
stderr: _,
@ -70,9 +66,3 @@ impl From<toml::de::Error> for Error {
Error::SerdeToml(e)
}
}
impl<T> From<PoisonError<T>> for Error {
fn from(_: PoisonError<T>) -> Self {
Error::PoisonedLockError
}
}

@ -4,6 +4,7 @@ extern crate failure;
extern crate indicatif;
#[macro_use]
extern crate lazy_static;
extern crate parking_lot;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

@ -123,20 +123,20 @@ pub fn write_package_json(
)
};
PBAR.step(step, &msg)?;
PBAR.step(step, &msg);
let pkg_file_path = format!("{}/pkg/package.json", path);
let mut pkg_file = File::create(pkg_file_path)?;
let crate_data = read_cargo_toml(path)?;
let npm_data = crate_data.into_npm(scope, disable_dts);
if npm_data.description.is_none() {
PBAR.warn(&warn_fmt("description"))?;
PBAR.warn(&warn_fmt("description"));
}
if npm_data.repository.is_none() {
PBAR.warn(&warn_fmt("repository"))?;
PBAR.warn(&warn_fmt("repository"));
}
if npm_data.license.is_none() {
PBAR.warn(&warn_fmt("license"))?;
PBAR.warn(&warn_fmt("license"));
}
let npm_json = serde_json::to_string_pretty(&npm_data)?;
@ -150,7 +150,7 @@ pub fn get_crate_name(path: &str) -> Result<String, Error> {
pub fn check_crate_config(path: &str, step: &Step) -> Result<(), Error> {
let msg = format!("{}Checking crate configuration...", emoji::WRENCH);
PBAR.step(&step, &msg)?;
PBAR.step(&step, &msg);
check_wasm_bindgen(path)?;
check_crate_type(path)?;
Ok(())

@ -1,9 +1,8 @@
use console::style;
use emoji;
use error::Error;
use indicatif::{ProgressBar, ProgressStyle};
use parking_lot::RwLock;
use std::fmt;
use std::sync::RwLock;
pub struct ProgressOutput {
spinner: RwLock<ProgressBar>,
@ -18,73 +17,62 @@ impl ProgressOutput {
}
}
pub fn step(&self, step: &Step, message: &str) -> Result<(), Error> {
pub fn step(&self, step: &Step, message: &str) {
let msg = format!("{} {}", style(step).bold().dim(), message);
self.message(&msg)
}
fn finish(&self) -> Result<(), Error> {
let spinner = self.spinner.read()?;
fn finish(&self) {
let spinner = self.spinner.read();
spinner.finish();
let mut message = self.messages.write()?;
print!("{}", message);
let mut message = self.messages.write();
print!("{}", *message);
message.clear();
Ok(())
}
pub fn message(&self, message: &str) -> Result<(), Error> {
self.finish()?;
pub fn message(&self, message: &str) {
self.finish();
let mut spinner = self.spinner.write()?;
let mut spinner = self.spinner.write();
*spinner = Self::progressbar(message);
Ok(())
}
fn add_message(&self, msg: &str) -> Result<(), Error> {
let mut message = self.messages.write()?;
fn add_message(&self, msg: &str) {
let mut message = self.messages.write();
message.push_str(" ");
message.push_str(msg);
message.push('\n');
Ok(())
}
pub fn info(&self, message: &str) -> Result<(), Error> {
pub fn info(&self, message: &str) {
let info = format!(
"{} {}: {}",
emoji::INFO,
style("[INFO]").bold().dim(),
message
);
self.add_message(&info)?;
Ok(())
self.add_message(&info);
}
pub fn warn(&self, message: &str) -> Result<(), Error> {
pub fn warn(&self, message: &str) {
let warn = format!(
"{} {}: {}",
emoji::WARN,
style("[WARN]").bold().dim(),
message
);
self.add_message(&warn)?;
Ok(())
self.add_message(&warn);
}
pub fn error(&self, message: String) -> Result<(), Error> {
pub fn error(&self, message: String) {
let err = format!(
"{} {}: {}",
emoji::ERROR,
style("[ERR]").bold().dim(),
message
);
self.add_message(&err)?;
Ok(())
self.add_message(&err);
}
fn progressbar(msg: &str) -> ProgressBar {
@ -99,9 +87,8 @@ impl ProgressOutput {
pb
}
pub fn done(&self) -> Result<(), Error> {
self.finish()?;
Ok(())
pub fn done(&self) {
self.finish();
}
}
@ -127,6 +114,6 @@ impl fmt::Display for Step {
impl Drop for ProgressOutput {
fn drop(&mut self) {
self.done().unwrap();
self.done();
}
}

@ -7,11 +7,11 @@ use PBAR;
pub fn copy_from_crate(path: &str, step: &Step) -> Result<(), Error> {
let msg = format!("{}Copying over your README...", emoji::DANCERS);
PBAR.step(step, &msg)?;
PBAR.step(step, &msg);
let crate_readme_path = format!("{}/README.md", path);
let new_readme_path = format!("{}/pkg/README.md", path);
if let Err(_) = fs::copy(&crate_readme_path, &new_readme_path) {
PBAR.warn("origin crate has no README")?;
PBAR.warn("origin crate has no README");
};
Ok(())
}

Loading…
Cancel
Save