From 7c3f497e3cbef69fe6229460ed78bf637950327e Mon Sep 17 00:00:00 2001 From: daubaris Date: Sat, 13 Oct 2018 10:47:38 +0300 Subject: [PATCH 01/10] added wasm-pack feature checking wasm-pack version --- src/build.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/command/build.rs | 14 ++++++++++++++ src/error.rs | 26 ++++++++++++++++++++++++++ src/manifest/mod.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+) diff --git a/src/build.rs b/src/build.rs index f539744c..1de948e4 100644 --- a/src/build.rs +++ b/src/build.rs @@ -4,6 +4,7 @@ use child; use emoji; use error::Error; use failure::ResultExt; +use manifest::Crate; use progressbar::Step; use slog::Logger; use std::path::Path; @@ -36,6 +37,26 @@ pub fn check_rustc_version(step: &Step) -> Result { } } +/// Checks if `wasm-pack` is updated to the latest version +pub fn check_wasm_pack_version(step: &Step) -> Result<(), failure::Error> { + let msg = format!("{}Checking `wasm-pack` version...", emoji::PACKAGE); + PBAR.step(step, &msg); + let wasm_pack_local_version = wasm_pack_local_version(); + let wasm_pack_latest_version = Crate::return_wasm_pack_latest_version(); + match wasm_pack_local_version { + Some(lv) => { + if !(lv == wasm_pack_latest_version) { + Ok(PBAR.info(&format!("There's a newer version of wasm-pack available, the new version is: {}, you are using: {}", wasm_pack_latest_version, lv))) + } else { + Ok(()) + } + }, + None => Err(Error::WasmPackMissing { + message: "We can't figure out what your wasm-pack version is, make sure the installation path is correct.".to_string(), + }.into()), + } +} + // from https://github.com/alexcrichton/proc-macro2/blob/79e40a113b51836f33214c6d00228934b41bd4ad/build.rs#L44-L61 fn rustc_minor_version() -> Option { macro_rules! otry { @@ -55,6 +76,29 @@ fn rustc_minor_version() -> Option { otry!(pieces.next()).parse().ok() } +fn wasm_pack_local_version() -> Option { + macro_rules! otry { + ($e:expr) => { + match $e { + Some(e) => e, + None => return None, + } + }; + } + + let output = otry!(Command::new("wasm-pack").arg("--version").output().ok()); + let version = otry!(str::from_utf8(&output.stdout).ok()); + let mut pieces = version.split(' '); + if pieces.next() != Some("wasm-pack") { + return None; + } + otry!(pieces.next()) + .to_string() + .trim() + .parse::() + .ok() +} + /// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for /// current toolchain pub fn rustup_add_wasm_target(log: &Logger, step: &Step) -> Result<(), failure::Error> { diff --git a/src/command/build.rs b/src/command/build.rs index be1de723..1de9538e 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -160,6 +160,7 @@ impl Build { match &mode { BuildMode::Normal => steps![ step_check_rustc_version, + step_check_wasm_pack_version, step_check_crate_config, step_add_wasm_target, step_build_wasm, @@ -171,6 +172,7 @@ impl Build { ], BuildMode::Noinstall => steps![ step_check_rustc_version, + step_check_wasm_pack_version, step_check_crate_config, step_build_wasm, step_create_dir, @@ -200,6 +202,18 @@ impl Build { Ok(()) } + fn step_check_wasm_pack_version( + &mut self, + step: &Step, + log: &Logger, + ) -> Result<(), failure::Error> { + info!(&log, "Checking wasm-pack version..."); + let version = build::check_wasm_pack_version(step)?; + let msg = format!("wasm-pack version is: {:?}.", version); + info!(&log, "{}", &msg); + Ok(()) + } + fn step_check_crate_config(&mut self, step: &Step, log: &Logger) -> Result<(), failure::Error> { info!(&log, "Checking crate configuration..."); manifest::check_crate_config(&self.crate_path, step)?; diff --git a/src/error.rs b/src/error.rs index 4fcc513c..c9bd8089 100644 --- a/src/error.rs +++ b/src/error.rs @@ -46,6 +46,24 @@ pub enum Error { local_minor_version: String, }, + #[fail(display = "{}", _0)] + /// An error in parsing your wasm-pack version. + WasmPackMissing { + /// Error message + message: String, + }, + + #[fail(display = "{}", _0)] + /// An error from having an older wasm-pack version. + WasmPackVersion { + /// Error message + message: String, + /// Local version of wasm-pack + local_version: String, + /// Latest version of wasm-pack + latest_version: String, + }, + /// An error invoking another CLI tool. #[fail( display = "Process exited with {}: {}.\n\nstdout:{}\n\nstderr:\n\n{}", @@ -163,6 +181,14 @@ impl Error { message: _, local_minor_version: _, } => "Your rustc version is not supported. Please install version 1.30.0 or higher.", + Error::WasmPackMissing { + message: _, + } => "We can't figure out what your wasm-pack version is, make sure the installation path is correct.", + Error::WasmPackVersion { + message: _, + local_version: _, + latest_version: _, + } => "There's a newer version of wasm-pack available, the new version is: , you are using: ", Error::Cli { message: _, stdout: _, diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index f253b15d..3f71fbfd 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -10,14 +10,25 @@ use std::path::Path; use self::npm::{ repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage, }; +use curl::easy; use emoji; use error::Error; use failure; use progressbar::Step; use serde_json; use toml; + use PBAR; +struct Collector(Vec); + +impl easy::Handler for Collector { + fn write(&mut self, data: &[u8]) -> Result { + self.0.extend_from_slice(data); + Ok(data.len()) + } +} + #[derive(Debug, Deserialize)] struct CargoManifest { package: CargoPackage, @@ -77,6 +88,39 @@ struct CargoLib { crate_type: Option>, } +/// Struct for crates.io api, currently checking wasm-pack latest version +#[derive(Deserialize, Debug)] +pub struct Crate { + #[serde(rename = "crate")] + crt: CrateInformation, +} + +#[derive(Deserialize, Debug)] +struct CrateInformation { + max_version: String, +} + +impl Crate { + /// Call to the crates.io api and return the latest version of `wasm-pack` + pub fn return_wasm_pack_latest_version() -> String { + let crt = Crate::check_wasm_pack_latest_version(); + crt.crt.max_version + } + + fn check_wasm_pack_latest_version() -> Crate { + let mut easy = easy::Easy2::new(Collector(Vec::new())); + easy.get(true).unwrap(); + easy.url("https://crates.io/api/v1/crates/wasm-pack") + .unwrap(); + easy.perform().unwrap(); + + let contents = easy.get_ref(); + let result = String::from_utf8_lossy(&contents.0); + + serde_json::from_str(result.into_owned().as_str()).unwrap() + } +} + fn read_cargo_toml(path: &Path) -> Result { let manifest_path = path.join("Cargo.toml"); if !manifest_path.is_file() { From f7c534ffe5a4d38e77113f887f1aba4881f2620d Mon Sep 17 00:00:00 2001 From: daubaris Date: Tue, 13 Nov 2018 20:45:01 +0200 Subject: [PATCH 02/10] updated from upstream --- src/build.rs | 9 ++--- src/command/build.rs | 6 +-- src/command/mod.rs | 12 ++++++ src/manifest/mod.rs | 22 +++++------ tests/all/bindgen.rs | 8 ++-- tests/all/build.rs | 7 ++-- tests/all/manifest.rs | 86 +++++++++++++++++++++++++------------------ 7 files changed, 84 insertions(+), 66 deletions(-) diff --git a/src/build.rs b/src/build.rs index 756491e8..825f626e 100644 --- a/src/build.rs +++ b/src/build.rs @@ -3,8 +3,6 @@ use child; use emoji; use failure::{Error, ResultExt}; -use error::Error; -use failure::ResultExt; use manifest::Crate; use progressbar::Step; use slog::Logger; @@ -38,7 +36,7 @@ pub fn check_wasm_pack_version(step: &Step) -> Result<(), failure::Error> { let msg = format!("{}Checking `wasm-pack` version...", emoji::PACKAGE); PBAR.step(step, &msg); let wasm_pack_local_version = wasm_pack_local_version(); - let wasm_pack_latest_version = Crate::return_wasm_pack_latest_version(); + let wasm_pack_latest_version = Crate::return_wasm_pack_latest_version()?; match wasm_pack_local_version { Some(lv) => { if !(lv == wasm_pack_latest_version) { @@ -47,9 +45,8 @@ pub fn check_wasm_pack_version(step: &Step) -> Result<(), failure::Error> { Ok(()) } }, - None => Err(Error::WasmPackMissing { - message: "We can't figure out what your wasm-pack version is, make sure the installation path is correct.".to_string(), - }.into()), + None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct."), + } } diff --git a/src/command/build.rs b/src/command/build.rs index 7772afd0..86e67f77 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -213,11 +213,7 @@ impl Build { Ok(()) } - fn step_check_wasm_pack_version( - &mut self, - step: &Step, - log: &Logger, - ) -> Result<(), failure::Error> { + fn step_check_wasm_pack_version(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { info!(&log, "Checking wasm-pack version..."); let version = build::check_wasm_pack_version(step)?; let msg = format!("wasm-pack version is: {:?}.", version); diff --git a/src/command/mod.rs b/src/command/mod.rs index 0b186c04..5d3a9e14 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -13,10 +13,12 @@ use self::login::login; use self::pack::pack; use self::publish::{access::Access, publish}; use self::test::{Test, TestOptions}; +use std::sync::mpsc; use failure::Error; use slog::Logger; use std::path::PathBuf; use std::result; +use std::thread; /// The various kinds of commands that `wasm-pack` can execute. #[derive(Debug, StructOpt)] @@ -82,6 +84,15 @@ pub enum Command { Test(TestOptions), } +/// Spawn a thread for wasm-pack version +fn background_check_for_updates() -> mpsc::Receiver<(String, String)> { + let (sender, receiver) = mpsc::channel(); + + let _detached_thread = thread::spawn(move || { + + }); +} + /// Run a command with the given logger! pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error> { // Run the correct command based off input and store the result of it so that we can clear @@ -89,6 +100,7 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error let status = match command { Command::Build(build_opts) => { info!(&log, "Running build command..."); + // Add the background_check_for_updates() here Build::try_from_opts(build_opts).and_then(|mut b| b.run(&log)) } Command::Pack { path } => { diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index cd708165..0508df59 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -4,7 +4,6 @@ mod npm; use std::fs; use std::path::Path; -use std::collections::HashMap; use self::npm::{ repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage, @@ -41,7 +40,7 @@ struct CargoManifest { package: CargoPackage, } -#[derive(Deserialize)] +#[derive(Debug, Deserialize)] struct CargoPackage { name: String, description: Option, @@ -70,22 +69,21 @@ struct CrateInformation { impl Crate { /// Call to the crates.io api and return the latest version of `wasm-pack` - pub fn return_wasm_pack_latest_version() -> String { - let crt = Crate::check_wasm_pack_latest_version(); - crt.crt.max_version + pub fn return_wasm_pack_latest_version() -> Result { + let crt = Crate::check_wasm_pack_latest_version()?; + Ok(crt.crt.max_version) } - fn check_wasm_pack_latest_version() -> Crate { + fn check_wasm_pack_latest_version() -> Result { let mut easy = easy::Easy2::new(Collector(Vec::new())); - easy.get(true).unwrap(); - easy.url("https://crates.io/api/v1/crates/wasm-pack") - .unwrap(); - easy.perform().unwrap(); + 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); - serde_json::from_str(result.into_owned().as_str()).unwrap() + Ok(serde_json::from_str(result.into_owned().as_str())?) } } @@ -134,8 +132,6 @@ impl CrateData { } } - - /// Check that the crate the given path is properly configured. pub fn check_crate_config(&self, step: &Step) -> Result<(), Error> { let msg = format!("{}Checking crate configuration...", emoji::WRENCH); diff --git a/tests/all/bindgen.rs b/tests/all/bindgen.rs index 985a4d00..ae836a8f 100644 --- a/tests/all/bindgen.rs +++ b/tests/all/bindgen.rs @@ -31,7 +31,9 @@ fn downloading_prebuilt_wasm_bindgen_handles_http_errors() { let error = result.err().unwrap(); assert!(error.iter_chain().any(|e| e.to_string().contains("404"))); - assert!(error - .iter_chain() - .any(|e| e.to_string().contains(bad_version))); + assert!( + error + .iter_chain() + .any(|e| e.to_string().contains(bad_version)) + ); } diff --git a/tests/all/build.rs b/tests/all/build.rs index 5757b8c2..14b35eed 100644 --- a/tests/all/build.rs +++ b/tests/all/build.rs @@ -18,9 +18,10 @@ fn build_in_non_crate_directory_doesnt_panic() { "running wasm-pack in a non-crate directory should fail, but it should not panic" ); let err = result.unwrap_err(); - assert!(err - .iter_chain() - .any(|e| e.to_string().contains("missing a `Cargo.toml`"))); + assert!( + err.iter_chain() + .any(|e| e.to_string().contains("missing a `Cargo.toml`")) + ); } #[test] diff --git a/tests/all/manifest.rs b/tests/all/manifest.rs index 2c60f781..9734f2ce 100644 --- a/tests/all/manifest.rs +++ b/tests/all/manifest.rs @@ -65,9 +65,11 @@ fn it_creates_a_package_json_default_path() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!(crate_data - .write_package_json(&out_dir, &None, false, "", &step) - .is_ok()); + assert!( + crate_data + .write_package_json(&out_dir, &None, false, "", &step) + .is_ok() + ); let package_json_path = &fixture.path.join("pkg").join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -88,9 +90,9 @@ fn it_creates_a_package_json_default_path() { "js_hello_world.d.ts", "js_hello_world.js", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -101,9 +103,11 @@ fn it_creates_a_package_json_provided_path() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!(crate_data - .write_package_json(&out_dir, &None, false, "", &step) - .is_ok()); + assert!( + crate_data + .write_package_json(&out_dir, &None, false, "", &step) + .is_ok() + ); let package_json_path = &fixture.path.join("pkg").join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -117,9 +121,9 @@ fn it_creates_a_package_json_provided_path() { "js_hello_world.d.ts", "js_hello_world.js", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -130,9 +134,11 @@ fn it_creates_a_package_json_provided_path_with_scope() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!(crate_data - .write_package_json(&out_dir, &Some("test".to_string()), false, "", &step) - .is_ok()); + assert!( + crate_data + .write_package_json(&out_dir, &Some("test".to_string()), false, "", &step) + .is_ok() + ); let package_json_path = &fixture.path.join("pkg").join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -146,9 +152,9 @@ fn it_creates_a_package_json_provided_path_with_scope() { "js_hello_world.d.ts", "js_hello_world.js", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -159,9 +165,11 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!(crate_data - .write_package_json(&out_dir, &None, false, "nodejs", &step) - .is_ok()); + assert!( + crate_data + .write_package_json(&out_dir, &None, false, "nodejs", &step) + .is_ok() + ); let package_json_path = &out_dir.join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -182,9 +190,9 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() { "js_hello_world.d.ts", "js_hello_world.js", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -195,9 +203,11 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!(crate_data - .write_package_json(&out_dir, &None, false, "no-modules", &step) - .is_ok()); + assert!( + crate_data + .write_package_json(&out_dir, &None, false, "no-modules", &step) + .is_ok() + ); let package_json_path = &out_dir.join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -217,9 +227,9 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { "js_hello_world.js", "js_hello_world.d.ts", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -230,9 +240,11 @@ fn it_creates_a_pkg_json_in_out_dir() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!(crate_data - .write_package_json(&out_dir, &None, false, "", &step) - .is_ok()); + assert!( + crate_data + .write_package_json(&out_dir, &None, false, "", &step) + .is_ok() + ); let package_json_path = &fixture.path.join(&out_dir).join("package.json"); fs::metadata(package_json_path).unwrap(); @@ -246,9 +258,11 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!(crate_data - .write_package_json(&out_dir, &None, true, "", &step) - .is_ok()); + assert!( + crate_data + .write_package_json(&out_dir, &None, true, "", &step) + .is_ok() + ); let package_json_path = &out_dir.join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); From 75b85e58c79cc085870e830c40cb2eef40258827 Mon Sep 17 00:00:00 2001 From: daubaris Date: Sun, 18 Nov 2018 23:24:14 +0200 Subject: [PATCH 03/10] addition of stamp file and additional thread for running version checks --- Cargo.toml | 1 + src/build.rs | 20 ++---- src/command/build.rs | 16 ++--- src/command/mod.rs | 21 ++++-- src/lib.rs | 1 + src/manifest/mod.rs | 150 +++++++++++++++++++++++++++++++++---------- 6 files changed, 147 insertions(+), 62 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b486071b..3c210d82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ tar = "0.4.16" toml = "0.4" which = "2.0.0" zip = "0.4.2" +chrono = "0.4.6" [dev-dependencies] tempfile = "3" diff --git a/src/build.rs b/src/build.rs index 58f3ee04..faef62b9 100644 --- a/src/build.rs +++ b/src/build.rs @@ -33,21 +33,15 @@ pub fn check_rustc_version(step: &Step) -> Result { } /// Checks if `wasm-pack` is updated to the latest version -pub fn check_wasm_pack_version(step: &Step) -> Result<(), failure::Error> { - let msg = format!("{}Checking `wasm-pack` version...", emoji::PACKAGE); - PBAR.step(step, &msg); - let wasm_pack_local_version = wasm_pack_local_version(); - let wasm_pack_latest_version = Crate::return_wasm_pack_latest_version()?; - match wasm_pack_local_version { - Some(lv) => { - if !(lv == wasm_pack_latest_version) { - Ok(PBAR.info(&format!("There's a newer version of wasm-pack available, the new version is: {}, you are using: {}", wasm_pack_latest_version, lv))) - } else { - Ok(()) +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."), - + None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct.") } } diff --git a/src/command/build.rs b/src/command/build.rs index af3738af..701901a5 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -203,7 +203,6 @@ impl Build { match &mode { BuildMode::Normal => steps![ step_check_rustc_version, - step_check_wasm_pack_version, step_check_crate_config, step_add_wasm_target, step_build_wasm, @@ -215,7 +214,6 @@ impl Build { ], BuildMode::Noinstall => steps![ step_check_rustc_version, - step_check_wasm_pack_version, step_check_crate_config, step_build_wasm, step_create_dir, @@ -233,6 +231,12 @@ impl Build { } } + /// Returns local and latest versions of wasm-pack + pub fn return_wasm_pack_versions() -> Result<(String, String), Error> { + let (local, latest) = build::check_wasm_pack_versions()?; + Ok((local, latest)) + } + fn step_check_rustc_version(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { info!(&log, "Checking rustc version..."); let version = build::check_rustc_version(step)?; @@ -241,14 +245,6 @@ impl Build { Ok(()) } - fn step_check_wasm_pack_version(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { - info!(&log, "Checking wasm-pack version..."); - let version = build::check_wasm_pack_version(step)?; - let msg = format!("wasm-pack version is: {:?}.", version); - info!(&log, "{}", &msg); - Ok(()) - } - fn step_check_crate_config(&mut self, step: &Step, log: &Logger) -> Result<(), Error> { info!(&log, "Checking crate configuration..."); self.crate_data.check_crate_config(step)?; diff --git a/src/command/mod.rs b/src/command/mod.rs index 5d3a9e14..9da3aa0c 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -13,11 +13,11 @@ use self::login::login; use self::pack::pack; use self::publish::{access::Access, publish}; use self::test::{Test, TestOptions}; -use std::sync::mpsc; use failure::Error; use slog::Logger; use std::path::PathBuf; use std::result; +use std::sync::mpsc; use std::thread; /// The various kinds of commands that `wasm-pack` can execute. @@ -84,23 +84,30 @@ pub enum Command { Test(TestOptions), } -/// Spawn a thread for wasm-pack version +/// Spawn a thread for wasm-pack version check 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 } /// Run a command with the given logger! pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error> { // Run the correct command based off input and store the result of it so that we can clear // the progress bar then return it + + let update_available = background_check_for_updates(); + let status = match command { Command::Build(build_opts) => { info!(&log, "Running build command..."); - // Add the background_check_for_updates() here Build::try_from_opts(build_opts).and_then(|mut b| b.run(&log)) } Command::Pack { path } => { @@ -136,6 +143,10 @@ pub fn run_wasm_pack(command: Command, log: &Logger) -> result::Result<(), Error } }; + 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: {}", update_available.1, update_available.0); + } + // Return the actual status of the program to the main function status } diff --git a/src/lib.rs b/src/lib.rs index 2cec7a83..b30d78a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,7 @@ extern crate siphasher; extern crate structopt; #[macro_use] extern crate slog; +extern crate chrono; extern crate slog_async; extern crate slog_term; extern crate tar; diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index a7dbd2bd..d2c6f957 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -9,6 +9,8 @@ use self::npm::{ repository::Repository, CommonJSPackage, ESModulesPackage, NoModulesPackage, NpmPackage, }; use cargo_metadata::Metadata; +use chrono::offset; +use chrono::DateTime; use command::build::BuildProfile; use curl::easy; use emoji; @@ -16,7 +18,9 @@ use failure::{Error, ResultExt}; use progressbar::Step; use serde::{self, Deserialize}; use serde_json; +use std::io::Write; use toml; +use which; use PBAR; /// Store for metadata learned about a crate @@ -26,7 +30,6 @@ pub struct CrateData { manifest: CargoManifest, } -#[derive(Deserialize)] struct Collector(Vec); impl easy::Handler for Collector { @@ -36,7 +39,7 @@ impl easy::Handler for Collector { } } -#[derive(Debug, Deserialize)] +#[derive(Deserialize)] struct CargoManifest { package: CargoPackage, } @@ -115,6 +118,117 @@ struct CargoWasmPackProfileWasmBindgen { dwarf_debug_info: Option, } +/// Struct for crate which is 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 { + let current_time = chrono::offset::Local::now(); + if let Some(contents) = Crate::return_wasm_pack_file() { + let (created, version) = Crate::return_stamp_file_values(&contents); + + if current_time.signed_duration_since(created).num_hours() > 24 { + return Crate::return_api_call_result(current_time); + } else { + return Some(version); + } + } else { + return Crate::return_api_call_result(current_time); + } + } + + fn return_api_call_result(current_time: DateTime) -> Option { + match Crate::call_for_wasm_pack_version() { + Some(version) => { + Crate::override_stamp_file(current_time, &version); + return Some(version); + } + None => return None, + } + } + + fn override_stamp_file(current_time: DateTime, 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 + ) {} + } + } + } + + fn return_wasm_pack_file() -> Option { + if let Ok(path) = which::which("wasm-pack") { + if let Ok(file) = fs::read_to_string(path.with_extension("stamp")) { + return Some(file); + } + return None; + } + None + } + + fn call_for_wasm_pack_version() -> Option { + if let Ok(crt) = Crate::check_wasm_pack_latest_version() { + return Some(crt.crt.max_version); + } + None + } + + fn return_stamp_file_values(file: &String) -> (DateTime, String) { + let created = file + .lines() + .find(|line| line.starts_with("created")) + .unwrap() + .split_whitespace() + .nth(1) + .unwrap(); + + let last_updated = DateTime::parse_from_str(created, "%+").unwrap(); + + let version = file + .lines() + .find(|line| line.starts_with("version")) + .unwrap() + .split_whitespace() + .nth(1) + .unwrap() + .to_string(); + + (last_updated, version) + } + + /// Call to the crates.io api and return the latest version of `wasm-pack` + fn check_wasm_pack_latest_version() -> Result { + 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 { @@ -207,38 +321,6 @@ struct NpmData { main: String, } -/// Struct for crates.io api, currently checking wasm-pack latest version -#[derive(Deserialize, Debug)] -pub struct Crate { - #[serde(rename = "crate")] - crt: CrateInformation, -} - -#[derive(Deserialize, Debug)] -struct CrateInformation { - max_version: String, -} - -impl Crate { - /// Call to the crates.io api and return the latest version of `wasm-pack` - pub fn return_wasm_pack_latest_version() -> Result { - let crt = Crate::check_wasm_pack_latest_version()?; - Ok(crt.crt.max_version) - } - - fn check_wasm_pack_latest_version() -> Result { - 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 CrateData { /// Reads all metadata for the crate whose manifest is inside the directory /// specified by `path`. From bbc759369fc460b470f6180b71028a832122acd9 Mon Sep 17 00:00:00 2001 From: daubaris Date: Sun, 18 Nov 2018 23:31:34 +0200 Subject: [PATCH 04/10] nightly fmt --- tests/all/bindgen.rs | 8 ++-- tests/all/build.rs | 7 ++-- tests/all/manifest.rs | 86 ++++++++++++++++++------------------------- 3 files changed, 42 insertions(+), 59 deletions(-) diff --git a/tests/all/bindgen.rs b/tests/all/bindgen.rs index ae836a8f..985a4d00 100644 --- a/tests/all/bindgen.rs +++ b/tests/all/bindgen.rs @@ -31,9 +31,7 @@ fn downloading_prebuilt_wasm_bindgen_handles_http_errors() { let error = result.err().unwrap(); assert!(error.iter_chain().any(|e| e.to_string().contains("404"))); - assert!( - error - .iter_chain() - .any(|e| e.to_string().contains(bad_version)) - ); + assert!(error + .iter_chain() + .any(|e| e.to_string().contains(bad_version))); } diff --git a/tests/all/build.rs b/tests/all/build.rs index 622d5a40..cc21fbb5 100644 --- a/tests/all/build.rs +++ b/tests/all/build.rs @@ -19,10 +19,9 @@ fn build_in_non_crate_directory_doesnt_panic() { "running wasm-pack in a non-crate directory should fail, but it should not panic" ); let err = result.unwrap_err(); - assert!( - err.iter_chain() - .any(|e| e.to_string().contains("missing a `Cargo.toml`")) - ); + assert!(err + .iter_chain() + .any(|e| e.to_string().contains("missing a `Cargo.toml`"))); } #[test] diff --git a/tests/all/manifest.rs b/tests/all/manifest.rs index ad8295d5..6bc9df8c 100644 --- a/tests/all/manifest.rs +++ b/tests/all/manifest.rs @@ -67,11 +67,9 @@ fn it_creates_a_package_json_default_path() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!( - crate_data - .write_package_json(&out_dir, &None, false, "", &step) - .is_ok() - ); + assert!(crate_data + .write_package_json(&out_dir, &None, false, "", &step) + .is_ok()); let package_json_path = &fixture.path.join("pkg").join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -92,9 +90,9 @@ fn it_creates_a_package_json_default_path() { "js_hello_world.d.ts", "js_hello_world.js", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -105,11 +103,9 @@ fn it_creates_a_package_json_provided_path() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!( - crate_data - .write_package_json(&out_dir, &None, false, "", &step) - .is_ok() - ); + assert!(crate_data + .write_package_json(&out_dir, &None, false, "", &step) + .is_ok()); let package_json_path = &fixture.path.join("pkg").join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -123,9 +119,9 @@ fn it_creates_a_package_json_provided_path() { "js_hello_world.d.ts", "js_hello_world.js", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -136,11 +132,9 @@ fn it_creates_a_package_json_provided_path_with_scope() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!( - crate_data - .write_package_json(&out_dir, &Some("test".to_string()), false, "", &step) - .is_ok() - ); + assert!(crate_data + .write_package_json(&out_dir, &Some("test".to_string()), false, "", &step) + .is_ok()); let package_json_path = &fixture.path.join("pkg").join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -154,9 +148,9 @@ fn it_creates_a_package_json_provided_path_with_scope() { "js_hello_world.d.ts", "js_hello_world.js", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -167,11 +161,9 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!( - crate_data - .write_package_json(&out_dir, &None, false, "nodejs", &step) - .is_ok() - ); + assert!(crate_data + .write_package_json(&out_dir, &None, false, "nodejs", &step) + .is_ok()); let package_json_path = &out_dir.join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -192,9 +184,9 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() { "js_hello_world.d.ts", "js_hello_world.js", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -205,11 +197,9 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!( - crate_data - .write_package_json(&out_dir, &None, false, "no-modules", &step) - .is_ok() - ); + assert!(crate_data + .write_package_json(&out_dir, &None, false, "no-modules", &step) + .is_ok()); let package_json_path = &out_dir.join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); @@ -229,9 +219,9 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { "js_hello_world.js", "js_hello_world.d.ts", ] - .iter() - .map(|&s| String::from(s)) - .collect(); + .iter() + .map(|&s| String::from(s)) + .collect(); assert_eq!(actual_files, expected_files); } @@ -242,11 +232,9 @@ fn it_creates_a_pkg_json_in_out_dir() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!( - crate_data - .write_package_json(&out_dir, &None, false, "", &step) - .is_ok() - ); + assert!(crate_data + .write_package_json(&out_dir, &None, false, "", &step) + .is_ok()); let package_json_path = &fixture.path.join(&out_dir).join("package.json"); fs::metadata(package_json_path).unwrap(); @@ -260,11 +248,9 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() { let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); let step = wasm_pack::progressbar::Step::new(1); wasm_pack::command::utils::create_pkg_dir(&out_dir, &step).unwrap(); - assert!( - crate_data - .write_package_json(&out_dir, &None, true, "", &step) - .is_ok() - ); + assert!(crate_data + .write_package_json(&out_dir, &None, true, "", &step) + .is_ok()); let package_json_path = &out_dir.join("package.json"); fs::metadata(package_json_path).unwrap(); utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); From ee3857d43671cae4ae29b5d057e70026b9756463 Mon Sep 17 00:00:00 2001 From: daubaris Date: Sat, 15 Dec 2018 12:51:38 +0200 Subject: [PATCH 05/10] refactoring mod --- src/manifest/mod.rs | 62 +++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index d2c6f957..285ff24c 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -134,27 +134,30 @@ impl Crate { /// Returns latest wasm-pack version pub fn return_wasm_pack_latest_version() -> Option { let current_time = chrono::offset::Local::now(); - if let Some(contents) = Crate::return_wasm_pack_file() { - let (created, version) = Crate::return_stamp_file_values(&contents); - - if current_time.signed_duration_since(created).num_hours() > 24 { - return Crate::return_api_call_result(current_time); - } else { - return Some(version); - } - } else { - return Crate::return_api_call_result(current_time); - } + 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) -> Option { - match Crate::call_for_wasm_pack_version() { - Some(version) => { - Crate::override_stamp_file(current_time, &version); - return Some(version); - } - None => return None, - } + Crate::call_for_wasm_pack_version().and_then(|v| { + Crate::override_stamp_file(current_time, &v); + Some(v) + }) } fn override_stamp_file(current_time: DateTime, version: &String) { @@ -182,7 +185,6 @@ impl Crate { if let Ok(file) = fs::read_to_string(path.with_extension("stamp")) { return Some(file); } - return None; } None } @@ -194,27 +196,15 @@ impl Crate { None } - fn return_stamp_file_values(file: &String) -> (DateTime, String) { + fn return_stamp_file_value(file: &String, word: &str) -> Option { let created = file .lines() - .find(|line| line.starts_with("created")) - .unwrap() - .split_whitespace() - .nth(1) - .unwrap(); + .find(|line| line.starts_with(word)) + .and_then(|l| l.split_whitespace().nth(1)); - let last_updated = DateTime::parse_from_str(created, "%+").unwrap(); + let value = created.map(|s| s.to_string()); - let version = file - .lines() - .find(|line| line.starts_with("version")) - .unwrap() - .split_whitespace() - .nth(1) - .unwrap() - .to_string(); - - (last_updated, version) + value } /// Call to the crates.io api and return the latest version of `wasm-pack` From 9934171d42944d3fd7d7982a67f7e9c8ae307d1f Mon Sep 17 00:00:00 2001 From: daubaris Date: Tue, 19 Mar 2019 21:56:03 +0200 Subject: [PATCH 06/10] Updated with the current master --- Cargo.lock | 25 +++++++++- Cargo.toml | 3 +- src/build.rs | 37 ++++++++++++++ src/command/build.rs | 6 +++ src/lib.rs | 2 + src/main.rs | 24 +++++++++ src/manifest/mod.rs | 116 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 211 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e4cc0348..7c04488d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,3 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "adler32" version = "1.0.3" @@ -163,6 +165,16 @@ name = "cfg-if" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chrono" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "clap" version = "2.32.0" @@ -575,6 +587,14 @@ name = "normalize-line-endings" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "num-integer" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num-traits" version = "0.2.6" @@ -1269,12 +1289,13 @@ dependencies = [ [[package]] name = "wasm-pack" -version = "0.7.0" +version = "0.6.0" dependencies = [ "assert_cmd 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "binary-install 0.0.2", "cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "console 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "curl 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", "dialoguer 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1404,6 +1425,7 @@ dependencies = [ "checksum cargo_metadata 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1b4d380e1bab994591a24c2bdd1b054f64b60bef483a8c598c7c345bc3bbe" "checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" +"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum clicolors-control 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f84dec9bc083ce2503908cd305af98bd363da6f54bf8d4bf0ac14ee749ad5d1" "checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9" @@ -1451,6 +1473,7 @@ dependencies = [ "checksum miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fe927a42e3807ef71defb191dc87d4e24479b221e67015fe38ae2b7b447bab" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum normalize-line-endings 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2e0a1a39eab95caf4f5556da9289b9e68f0aafac901b2ce80daaf020d3b733a8" +"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum openssl 0.10.19 (registry+https://github.com/rust-lang/crates.io-index)" = "84321fb9004c3bce5611188a644d6171f895fa2889d155927d528782edb21c5d" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" diff --git a/Cargo.toml b/Cargo.toml index 41a4b738..7a4b7fd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "wasm-pack" description = "📦✨ your favorite rust -> wasm workflow tool!" -version = "0.7.0" +version = "0.6.0" authors = ["Ashley Williams "] repository = "https://github.com/ashleygwilliams/wasm-pack.git" license = "MIT/Apache-2.0" @@ -34,6 +34,7 @@ toml = "0.4" which = "2.0.0" binary-install = { version = "0.0.2", path = "./binary-install" } walkdir = "2" +chrono = "0.4.6" [dev-dependencies] assert_cmd = "0.10.2" diff --git a/src/build.rs b/src/build.rs index 2b32b674..7f619272 100644 --- a/src/build.rs +++ b/src/build.rs @@ -8,6 +8,7 @@ use log::info; use std::path::{Path, PathBuf}; use std::process::Command; use std::str; +use manifest::Crate; use PBAR; /// Ensure that `rustc` is present and that it is >= 1.30.0 @@ -47,6 +48,42 @@ fn rustc_minor_version() -> Option { 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 { + macro_rules! otry { + ($e:expr) => { + match $e { + Some(e) => e, + None => return None, + } + }; + } + + let output = otry!(Command::new("wasm-pack").arg("--version").output().ok()); + let version = otry!(str::from_utf8(&output.stdout).ok()); + let mut pieces = version.split(' '); + if pieces.next() != Some("wasm-pack") { + return None; + } + otry!(pieces.next()) + .to_string() + .trim() + .parse::() + .ok() +} + /// Get rustc's sysroot as a PathBuf fn get_rustc_sysroot() -> Result { let command = Command::new("rustc") diff --git a/src/command/build.rs b/src/command/build.rs index 924ef8e6..16ee9e75 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -248,6 +248,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),+) => { diff --git a/src/lib.rs b/src/lib.rs index e8b7ceb6..433347ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,6 +22,8 @@ extern crate dialoguer; extern crate log; extern crate toml; extern crate walkdir; +extern crate chrono; +extern crate curl; pub mod bindgen; pub mod build; diff --git a/src/main.rs b/src/main.rs index c99f5af0..08b6a3a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,13 +7,30 @@ extern crate human_panic; extern crate structopt; extern crate wasm_pack; extern crate which; +extern crate log; use std::env; use structopt::StructOpt; use wasm_pack::{command::run_wasm_pack, Cli}; +use wasm_pack::command::build::{Build}; +use std::sync::mpsc; +use std::thread; 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(); setup_panic!(); @@ -27,6 +44,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"); @@ -47,5 +66,10 @@ 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: {}", update_available.1, update_available.0); + } + Ok(()) } diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 617af868..a9d7e294 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -15,8 +15,13 @@ use command::build::{BuildProfile, Target}; use failure::{Error, ResultExt}; use serde::{self, Deserialize}; use serde_json; +use chrono::offset; +use chrono::DateTime; +use curl::easy; +use std::io::Write; use std::collections::BTreeSet; use strsim::levenshtein; +use which; use toml; use PBAR; @@ -112,6 +117,117 @@ struct CargoWasmPackProfileWasmBindgen { dwarf_debug_info: Option, } + +struct Collector(Vec); + +impl easy::Handler for Collector { + fn write(&mut self, data: &[u8]) -> Result { + 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 { + 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) -> Option { + Crate::call_for_wasm_pack_version().and_then(|v| { + Crate::override_stamp_file(current_time, &v); + Some(v) + }) + } + + fn override_stamp_file(current_time: DateTime, 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 + ) {} + } + } + } + + fn return_wasm_pack_file() -> Option { + if let Ok(path) = which::which("wasm-pack") { + if let Ok(file) = fs::read_to_string(path.with_extension("stamp")) { + return Some(file); + } + } + None + } + + fn call_for_wasm_pack_version() -> Option { + if let Ok(crt) = Crate::check_wasm_pack_latest_version() { + return Some(crt.crt.max_version); + } + None + } + + fn return_stamp_file_value(file: &String, word: &str) -> Option { + 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 { + 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 { From d495bd52c31d6eb2ec7e8b7baf4b6e60070d5a3f Mon Sep 17 00:00:00 2001 From: daubaris Date: Tue, 19 Mar 2019 22:00:33 +0200 Subject: [PATCH 07/10] rustfmt --- src/build.rs | 2 +- src/lib.rs | 4 ++-- src/main.rs | 8 ++++---- src/manifest/mod.rs | 11 +++++------ 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/build.rs b/src/build.rs index 7f619272..49ece5c2 100644 --- a/src/build.rs +++ b/src/build.rs @@ -5,10 +5,10 @@ use command::build::BuildProfile; use emoji; use failure::{Error, ResultExt}; use log::info; +use manifest::Crate; use std::path::{Path, PathBuf}; use std::process::Command; use std::str; -use manifest::Crate; use PBAR; /// Ensure that `rustc` is present and that it is >= 1.30.0 diff --git a/src/lib.rs b/src/lib.rs index 433347ed..30c59bd4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,12 +18,12 @@ 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; extern crate walkdir; -extern crate chrono; -extern crate curl; pub mod bindgen; pub mod build; diff --git a/src/main.rs b/src/main.rs index 08b6a3a8..55e74a13 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,17 +4,17 @@ extern crate env_logger; extern crate failure; #[macro_use] extern crate human_panic; +extern crate log; extern crate structopt; extern crate wasm_pack; extern crate which; -extern crate log; use std::env; -use structopt::StructOpt; -use wasm_pack::{command::run_wasm_pack, Cli}; -use wasm_pack::command::build::{Build}; 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; diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index a9d7e294..71ce9f62 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -11,18 +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 chrono::offset; -use chrono::DateTime; -use curl::easy; -use std::io::Write; use std::collections::BTreeSet; +use std::io::Write; use strsim::levenshtein; -use which; use toml; +use which; use PBAR; const WASM_PACK_METADATA_KEY: &str = "package.metadata.wasm-pack"; @@ -117,7 +117,6 @@ struct CargoWasmPackProfileWasmBindgen { dwarf_debug_info: Option, } - struct Collector(Vec); impl easy::Handler for Collector { From b7534ad6a52ffc625f383f5baa1968807ad396c6 Mon Sep 17 00:00:00 2001 From: daubaris Date: Tue, 19 Mar 2019 22:03:10 +0200 Subject: [PATCH 08/10] Reset cargo version to latest --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c04488d..60218e2f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1289,7 +1289,7 @@ dependencies = [ [[package]] name = "wasm-pack" -version = "0.6.0" +version = "0.7.0" dependencies = [ "assert_cmd 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 7a4b7fd0..372b5475 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "wasm-pack" description = "📦✨ your favorite rust -> wasm workflow tool!" -version = "0.6.0" +version = "0.7.0" authors = ["Ashley Williams "] repository = "https://github.com/ashleygwilliams/wasm-pack.git" license = "MIT/Apache-2.0" From b30b72b99aa961249bbe6db6f302243522eca282 Mon Sep 17 00:00:00 2001 From: daubaris Date: Tue, 26 Mar 2019 20:56:03 +0200 Subject: [PATCH 09/10] Removed unnecessary macro and added comments --- src/build.rs | 22 ++-------------------- src/main.rs | 3 ++- src/manifest/mod.rs | 7 +++++-- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/build.rs b/src/build.rs index 49ece5c2..2d2ce6af 100644 --- a/src/build.rs +++ b/src/build.rs @@ -62,26 +62,8 @@ pub fn check_wasm_pack_versions() -> Result<(String, String), Error> { } fn wasm_pack_local_version() -> Option { - macro_rules! otry { - ($e:expr) => { - match $e { - Some(e) => e, - None => return None, - } - }; - } - - let output = otry!(Command::new("wasm-pack").arg("--version").output().ok()); - let version = otry!(str::from_utf8(&output.stdout).ok()); - let mut pieces = version.split(' '); - if pieces.next() != Some("wasm-pack") { - return None; - } - otry!(pieces.next()) - .to_string() - .trim() - .parse::() - .ok() + let output = env!("CARGO_PKG_VERSION"); + Some(output.to_string()) } /// Get rustc's sysroot as a PathBuf diff --git a/src/main.rs b/src/main.rs index 55e74a13..e4d78009 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,7 +68,8 @@ fn run() -> Result<(), failure::Error> { 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: {}", update_available.1, update_available.0); + 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(()) diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 71ce9f62..47a2440c 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -162,7 +162,7 @@ impl Crate { } fn return_api_call_result(current_time: DateTime) -> Option { - Crate::call_for_wasm_pack_version().and_then(|v| { + Crate::return_latest_wasm_pack_version().and_then(|v| { Crate::override_stamp_file(current_time, &v); Some(v) }) @@ -188,6 +188,7 @@ impl Crate { } } + /// Return stamp file where metadata is stored. fn return_wasm_pack_file() -> Option { if let Ok(path) = which::which("wasm-pack") { if let Ok(file) = fs::read_to_string(path.with_extension("stamp")) { @@ -197,13 +198,15 @@ impl Crate { None } - fn call_for_wasm_pack_version() -> Option { + /// Returns wasm-pack latest version (if it's received) by executing check_wasm_pack_latest_version function. + fn return_latest_wasm_pack_version() -> Option { 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 { let created = file .lines() From 38606621bcca141b1dd18ff2f267dadfd83cf12d Mon Sep 17 00:00:00 2001 From: daubaris Date: Sun, 31 Mar 2019 11:23:32 +0300 Subject: [PATCH 10/10] cargo fmt --- src/build/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build/mod.rs b/src/build/mod.rs index 7917d491..65df0f61 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -4,8 +4,8 @@ use child; use command::build::BuildProfile; use emoji; use failure::{Error, ResultExt}; -use std::path::Path; use manifest::Crate; +use std::path::Path; use std::process::Command; use std::str; use PBAR;