Migrate output towards the 1.0 strategy

This commit is the first in what is hopefully a series to help move
`wasm-pack`'s CLI output and interactions to a "1.0 status". This was
[discussed at the recent Rust All Hands][discussion] where the salient
points we ended up extracting were:

* At all times if a user is waiting for `wasm-pack` to finish it should
  be clear what's being waited on.
  * As an example, Cargo's own output shows what crate is being built.
  * As another example, something that always takes only a handful of
    milliseconds to complete doesn't need an informational message.
* The final output products of a command should always be clear and
  printed. For example the output location of artifacts should always be
  printed.
* The `wasm-pack` CLI tool should use "progressive enhancement" to
  incrementally detect features of the output it can use (like colors,
  emoji, etc) but always work in the absence of these features. This'll
  help us support a wide range of use cases and terminals.

The goal of this commit is to not get us all the way there but start us
down the path to satisfying these goals. To that end the major change
here is to remove the dependency on `indicatif`. Using `indicatif`
requires that all output is piped through the `indicatif` crate itself,
which causes the third item here to not work for one of the main parts
of `wasm-pack build`, the `cargo` pieces. Cargo (and the Rust compiler)
are unable to use thir own tools for progressive enhancement when the
output is captured and sent through `indicatif`.

Lots more refactoring will be needed internally to fully polish off the
input/output to a "1.0 status", but this is hopefully a good start!

[discussion]: https://gist.github.com/fitzgen/23a62ebbd67574b9f6f72e5ac8eaeb67#file-road-to-wasm-pack-1-0-md
master
Alex Crichton 6 years ago
parent f2d7dd0b62
commit 64239747a0
  1. 1582
      Cargo.lock
  2. 3
      Cargo.toml
  3. 3
      src/command/build.rs
  4. 3
      src/command/test.rs
  5. 12
      src/command/utils.rs
  6. 9
      src/lib.rs
  7. 66
      src/progressbar.rs

1582
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -20,8 +20,6 @@ env_logger = { version = "0.5.13", default-features = false }
failure = "0.1.2"
human-panic = "1.0.1"
glob = "0.2"
indicatif = "0.9.0"
lazy_static = "1.1.0"
log = "0.4.6"
openssl = { version = '0.10.11', optional = true }
parking_lot = "0.6"
@ -39,6 +37,7 @@ walkdir = "2"
[dev-dependencies]
assert_cmd = "0.10.2"
lazy_static = "1.1.0"
predicates = "1.0.0"
tempfile = "3"

@ -7,7 +7,6 @@ use cache;
use command::utils::{create_pkg_dir, set_crate_path};
use emoji;
use failure::Error;
use indicatif::HumanDuration;
use license;
use lockfile::Lockfile;
use log::info;
@ -236,7 +235,7 @@ impl Build {
step_counter.inc();
}
let duration = HumanDuration(started.elapsed());
let duration = crate::command::utils::elapsed(started.elapsed());
info!("Done in {}.", &duration);
info!(
"Your wasm pkg is ready to publish at {}.",

@ -9,7 +9,6 @@ use command::utils::set_crate_path;
use console::style;
use emoji;
use failure::Error;
use indicatif::HumanDuration;
use lockfile::Lockfile;
use log::info;
use manifest;
@ -172,7 +171,7 @@ impl Test {
process_step(&mut self, &step_counter)?;
step_counter.inc();
}
let duration = HumanDuration(started.elapsed());
let duration = crate::command::utils::elapsed(started.elapsed());
info!("Done in {}.", &duration);
Ok(())

@ -5,6 +5,7 @@ use failure;
use progressbar::Step;
use std::fs;
use std::path::{Path, PathBuf};
use std::time::Duration;
use walkdir::WalkDir;
use PBAR;
@ -39,3 +40,14 @@ pub fn find_pkg_directory(path: &Path) -> Option<PathBuf> {
fn is_pkg_directory(path: &Path) -> bool {
path.exists() && path.is_dir() && path.ends_with("pkg")
}
/// Render a `Duration` to a form suitable for display on a console
pub fn elapsed(duration: Duration) -> String {
let secs = duration.as_secs();
if secs >= 60 {
format!("{}m {:02}s", secs / 60, secs % 60)
} else {
format!("{}.{:02}s", secs, duration.subsec_nanos() / 10_000_000)
}
}

@ -8,12 +8,9 @@ extern crate strsim;
#[macro_use]
extern crate failure;
extern crate glob;
extern crate indicatif;
extern crate which;
#[macro_use]
extern crate lazy_static;
extern crate parking_lot;
extern crate serde;
extern crate which;
#[macro_use]
extern crate serde_derive;
extern crate serde_ignored;
@ -43,10 +40,8 @@ pub mod test;
use progressbar::ProgressOutput;
lazy_static! {
/// The global progress bar and user-facing message output.
pub static ref PBAR: ProgressOutput = { ProgressOutput::new() };
}
pub static PBAR: ProgressOutput = ProgressOutput;
/// 📦 ✨ pack and publish your wasm!
#[derive(Debug, StructOpt)]

@ -2,25 +2,12 @@
use console::style;
use emoji;
use indicatif::{ProgressBar, ProgressStyle};
use parking_lot::RwLock;
use std::fmt;
/// Synchronized progress bar and status message printing.
pub struct ProgressOutput {
spinner: RwLock<ProgressBar>,
messages: RwLock<String>,
}
pub struct ProgressOutput;
impl ProgressOutput {
/// Construct a new `ProgressOutput`.
pub fn new() -> Self {
Self {
spinner: RwLock::new(ProgressBar::new_spinner()),
messages: RwLock::new(String::from("")),
}
}
/// Inform the user that the given `step` is being executed, with details in
/// `message`.
pub fn step(&self, step: &Step, message: &str) {
@ -28,35 +15,13 @@ impl ProgressOutput {
self.message(&msg)
}
fn finish(&self) {
let spinner = self.spinner.read();
spinner.finish();
let mut message = self.messages.write();
print!("{}", *message);
message.clear();
}
/// Print the given message.
pub fn message(&self, message: &str) {
self.finish();
let mut spinner = self.spinner.write();
*spinner = Self::progressbar(message);
if !atty::is(atty::Stream::Stderr) {
// `indicatif` won't print any output if `stderr` is not a tty, so
// to ensure that our output is still emitted, we print it manually
// here.
eprintln!("{}", message)
}
eprintln!(" {}", message);
}
fn add_message(&self, msg: &str) {
let mut message = self.messages.write();
message.push_str(" ");
message.push_str(msg);
message.push('\n');
println!("{}", msg);
}
/// Add an informational message.
@ -91,23 +56,6 @@ impl ProgressOutput {
);
self.add_message(&err);
}
fn progressbar(msg: &str) -> ProgressBar {
let pb = ProgressBar::new_spinner();
pb.enable_steady_tick(200);
pb.set_style(
ProgressStyle::default_spinner()
.tick_chars("/|\\- ")
.template("{spinner:.dim.bold} {wide_msg}"),
);
pb.set_message(&msg);
pb
}
/// After having built up a series of messages, print all of them out.
pub fn done(&self) {
self.finish();
}
}
/// For processes that can be broken down into N fractional steps, with messages
@ -137,14 +85,8 @@ impl fmt::Display for Step {
}
}
impl Drop for ProgressOutput {
fn drop(&mut self) {
self.done();
}
}
impl Default for ProgressOutput {
fn default() -> Self {
Self::new()
ProgressOutput
}
}

Loading…
Cancel
Save