Skip to content
This repository has been archived by the owner on Nov 8, 2021. It is now read-only.

Commit

Permalink
Merge pull request rustwasm#409 from daubaris/master
Browse files Browse the repository at this point in the history
added wasm-pack feature which compares local and latest wasm-pack versions
  • Loading branch information
drager authored Apr 14, 2019
2 parents 9423867 + 3860662 commit ae89be4
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 0 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ toml = "0.4"
which = "2.0.0"
binary-install = "0.0.2"
walkdir = "2"
chrono = "0.4.6"

[dev-dependencies]
assert_cmd = "0.10.2"
Expand Down
19 changes: 19 additions & 0 deletions src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use child;
use command::build::BuildProfile;
use emoji;
use failure::{Error, ResultExt};
use manifest::Crate;
use std::path::Path;
use std::process::Command;
use std::str;
Expand Down Expand Up @@ -48,6 +49,24 @@ fn rustc_minor_version() -> Option<u32> {
otry!(pieces.next()).parse().ok()
}

/// Checks and returns local and latest versions of wasm-pack
pub fn check_wasm_pack_versions() -> Result<(String, String), Error> {
match wasm_pack_local_version() {
Some(local) => {
match Crate::return_wasm_pack_latest_version() {
Some(latest) => Ok((local, latest)),
None => Ok((local, "".to_string()))
}
},
None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct.")
}
}

fn wasm_pack_local_version() -> Option<String> {
let output = env!("CARGO_PKG_VERSION");
Some(output.to_string())
}

/// Run `cargo build` targetting `wasm32-unknown-unknown`.
pub fn cargo_build_wasm(
path: &Path,
Expand Down
6 changes: 6 additions & 0 deletions src/command/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ impl Build {
Ok(())
}

/// Returns local and latest wasm-pack versions.
pub fn return_wasm_pack_versions() -> Result<(String, String), Error> {
let (local, latest) = build::check_wasm_pack_versions()?;
Ok((local, latest))
}

fn get_process_steps(mode: BuildMode) -> Vec<(&'static str, BuildStep)> {
macro_rules! steps {
($($name:ident),+) => {
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ extern crate serde_json;
#[macro_use]
extern crate structopt;
extern crate binary_install;
extern crate chrono;
extern crate curl;
extern crate dialoguer;
extern crate log;
extern crate toml;
Expand Down
25 changes: 25 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,34 @@ extern crate env_logger;
#[macro_use]
extern crate failure;
extern crate human_panic;
extern crate log;
extern crate structopt;
extern crate wasm_pack;
extern crate which;

use std::env;
use std::panic;
use std::sync::mpsc;
use std::thread;
use structopt::StructOpt;
use wasm_pack::command::build::Build;
use wasm_pack::{command::run_wasm_pack, Cli};

mod installer;

fn background_check_for_updates() -> mpsc::Receiver<(String, String)> {
let (sender, receiver) = mpsc::channel();
let _detached_thread = thread::spawn(move || {
if let Ok((local, latest)) = Build::return_wasm_pack_versions() {
if !local.is_empty() && !latest.is_empty() && local != latest {
sender.send((local, latest)).unwrap();
}
}
});

receiver
}

fn main() {
env_logger::init();

Expand All @@ -29,6 +46,8 @@ fn main() {
}

fn run() -> Result<(), failure::Error> {
let update_available = background_check_for_updates();

// Deprecate `init`
if let Some("init") = env::args().nth(1).as_ref().map(|arg| arg.as_str()) {
println!("wasm-pack init is deprecated, consider using wasm-pack build");
Expand All @@ -49,6 +68,12 @@ fn run() -> Result<(), failure::Error> {

let args = Cli::from_args();
run_wasm_pack(args.cmd)?;

if let Ok(update_available) = update_available.try_recv() {
println!("There's a newer version of wasm-pack available, the new version is: {}, you are using: {}. \
To update, navigate to: https://rustwasm.github.io/wasm-pack/installer/", update_available.1, update_available.0);
}

Ok(())
}

Expand Down
118 changes: 118 additions & 0 deletions src/manifest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ use self::npm::{
repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage,
};
use cargo_metadata::Metadata;
use chrono::offset;
use chrono::DateTime;
use command::build::{BuildProfile, Target};
use curl::easy;
use failure::{Error, ResultExt};
use serde::{self, Deserialize};
use serde_json;
use std::collections::BTreeSet;
use std::io::Write;
use strsim::levenshtein;
use toml;
use which;
use PBAR;

const WASM_PACK_METADATA_KEY: &str = "package.metadata.wasm-pack";
Expand Down Expand Up @@ -113,6 +118,119 @@ struct CargoWasmPackProfileWasmBindgen {
dwarf_debug_info: Option<bool>,
}

struct Collector(Vec<u8>);

impl easy::Handler for Collector {
fn write(&mut self, data: &[u8]) -> Result<usize, easy::WriteError> {
self.0.extend_from_slice(data);
Ok(data.len())
}
}

/// Struct for storing information received from crates.io
#[derive(Deserialize, Debug)]
pub struct Crate {
#[serde(rename = "crate")]
crt: CrateInformation,
}

#[derive(Deserialize, Debug)]
struct CrateInformation {
max_version: String,
}

impl Crate {
/// Returns latest wasm-pack version
pub fn return_wasm_pack_latest_version() -> Option<String> {
let current_time = chrono::offset::Local::now();
Crate::return_wasm_pack_file().and_then(|contents| {
let last_updated = Crate::return_stamp_file_value(&contents, "created")
.and_then(|t| Some(DateTime::parse_from_str(t.as_str(), "%+").unwrap()));
let version = Crate::return_stamp_file_value(&contents, "version").and_then(|v| {
if current_time
.signed_duration_since(last_updated.unwrap())
.num_hours()
> 24
{
return Crate::return_api_call_result(current_time);
} else {
return Some(v);
}
});
version
});
return Crate::return_api_call_result(current_time);
}

fn return_api_call_result(current_time: DateTime<offset::Local>) -> Option<String> {
Crate::return_latest_wasm_pack_version().and_then(|v| {
Crate::override_stamp_file(current_time, &v);
Some(v)
})
}

fn override_stamp_file(current_time: DateTime<offset::Local>, version: &String) {
if let Ok(path) = which::which("wasm-pack") {
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.append(true)
.create(true)
.open(path.with_extension("stamp"));

if let Ok(()) = file.as_ref().unwrap().set_len(0) {
if let Err(_) = write!(
file.unwrap(),
"created {:?}\nversion {}",
current_time,
version
) {}
}
}
}

/// Return stamp file where metadata is stored.
fn return_wasm_pack_file() -> Option<String> {
if let Ok(path) = which::which("wasm-pack") {
if let Ok(file) = fs::read_to_string(path.with_extension("stamp")) {
return Some(file);
}
}
None
}

/// Returns wasm-pack latest version (if it's received) by executing check_wasm_pack_latest_version function.
fn return_latest_wasm_pack_version() -> Option<String> {
if let Ok(crt) = Crate::check_wasm_pack_latest_version() {
return Some(crt.crt.max_version);
}
None
}

/// Read the stamp file and return value assigned to a certain key.
fn return_stamp_file_value(file: &String, word: &str) -> Option<String> {
let created = file
.lines()
.find(|line| line.starts_with(word))
.and_then(|l| l.split_whitespace().nth(1));

let value = created.map(|s| s.to_string());

value
}

/// Call to the crates.io api and return the latest version of `wasm-pack`
fn check_wasm_pack_latest_version() -> Result<Crate, Error> {
let mut easy = easy::Easy2::new(Collector(Vec::new()));
easy.get(true)?;
easy.url("https://crates.io/api/v1/crates/wasm-pack")?;
easy.perform()?;
let contents = easy.get_ref();
let result = String::from_utf8_lossy(&contents.0);
Ok(serde_json::from_str(result.into_owned().as_str())?)
}
}

impl CargoWasmPackProfile {
fn default_dev() -> Self {
CargoWasmPackProfile {
Expand Down

0 comments on commit ae89be4

Please sign in to comment.