diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..6313b56c57 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/Cargo.lock b/Cargo.lock index 1061955f45..7c46383d4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,9 +106,9 @@ dependencies = [ [[package]] name = "curl" version = "0.3.0" -source = "git+https://github.com/alexcrichton/curl-rust?rev=ccf35d3e#ccf35d3e4a41f1542fa025fe2da77d036f708092" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "curl-sys 0.2.0 (git+https://github.com/alexcrichton/curl-rust?rev=ccf35d3e)", + "curl-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -116,7 +116,7 @@ dependencies = [ [[package]] name = "curl-sys" version = "0.2.0" -source = "git+https://github.com/alexcrichton/curl-rust?rev=ccf35d3e#ccf35d3e4a41f1542fa025fe2da77d036f708092" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -390,7 +390,7 @@ name = "rustup-utils" version = "0.1.12" dependencies = [ "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "curl 0.3.0 (git+https://github.com/alexcrichton/curl-rust?rev=ccf35d3e)", + "curl 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.1.12", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/rustup-cli/common.rs b/src/rustup-cli/common.rs index 25eb0fb489..2d805ab1d9 100644 --- a/src/rustup-cli/common.rs +++ b/src/rustup-cli/common.rs @@ -9,6 +9,7 @@ use self_update; use std::io::{Write, BufRead}; use std::process::Command; use std::{cmp, iter}; +use std::sync::Arc; use std; use term2; @@ -101,7 +102,7 @@ pub fn set_globals(verbose: bool) -> Result { let download_tracker = RefCell::new(DownloadTracker::new()); - Ok(try!(Cfg::from_env(shared_ntfy!(move |n: Notification| { + Ok(try!(Cfg::from_env(Arc::new(move |n: Notification| { if download_tracker.borrow_mut().handle_notification(&n) { return; } diff --git a/src/rustup-cli/multirust_mode.rs b/src/rustup-cli/multirust_mode.rs index d1bfceaedf..4b700ab0b8 100644 --- a/src/rustup-cli/multirust_mode.rs +++ b/src/rustup-cli/multirust_mode.rs @@ -10,6 +10,7 @@ use rustup_dist::dist::TargetTriple; use self_update; use std::env; use std::path::{Path, PathBuf}; +use std::sync::Arc; use job; pub fn main() -> Result<()> { @@ -17,7 +18,7 @@ pub fn main() -> Result<()> { let need_metadata = try!(command_requires_metadata()); if need_metadata { - let cfg = try!(Cfg::from_env(shared_ntfy!(move |_: Notification| { }))); + let cfg = try!(Cfg::from_env(Arc::new(move |_: Notification| { }))); try!(cfg.check_metadata_version()); } diff --git a/src/rustup-cli/self_update.rs b/src/rustup-cli/self_update.rs index 2842086042..8a016780b6 100644 --- a/src/rustup-cli/self_update.rs +++ b/src/rustup-cli/self_update.rs @@ -31,7 +31,6 @@ //! and racy on Windows. use common::{self, Confirm}; -use rustup::{NotifyHandler}; use errors::*; use rustup_dist::dist; use rustup_utils::utils; @@ -463,7 +462,7 @@ fn install_bins() -> Result<()> { let ref this_exe_path = try!(utils::current_exe()); let ref multirust_path = bin_path.join(&format!("multirust{}", EXE_SUFFIX)); - try!(utils::ensure_dir_exists("bin", bin_path, ntfy!(&NotifyHandler::none()))); + try!(utils::ensure_dir_exists("bin", bin_path, &|_| {})); // NB: Even on Linux we can't just copy the new binary over the (running) // old binary; we must unlink it first. if multirust_path.exists() { @@ -528,7 +527,7 @@ pub fn uninstall(no_prompt: bool) -> Result<()> { // Delete RUSTUP_HOME let ref multirust_dir = try!(utils::multirust_home()); if multirust_dir.exists() { - try!(utils::remove_dir("multirust_home", multirust_dir, ntfy!(&NotifyHandler::none()))); + try!(utils::remove_dir("multirust_home", multirust_dir, &|_| {})); } let read_dir_err = "failure reading directory"; @@ -546,7 +545,7 @@ pub fn uninstall(no_prompt: bool) -> Result<()> { let dirent = try!(dirent.chain_err(|| read_dir_err)); if dirent.file_name().to_str() != Some("bin") { if dirent.path().is_dir() { - try!(utils::remove_dir("cargo_home", &dirent.path(), ntfy!(&NotifyHandler::none()))); + try!(utils::remove_dir("cargo_home", &dirent.path(), &|_| {})); } else { try!(utils::remove_file("cargo_home", &dirent.path())); } @@ -563,7 +562,7 @@ pub fn uninstall(no_prompt: bool) -> Result<()> { let file_is_tool = name.to_str().map(|n| tools.iter().any(|t| *t == n)); if file_is_tool == Some(false) { if dirent.path().is_dir() { - try!(utils::remove_dir("cargo_home", &dirent.path(), ntfy!(&NotifyHandler::none()))); + try!(utils::remove_dir("cargo_home", &dirent.path(), &|_| {})); } else { try!(utils::remove_file("cargo_home", &dirent.path())); } @@ -585,7 +584,7 @@ pub fn uninstall(no_prompt: bool) -> Result<()> { #[cfg(unix)] fn delete_multirust_and_cargo_home() -> Result<()> { let ref cargo_home = try!(utils::cargo_home()); - try!(utils::remove_dir("cargo_home", cargo_home, ntfy!(&NotifyHandler::none()))); + try!(utils::remove_dir("cargo_home", cargo_home, &|_| ())); Ok(()) } @@ -693,7 +692,6 @@ fn delete_multirust_and_cargo_home() -> Result<()> { /// Run by multirust-gc-$num.exe to delete CARGO_HOME #[cfg(windows)] pub fn complete_windows_uninstall() -> Result<()> { - use rustup::NotifyHandler; use std::ffi::OsStr; use std::process::Stdio; @@ -701,7 +699,7 @@ pub fn complete_windows_uninstall() -> Result<()> { // Now that the parent has exited there are hopefully no more files open in CARGO_HOME let ref cargo_home = try!(utils::cargo_home()); - try!(utils::remove_dir("cargo_home", cargo_home, ntfy!(&NotifyHandler::none()))); + try!(utils::remove_dir("cargo_home", cargo_home, &|_| ())); // Now, run a *system* binary to inherit the DELETE_ON_CLOSE // handle to *this* process, then exit. The OS will delete the gc @@ -1108,7 +1106,7 @@ pub fn prepare_update() -> Result> { info!("checking for self-updates"); let hash_url = try!(utils::parse_url(&(url.clone() + ".sha256"))); let hash_file = tempdir.path().join("hash"); - try!(utils::download_file(&hash_url, &hash_file, None, ntfy!(&NotifyHandler::none()))); + try!(utils::download_file(&hash_url, &hash_file, None, &|_| ())); let mut latest_hash = try!(utils::read_file("hash", &hash_file)); latest_hash.truncate(64); @@ -1127,7 +1125,7 @@ pub fn prepare_update() -> Result> { try!(utils::download_file(&download_url, &setup_path, Some(&mut hasher), - ntfy!(&NotifyHandler::none()))); + &|_| ())); let download_hash = hasher.result_str(); // Check that hash is correct diff --git a/src/rustup-dist/build.rs b/src/rustup-dist/build.rs index 9531e7434e..c3ea28b8ab 100644 --- a/src/rustup-dist/build.rs +++ b/src/rustup-dist/build.rs @@ -8,4 +8,5 @@ fn main() { let target = env::var("TARGET").unwrap(); File::create(out_dir.join("target.txt")).unwrap().write_all(target.as_bytes()).unwrap(); + println!("cargo:rerun-if-changed=build.rs"); } diff --git a/src/rustup-dist/src/component/components.rs b/src/rustup-dist/src/component/components.rs index 5568a16031..c8b53658fb 100644 --- a/src/rustup-dist/src/component/components.rs +++ b/src/rustup-dist/src/component/components.rs @@ -86,7 +86,6 @@ impl Components { } } -#[derive(Debug)] pub struct ComponentBuilder<'a> { components: Components, name: String, diff --git a/src/rustup-dist/src/component/transaction.rs b/src/rustup-dist/src/component/transaction.rs index 87de10278d..d1b3595cff 100644 --- a/src/rustup-dist/src/component/transaction.rs +++ b/src/rustup-dist/src/component/transaction.rs @@ -9,7 +9,7 @@ //! FIXME: This uses ensure_dir_exists in some places but rollback //! does not remove any dirs created by it. -use rustup_utils::{self, utils}; +use rustup_utils::utils; use temp; use prefix::InstallPrefix; use errors::*; @@ -31,19 +31,18 @@ use std::path::{Path, PathBuf}; /// /// All operations that create files will fail if the destination /// already exists. -#[derive(Debug)] pub struct Transaction<'a> { prefix: InstallPrefix, changes: Vec>, temp_cfg: &'a temp::Cfg, - notify_handler: NotifyHandler<'a>, + notify_handler: &'a Fn(Notification), committed: bool, } impl<'a> Transaction<'a> { pub fn new(prefix: InstallPrefix, temp_cfg: &'a temp::Cfg, - notify_handler: NotifyHandler<'a>) + notify_handler: &'a Fn(Notification)) -> Self { Transaction { prefix: prefix, @@ -131,7 +130,7 @@ impl<'a> Transaction<'a> { pub fn temp(&self) -> &'a temp::Cfg { self.temp_cfg } - pub fn notify_handler(&self) -> NotifyHandler<'a> { + pub fn notify_handler(&self) -> &'a Fn(Notification) { self.notify_handler } } @@ -141,11 +140,16 @@ impl<'a> Transaction<'a> { impl<'a> Drop for Transaction<'a> { fn drop(&mut self) { if !self.committed { - self.notify_handler.call(Notification::RollingBack); + (self.notify_handler)(Notification::RollingBack); for item in self.changes.iter().rev() { - ok_ntfy!(self.notify_handler, - Notification::NonFatalError, - item.roll_back(&self.prefix)); + // ok_ntfy!(self.notify_handler, + // Notification::NonFatalError, + match item.roll_back(&self.prefix) { + Ok(()) => {} + Err(e) => { + (self.notify_handler)(Notification::NonFatalError(&e)); + } + } } } } @@ -172,7 +176,7 @@ impl<'a> ChangedItem<'a> { AddedDir(ref path) => { try!(utils::remove_dir("component", &prefix.abs_path(path), - rustup_utils::NotifyHandler::none())) + &|_| ())) } RemovedFile(ref path, ref tmp) | ModifiedFile(ref path, Some(ref tmp)) => { try!(utils::rename_file("component", &tmp, &prefix.abs_path(path))) @@ -198,7 +202,7 @@ impl<'a> ChangedItem<'a> { }.into()) } else { if let Some(p) = abs_path.parent() { - try!(utils::ensure_dir_exists("component", p, rustup_utils::NotifyHandler::none())); + try!(utils::ensure_dir_exists("component", p, &|_| ())); } let file = try!(File::create(&abs_path) .chain_err(|| format!("error creating file '{}'", abs_path.display()))); @@ -218,7 +222,7 @@ impl<'a> ChangedItem<'a> { }.into()) } else { if let Some(p) = abs_path.parent() { - try!(utils::ensure_dir_exists("component", p, rustup_utils::NotifyHandler::none())); + try!(utils::ensure_dir_exists("component", p, &|_| ())); } try!(utils::copy_file(src, &abs_path)); Ok(ChangedItem::AddedFile(relpath)) @@ -233,9 +237,9 @@ impl<'a> ChangedItem<'a> { }.into()) } else { if let Some(p) = abs_path.parent() { - try!(utils::ensure_dir_exists("component", p, rustup_utils::NotifyHandler::none())); + try!(utils::ensure_dir_exists("component", p, &|_| ())); } - try!(utils::copy_dir(src, &abs_path, rustup_utils::NotifyHandler::none())); + try!(utils::copy_dir(src, &abs_path, &|_| ())); Ok(ChangedItem::AddedDir(relpath)) } } @@ -274,7 +278,7 @@ impl<'a> ChangedItem<'a> { Ok(ChangedItem::ModifiedFile(relpath, Some(backup))) } else { if let Some(p) = abs_path.parent() { - try!(utils::ensure_dir_exists("component", p, rustup_utils::NotifyHandler::none())); + try!(utils::ensure_dir_exists("component", p, &|_| {})); } Ok(ChangedItem::ModifiedFile(relpath, None)) } diff --git a/src/rustup-dist/src/dist.rs b/src/rustup-dist/src/dist.rs index 76604c1d87..b2d550ff51 100644 --- a/src/rustup-dist/src/dist.rs +++ b/src/rustup-dist/src/dist.rs @@ -418,10 +418,10 @@ pub fn download_and_check<'a>(url_str: &str, return Ok(None); } } else { - cfg.notify_handler.call(Notification::CantReadUpdateHash(hash_file)); + (cfg.notify_handler)(Notification::CantReadUpdateHash(hash_file)); } } else { - cfg.notify_handler.call(Notification::NoUpdateHash(hash_file)); + (cfg.notify_handler)(Notification::NoUpdateHash(hash_file)); } } @@ -429,7 +429,8 @@ pub fn download_and_check<'a>(url_str: &str, let file = try!(cfg.temp_cfg.new_file_with_ext("", ext)); let mut hasher = Sha256::new(); - try!(utils::download_file(&url, &file, Some(&mut hasher), ntfy!(&cfg.notify_handler))); + try!(utils::download_file(&url, &file, Some(&mut hasher), + &|n| (cfg.notify_handler)(n.into()))); let actual_hash = hasher.result_str(); if hash != actual_hash { @@ -440,7 +441,7 @@ pub fn download_and_check<'a>(url_str: &str, calculated: actual_hash, }.into()); } else { - cfg.notify_handler.call(Notification::ChecksumValid(url_str)); + (cfg.notify_handler)(Notification::ChecksumValid(url_str)); } // TODO: Check the signature of the file @@ -448,18 +449,19 @@ pub fn download_and_check<'a>(url_str: &str, Ok(Some((file, partial_hash))) } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone)] pub struct DownloadCfg<'a> { pub dist_root: &'a str, pub temp_cfg: &'a temp::Cfg, - pub notify_handler: NotifyHandler<'a>, + pub notify_handler: &'a Fn(Notification), } pub fn download_hash(url: &str, cfg: DownloadCfg) -> Result { let hash_url = try!(utils::parse_url(&(url.to_owned() + ".sha256"))); let hash_file = try!(cfg.temp_cfg.new_file()); - try!(utils::download_file(&hash_url, &hash_file, None, ntfy!(&cfg.notify_handler))); + try!(utils::download_file(&hash_url, &hash_file, None, + &|n| (cfg.notify_handler)(n.into()))); Ok(try!(utils::read_file("hash", &hash_file).map(|s| s[0..64].to_owned()))) } @@ -486,7 +488,7 @@ pub fn update_from_dist<'a>(download: DownloadCfg<'a>, }; // TODO: Add a notification about which manifest version is going to be used - download.notify_handler.call(Notification::DownloadingManifest(&toolchain_str)); + (download.notify_handler)(Notification::DownloadingManifest(&toolchain_str)); match dl_v2_manifest(download, update_hash, toolchain) { Ok(Some((m, hash))) => { return match try!(manifestation.update(&m, changes, &download.temp_cfg, @@ -498,7 +500,7 @@ pub fn update_from_dist<'a>(download: DownloadCfg<'a>, Ok(None) => return Ok(None), Err(Error(ErrorKind::Utils(::rustup_utils::ErrorKind::Download404 { .. }), _)) => { // Proceed to try v1 as a fallback - download.notify_handler.call(Notification::DownloadingLegacyManifest); + (download.notify_handler)(Notification::DownloadingLegacyManifest); } Err(e) => return Err(e) } diff --git a/src/rustup-dist/src/download.rs b/src/rustup-dist/src/download.rs index 09b9ea907e..81f1103cec 100644 --- a/src/rustup-dist/src/download.rs +++ b/src/rustup-dist/src/download.rs @@ -8,10 +8,9 @@ use sha2::{Sha256, Digest}; use std::path::Path; use std::process::Command; -#[derive(Debug)] pub struct DownloadCfg<'a> { pub temp_cfg: &'a temp::Cfg, - pub notify_handler: NotifyHandler<'a>, + pub notify_handler: &'a Fn(Notification), pub gpg_key: Option<&'a str>, } @@ -22,7 +21,8 @@ impl<'a> DownloadCfg<'a> { let sig_url = try!(utils::parse_url(&format!("{}.asc", url))); let sig_file = try!(self.temp_cfg.new_file()); - try!(utils::download_file(&sig_url, &sig_file, None, ntfy!(&self.notify_handler))); + try!(utils::download_file(&sig_url, &sig_file, None, + &|n| (self.notify_handler)(n.into()))); let target_url = try!(utils::parse_url(url)); let target_file = try!(self.temp_cfg.new_file()); @@ -32,7 +32,7 @@ impl<'a> DownloadCfg<'a> { try!(utils::download_file(&target_url, &target_file, None, - ntfy!(&self.notify_handler))); + &|n| (self.notify_handler)(n.into()))); let key_file = try!(self.temp_cfg.new_file()); let key_filename: &Path = &key_file; @@ -62,7 +62,8 @@ impl<'a> DownloadCfg<'a> { let hash_url = try!(utils::parse_url(&format!("{}.sha256", url))); let hash_file = try!(self.temp_cfg.new_file()); - try!(utils::download_file(&hash_url, &hash_file, None, ntfy!(&self.notify_handler))); + try!(utils::download_file(&hash_url, &hash_file, None, + &|n| (self.notify_handler)(n.into()))); let hash = try!(utils::read_file("hash", &hash_file).map(|s| s[0..64].to_owned())); let mut hasher = Sha256::new(); @@ -72,7 +73,7 @@ impl<'a> DownloadCfg<'a> { try!(utils::download_file(&target_url, &target_file, Some(&mut hasher), - ntfy!(&self.notify_handler))); + &|n| (self.notify_handler)(n.into()))); let actual_hash = hasher.result_str(); @@ -84,7 +85,7 @@ impl<'a> DownloadCfg<'a> { calculated: actual_hash, }.into()); } else { - self.notify_handler.call(Notification::ChecksumValid(url)); + (self.notify_handler)(Notification::ChecksumValid(url)); } Ok(target_file) diff --git a/src/rustup-dist/src/lib.rs b/src/rustup-dist/src/lib.rs index 6d8716aa72..5a4343b587 100644 --- a/src/rustup-dist/src/lib.rs +++ b/src/rustup-dist/src/lib.rs @@ -27,7 +27,7 @@ extern crate gcc; extern crate libc; pub use errors::*; -pub use notifications::{Notification, NotifyHandler}; +pub use notifications::{Notification}; pub mod temp; diff --git a/src/rustup-dist/src/manifestation.rs b/src/rustup-dist/src/manifestation.rs index ee82fcfdab..9d37e5a41d 100644 --- a/src/rustup-dist/src/manifestation.rs +++ b/src/rustup-dist/src/manifestation.rs @@ -74,7 +74,7 @@ impl Manifestation { new_manifest: &Manifest, changes: Changes, temp_cfg: &temp::Cfg, - notify_handler: NotifyHandler) -> Result { + notify_handler: &Fn(Notification)) -> Result { // Some vars we're going to need a few times let prefix = self.installation.prefix(); @@ -126,17 +126,21 @@ impl Manifestation { let mut things_to_install: Vec<(Component, temp::File)> = Vec::new(); for (component, url, hash) in components_urls_and_hashes { - notify_handler.call(Notification::DownloadingComponent(&component.pkg, - &self.target_triple, - &component.target)); + notify_handler(Notification::DownloadingComponent(&component.pkg, + &self.target_triple, + &component.target)); // Download each package to temp file let temp_file = try!(temp_cfg.new_file()); let url_url = try!(utils::parse_url(&url)); let mut hasher = Sha256::new(); - try!(utils::download_file(&url_url, &temp_file, Some(&mut hasher), ntfy!(¬ify_handler)) - .chain_err(|| ErrorKind::ComponentDownloadFailed(component.clone()))); + try!(utils::download_file(&url_url, + &temp_file, + Some(&mut hasher), + &|n| notify_handler(n.into())).chain_err(|| { + ErrorKind::ComponentDownloadFailed(component.clone()) + })); let actual_hash = hasher.result_str(); @@ -148,7 +152,7 @@ impl Manifestation { calculated: actual_hash, }.into()); } else { - notify_handler.call(Notification::ChecksumValid(&url)); + notify_handler(Notification::ChecksumValid(&url)); } things_to_install.push((component, temp_file)); @@ -169,9 +173,9 @@ impl Manifestation { // Install components for (component, installer_file) in things_to_install { - notify_handler.call(Notification::InstallingComponent(&component.pkg, - &self.target_triple, - &component.target)); + notify_handler(Notification::InstallingComponent(&component.pkg, + &self.target_triple, + &component.target)); let package = try!(TarGzPackage::new_file(&installer_file, temp_cfg)); @@ -218,7 +222,7 @@ impl Manifestation { Ok(UpdateStatus::Changed) } - pub fn uninstall(&self, temp_cfg: &temp::Cfg, notify_handler: NotifyHandler) -> Result<()> { + pub fn uninstall(&self, temp_cfg: &temp::Cfg, notify_handler: &Fn(Notification)) -> Result<()> { let prefix = self.installation.prefix(); let mut tx = Transaction::new(prefix.clone(), temp_cfg, notify_handler); @@ -238,7 +242,7 @@ impl Manifestation { } fn uninstall_component<'a>(&self, component: &Component, mut tx: Transaction<'a>, - notify_handler: NotifyHandler) -> Result> { + notify_handler: &Fn(Notification)) -> Result> { // For historical reasons, the rust-installer component // names are not the same as the dist manifest component // names. Some are just the component name some are the @@ -250,7 +254,7 @@ impl Manifestation { } else if let Some(c) = try!(self.installation.find(&short_name)) { tx = try!(c.uninstall(tx)); } else { - notify_handler.call(Notification::MissingInstalledComponent(&name)); + notify_handler(Notification::MissingInstalledComponent(&name)); } Ok(tx) @@ -286,7 +290,7 @@ impl Manifestation { new_manifest: &[String], update_hash: Option<&Path>, temp_cfg: &temp::Cfg, - notify_handler: NotifyHandler) -> Result> { + notify_handler: &Fn(Notification)) -> Result> { // If there's already a v2 installation then something has gone wrong if try!(self.read_config()).is_some() { return Err("the server unexpectedly provided an obsolete version of the distribution manifest".into()); @@ -299,9 +303,9 @@ impl Manifestation { } let url = url.unwrap(); - notify_handler.call(Notification::DownloadingComponent("rust", - &self.target_triple, - &self.target_triple)); + notify_handler(Notification::DownloadingComponent("rust", + &self.target_triple, + &self.target_triple)); let dlcfg = DownloadCfg { dist_root: "bogus", @@ -317,9 +321,9 @@ impl Manifestation { let prefix = self.installation.prefix(); - notify_handler.call(Notification::InstallingComponent("rust", - &self.target_triple, - &self.target_triple)); + notify_handler(Notification::InstallingComponent("rust", + &self.target_triple, + &self.target_triple)); // Begin transaction let mut tx = Transaction::new(prefix.clone(), temp_cfg, notify_handler); @@ -372,7 +376,7 @@ fn build_update_component_lists( config: &Option, changes: Changes, rust_target_package: &TargettedPackage, - notify_handler: NotifyHandler, + notify_handler: &Fn(Notification), ) -> Result<(Vec, Vec, Vec)> { // Check some invariantns @@ -449,7 +453,7 @@ fn build_update_component_lists( components_to_install.push(component.clone()); } else { if changes.add_extensions.contains(&component) { - notify_handler.call(Notification::ComponentAlreadyInstalled(&component)); + notify_handler(Notification::ComponentAlreadyInstalled(&component)); } } } diff --git a/src/rustup-dist/src/notifications.rs b/src/rustup-dist/src/notifications.rs index f6b238c43f..887720ae63 100644 --- a/src/rustup-dist/src/notifications.rs +++ b/src/rustup-dist/src/notifications.rs @@ -2,7 +2,7 @@ use std::path::Path; use std::fmt::{self, Display}; use temp; use rustup_utils; -use rustup_utils::notify::{self, NotificationLevel, Notifyable}; +use rustup_utils::notify::{NotificationLevel}; use manifest::Component; use dist::TargetTriple; use errors::*; @@ -28,12 +28,17 @@ pub enum Notification<'a> { DownloadingLegacyManifest, } -pub type NotifyHandler<'a> = notify::NotifyHandler<'a, for<'b> Notifyable>>; -pub type SharedNotifyHandler = - notify::SharedNotifyHandler Notifyable>>; +impl<'a> From> for Notification<'a> { + fn from(n: rustup_utils::Notification<'a>) -> Notification<'a> { + Notification::Utils(n) + } +} -extend_notification!(Notification: rustup_utils::Notification, n => Notification::Utils(n)); -extend_notification!(Notification: temp::Notification, n => Notification::Temp(n)); +impl<'a> From> for Notification<'a> { + fn from(n: temp::Notification<'a>) -> Notification<'a> { + Notification::Temp(n) + } +} impl<'a> Notification<'a> { pub fn level(&self) -> NotificationLevel { diff --git a/src/rustup-dist/src/temp.rs b/src/rustup-dist/src/temp.rs index 826b666ed5..c65aa26efc 100644 --- a/src/rustup-dist/src/temp.rs +++ b/src/rustup-dist/src/temp.rs @@ -6,7 +6,7 @@ use std::ops; use std::fmt::{self, Display}; use rustup_utils::raw; -use rustup_utils::notify::{self, NotificationLevel, Notifyable}; +use rustup_utils::notify::NotificationLevel; #[derive(Debug)] pub enum Error { @@ -25,8 +25,6 @@ pub enum Error { } pub type Result = ::std::result::Result; -pub type NotifyHandler<'a> = notify::NotifyHandler<'a, for<'b> Notifyable>>; -pub type SharedNotifyHandler = notify::SharedNotifyHandler Notifyable>>; #[derive(Debug)] pub enum Notification<'a> { @@ -37,10 +35,9 @@ pub enum Notification<'a> { DirectoryDeletion(&'a Path, io::Result<()>), } -#[derive(Debug)] pub struct Cfg { root_directory: PathBuf, - notify_handler: SharedNotifyHandler, + notify_handler: Box, } #[derive(Debug)] @@ -134,7 +131,7 @@ impl Display for Error { } impl Cfg { - pub fn new(root_directory: PathBuf, notify_handler: SharedNotifyHandler) -> Self { + pub fn new(root_directory: PathBuf, notify_handler: Box) -> Self { Cfg { root_directory: root_directory, notify_handler: notify_handler, @@ -143,7 +140,7 @@ impl Cfg { pub fn create_root(&self) -> Result { raw::ensure_dir_exists(&self.root_directory, |p| { - self.notify_handler.call(Notification::CreatingRoot(p)); + (self.notify_handler)(Notification::CreatingRoot(p)); }) .map_err(|e| { Error::CreatingRoot { @@ -164,7 +161,7 @@ impl Cfg { // This is technically racey, but the probability of getting the same // random names at exactly the same time is... low. if !raw::path_exists(&temp_dir) { - self.notify_handler.call(Notification::CreatingDirectory(&temp_dir)); + (self.notify_handler)(Notification::CreatingDirectory(&temp_dir)); try!(fs::create_dir(&temp_dir).map_err(|e| { Error::CreatingDirectory { path: PathBuf::from(&temp_dir), @@ -194,7 +191,7 @@ impl Cfg { // This is technically racey, but the probability of getting the same // random names at exactly the same time is... low. if !raw::path_exists(&temp_file) { - self.notify_handler.call(Notification::CreatingFile(&temp_file)); + (self.notify_handler)(Notification::CreatingFile(&temp_file)); try!(fs::File::create(&temp_file).map_err(|e| { Error::CreatingFile { path: PathBuf::from(&temp_file), @@ -210,6 +207,15 @@ impl Cfg { } } +impl fmt::Debug for Cfg { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Cfg") + .field("root_directory", &self.root_directory) + .field("notify_handler", &"...") + .finish() + } +} + impl<'a> ops::Deref for Dir<'a> { type Target = Path; @@ -229,9 +235,8 @@ impl<'a> ops::Deref for File<'a> { impl<'a> Drop for Dir<'a> { fn drop(&mut self) { if raw::is_directory(&self.path) { - self.cfg - .notify_handler - .call(Notification::DirectoryDeletion(&self.path, fs::remove_dir_all(&self.path))); + let n = Notification::DirectoryDeletion(&self.path, fs::remove_dir_all(&self.path)); + (self.cfg.notify_handler)(n); } } } @@ -239,9 +244,8 @@ impl<'a> Drop for Dir<'a> { impl<'a> Drop for File<'a> { fn drop(&mut self) { if raw::is_file(&self.path) { - self.cfg - .notify_handler - .call(Notification::FileDeletion(&self.path, fs::remove_file(&self.path))); + let n = Notification::FileDeletion(&self.path, fs::remove_file(&self.path)); + (self.cfg.notify_handler)(n); } } } diff --git a/src/rustup-dist/tests/dist.rs b/src/rustup-dist/tests/dist.rs index 16b60b69d4..d4dd59b590 100644 --- a/src/rustup-dist/tests/dist.rs +++ b/src/rustup-dist/tests/dist.rs @@ -15,10 +15,11 @@ extern crate url; use rustup_mock::dist::*; use rustup_mock::{MockCommand, MockInstallerBuilder}; use rustup_dist::prefix::InstallPrefix; -use rustup_dist::{ErrorKind, NotifyHandler}; +use rustup_dist::ErrorKind; use rustup_dist::errors::Result; use rustup_dist::dist::{ToolchainDesc, TargetTriple}; use rustup_dist::download::DownloadCfg; +use rustup_dist::Notification; use rustup_utils::utils; use rustup_utils::raw as utils_raw; use rustup_dist::temp; @@ -268,7 +269,7 @@ fn update_from_dist(dist_server: &Url, add: &[Component], remove: &[Component], temp_cfg: &temp::Cfg, - notify_handler: NotifyHandler) -> Result { + notify_handler: &Fn(Notification)) -> Result { // Download the dist manifest and place it into the installation prefix let ref manifest_url = try!(make_manifest_url(dist_server, toolchain)); @@ -300,7 +301,7 @@ fn make_manifest_url(dist_server: &Url, toolchain: &ToolchainDesc) -> Result Result<()> { + notify_handler: &Fn(Notification)) -> Result<()> { let trip = toolchain.target.clone(); let manifestation = try!(Manifestation::open(prefix.clone(), trip)); @@ -317,7 +318,8 @@ fn setup(edit: Option<&Fn(&str, &mut MockPackage)>, let prefix_tempdir = TempDir::new("multirust").unwrap(); let work_tempdir = TempDir::new("multirust").unwrap(); - let ref temp_cfg = temp::Cfg::new(work_tempdir.path().to_owned(), temp::SharedNotifyHandler::none()); + let ref temp_cfg = temp::Cfg::new(work_tempdir.path().to_owned(), + Box::new(|_| ())); let ref url = Url::parse(&format!("file://{}", dist_tempdir.path().to_string_lossy())).unwrap(); let ref toolchain = ToolchainDesc::from_str("nightly-x86_64-apple-darwin").unwrap(); @@ -329,7 +331,7 @@ fn setup(edit: Option<&Fn(&str, &mut MockPackage)>, #[test] fn initial_install() { setup(None, &|url, toolchain, prefix, temp_cfg| { - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/rustc"))); assert!(utils::path_exists(&prefix.path().join("lib/libstd.rlib"))); @@ -339,8 +341,8 @@ fn initial_install() { #[test] fn test_uninstall() { setup(None, &|url, toolchain, prefix, temp_cfg| { - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); - uninstall(toolchain, prefix, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); + uninstall(toolchain, prefix, temp_cfg, &|_| ()).unwrap(); assert!(!utils::path_exists(&prefix.path().join("bin/rustc"))); assert!(!utils::path_exists(&prefix.path().join("lib/libstd.rlib"))); @@ -350,9 +352,9 @@ fn test_uninstall() { #[test] fn uninstall_removes_config_file() { setup(None, &|url, toolchain, prefix, temp_cfg| { - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.manifest_file("multirust-config.toml"))); - uninstall(toolchain, prefix, temp_cfg, NotifyHandler::none()).unwrap(); + uninstall(toolchain, prefix, temp_cfg, &|_| ()).unwrap(); assert!(!utils::path_exists(&prefix.manifest_file("multirust-config.toml"))); }); } @@ -361,10 +363,10 @@ fn uninstall_removes_config_file() { fn upgrade() { setup(None, &|url, toolchain, prefix, temp_cfg| { change_channel_date(url, "nightly", "2016-02-01"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert_eq!("2016-02-01", utils_raw::read_file(&prefix.path().join("bin/rustc")).unwrap()); change_channel_date(url, "nightly", "2016-02-02"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert_eq!("2016-02-02", utils_raw::read_file(&prefix.path().join("bin/rustc")).unwrap()); }); } @@ -383,10 +385,10 @@ fn update_removes_components_that_dont_exist() { }; setup(Some(edit), &|url, toolchain, prefix, temp_cfg| { change_channel_date(url, "nightly", "2016-02-01"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/bonus"))); change_channel_date(url, "nightly", "2016-02-02"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert!(!utils::path_exists(&prefix.path().join("bin/bonus"))); }); } @@ -404,13 +406,13 @@ fn update_preserves_extensions() { ]; change_channel_date(url, "nightly", "2016-02-01"); - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); change_channel_date(url, "nightly", "2016-02-02"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); @@ -443,12 +445,12 @@ fn update_preserves_extensions_that_became_components() { ]; change_channel_date(url, "nightly", "2016-02-01"); - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/bonus"))); change_channel_date(url, "nightly", "2016-02-02"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/bonus"))); }); } @@ -473,10 +475,10 @@ fn update_preserves_components_that_became_extensions() { }; setup(Some(edit), &|url, toolchain, prefix, temp_cfg| { change_channel_date(url, "nightly", "2016-02-01"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/bonus"))); change_channel_date(url, "nightly", "2016-02-02"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/bonus"))); }); } @@ -484,9 +486,9 @@ fn update_preserves_components_that_became_extensions() { #[test] fn update_makes_no_changes_for_identical_manifest() { setup(None, &|url, toolchain, prefix, temp_cfg| { - let status = update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + let status = update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert_eq!(status, UpdateStatus::Changed); - let status = update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + let status = update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); assert_eq!(status, UpdateStatus::Unchanged); }); } @@ -503,7 +505,7 @@ fn add_extensions_for_initial_install() { } ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); }); @@ -512,7 +514,7 @@ fn add_extensions_for_initial_install() { #[test] fn add_extensions_for_same_manifest() { setup(None, &|url, toolchain, prefix, temp_cfg| { - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); let ref adds = vec![ Component { @@ -523,7 +525,7 @@ fn add_extensions_for_same_manifest() { } ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); @@ -535,7 +537,7 @@ fn add_extensions_for_upgrade() { setup(None, &|url, toolchain, prefix, temp_cfg| { change_channel_date(url, "nightly", "2016-02-01"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); change_channel_date(url, "nightly", "2016-02-02"); @@ -548,7 +550,7 @@ fn add_extensions_for_upgrade() { } ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); @@ -565,7 +567,7 @@ fn add_extension_not_in_manifest() { }, ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); }); } @@ -579,7 +581,7 @@ fn add_extension_that_is_required_component() { }, ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); }); } @@ -596,7 +598,7 @@ fn add_extensions_for_same_manifest_when_extension_already_installed() { #[test] fn add_extensions_does_not_remove_other_components() { setup(None, &|url, toolchain, prefix, temp_cfg| { - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); let ref adds = vec![ Component { @@ -604,7 +606,7 @@ fn add_extensions_does_not_remove_other_components() { }, ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/rustc"))); }); @@ -621,7 +623,7 @@ fn remove_extensions_for_initial_install() { }, ]; - update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); } @@ -637,7 +639,7 @@ fn remove_extensions_for_same_manifest() { } ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); let ref removes = vec![ Component { @@ -645,7 +647,7 @@ fn remove_extensions_for_same_manifest() { }, ]; - update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); assert!(!utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); @@ -666,7 +668,7 @@ fn remove_extensions_for_upgrade() { } ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); change_channel_date(url, "nightly", "2016-02-02"); @@ -676,7 +678,7 @@ fn remove_extensions_for_upgrade() { }, ]; - update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); assert!(!utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); @@ -689,7 +691,7 @@ fn remove_extension_not_in_manifest() { setup(None, &|url, toolchain, prefix, temp_cfg| { change_channel_date(url, "nightly", "2016-02-01"); - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); change_channel_date(url, "nightly", "2016-02-02"); @@ -699,7 +701,7 @@ fn remove_extension_not_in_manifest() { }, ]; - update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); } @@ -726,7 +728,7 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { pkg: "bonus".to_string(), target: TargetTriple::from_str("x86_64-apple-darwin") }, ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/bonus"))); change_channel_date(url, "nightly", "2016-02-02"); @@ -736,7 +738,7 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { pkg: "bonus".to_string(), target: TargetTriple::from_str("x86_64-apple-darwin") }, ]; - update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); } @@ -744,7 +746,7 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { #[should_panic] fn remove_extension_that_is_required_component() { setup(None, &|url, toolchain, prefix, temp_cfg| { - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); let ref removes = vec![ Component { @@ -752,7 +754,7 @@ fn remove_extension_that_is_required_component() { }, ]; - update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); } @@ -760,7 +762,7 @@ fn remove_extension_that_is_required_component() { #[should_panic] fn remove_extension_not_installed() { setup(None, &|url, toolchain, prefix, temp_cfg| { - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); let ref removes = vec![ Component { @@ -768,7 +770,7 @@ fn remove_extension_not_installed() { }, ]; - update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); } @@ -786,7 +788,7 @@ fn remove_extensions_does_not_remove_other_components() { }, ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); let ref removes = vec![ Component { @@ -794,7 +796,7 @@ fn remove_extensions_does_not_remove_other_components() { }, ]; - update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/rustc"))); }); @@ -811,7 +813,7 @@ fn add_and_remove_for_upgrade() { }, ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); change_channel_date(url, "nightly", "2016-02-02"); @@ -827,7 +829,7 @@ fn add_and_remove_for_upgrade() { }, ]; - update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(!utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); @@ -843,7 +845,7 @@ fn add_and_remove() { }, ]; - update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); let ref adds = vec![ Component { @@ -857,7 +859,7 @@ fn add_and_remove() { }, ]; - update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); assert!(!utils::path_exists(&prefix.path().join("lib/i686-unknown-linux-gnu/libstd.rlib"))); @@ -868,7 +870,7 @@ fn add_and_remove() { #[should_panic] fn add_and_remove_same_component() { setup(None, &|url, toolchain, prefix, temp_cfg| { - update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap(); let ref adds = vec![ Component { @@ -882,7 +884,7 @@ fn add_and_remove_same_component() { }, ]; - update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, NotifyHandler::none()).unwrap(); + update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, &|_| ()).unwrap(); }); } @@ -893,7 +895,7 @@ fn bad_component_hash() { let path = path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz"); utils_raw::write_file(&path, "bogus").unwrap(); - let err = update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap_err(); + let err = update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap_err(); match *err.kind() { ErrorKind::ChecksumFailed { .. } => (), @@ -909,7 +911,7 @@ fn unable_to_download_component() { let path = path.join("dist/2016-02-02/rustc-nightly-x86_64-apple-darwin.tar.gz"); fs::remove_file(&path).unwrap(); - let err = update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, NotifyHandler::none()).unwrap_err(); + let err = update_from_dist(url, toolchain, prefix, &[], &[], temp_cfg, &|_| ()).unwrap_err(); match *err.kind() { ErrorKind::ComponentDownloadFailed(..) => (), diff --git a/src/rustup-dist/tests/install.rs b/src/rustup-dist/tests/install.rs index e0c3b08e06..196c779e75 100644 --- a/src/rustup-dist/tests/install.rs +++ b/src/rustup-dist/tests/install.rs @@ -8,8 +8,8 @@ use rustup_dist::component::{DirectoryPackage, Package}; use rustup_dist::component::Transaction; use rustup_dist::temp; use rustup_dist::ErrorKind; +use rustup_dist::Notification; use rustup_utils::utils; -use rustup_dist::NotifyHandler; use rustup_dist::prefix::InstallPrefix; use std::fs::File; use std::io::Write; @@ -108,11 +108,10 @@ fn basic_install() { let instdir = TempDir::new("multirust").unwrap(); let prefix = InstallPrefix::from(instdir.path().to_owned()); - let notify = temp::SharedNotifyHandler::none(); let tmpdir = TempDir::new("multirust").unwrap(); - let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), notify); - let notify = NotifyHandler::none(); - let tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), Box::new(|_| ())); + let notify = |_: Notification| (); + let tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let components = Components::open(prefix.clone()).unwrap(); @@ -147,11 +146,10 @@ fn multiple_component_install() { let instdir = TempDir::new("multirust").unwrap(); let prefix = InstallPrefix::from(instdir.path().to_owned()); - let notify = temp::SharedNotifyHandler::none(); let tmpdir = TempDir::new("multirust").unwrap(); - let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), notify); - let notify = NotifyHandler::none(); - let tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), Box::new(|_| ())); + let notify = |_: Notification| (); + let tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let components = Components::open(prefix.clone()).unwrap(); @@ -191,11 +189,10 @@ fn uninstall() { let instdir = TempDir::new("multirust").unwrap(); let prefix = InstallPrefix::from(instdir.path().to_owned()); - let notify = temp::SharedNotifyHandler::none(); let tmpdir = TempDir::new("multirust").unwrap(); - let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), notify); - let notify = NotifyHandler::none(); - let tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), Box::new(|_| ())); + let notify = |_: Notification| (); + let tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let components = Components::open(prefix.clone()).unwrap(); @@ -206,8 +203,8 @@ fn uninstall() { tx.commit(); // Now uninstall - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); for component in components.list().unwrap() { tx = component.uninstall(tx).unwrap(); } @@ -244,11 +241,10 @@ fn component_bad_version() { let instdir = TempDir::new("multirust").unwrap(); let prefix = InstallPrefix::from(instdir.path().to_owned()); - let notify = temp::SharedNotifyHandler::none(); let tmpdir = TempDir::new("multirust").unwrap(); - let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), notify); - let notify = NotifyHandler::none(); - let tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), Box::new(|_| ())); + let notify = |_: Notification| (); + let tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let components = Components::open(prefix.clone()).unwrap(); @@ -291,11 +287,10 @@ fn unix_permissions() { let instdir = TempDir::new("multirust").unwrap(); let prefix = InstallPrefix::from(instdir.path().to_owned()); - let notify = temp::SharedNotifyHandler::none(); let tmpdir = TempDir::new("multirust").unwrap(); - let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), notify); - let notify = NotifyHandler::none(); - let tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), Box::new(|_| ())); + let notify = |_: Notification| (); + let tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let components = Components::open(prefix.clone()).unwrap(); @@ -336,11 +331,10 @@ fn install_to_prefix_that_does_not_exist() { let does_not_exist = instdir.path().join("super_not_real"); let prefix = InstallPrefix::from(does_not_exist.clone()); - let notify = temp::SharedNotifyHandler::none(); let tmpdir = TempDir::new("multirust").unwrap(); - let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), notify); - let notify = NotifyHandler::none(); - let tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let tmpcfg = temp::Cfg::new(tmpdir.path().to_owned(), Box::new(|_| ())); + let notify = |_: Notification| (); + let tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let components = Components::open(prefix.clone()).unwrap(); diff --git a/src/rustup-dist/tests/transactions.rs b/src/rustup-dist/tests/transactions.rs index c0b9d1131e..0e927fbd4c 100644 --- a/src/rustup-dist/tests/transactions.rs +++ b/src/rustup-dist/tests/transactions.rs @@ -2,10 +2,10 @@ extern crate rustup_dist; extern crate rustup_utils; extern crate tempdir; -use rustup_dist::NotifyHandler; use rustup_dist::prefix::InstallPrefix; use rustup_dist::component::Transaction; use rustup_dist::temp; +use rustup_dist::Notification; use rustup_utils::utils; use rustup_utils::raw as utils_raw; use rustup_dist::ErrorKind; @@ -21,11 +21,10 @@ fn add_file() { let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let mut file = tx.add_file("c", PathBuf::from("foo/bar")).unwrap(); write!(&mut file, "test").unwrap(); @@ -44,11 +43,10 @@ fn add_file_then_rollback() { let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); tx.add_file("c", PathBuf::from("foo/bar")).unwrap(); drop(tx); @@ -61,13 +59,12 @@ fn add_file_that_exists() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); fs::create_dir_all(&prefixdir.path().join("foo")).unwrap(); utils::write_file("", &prefixdir.path().join("foo/bar"), "").unwrap(); @@ -89,13 +86,12 @@ fn copy_file() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let srcpath = srcdir.path().join("bar"); utils::write_file("", &srcpath, "").unwrap(); @@ -112,13 +108,12 @@ fn copy_file_then_rollback() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let srcpath = srcdir.path().join("bar"); utils::write_file("", &srcpath, "").unwrap(); @@ -135,13 +130,12 @@ fn copy_file_that_exists() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let srcpath = srcdir.path().join("bar"); utils::write_file("", &srcpath, "").unwrap(); @@ -166,13 +160,12 @@ fn copy_dir() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let srcpath1 = srcdir.path().join("foo"); let srcpath2 = srcdir.path().join("bar/baz"); @@ -197,13 +190,12 @@ fn copy_dir_then_rollback() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let srcpath1 = srcdir.path().join("foo"); let srcpath2 = srcdir.path().join("bar/baz"); @@ -228,13 +220,12 @@ fn copy_dir_that_exists() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); fs::create_dir_all(prefix.path().join("a")).unwrap(); @@ -254,13 +245,12 @@ fn remove_file() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let filepath = prefixdir.path().join("foo"); utils::write_file("", &filepath, "").unwrap(); @@ -276,13 +266,12 @@ fn remove_file_then_rollback() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let filepath = prefixdir.path().join("foo"); utils::write_file("", &filepath, "").unwrap(); @@ -298,13 +287,12 @@ fn remove_file_that_not_exists() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let err = tx.remove_file("c", PathBuf::from("foo")).unwrap_err(); @@ -322,13 +310,12 @@ fn remove_dir() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let filepath = prefixdir.path().join("foo/bar"); fs::create_dir_all(filepath.parent().unwrap()).unwrap(); @@ -345,13 +332,12 @@ fn remove_dir_then_rollback() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let filepath = prefixdir.path().join("foo/bar"); fs::create_dir_all(filepath.parent().unwrap()).unwrap(); @@ -368,13 +354,12 @@ fn remove_dir_that_not_exists() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let err = tx.remove_dir("c", PathBuf::from("foo")).unwrap_err(); @@ -392,13 +377,12 @@ fn write_file() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let content = "hi".to_string(); tx.write_file("c", PathBuf::from("foo/bar"), content.clone()).unwrap(); @@ -415,13 +399,12 @@ fn write_file_then_rollback() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let content = "hi".to_string(); tx.write_file("c", PathBuf::from("foo/bar"), content.clone()).unwrap(); @@ -435,13 +418,12 @@ fn write_file_that_exists() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let content = "hi".to_string(); utils_raw::write_file(&prefix.path().join("a"), &content).unwrap(); @@ -463,13 +445,12 @@ fn modify_file_that_not_exists() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); tx.modify_file(PathBuf::from("foo/bar")).unwrap(); tx.commit(); @@ -484,13 +465,12 @@ fn modify_file_that_exists() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let ref path = prefix.path().join("foo"); utils_raw::write_file(path, "wow").unwrap(); @@ -505,13 +485,12 @@ fn modify_file_that_not_exists_then_rollback() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); tx.modify_file(PathBuf::from("foo/bar")).unwrap(); drop(tx); @@ -524,13 +503,12 @@ fn modify_file_that_exists_then_rollback() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let ref path = prefix.path().join("foo"); utils_raw::write_file(path, "wow").unwrap(); @@ -548,13 +526,12 @@ fn modify_twice_then_rollback() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); let ref path = prefix.path().join("foo"); utils_raw::write_file(path, "wow").unwrap(); @@ -572,13 +549,12 @@ fn do_multiple_op_transaction(rollback: bool) { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); // copy_file let relpath1 = PathBuf::from("bin/rustc"); @@ -669,13 +645,12 @@ fn rollback_failure_keeps_going() { let prefixdir = TempDir::new("multirust").unwrap(); let txdir = TempDir::new("multirust").unwrap(); - let tmpnotify = temp::SharedNotifyHandler::none(); - let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), tmpnotify); + let tmpcfg = temp::Cfg::new(txdir.path().to_owned(), Box::new(|_| ())); let prefix = InstallPrefix::from(prefixdir.path().to_owned()); - let notify = NotifyHandler::none(); - let mut tx = Transaction::new(prefix.clone(), &tmpcfg, notify); + let notify = |_: Notification| (); + let mut tx = Transaction::new(prefix.clone(), &tmpcfg, ¬ify); write!(&mut tx.add_file("", PathBuf::from("foo")).unwrap(), "").unwrap(); write!(&mut tx.add_file("", PathBuf::from("bar")).unwrap(), "").unwrap(); diff --git a/src/rustup-mock/src/clitools.rs b/src/rustup-mock/src/clitools.rs index 3619fba135..dcf6edba61 100644 --- a/src/rustup-mock/src/clitools.rs +++ b/src/rustup-mock/src/clitools.rs @@ -6,7 +6,7 @@ use std::env; use std::process::Command; use std::env::consts::EXE_SUFFIX; use std::fs::{self, File}; -use std::io::{Read, Write}; +use std::io::{self, Read, Write}; use std::sync::Mutex; use tempdir::TempDir; use {MockInstallerBuilder, MockCommand}; @@ -92,7 +92,22 @@ pub fn setup(s: Scenario, f: &Fn(&Config)) { let rustc_path = config.exedir.join(format!("rustc{}", EXE_SUFFIX)); let cargo_path = config.exedir.join(format!("cargo{}", EXE_SUFFIX)); - fs::copy(build_path, rustup_path).unwrap(); + // Don't copy an executable via `fs::copy` on Unix because that'll require + // opening up the destination for writing. If one thread in our process then + // forks the child will have the destination open as well (fd inheritance) + // which will prevent us from then executing that binary. + // + // On Windows, however, handles aren't inherited across processes so we can + // do fs::copy there, and on Unix we just do symlinks. + #[cfg(windows)] + fn copy_binary(src: &Path, dst: &Path) -> io::Result<()> { + fs::copy(src, dst).map(|_| ()) + } + #[cfg(unix)] + fn copy_binary(src: &Path, dst: &Path) -> io::Result<()> { + ::std::os::unix::fs::symlink(src, dst) + } + copy_binary(&build_path, &rustup_path).unwrap(); fs::hard_link(rustup_path, setup_path).unwrap(); fs::hard_link(rustup_path, multirust_setup_path).unwrap(); fs::hard_link(rustup_path, rustc_path).unwrap(); diff --git a/src/rustup-utils/Cargo.toml b/src/rustup-utils/Cargo.toml index 689ab85c33..28a4574d35 100644 --- a/src/rustup-utils/Cargo.toml +++ b/src/rustup-utils/Cargo.toml @@ -18,7 +18,7 @@ error-chain = { path = "../error-chain", version = "0.1.12" } libc = "0.2.0" rustc-serialize = "0.3.19" sha2 = "0.1.2" -curl = { git = "https://github.com/alexcrichton/curl-rust", rev = "ccf35d3e" } +curl = "0.3" url = "1.1" toml = "0.1.27" diff --git a/src/rustup-utils/src/lib.rs b/src/rustup-utils/src/lib.rs index 721bebe39c..07f74373c3 100644 --- a/src/rustup-utils/src/lib.rs +++ b/src/rustup-utils/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(core_intrinsics)] // For type_name(). -#![feature(fundamental)] #![recursion_limit = "1024"] // for error_chain! extern crate curl; @@ -30,7 +28,6 @@ extern crate userenv; #[cfg(unix)] extern crate libc; -pub mod notify; pub mod errors; pub mod notifications; pub mod raw; @@ -39,4 +36,5 @@ pub mod utils; pub mod toml_utils; pub use errors::*; -pub use notifications::{Notification, NotifyHandler}; +pub use notifications::{Notification}; +pub mod notify; diff --git a/src/rustup-utils/src/notifications.rs b/src/rustup-utils/src/notifications.rs index 8dcc880e92..42cd8e97bb 100644 --- a/src/rustup-utils/src/notifications.rs +++ b/src/rustup-utils/src/notifications.rs @@ -3,7 +3,7 @@ use std::fmt::{self, Display}; use url::Url; -use notify::{self, NotificationLevel, Notifyable}; +use notify::NotificationLevel; #[derive(Debug)] pub enum Notification<'a> { @@ -21,8 +21,6 @@ pub enum Notification<'a> { NoCanonicalPath(&'a Path), } -pub type NotifyHandler<'a> = notify::NotifyHandler<'a, for<'b> Notifyable>>; - impl<'a> Notification<'a> { pub fn level(&self) -> NotificationLevel { use self::Notification::*; diff --git a/src/rustup-utils/src/notify.rs b/src/rustup-utils/src/notify.rs index 48fe6d3b29..17c5bc80e8 100644 --- a/src/rustup-utils/src/notify.rs +++ b/src/rustup-utils/src/notify.rs @@ -1,116 +1,3 @@ -//! Notification handlers. -//! -//! These are used to bubble up information about what is happening -//! inside the program. They are composed as error types commonly are. -//! -//! The major types: -//! -//! * `Notifyable`. Types implementing this can receive -//! notifications of `N` through the `call` method. These are -//! passed around as trait objects. Closures over `N` automatically -//! implement `Notifyable`. -//! * `NotifyHandler<'a, N>(Option<&N>)`. A wrapper around -//! `Notifyable` objects, passed as values. Functions that need to -//! emit notifications take these by value. -//! * `Notification`. By convention, the name of an enum in each -//! module that defines the notifications that module emits. -//! -//! Notifications are composed in a hierarchy. For example, this crate -//! defines `temp::Notification`, and `utils::Notification`, and -//! futher defines `errors::Notification`, the top-level notification -//! enum which encapsulates both in the variants -//! `Notification::Temp(temp::Notification)` and -//! `Notification::Utils(utils::Notification)`. -//! -//! A `NotifyHandler<_, error::Notification>` can be turned into a -//! `NotifyHandler<_, temp::Notification>` by calling -//! `temp::NotifyHandler::some(&my_error_notify_handler)`. This works -//! because `NotifyHandler<_, error::Notification>` implements -//! `Notifyable` via the `extend_notification!` -//! macro. - -use std::fmt; -use std::intrinsics::type_name; -use std::sync::Arc; - -#[fundamental] -pub trait Notifyable { - fn call(&self, n: N); -} - -impl Notifyable for F { - fn call(&self, n: N) { - self(n) - } -} - -#[fundamental] -pub struct NotifyHandler<'a, T: 'a + ?Sized>(Option<&'a T>); - -impl<'a, T: 'a + ?Sized> fmt::Debug for NotifyHandler<'a, T> { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "NotifyHandler<{}>", unsafe { type_name::() }) - } -} - -impl<'a, T: 'a + ?Sized> Copy for NotifyHandler<'a, T> {} -impl<'a, T: 'a + ?Sized> Clone for NotifyHandler<'a, T> { - fn clone(&self) -> Self { - *self - } -} - -#[fundamental] -pub struct SharedNotifyHandler(Option>); - -impl Clone for SharedNotifyHandler { - fn clone(&self) -> Self { - SharedNotifyHandler(self.0.clone()) - } -} - -impl fmt::Debug for SharedNotifyHandler { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "SharedNotifyHandler<{}>", unsafe { type_name::() }) - } -} - -impl<'a, T: 'a + ?Sized> NotifyHandler<'a, T> { - pub fn some(arg: &'a T) -> Self { - NotifyHandler(Some(arg)) - } - pub fn none() -> Self { - NotifyHandler(None) - } - pub fn call(&self, arg: U) - where T: Notifyable - { - if let Some(f) = self.0 { - f.call(arg); - } - } -} - -impl SharedNotifyHandler { - pub fn some(arg: Arc) -> Self { - SharedNotifyHandler(Some(arg)) - } - pub fn none() -> Self { - SharedNotifyHandler(None) - } - pub fn as_ref<'a>(&'a self) -> NotifyHandler<'a, T> { - match self.0 { - Some(ref f) => NotifyHandler(Some(f)), - None => NotifyHandler(None), - } - } - pub fn call(&self, arg: U) - where T: Notifyable - { - self.as_ref().call(arg) - } -} - #[derive(Debug)] pub enum NotificationLevel { Verbose, @@ -118,55 +5,3 @@ pub enum NotificationLevel { Warn, Error, } - -#[macro_export] -macro_rules! extend_notification { - ($( $cur:ident )::*: $( $base:ident )::*, $p:ident => $e:expr) => ( - impl<'a, 'b> $crate::notify::Notifyable<$($base)::*<'a>> for $crate::notify::NotifyHandler<'b, for<'c> $crate::notify::Notifyable<$($cur)::*<'c>>> { - fn call(&self, $p: $($base)::*<'a>) { - self.call($e) - } - } - impl<'a> $crate::notify::Notifyable<$($base)::*<'a>> for $crate::notify::SharedNotifyHandler $crate::notify::Notifyable<$($cur)::*<'b>>> { - fn call(&self, $p: $($base)::*<'a>) { - self.call($e) - } - } - ) -} -#[macro_export] -macro_rules! declare_notification { - ($( $cur:ident )::*: $( $base:ident )::*, $p:ident => $e:expr) => ( - impl<'a, 'b> $crate::notify::Notifyable<$($base)::*<'a>> for $crate::notify::NotifyHandler<'b, for<'c> $crate::notify::Notifyable<$($cur)::*<'c>>> { - fn call(&self, $p: $($base)::*<'a>) { - self.call($e) - } - } - impl<'a> $crate::notify::Notifyable<$($base)::*<'a>> for $crate::notify::SharedNotifyHandler $crate::notify::Notifyable<$($cur)::*<'b>>> { - fn call(&self, $p: $($base)::*<'a>) { - self.call($e) - } - } - ) -} -#[macro_export] -macro_rules! ntfy { - ($e:expr) => ( - $crate::notify::NotifyHandler::some($e) - ) -} -#[macro_export] -macro_rules! shared_ntfy { - ($e:expr) => ( - $crate::notify::SharedNotifyHandler::some(::std::sync::Arc::new($e)) - ) -} -#[macro_export] -macro_rules! ok_ntfy { - ($n:expr, $w:path, $e:expr) => ( - match $e { - Err(e) => { $n.call($w(&e)); None }, - Ok(r) => Some(r) - } - ) -} diff --git a/src/rustup-utils/src/raw.rs b/src/rustup-utils/src/raw.rs index 37a67c69a3..20cbe474ab 100644 --- a/src/rustup-utils/src/raw.rs +++ b/src/rustup-utils/src/raw.rs @@ -1,5 +1,3 @@ -use notifications::NotifyHandler; - use std::cell::RefCell; use std::char::from_u32; use std::error; @@ -20,6 +18,8 @@ use url::Url; use rand::random; +use notifications::Notification; + pub fn ensure_dir_exists, F: FnOnce(&Path)>(path: P, callback: F) -> io::Result { @@ -158,88 +158,88 @@ pub fn tee_file(path: &Path, mut w: &mut W) -> io::Result<()> { pub fn download_file(url: &Url, path: &Path, mut hasher: Option<&mut Sha256>, - notify_handler: NotifyHandler) + notify_handler: &Fn(Notification)) -> Result<()> { use notifications::Notification; use std::io::Write; let mut file = try!(fs::File::create(&path).chain_err( || "error creating file for download")); - let fserr = RefCell::new(None); - - // Data callback for libcurl which is called with data that's downloaded. We - // just feed it into our hasher and also write it out to disk. - let mut ondata = |data: &[u8]| { - if let Some(ref mut h) = hasher { - h.input(data); - } - notify_handler.call(Notification::DownloadDataReceived(data.len())); - match file.write_all(data) { - Ok(()) => data.len(), - Err(e) => { - *fserr.borrow_mut() = Some(e); - 0 - } - } - }; - - // Listen for headers and parse out a `Content-Length` if it comes so we - // know how much we're downloading. - let mut onheader = |data: &[u8]| { - if let Ok(data) = str::from_utf8(data) { - let prefix = "Content-Length: "; - if data.starts_with(prefix) { - if let Ok(s) = data[prefix.len()..].trim().parse() { - notify_handler.call(Notification::DownloadContentLengthReceived(s)); - } - } - } - true - }; // Fetch either a cached libcurl handle (which will preserve open // connections) or create a new one if it isn't listed. // // Once we've acquired it, reset the lifetime from 'static to our local // scope. - thread_local!(static EASY: RefCell>> = RefCell::new(None)); - let handle = EASY.with(|e| e.borrow_mut().take()).unwrap_or(Easy::new()); - let mut handle = handle.reset_lifetime(); - - try!(handle.url(&url.to_string()).chain_err(|| "failed to set url")); - try!(handle.follow_location(true).chain_err(|| "failed to set follow redirects")); - try!(handle.write_function(&mut ondata).chain_err(|| "failed to set write")); - try!(handle.header_function(&mut onheader).chain_err(|| "failed to set header")); - - // Take at most 30s to connect - try!(handle.connect_timeout(Duration::new(30, 0)).chain_err(|| "failed to set connect timeout")); - - // Fail if less than 10 bytes are transferred every 30 seconds - try!(handle.low_speed_limit(10).chain_err(|| "failed to set low speed limit")); - try!(handle.low_speed_time(Duration::new(30, 0)).chain_err(|| "failed to set low speed time")); - - // If an error happens check to see if we had a filesystem error up in - // `fserr`, but we always want to punt it up. - try!(handle.perform().or_else(|e| { - match fserr.borrow_mut().take() { - Some(fs) => Err(fs).chain_err(|| ErrorKind::HttpError(e)), - None => Err(ErrorKind::HttpError(e).into()) + thread_local!(static EASY: RefCell = RefCell::new(Easy::new())); + EASY.with(|handle| { + let mut handle = handle.borrow_mut(); + + try!(handle.url(&url.to_string()).chain_err(|| "failed to set url")); + try!(handle.follow_location(true).chain_err(|| "failed to set follow redirects")); + + // Take at most 30s to connect + try!(handle.connect_timeout(Duration::new(30, 0)).chain_err(|| "failed to set connect timeout")); + + // Fail if less than 10 bytes are transferred every 30 seconds + try!(handle.low_speed_limit(10).chain_err(|| "failed to set low speed limit")); + try!(handle.low_speed_time(Duration::new(30, 0)).chain_err(|| "failed to set low speed time")); + + { + let fserr = RefCell::new(None); + let mut transfer = handle.transfer(); + + // Data callback for libcurl which is called with data that's + // downloaded. We just feed it into our hasher and also write it out + // to disk. + try!(transfer.write_function(|data| { + if let Some(ref mut h) = hasher { + h.input(data); + } + notify_handler(Notification::DownloadDataReceived(data.len())); + match file.write_all(data) { + Ok(()) => Ok(data.len()), + Err(e) => { + *fserr.borrow_mut() = Some(e); + Ok(0) + } + } + }).chain_err(|| "failed to set write")); + + // Listen for headers and parse out a `Content-Length` if it comes + // so we know how much we're downloading. + try!(transfer.header_function(|header| { + if let Ok(data) = str::from_utf8(header) { + let prefix = "Content-Length: "; + if data.starts_with(prefix) { + if let Ok(s) = data[prefix.len()..].trim().parse() { + let msg = Notification::DownloadContentLengthReceived(s); + notify_handler(msg); + } + } + } + true + }).chain_err(|| "failed to set header")); + + // If an error happens check to see if we had a filesystem error up + // in `fserr`, but we always want to punt it up. + try!(transfer.perform().or_else(|e| { + match fserr.borrow_mut().take() { + Some(fs) => Err(fs).chain_err(|| ErrorKind::HttpError(e)), + None => Err(ErrorKind::HttpError(e).into()) + } + })); } - })); - // If we didn't get a 200 or 0 ("OK" for files) then return an error - let code = try!(handle.response_code().chain_err(|| "failed to get response code")); - if code != 200 && code != 0 { - return Err(ErrorKind::HttpStatus(code).into()); - } + // If we didn't get a 200 or 0 ("OK" for files) then return an error + let code = try!(handle.response_code().chain_err(|| "failed to get response code")); + if code != 200 && code != 0 { + return Err(ErrorKind::HttpStatus(code).into()); + } - // If everything worked out, put our handle back (with a reset to 'static) - // and then send off a notification for the completed download. - EASY.with(|e| { - *e.borrow_mut() = Some(handle.reset_lifetime()); - }); - notify_handler.call(Notification::DownloadFinished); - Ok(()) + notify_handler(Notification::DownloadFinished); + Ok(()) + }) } pub fn symlink_dir(src: &Path, dest: &Path) -> io::Result<()> { diff --git a/src/rustup-utils/src/utils.rs b/src/rustup-utils/src/utils.rs index 5ca392211b..943b17ccc8 100644 --- a/src/rustup-utils/src/utils.rs +++ b/src/rustup-utils/src/utils.rs @@ -6,7 +6,7 @@ use std::process::Command; use std::ffi::OsString; use std::env; use sha2::Sha256; -use notifications::{Notification, NotifyHandler}; +use notifications::{Notification}; use raw; #[cfg(windows)] use winapi::DWORD; @@ -20,10 +20,10 @@ pub use raw::{is_directory, is_file, path_exists, if_not_empty, random_string, p pub fn ensure_dir_exists(name: &'static str, path: &Path, - notify_handler: NotifyHandler) + notify_handler: &Fn(Notification)) -> Result { raw::ensure_dir_exists(path, - |p| notify_handler.call(Notification::CreatingDirectory(name, p))) + |p| notify_handler(Notification::CreatingDirectory(name, p))) .chain_err(|| { ErrorKind::CreatingDirectory { name: name, @@ -123,9 +123,9 @@ pub fn match_file Option>(name: &'static str, }) } -pub fn canonicalize_path(path: &Path, notify_handler: NotifyHandler) -> PathBuf { +pub fn canonicalize_path(path: &Path, notify_handler: &Fn(Notification)) -> PathBuf { fs::canonicalize(path).unwrap_or_else(|_| { - notify_handler.call(Notification::NoCanonicalPath(path)); + notify_handler(Notification::NoCanonicalPath(path)); PathBuf::from(path) }) } @@ -142,9 +142,9 @@ pub fn tee_file(name: &'static str, path: &Path, w: &mut W) -> Res pub fn download_file(url: &Url, path: &Path, hasher: Option<&mut Sha256>, - notify_handler: NotifyHandler) + notify_handler: &Fn(Notification)) -> Result<()> { - notify_handler.call(Notification::DownloadingFile(url, path)); + notify_handler(Notification::DownloadingFile(url, path)); match raw::download_file(url, path, hasher, notify_handler) { Ok(_) => Ok(()), Err(Error(ErrorKind::HttpError(e), d)) => { @@ -200,8 +200,8 @@ pub fn assert_is_directory(path: &Path) -> Result<()> { } } -pub fn symlink_dir(src: &Path, dest: &Path, notify_handler: NotifyHandler) -> Result<()> { - notify_handler.call(Notification::LinkingDirectory(src, dest)); +pub fn symlink_dir(src: &Path, dest: &Path, notify_handler: &Fn(Notification)) -> Result<()> { + notify_handler(Notification::LinkingDirectory(src, dest)); raw::symlink_dir(src, dest).chain_err(|| { ErrorKind::LinkingDirectory { src: PathBuf::from(src), @@ -219,8 +219,8 @@ pub fn hardlink_file(src: &Path, dest: &Path) -> Result<()> { }) } -pub fn copy_dir(src: &Path, dest: &Path, notify_handler: NotifyHandler) -> Result<()> { - notify_handler.call(Notification::CopyingDirectory(src, dest)); +pub fn copy_dir(src: &Path, dest: &Path, notify_handler: &Fn(Notification)) -> Result<()> { + notify_handler(Notification::CopyingDirectory(src, dest)); raw::copy_dir(src, dest).chain_err(|| { ErrorKind::CopyingDirectory { src: PathBuf::from(src), @@ -240,8 +240,8 @@ pub fn copy_file(src: &Path, dest: &Path) -> Result<()> { .map(|_| ()) } -pub fn remove_dir(name: &'static str, path: &Path, notify_handler: NotifyHandler) -> Result<()> { - notify_handler.call(Notification::RemovingDirectory(name, path)); +pub fn remove_dir(name: &'static str, path: &Path, notify_handler: &Fn(Notification)) -> Result<()> { + notify_handler(Notification::RemovingDirectory(name, path)); raw::remove_dir(path).chain_err(|| { ErrorKind::RemovingDirectory { name: name, diff --git a/src/rustup/command.rs b/src/rustup/command.rs index 4d280cb8b6..bbd4cd3c8b 100644 --- a/src/rustup/command.rs +++ b/src/rustup/command.rs @@ -101,7 +101,7 @@ fn telemetry_rustc>(mut cmd: Command, args: &[S], cfg: &Cfg) -> errors: e }; let _ = t.log_telemetry(te).map_err(|xe| { - cfg.notify_handler.call(Notification::TelemetryCleanupError(&xe)); + (cfg.notify_handler)(Notification::TelemetryCleanupError(&xe)); }); process::exit(exit_code); @@ -113,7 +113,7 @@ fn telemetry_rustc>(mut cmd: Command, args: &[S], cfg: &Cfg) -> errors: None }; let _ = t.log_telemetry(te).map_err(|xe| { - cfg.notify_handler.call(Notification::TelemetryCleanupError(&xe)); + (cfg.notify_handler)(Notification::TelemetryCleanupError(&xe)); }); Err(e).chain_err(|| rustup_utils::ErrorKind::RunningCommand { diff --git a/src/rustup/config.rs b/src/rustup/config.rs index 6bab31bb8b..9ecc35ba94 100644 --- a/src/rustup/config.rs +++ b/src/rustup/config.rs @@ -4,6 +4,7 @@ use std::env; use std::io; use std::process::Command; use std::fmt::{self, Display}; +use std::sync::Arc; use errors::*; use notifications::*; @@ -32,7 +33,6 @@ impl Display for OverrideReason { } } -#[derive(Debug)] pub struct Cfg { pub multirust_dir: PathBuf, pub settings_file: SettingsFile, @@ -42,15 +42,16 @@ pub struct Cfg { pub gpg_key: Cow<'static, str>, pub env_override: Option, pub dist_root_url: Cow<'static, str>, - pub notify_handler: SharedNotifyHandler, + pub notify_handler: Arc, } impl Cfg { - pub fn from_env(notify_handler: SharedNotifyHandler) -> Result { + pub fn from_env(notify_handler: Arc) -> Result { // Set up the multirust home directory let multirust_dir = try!(utils::multirust_home()); - try!(utils::ensure_dir_exists("home", &multirust_dir, ntfy!(¬ify_handler))); + try!(utils::ensure_dir_exists("home", &multirust_dir, + &|n| notify_handler(n.into()))); let settings_file = SettingsFile::new(multirust_dir.join("settings.toml")); // Convert from old settings format if necessary @@ -61,8 +62,8 @@ impl Cfg { let notify_clone = notify_handler.clone(); let temp_cfg = temp::Cfg::new(multirust_dir.join("tmp"), - shared_ntfy!(move |n: temp::Notification| { - notify_clone.call(Notification::Temp(n)); + Box::new(move |n| { + (notify_clone)(n.into()) })); // GPG key @@ -101,7 +102,7 @@ impl Cfg { s.default_toolchain = Some(toolchain.to_owned()); Ok(()) })); - self.notify_handler.call(Notification::SetDefaultToolchain(toolchain)); + (self.notify_handler)(Notification::SetDefaultToolchain(toolchain)); Ok(()) } @@ -109,7 +110,7 @@ impl Cfg { if create_parent { try!(utils::ensure_dir_exists("toolchains", &self.toolchains_dir, - ntfy!(&self.notify_handler))); + &|n| (self.notify_handler)(n.into()))); } Toolchain::from(self, name) @@ -125,7 +126,7 @@ impl Cfg { if create_parent { try!(utils::ensure_dir_exists("update-hash", &self.update_hash_dir, - ntfy!(&self.notify_handler))); + &|n| (self.notify_handler)(n.into()))); } Ok(self.update_hash_dir.join(toolchain)) @@ -145,25 +146,24 @@ impl Cfg { let current_version = try!(self.settings_file.with(|s| Ok(s.version.clone()))); if current_version == DEFAULT_METADATA_VERSION { - self.notify_handler - .call(Notification::MetadataUpgradeNotNeeded(¤t_version)); + (self.notify_handler) + (Notification::MetadataUpgradeNotNeeded(¤t_version)); return Ok(()); } - self.notify_handler - .call(Notification::UpgradingMetadata(¤t_version, DEFAULT_METADATA_VERSION)); + (self.notify_handler) + (Notification::UpgradingMetadata(¤t_version, DEFAULT_METADATA_VERSION)); match &*current_version { "2" => { // The toolchain installation format changed. Just delete them all. - self.notify_handler - .call(Notification::UpgradeRemovesToolchains); + (self.notify_handler)(Notification::UpgradeRemovesToolchains); let dirs = try!(utils::read_dir("toolchains", &self.toolchains_dir)); for dir in dirs { let dir = try!(dir.chain_err(|| ErrorKind::UpgradeIoError)); try!(utils::remove_dir("toolchain", &dir.path(), - ::rustup_utils::NotifyHandler::some(&self.notify_handler))); + &|n| (self.notify_handler)(n.into()))); } // Also delete the update hashes @@ -184,7 +184,8 @@ impl Cfg { pub fn delete_data(&self) -> Result<()> { if utils::path_exists(&self.multirust_dir) { - Ok(try!(utils::remove_dir("home", &self.multirust_dir, ntfy!(&self.notify_handler)))) + Ok(try!(utils::remove_dir("home", &self.multirust_dir, + &|n| (self.notify_handler)(n.into())))) } else { Ok(()) } @@ -264,7 +265,7 @@ impl Cfg { let t = t.and_then(|t| { let t = t.install_from_dist(); if let Err(ref e) = t { - self.notify_handler.call(Notification::NonFatalError(e)); + (self.notify_handler)(Notification::NonFatalError(e)); } t }); @@ -279,7 +280,7 @@ impl Cfg { try!(utils::assert_is_directory(&self.multirust_dir)); self.settings_file.with(|s| { - self.notify_handler.call(Notification::ReadMetadataVersion(&s.version)); + (self.notify_handler)(Notification::ReadMetadataVersion(&s.version)); if s.version == DEFAULT_METADATA_VERSION { Ok(()) } else { @@ -388,9 +389,9 @@ impl Cfg { })); let _ = utils::ensure_dir_exists("telemetry", &self.multirust_dir.join("telemetry"), - ntfy!(&NotifyHandler::none())); + &|_| ()); - self.notify_handler.call(Notification::SetTelemetry("on")); + (self.notify_handler)(Notification::SetTelemetry("on")); Ok(()) } @@ -401,7 +402,7 @@ impl Cfg { Ok(()) })); - self.notify_handler.call(Notification::SetTelemetry("off")); + (self.notify_handler)(Notification::SetTelemetry("off")); Ok(()) } diff --git a/src/rustup/install.rs b/src/rustup/install.rs index 5a3c237ce0..1990d56728 100644 --- a/src/rustup/install.rs +++ b/src/rustup/install.rs @@ -1,7 +1,7 @@ //! Installation and upgrade of both distribution-managed and local //! toolchains -use rustup_dist::{NotifyHandler, Notification}; +use rustup_dist::{Notification}; use rustup_dist::prefix::InstallPrefix; use rustup_utils::utils; use rustup_dist::temp; @@ -10,7 +10,7 @@ use rustup_dist::component::{Components, TarGzPackage, Transaction, Package}; use errors::Result; use std::path::Path; -#[derive(Debug, Copy, Clone)] +#[derive(Copy, Clone)] pub enum InstallMethod<'a> { Copy(&'a Path), Link(&'a Path), @@ -19,7 +19,7 @@ pub enum InstallMethod<'a> { } impl<'a> InstallMethod<'a> { - pub fn run(self, path: &Path, notify_handler: NotifyHandler) -> Result { + pub fn run(self, path: &Path, notify_handler: &Fn(Notification)) -> Result { if path.exists() { // Don't uninstall first for Dist method match self { @@ -33,11 +33,11 @@ impl<'a> InstallMethod<'a> { match self { InstallMethod::Copy(src) => { - try!(utils::copy_dir(src, path, ntfy!(¬ify_handler))); + try!(utils::copy_dir(src, path, &|n| notify_handler(n.into()))); Ok(true) } InstallMethod::Link(src) => { - try!(utils::symlink_dir(src, &path, ntfy!(¬ify_handler))); + try!(utils::symlink_dir(src, &path, &|n| notify_handler(n.into()))); Ok(true) } InstallMethod::Installer(src, temp_cfg) => { @@ -68,8 +68,8 @@ impl<'a> InstallMethod<'a> { } fn tar_gz(src: &Path, path: &Path, temp_cfg: &temp::Cfg, - notify_handler: NotifyHandler) -> Result<()> { - notify_handler.call(Notification::Extracting(src, path)); + notify_handler: &Fn(Notification)) -> Result<()> { + notify_handler(Notification::Extracting(src, path)); let prefix = InstallPrefix::from(path.to_owned()); let installation = try!(Components::open(prefix.clone())); @@ -87,6 +87,7 @@ impl<'a> InstallMethod<'a> { } } -pub fn uninstall(path: &Path, notify_handler: NotifyHandler) -> Result<()> { - Ok(try!(utils::remove_dir("install", path, ntfy!(¬ify_handler)))) +pub fn uninstall(path: &Path, notify_handler: &Fn(Notification)) -> Result<()> { + Ok(try!(utils::remove_dir("install", path, + &|n| notify_handler(n.into())))) } diff --git a/src/rustup/notifications.rs b/src/rustup/notifications.rs index 47f8f67b0a..2b06ccfc1f 100644 --- a/src/rustup/notifications.rs +++ b/src/rustup/notifications.rs @@ -5,7 +5,7 @@ use errors::*; use rustup_dist::{self, temp}; use rustup_utils; -use rustup_utils::notify::{self, NotificationLevel, Notifyable}; +use rustup_utils::notify::NotificationLevel; #[derive(Debug)] pub enum Notification<'a> { @@ -37,12 +37,21 @@ pub enum Notification<'a> { TelemetryCleanupError(&'a Error), } -pub type NotifyHandler<'a> = notify::NotifyHandler<'a, for<'b> Notifyable>>; -pub type SharedNotifyHandler = notify::SharedNotifyHandler Notifyable>>; - -extend_notification!(Notification: rustup_dist::Notification, n => Notification::Install(n)); -extend_notification!(Notification: rustup_utils::Notification, n => Notification::Utils(n)); -extend_notification!(Notification: temp::Notification, n => Notification::Temp(n)); +impl<'a> From> for Notification<'a> { + fn from(n: rustup_dist::Notification<'a>) -> Notification<'a> { + Notification::Install(n) + } +} +impl<'a> From> for Notification<'a> { + fn from(n: rustup_utils::Notification<'a>) -> Notification<'a> { + Notification::Utils(n) + } +} +impl<'a> From> for Notification<'a> { + fn from(n: temp::Notification<'a>) -> Notification<'a> { + Notification::Temp(n) + } +} impl<'a> Notification<'a> { pub fn level(&self) -> NotificationLevel { @@ -58,7 +67,7 @@ impl<'a> Notification<'a> { UpdatingToolchain(_) | ReadMetadataVersion(_) | InstalledToolchain(_) | - UpdateHashMatches | + UpdateHashMatches | TelemetryCleanupError(_) => NotificationLevel::Verbose, SetDefaultToolchain(_) | SetOverrideToolchain(_, _) | diff --git a/src/rustup/settings.rs b/src/rustup/settings.rs index eca7e0f01a..5398043d57 100644 --- a/src/rustup/settings.rs +++ b/src/rustup/settings.rs @@ -143,26 +143,26 @@ impl Default for Settings { } impl Settings { - fn path_to_key(path: &Path, notify_handler: NotifyHandler) -> String { - utils::canonicalize_path(path, ntfy!(¬ify_handler)) + fn path_to_key(path: &Path, notify_handler: &Fn(Notification)) -> String { + utils::canonicalize_path(path, &|n| notify_handler(n.into())) .display() .to_string() } - pub fn remove_override(&mut self, path: &Path, notify_handler: NotifyHandler) -> bool { + pub fn remove_override(&mut self, path: &Path, notify_handler: &Fn(Notification)) -> bool { let key = Self::path_to_key(path, notify_handler); self.overrides.remove(&key).is_some() } - pub fn add_override(&mut self, path: &Path, toolchain: String, notify_handler: NotifyHandler) { + pub fn add_override(&mut self, path: &Path, toolchain: String, notify_handler: &Fn(Notification)) { let key = Self::path_to_key(path, notify_handler); - notify_handler.call(Notification::SetOverrideToolchain(path, &toolchain)); + notify_handler(Notification::SetOverrideToolchain(path, &toolchain)); self.overrides.insert(key, toolchain); } - pub fn find_override(&self, dir_unresolved: &Path, notify_handler: NotifyHandler) + pub fn find_override(&self, dir_unresolved: &Path, notify_handler: &Fn(Notification)) -> Option<(String, PathBuf)> { - let dir = utils::canonicalize_path(dir_unresolved, ntfy!(¬ify_handler)); + let dir = utils::canonicalize_path(dir_unresolved, &|n| notify_handler(n.into())); let mut maybe_path = Some(&*dir); while let Some(path) = maybe_path { let key = Self::path_to_key(path, notify_handler); diff --git a/src/rustup/toolchain.rs b/src/rustup/toolchain.rs index 871a7ec1f3..7ec8c6b81b 100644 --- a/src/rustup/toolchain.rs +++ b/src/rustup/toolchain.rs @@ -1,5 +1,6 @@ use errors::*; use notifications::*; +use rustup_dist; use rustup_dist::dist; use rustup_utils::utils; use rustup_dist::prefix::InstallPrefix; @@ -19,12 +20,12 @@ use std::env; use url::Url; -#[derive(Debug)] pub struct Toolchain<'a> { cfg: &'a Cfg, name: String, path: PathBuf, telemetry: telemetry::Telemetry, + dist_handler: Box, } /// Used by the list_component function @@ -49,6 +50,9 @@ impl<'a> Toolchain<'a> { name: resolved_name, path: path.clone(), telemetry: Telemetry::new(cfg.multirust_dir.join("telemetry")), + dist_handler: Box::new(move |n| { + (cfg.notify_handler)(n.into()) + }) }) } pub fn name(&self) -> &str { @@ -68,18 +72,18 @@ impl<'a> Toolchain<'a> { } pub fn remove(&self) -> Result<()> { if self.exists() { - self.cfg.notify_handler.call(Notification::UninstallingToolchain(&self.name)); + (self.cfg.notify_handler)(Notification::UninstallingToolchain(&self.name)); } else { - self.cfg.notify_handler.call(Notification::ToolchainNotInstalled(&self.name)); + (self.cfg.notify_handler)(Notification::ToolchainNotInstalled(&self.name)); return Ok(()); } if let Some(update_hash) = try!(self.update_hash()) { try!(utils::remove_file("update hash", &update_hash)); } - let handler = self.cfg.notify_handler.as_ref(); - let result = install::uninstall(&self.path, ntfy!(&handler)); + let result = install::uninstall(&self.path, + &|n| (self.cfg.notify_handler)(n.into())); if !self.exists() { - self.cfg.notify_handler.call(Notification::UninstalledToolchain(&self.name)); + (self.cfg.notify_handler)(Notification::UninstalledToolchain(&self.name)); } Ok(try!(result)) } @@ -87,20 +91,19 @@ impl<'a> Toolchain<'a> { assert!(self.is_valid_install_method(install_method)); let exists = self.exists(); if exists { - self.cfg.notify_handler.call(Notification::UpdatingToolchain(&self.name)); + (self.cfg.notify_handler)(Notification::UpdatingToolchain(&self.name)); } else { - self.cfg.notify_handler.call(Notification::InstallingToolchain(&self.name)); + (self.cfg.notify_handler)(Notification::InstallingToolchain(&self.name)); } - self.cfg - .notify_handler - .call(Notification::ToolchainDirectory(&self.path, &self.name)); - let handler = self.cfg.notify_handler.as_ref(); - let updated = try!(install_method.run(&self.path, ntfy!(&handler))); + (self.cfg.notify_handler) + (Notification::ToolchainDirectory(&self.path, &self.name)); + let updated = try!(install_method.run(&self.path, + &|n| (self.cfg.notify_handler)(n.into()))); if !updated { - self.cfg.notify_handler.call(Notification::UpdateHashMatches); + (self.cfg.notify_handler)(Notification::UpdateHashMatches); } else { - self.cfg.notify_handler.call(Notification::InstalledToolchain(&self.name)); + (self.cfg.notify_handler)(Notification::InstalledToolchain(&self.name)); } let status = match (updated, exists) { @@ -114,11 +117,11 @@ impl<'a> Toolchain<'a> { } fn install_if_not_installed(&self, install_method: InstallMethod) -> Result { assert!(self.is_valid_install_method(install_method)); - self.cfg.notify_handler.call(Notification::LookingForToolchain(&self.name)); + (self.cfg.notify_handler)(Notification::LookingForToolchain(&self.name)); if !self.exists() { Ok(try!(self.install(install_method))) } else { - self.cfg.notify_handler.call(Notification::UsingExistingToolchain(&self.name)); + (self.cfg.notify_handler)(Notification::UsingExistingToolchain(&self.name)); Ok(UpdateStatus::Unchanged) } } @@ -138,11 +141,11 @@ impl<'a> Toolchain<'a> { } } - fn download_cfg(&self) -> dist::DownloadCfg { + fn download_cfg<'b>(&'b self) -> dist::DownloadCfg<'b> { dist::DownloadCfg { dist_root: &self.cfg.dist_root_url, temp_cfg: &self.cfg.temp_cfg, - notify_handler: ntfy!(&self.cfg.notify_handler), + notify_handler: &*self.dist_handler, } } @@ -170,7 +173,7 @@ impl<'a> Toolchain<'a> { match self.telemetry.log_telemetry(te) { Ok(_) => Ok(us), Err(e) => { - self.cfg.notify_handler.call(Notification::TelemetryCleanupError(&e)); + (self.cfg.notify_handler)(Notification::TelemetryCleanupError(&e)); Ok(us) } } @@ -179,7 +182,7 @@ impl<'a> Toolchain<'a> { let te = TelemetryEvent::ToolchainUpdate { toolchain: self.name().to_string() , success: true }; let _ = self.telemetry.log_telemetry(te).map_err(|xe| { - self.cfg.notify_handler.call(Notification::TelemetryCleanupError(&xe)); + (self.cfg.notify_handler)(Notification::TelemetryCleanupError(&xe)); }); Err(e) } @@ -239,7 +242,7 @@ impl<'a> Toolchain<'a> { try!(utils::download_file(&url, &local_installer, None, - ntfy!(&self.cfg.notify_handler))); + &|n| (self.cfg.notify_handler)(n.into()))); try!(self.install(InstallMethod::Installer(&local_installer, &self.cfg.temp_cfg))); } else { // If installer is a filename @@ -418,7 +421,7 @@ impl<'a> Toolchain<'a> { match self.telemetry.log_telemetry(te) { Ok(_) => Ok(()), Err(e) => { - self.cfg.notify_handler.call(Notification::TelemetryCleanupError(&e)); + (self.cfg.notify_handler)(Notification::TelemetryCleanupError(&e)); Ok(()) } } @@ -428,7 +431,7 @@ impl<'a> Toolchain<'a> { success: false }; let _ = self.telemetry.log_telemetry(te).map_err(|xe| { - self.cfg.notify_handler.call(Notification::TelemetryCleanupError(&xe)); + (self.cfg.notify_handler)(Notification::TelemetryCleanupError(&xe)); }); Err(e) }