diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 16fe87b06e..11069edd79 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -192,7 +192,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/rustup-init.sh b/rustup-init.sh index c8e2c4886b..a49ab3b272 100755 --- a/rustup-init.sh +++ b/rustup-init.sh @@ -32,9 +32,9 @@ main() { local _ext="" case "$_arch" in - *windows*) - _ext=".exe" - ;; + *windows*) + _ext=".exe" + ;; esac local _url="$RUSTUP_UPDATE_ROOT/$_arch/rustup-init$_ext" @@ -48,9 +48,9 @@ main() { ensure curl -sSfL "$_url" -o "$_file" ensure chmod u+x "$_file" if [ ! -x "$_file" ]; then - echo "Cannot execute $_file (likely because of mounting /tmp as noexec)." - echo "Please copy the file to a location where you can execute binaries and run ./rustup-init$_ext." - exit 1 + echo "Cannot execute $_file (likely because of mounting /tmp as noexec)." + echo "Please copy the file to a location where you can execute binaries and run ./rustup-init$_ext." + exit 1 fi # check if we have to use /dev/tty to prompt the user @@ -149,9 +149,9 @@ get_architecture() { local _ostype="${_ostype}eabihf" ;; - aarch64) - local _cputype=aarch64 - ;; + aarch64) + local _cputype=aarch64 + ;; x86_64 | x86-64 | x64 | amd64) local _cputype=x86_64 diff --git a/src/ca-loader/src/sys/macos.rs b/src/ca-loader/src/sys/macos.rs index 469a09c205..dd20fbed96 100644 --- a/src/ca-loader/src/sys/macos.rs +++ b/src/ca-loader/src/sys/macos.rs @@ -20,7 +20,7 @@ impl IntoIterator for CertBundle { type IntoIter = CertIter; fn into_iter(self) -> Self::IntoIter { - CertIter { it: Box::new(self.rv.into_iter()) } + CertIter { it: Box::new(self.rv.into_iter()) } } } @@ -28,26 +28,26 @@ impl Iterator for CertIter { type Item = CertItem; fn next(&mut self) -> Option { - if let Some(res) = self.it.next() { - if let Some(ref rref) = res.reference { - match rref { - &Reference::Certificate(ref cert) => return Some(CertItem::Blob(cert.to_der())), - _ => () - } - } - return self.next(); - } - None + if let Some(res) = self.it.next() { + if let Some(ref rref) = res.reference { + match rref { + &Reference::Certificate(ref cert) => return Some(CertItem::Blob(cert.to_der())), + _ => () + } + } + return self.next(); + } + None } } impl CertBundle { pub fn new() -> Result { - let root_kc = try!(SecKeychain::open("/System/Library/Keychains/SystemRootCertificates.keychain").map_err(|_| ())); - let chains = [ root_kc ]; - let mut opts = ItemSearchOptions::new(); - let opts = opts.keychains(&chains).class(ItemClass::Certificate).load_refs(true).limit(i32::MAX as i64); - let rv = try!(opts.search().map_err(|_| ())); - Ok(CertBundle { rv: rv }) + let root_kc = try!(SecKeychain::open("/System/Library/Keychains/SystemRootCertificates.keychain").map_err(|_| ())); + let chains = [ root_kc ]; + let mut opts = ItemSearchOptions::new(); + let opts = opts.keychains(&chains).class(ItemClass::Certificate).load_refs(true).limit(i32::MAX as i64); + let rv = try!(opts.search().map_err(|_| ())); + Ok(CertBundle { rv: rv }) } } diff --git a/src/ca-loader/src/sys/mod.rs b/src/ca-loader/src/sys/mod.rs index 1bf5bdd0e7..3a442a70a4 100644 --- a/src/ca-loader/src/sys/mod.rs +++ b/src/ca-loader/src/sys/mod.rs @@ -1,14 +1,14 @@ cfg_if! { if #[cfg(windows)] { - mod windows; - pub use self::windows::CertBundle; + mod windows; + pub use self::windows::CertBundle; } else if #[cfg(target_os = "macos")] { - mod macos; - pub use self::macos::CertBundle; + mod macos; + pub use self::macos::CertBundle; } else if #[cfg(unix)] { - mod unix; - pub use self::unix::CertBundle; + mod unix; + pub use self::unix::CertBundle; } else { - // Unknown + // Unknown } } diff --git a/src/ca-loader/src/sys/unix.rs b/src/ca-loader/src/sys/unix.rs index d974bc1e06..658264e6aa 100644 --- a/src/ca-loader/src/sys/unix.rs +++ b/src/ca-loader/src/sys/unix.rs @@ -8,78 +8,78 @@ use super::super::CertItem; cfg_if! { if #[cfg(any(target_os = "android", target_os = "solaris"))] { - use std::fs::{read_dir, ReadDir}; - - pub struct CertBundle(&'static str); - - pub struct CertIter(&'static str, Option); - - impl IntoIterator for CertBundle { - type Item = CertItem; - type IntoIter = CertIter; - - fn into_iter(self) -> Self::IntoIter { - if let Ok(dir) = read_dir(self.0) { - CertIter(self.0, Some(dir)) - } else { - CertIter(self.0, None) - } - } - } - - impl Iterator for CertIter { - type Item = CertItem; - - fn next(&mut self) -> Option { - match self.1 { - None => return None, - Some(ref mut dir) => { - match dir.next() { - None => return None, - Some(Err(_)) => return None, - Some(Ok(ref de)) => { - if let Ok(ftyp) = de.file_type() { - if !ftyp.is_dir() { - if let Some(s) = de.file_name().to_str() { - let mut full_name = String::from(self.0); - full_name.push('/'); - full_name.push_str(s); - return Some(CertItem::File(full_name)); - } - } - } - } - } - } - } - self.next() - } - } - - impl CertBundle { - pub fn new() -> Result { - Ok(CertBundle(try!(sys_path()))) - } - } + use std::fs::{read_dir, ReadDir}; + + pub struct CertBundle(&'static str); + + pub struct CertIter(&'static str, Option); + + impl IntoIterator for CertBundle { + type Item = CertItem; + type IntoIter = CertIter; + + fn into_iter(self) -> Self::IntoIter { + if let Ok(dir) = read_dir(self.0) { + CertIter(self.0, Some(dir)) + } else { + CertIter(self.0, None) + } + } + } + + impl Iterator for CertIter { + type Item = CertItem; + + fn next(&mut self) -> Option { + match self.1 { + None => return None, + Some(ref mut dir) => { + match dir.next() { + None => return None, + Some(Err(_)) => return None, + Some(Ok(ref de)) => { + if let Ok(ftyp) = de.file_type() { + if !ftyp.is_dir() { + if let Some(s) = de.file_name().to_str() { + let mut full_name = String::from(self.0); + full_name.push('/'); + full_name.push_str(s); + return Some(CertItem::File(full_name)); + } + } + } + } + } + } + } + self.next() + } + } + + impl CertBundle { + pub fn new() -> Result { + Ok(CertBundle(try!(sys_path()))) + } + } } else { - use std::option; + use std::option; - pub struct CertBundle(Option); + pub struct CertBundle(Option); - impl IntoIterator for CertBundle { - type Item = CertItem; - type IntoIter = option::IntoIter; + impl IntoIterator for CertBundle { + type Item = CertItem; + type IntoIter = option::IntoIter; - fn into_iter(self) -> Self::IntoIter { - self.0.into_iter() - } - } + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } + } - impl CertBundle { - pub fn new() -> Result { - Ok(CertBundle(Some(CertItem::File(try!(sys_path()).to_string())))) - } - } + impl CertBundle { + pub fn new() -> Result { + Ok(CertBundle(Some(CertItem::File(try!(sys_path()).to_string())))) + } + } } } @@ -91,50 +91,50 @@ pub fn sys_path() -> Result<&'static str, ()> { // the contents of struct utsname on input, and will fill it with // properly NUL-terminated strings on successful return. unsafe { - let mut uts = mem::uninitialized::(); - - if libc::uname(&mut uts) < 0 { - return Err(()); - } - let sysname = try!(CStr::from_ptr(uts.sysname.as_ptr()).to_str().map_err(|_| ())); - let release = try!(CStr::from_ptr(uts.release.as_ptr()).to_str().map_err(|_| ())); - let path = match sysname { - "FreeBSD" | "OpenBSD" => "/etc/ssl/cert.pem", - "NetBSD" => "/etc/ssl/certs", - "Linux" => linux_distro_guess_ca_path(), - "SunOS" => { - let major = release.split('.').take(1).collect::(); - let major = major.parse::().unwrap_or(5); - let minor = release.split('.').skip(1).take(1).collect::(); - let minor = minor.parse::().unwrap_or(10); - if major < 5 || (major == 5 && minor < 11) { - "/opt/csw/share/cacertificates/mozilla" - } else { - "/etc/certs/CA" - } - } - _ => unimplemented!() - }; - Ok(path) + let mut uts = mem::uninitialized::(); + + if libc::uname(&mut uts) < 0 { + return Err(()); + } + let sysname = try!(CStr::from_ptr(uts.sysname.as_ptr()).to_str().map_err(|_| ())); + let release = try!(CStr::from_ptr(uts.release.as_ptr()).to_str().map_err(|_| ())); + let path = match sysname { + "FreeBSD" | "OpenBSD" => "/etc/ssl/cert.pem", + "NetBSD" => "/etc/ssl/certs", + "Linux" => linux_distro_guess_ca_path(), + "SunOS" => { + let major = release.split('.').take(1).collect::(); + let major = major.parse::().unwrap_or(5); + let minor = release.split('.').skip(1).take(1).collect::(); + let minor = minor.parse::().unwrap_or(10); + if major < 5 || (major == 5 && minor < 11) { + "/opt/csw/share/cacertificates/mozilla" + } else { + "/etc/certs/CA" + } + } + _ => unimplemented!() + }; + Ok(path) } } cfg_if! { if #[cfg(target_os = "android")] { - fn linux_distro_guess_ca_path() -> &'static str { - "/system/etc/security/cacerts" - } + fn linux_distro_guess_ca_path() -> &'static str { + "/system/etc/security/cacerts" + } } else { - fn linux_distro_guess_ca_path() -> &'static str { - if let Ok(_debian) = fs::metadata("/etc/debian_version") { - "/etc/ssl/certs/ca-certificates.crt" - } else if let Ok(_rh) = fs::metadata("/etc/redhat-release") { - "/etc/pki/tls/certs/ca-bundle.crt" - } else if let Ok(_suse) = fs::metadata("/etc/SuSE-release") { - "/etc/ssl/ca-bundle.pem" - } else { // fallback - "/etc/pki/tls/cacert.pem" - } - } + fn linux_distro_guess_ca_path() -> &'static str { + if let Ok(_debian) = fs::metadata("/etc/debian_version") { + "/etc/ssl/certs/ca-certificates.crt" + } else if let Ok(_rh) = fs::metadata("/etc/redhat-release") { + "/etc/pki/tls/certs/ca-bundle.crt" + } else if let Ok(_suse) = fs::metadata("/etc/SuSE-release") { + "/etc/ssl/ca-bundle.pem" + } else { // fallback + "/etc/pki/tls/cacert.pem" + } + } } } diff --git a/src/ca-loader/src/sys/windows.rs b/src/ca-loader/src/sys/windows.rs index e779333867..0adb5b005a 100644 --- a/src/ca-loader/src/sys/windows.rs +++ b/src/ca-loader/src/sys/windows.rs @@ -21,7 +21,7 @@ impl IntoIterator for CertBundle { type IntoIter = CertIter; fn into_iter(self) -> Self::IntoIter { - CertIter { bundle: self } + CertIter { bundle: self } } } @@ -29,51 +29,51 @@ impl Iterator for CertIter { type Item = CertItem; fn next(&mut self) -> Option { - if self.bundle.ctx_p.is_null() { - return None; - } - unsafe { - let ctx = *self.bundle.ctx_p; - let enc_slice = from_raw_parts( - ctx.pbCertEncoded as *const u8, - ctx.cbCertEncoded as usize); - let mut blob = Vec::with_capacity(ctx.cbCertEncoded as usize); - blob.extend_from_slice(enc_slice); - self.bundle.ctx_p = crypt32::CertEnumCertificatesInStore( - self.bundle.store, - self.bundle.ctx_p); - Some(CertItem::Blob(blob)) - } + if self.bundle.ctx_p.is_null() { + return None; + } + unsafe { + let ctx = *self.bundle.ctx_p; + let enc_slice = from_raw_parts( + ctx.pbCertEncoded as *const u8, + ctx.cbCertEncoded as usize); + let mut blob = Vec::with_capacity(ctx.cbCertEncoded as usize); + blob.extend_from_slice(enc_slice); + self.bundle.ctx_p = crypt32::CertEnumCertificatesInStore( + self.bundle.store, + self.bundle.ctx_p); + Some(CertItem::Blob(blob)) + } } } impl CertBundle { pub fn new() -> Result { - unsafe { - let store = crypt32::CertOpenSystemStoreA( - 0, - CString::new("Root").unwrap().as_ptr() as winapi::LPCSTR); - if store.is_null() { - return Err(()); - } - let ctx_p = crypt32::CertEnumCertificatesInStore( - store, - ptr::null()); - Ok(CertBundle { - store: store, - ctx_p: ctx_p - }) - } + unsafe { + let store = crypt32::CertOpenSystemStoreA( + 0, + CString::new("Root").unwrap().as_ptr() as winapi::LPCSTR); + if store.is_null() { + return Err(()); + } + let ctx_p = crypt32::CertEnumCertificatesInStore( + store, + ptr::null()); + Ok(CertBundle { + store: store, + ctx_p: ctx_p + }) + } } } impl Drop for CertBundle { fn drop(&mut self) { - unsafe { - if !self.ctx_p.is_null() { - crypt32::CertFreeCertificateContext(self.ctx_p); - } - crypt32::CertCloseStore(self.store, 0); - } + unsafe { + if !self.ctx_p.is_null() { + crypt32::CertFreeCertificateContext(self.ctx_p); + } + crypt32::CertCloseStore(self.store, 0); + } } } diff --git a/src/download/src/lib.rs b/src/download/src/lib.rs index 3cca8a8508..7d53a019e6 100644 --- a/src/download/src/lib.rs +++ b/src/download/src/lib.rs @@ -240,6 +240,7 @@ pub mod hyper { use std::io::{Read, Write}; use std::net::{SocketAddr, Shutdown}; use std::sync::{Arc, Mutex, MutexGuard}; + use std::fmt::Debug; pub fn download(url: &Url, callback: &Fn(Event) -> Result<()>) @@ -254,7 +255,7 @@ pub mod hyper { fn maybe_init_certs() { maybe_init_certs() } } - impl SslClient for NativeSslClient { + impl SslClient for NativeSslClient { type Stream = NativeSslStream; fn wrap_client(&self, stream: T, host: &str) -> HyperResult { @@ -397,7 +398,7 @@ pub mod rustls { } fn global_config() -> Arc { - use ca_loader::{CertBundle, CertItem}; + use ca_loader::{CertBundle, CertItem}; use std::fs::File; use std::io::BufReader; @@ -407,33 +408,33 @@ pub mod rustls { fn init() -> Arc { let mut config = rustls::ClientConfig::new(); - let bundle = CertBundle::new().expect("cannot initialize CA cert bundle"); - let mut added = 0; - let mut invalid = 0; - for cert in bundle { - let (c_added, c_invalid) = match cert { - CertItem::Blob(blob) => match config.root_store.add(&blob) { - Ok(_) => (1, 0), - Err(_) => (0, 1) - }, - CertItem::File(name) => { - if let Ok(cf) = File::open(name) { - let mut reader = BufReader::new(cf); - match config.root_store.add_pem_file(&mut reader) { - Ok(pair) => pair, - Err(_) => (0, 1) - } - } else { - (0, 1) - } - } - }; - added += c_added; - invalid += c_invalid; - } - if added == 0 { - panic!("no CA certs added, {} were invalid", invalid); - } + let bundle = CertBundle::new().expect("cannot initialize CA cert bundle"); + let mut added = 0; + let mut invalid = 0; + for cert in bundle { + let (c_added, c_invalid) = match cert { + CertItem::Blob(blob) => match config.root_store.add(&blob) { + Ok(_) => (1, 0), + Err(_) => (0, 1) + }, + CertItem::File(name) => { + if let Ok(cf) = File::open(name) { + let mut reader = BufReader::new(cf); + match config.root_store.add_pem_file(&mut reader) { + Ok(pair) => pair, + Err(_) => (0, 1) + } + } else { + (0, 1) + } + } + }; + added += c_added; + invalid += c_invalid; + } + if added == 0 { + panic!("no CA certs added, {} were invalid", invalid); + } Arc::new(config) } @@ -493,17 +494,17 @@ pub mod rustls { let (ref mut stream, ref mut tls) = *t; while tls.wants_read() { match tls.read_tls(stream) { - Ok(_) => { - match tls.process_new_packets() { - Ok(_) => (), - Err(e) => return Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e))) - } - while tls.wants_write() { - try!(tls.write_tls(stream)); - } - }, - Err(e) => return Err(e), - } + Ok(_) => { + match tls.process_new_packets() { + Ok(_) => (), + Err(e) => return Err(io::Error::new(io::ErrorKind::Other, format!("{:?}", e))) + } + while tls.wants_write() { + try!(tls.write_tls(stream)); + } + }, + Err(e) => return Err(e), + } } tls.read(buf) diff --git a/src/rustup-cli/common.rs b/src/rustup-cli/common.rs index de8a2b78fc..57a62acd61 100644 --- a/src/rustup-cli/common.rs +++ b/src/rustup-cli/common.rs @@ -242,14 +242,20 @@ pub fn rustc_version(toolchain: &Toolchain) -> String { } pub fn list_targets(toolchain: &Toolchain) -> Result<()> { + let mut t = term2::stdout(); for component in try!(toolchain.list_components()) { if component.component.pkg == "rust-std" { + let target = component.component.target.as_ref().expect("rust-std should have a target"); if component.required { - println!("{} (default)", component.component.target); + let _ = t.attr(term2::Attr::Bold); + let _ = writeln!(t, "{} (default)", target); + let _ = t.reset(); } else if component.installed { - println!("{} (installed)", component.component.target); + let _ = t.attr(term2::Attr::Bold); + let _ = writeln!(t, "{} (installed)", target); + let _ = t.reset(); } else if component.available { - println!("{}", component.component.target); + let _ = writeln!(t, "{}", target); } } } @@ -257,6 +263,26 @@ pub fn list_targets(toolchain: &Toolchain) -> Result<()> { Ok(()) } +pub fn list_components(toolchain: &Toolchain) -> Result<()> { + let mut t = term2::stdout(); + for component in try!(toolchain.list_components()) { + let name = component.component.name(); + if component.required { + let _ = t.attr(term2::Attr::Bold); + let _ = writeln!(t, "{} (default)", name); + let _ = t.reset(); + } else if component.installed { + let _ = t.attr(term2::Attr::Bold); + let _ = writeln!(t, "{} (installed)", name); + let _ = t.reset(); + } else if component.available { + let _ = writeln!(t, "{}", name); + } + } + + Ok(()) +} + pub fn list_toolchains(cfg: &Cfg) -> Result<()> { let toolchains = try!(cfg.list_toolchains()); diff --git a/src/rustup-cli/rustup_mode.rs b/src/rustup-cli/rustup_mode.rs index 1de578f447..4402b588f4 100644 --- a/src/rustup-cli/rustup_mode.rs +++ b/src/rustup-cli/rustup_mode.rs @@ -56,6 +56,14 @@ pub fn main() -> Result<()> { (_, _) => unreachable!(), } } + ("component", Some(c)) => { + match c.subcommand() { + ("list", Some(m)) => try!(component_list(cfg, m)), + ("add", Some(m)) => try!(component_add(cfg, m)), + ("remove", Some(m)) => try!(component_remove(cfg, m)), + (_, _) => unreachable!(), + } + } ("override", Some(c)) => { match c.subcommand() { ("list", Some(_)) => try!(common::list_overrides(cfg)), @@ -206,6 +214,36 @@ pub fn cli() -> App<'static, 'static> { .arg(Arg::with_name("toolchain") .long("toolchain") .takes_value(true)))) + .subcommand(SubCommand::with_name("component") + .about("Modify a toolchain's installed components") + .setting(AppSettings::VersionlessSubcommands) + .setting(AppSettings::DeriveDisplayOrder) + .setting(AppSettings::SubcommandRequiredElseHelp) + .subcommand(SubCommand::with_name("list") + .about("List installed and available components") + .arg(Arg::with_name("toolchain") + .long("toolchain") + .takes_value(true))) + .subcommand(SubCommand::with_name("add") + .about("Add a component to a Rust toolchain") + .arg(Arg::with_name("component") + .required(true)) + .arg(Arg::with_name("toolchain") + .long("toolchain") + .takes_value(true)) + .arg(Arg::with_name("target") + .long("target") + .takes_value(true))) + .subcommand(SubCommand::with_name("remove") + .about("Remove a component from a Rust toolchain") + .arg(Arg::with_name("component") + .required(true)) + .arg(Arg::with_name("toolchain") + .long("toolchain") + .takes_value(true)) + .arg(Arg::with_name("target") + .long("target") + .takes_value(true)))) .subcommand(SubCommand::with_name("override") .about("Modify directory toolchain overrides") .after_help(OVERRIDE_HELP) @@ -308,7 +346,7 @@ fn maybe_upgrade_data(cfg: &Cfg, m: &ArgMatches) -> Result { fn update_bare_triple_check(cfg: &Cfg, name: &str) -> Result<()> { if let Some(triple) = PartialTargetTriple::from_str(name) { - warn!("(partial) target triple specified instead of toolchain name"); + warn!("(partial) target triple specified instead of toolchain name"); let installed_toolchains = try!(cfg.list_toolchains()); let default = try!(cfg.find_default()); let default_name = default.map(|t| t.name().to_string()) @@ -316,8 +354,8 @@ fn update_bare_triple_check(cfg: &Cfg, name: &str) -> Result<()> { let mut candidates = vec![]; for t in installed_toolchains { if t == default_name { - continue; - } + continue; + } if let Ok(desc) = PartialToolchainDesc::from_str(&t) { fn triple_comp_eq(given: &String, from_desc: Option<&String>) -> bool { from_desc.map_or(false, |s| *s == *given) @@ -332,17 +370,17 @@ fn update_bare_triple_check(cfg: &Cfg, name: &str) -> Result<()> { } } } - match candidates.len() { - 0 => err!("no candidate toolchains found"), - 1 => println!("\nyou may use the following toolchain: {}\n", candidates[0]), - _ => { - println!("\nyou may use one of the following toolchains:"); - for n in candidates.iter() { - println!("{}", n); - } - println!(""); - } - } + match candidates.len() { + 0 => err!("no candidate toolchains found"), + 1 => println!("\nyou may use the following toolchain: {}\n", candidates[0]), + _ => { + println!("\nyou may use one of the following toolchains:"); + for n in candidates.iter() { + println!("{}", n); + } + println!(""); + } + } return Err(ErrorKind::ToolchainNotInstalled(name.to_string()).into()); } Ok(()) @@ -354,17 +392,17 @@ fn default_bare_triple_check(cfg: &Cfg, name: &str) -> Result<()> { let default = try!(cfg.find_default()); let default_name = default.map(|t| t.name().to_string()) .unwrap_or("".into()); - if let Ok(mut desc) = PartialToolchainDesc::from_str(&default_name) { - desc.target = triple; - let maybe_toolchain = format!("{}", desc); - let ref toolchain = try!(cfg.get_toolchain(maybe_toolchain.as_ref(), false)); - if toolchain.name() == default_name { - warn!("(partial) triple '{}' resolves to a toolchain that is already default", name); - } else { - println!("\nyou may use the following toolchain: {}\n", toolchain.name()); - } - return Err(ErrorKind::ToolchainNotInstalled(name.to_string()).into()); - } + if let Ok(mut desc) = PartialToolchainDesc::from_str(&default_name) { + desc.target = triple; + let maybe_toolchain = format!("{}", desc); + let ref toolchain = try!(cfg.get_toolchain(maybe_toolchain.as_ref(), false)); + if toolchain.name() == default_name { + warn!("(partial) triple '{}' resolves to a toolchain that is already default", name); + } else { + println!("\nyou may use the following toolchain: {}\n", toolchain.name()); + } + return Err(ErrorKind::ToolchainNotInstalled(name.to_string()).into()); + } } Ok(()) } @@ -454,13 +492,13 @@ fn show(cfg: &Cfg) -> Result<()> { let active_toolchain = try!(cfg.find_override_toolchain_or_default(cwd)); let active_targets = if let Some((ref t, _)) = active_toolchain { match t.list_components() { - Ok(cs_vec) => cs_vec - .into_iter() - .filter(|c| c.component.pkg == "rust-std") - .filter(|c| c.installed) - .collect(), - Err(_) => vec![] - } + Ok(cs_vec) => cs_vec + .into_iter() + .filter(|c| c.component.pkg == "rust-std") + .filter(|c| c.installed) + .collect(), + Err(_) => vec![] + } } else { vec![] }; @@ -496,7 +534,7 @@ fn show(cfg: &Cfg) -> Result<()> { print_header("installed targets for active toolchain"); } for t in active_targets { - println!("{}", t.component.target); + println!("{}", t.component.target.as_ref().expect("rust-std should have a target")); } if show_headers { println!("") }; } @@ -544,7 +582,7 @@ fn target_add(cfg: &Cfg, m: &ArgMatches) -> Result<()> { let target = m.value_of("target").expect(""); let new_component = Component { pkg: "rust-std".to_string(), - target: TargetTriple::from_str(target), + target: Some(TargetTriple::from_str(target)), }; Ok(try!(toolchain.add_component(new_component))) @@ -555,7 +593,41 @@ fn target_remove(cfg: &Cfg, m: &ArgMatches) -> Result<()> { let target = m.value_of("target").expect(""); let new_component = Component { pkg: "rust-std".to_string(), - target: TargetTriple::from_str(target), + target: Some(TargetTriple::from_str(target)), + }; + + Ok(try!(toolchain.remove_component(new_component))) +} + +fn component_list(cfg: &Cfg, m: &ArgMatches) -> Result<()> { + let toolchain = try!(explicit_or_dir_toolchain(cfg, m)); + + common::list_components(&toolchain) +} + +fn component_add(cfg: &Cfg, m: &ArgMatches) -> Result<()> { + let toolchain = try!(explicit_or_dir_toolchain(cfg, m)); + let target = m.value_of("target").map(TargetTriple::from_str).or_else(|| { + toolchain.desc().as_ref().ok().map(|desc| desc.target.clone()) + }); + + let new_component = Component { + pkg: "rust-std".to_string(), + target: target, + }; + + Ok(try!(toolchain.add_component(new_component))) +} + +fn component_remove(cfg: &Cfg, m: &ArgMatches) -> Result<()> { + let toolchain = try!(explicit_or_dir_toolchain(cfg, m)); + let target = m.value_of("target").map(TargetTriple::from_str).or_else(|| { + toolchain.desc().as_ref().ok().map(|desc| desc.target.clone()) + }); + + let new_component = Component { + pkg: "rust-std".to_string(), + target: target, }; Ok(try!(toolchain.remove_component(new_component))) diff --git a/src/rustup-cli/self_update.rs b/src/rustup-cli/self_update.rs index 0049072713..923776943c 100644 --- a/src/rustup-cli/self_update.rs +++ b/src/rustup-cli/self_update.rs @@ -370,50 +370,50 @@ fn do_pre_install_sanity_checks() -> Result<()> { fn do_anti_sudo_check(no_prompt: bool) -> Result<()> { #[cfg(unix)] pub fn home_mismatch() -> bool { - extern crate libc as c; - - use std::env; - use std::ffi::CStr; - use std::mem; - use std::ops::Deref; - use std::ptr; - - // test runner should set this, nothing else - if env::var("RUSTUP_INIT_SKIP_SUDO_CHECK").as_ref().map(Deref::deref).ok() == Some("yes") { - return false; - } - let mut pwd = unsafe { mem::uninitialized::() }; - let mut pwdp: *mut c::passwd = ptr::null_mut(); - let mut buf = [0u8; 1024]; - let rv = unsafe { c::getpwuid_r(c::geteuid(), &mut pwd, mem::transmute(&mut buf), buf.len(), &mut pwdp) }; - if rv != 0 || pwdp == ptr::null_mut() { - warn!("getpwuid_r: couldn't get user data"); - return false; - } - let pw_dir = unsafe { CStr::from_ptr(pwd.pw_dir) }.to_str().ok(); - let env_home = env::var_os("HOME"); - let env_home = env_home.as_ref().map(Deref::deref); - match (env_home, pw_dir) { - (None, _) | (_, None) => false, - (Some(ref eh), Some(ref pd)) => eh != pd - } + extern crate libc as c; + + use std::env; + use std::ffi::CStr; + use std::mem; + use std::ops::Deref; + use std::ptr; + + // test runner should set this, nothing else + if env::var("RUSTUP_INIT_SKIP_SUDO_CHECK").as_ref().map(Deref::deref).ok() == Some("yes") { + return false; + } + let mut pwd = unsafe { mem::uninitialized::() }; + let mut pwdp: *mut c::passwd = ptr::null_mut(); + let mut buf = [0u8; 1024]; + let rv = unsafe { c::getpwuid_r(c::geteuid(), &mut pwd, mem::transmute(&mut buf), buf.len(), &mut pwdp) }; + if rv != 0 || pwdp == ptr::null_mut() { + warn!("getpwuid_r: couldn't get user data"); + return false; + } + let pw_dir = unsafe { CStr::from_ptr(pwd.pw_dir) }.to_str().ok(); + let env_home = env::var_os("HOME"); + let env_home = env_home.as_ref().map(Deref::deref); + match (env_home, pw_dir) { + (None, _) | (_, None) => false, + (Some(ref eh), Some(ref pd)) => eh != pd + } } #[cfg(not(unix))] pub fn home_mismatch() -> bool { - false + false } match (home_mismatch(), no_prompt) { - (false, _) => (), - (true, false) => { - err!("$HOME differs from euid-obtained home directory: you may be using sudo"); - err!("if this is what you want, restart the installation with `-y'"); - process::exit(1); - }, - (true, true) => { - warn!("$HOME differs from euid-obtained home directory: you may be using sudo"); - } + (false, _) => (), + (true, false) => { + err!("$HOME differs from euid-obtained home directory: you may be using sudo"); + err!("if this is what you want, restart the installation with `-y'"); + process::exit(1); + }, + (true, true) => { + warn!("$HOME differs from euid-obtained home directory: you may be using sudo"); + } } Ok(()) diff --git a/src/rustup-dist/src/errors.rs b/src/rustup-dist/src/errors.rs index 7a1245b314..d4be295466 100644 --- a/src/rustup-dist/src/errors.rs +++ b/src/rustup-dist/src/errors.rs @@ -83,7 +83,13 @@ error_chain! { } ComponentDownloadFailed(c: Component) { description("component download failed") - display("component download failed for {}-{}", c.pkg, c.target) + display("component download failed for {}{}", c.pkg, { + if let Some(ref t) = c.target { + format!("-{}", t) + } else { + "".to_owned() + } + }) } Parsing(e: Vec) { description("error parsing manifest") @@ -108,19 +114,26 @@ fn component_unavailable_msg(cs: &[Component]) -> String { let mut buf = vec![]; + fn format_component(c: &Component) -> String { + if let Some(ref t) = c.target { + format!("'{}' for '{}", c.pkg, t) + } else { + format!("'{}'", c.pkg) + } + } + if cs.len() == 1 { - let _ = write!(buf, "component '{}' for '{}' is unavailable for download", - cs[0].pkg, cs[0].target); + let _ = write!(buf, "component {} is unavailable for download", format_component(&cs[0])); } else { use itertools::Itertools; - let same_target = cs.iter().all(|c| c.target == cs[0].target); + let same_target = cs.iter().all(|c| c.target == cs[0].target || c.target.is_none()); if same_target { let mut cs_strs = cs.iter().map(|c| format!("'{}'", c.pkg)); let cs_str = cs_strs.join(", "); let _ = write!(buf, "some components unavailable for download: {}", cs_str); } else { - let mut cs_strs = cs.iter().map(|c| format!("'{}' for '{}'", c.pkg, c.target)); + let mut cs_strs = cs.iter().map(format_component); let cs_str = cs_strs.join(", "); let _ = write!(buf, "some components unavailable for download: {}", cs_str); diff --git a/src/rustup-dist/src/manifest.rs b/src/rustup-dist/src/manifest.rs index 9873b569c2..5fc5404fac 100644 --- a/src/rustup-dist/src/manifest.rs +++ b/src/rustup-dist/src/manifest.rs @@ -30,11 +30,17 @@ pub struct Manifest { #[derive(Clone, Debug, PartialEq)] pub struct Package { pub version: String, - pub targets: HashMap, + pub targets: PackageTargets, } #[derive(Clone, Debug, PartialEq)] -pub struct TargettedPackage { +pub enum PackageTargets { + Wildcard(TargetedPackage), + Targeted(HashMap) +} + +#[derive(Clone, Debug, PartialEq)] +pub struct TargetedPackage { pub available: bool, pub url: String, pub hash: String, @@ -45,7 +51,7 @@ pub struct TargettedPackage { #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Component { pub pkg: String, - pub target: TargetTriple, + pub target: Option, } impl Manifest { @@ -106,19 +112,30 @@ impl Manifest { result } - pub fn get_package(&self, name: &str) -> Result<&Package> { self.packages.get(name).ok_or_else( || format!("package not found: '{}'", name).into()) } + fn validate_targeted_package(&self, tpkg: &TargetedPackage) -> Result<()> { + for c in tpkg.components.iter().chain(tpkg.extensions.iter()) { + let cpkg = try!(self.get_package(&c.pkg).chain_err(|| ErrorKind::MissingPackageForComponent(c.clone()))); + let _ctpkg = try!(cpkg.get_target(c.target.as_ref()).chain_err(|| ErrorKind::MissingPackageForComponent(c.clone()))); + } + Ok(()) + } + fn validate(&self) -> Result<()> { // Every component mentioned must have an actual package to download for (_, pkg) in &self.packages { - for (_, tpkg) in &pkg.targets { - for c in tpkg.components.iter().chain(tpkg.extensions.iter()) { - let cpkg = try!(self.get_package(&c.pkg).chain_err(|| ErrorKind::MissingPackageForComponent(c.clone()))); - let _ctpkg = try!(cpkg.get_target(&c.target).chain_err(|| ErrorKind::MissingPackageForComponent(c.clone()))); + match pkg.targets { + PackageTargets::Wildcard(ref tpkg) => { + try!(self.validate_targeted_package(tpkg)); + }, + PackageTargets::Targeted(ref tpkgs) => { + for (_, tpkg) in tpkgs { + try!(self.validate_targeted_package(tpkg)); + } } } } @@ -145,37 +162,71 @@ impl Package { result } - fn toml_to_targets(mut table: toml::Table, path: &str) -> Result> { - let mut result = HashMap::new(); - let target_table = try!(get_table(&mut table, "target", path)); + fn toml_to_targets(mut table: toml::Table, path: &str) -> Result { + let mut target_table = try!(get_table(&mut table, "target", path)); - for (k, v) in target_table { - if let toml::Value::Table(t) = v { - result.insert(TargetTriple::from_str(&k), try!(TargettedPackage::from_toml(t, &path))); + if let Some(toml::Value::Table(t)) = target_table.remove("*") { + Ok(PackageTargets::Wildcard(try!(TargetedPackage::from_toml(t, &path)))) + } else { + let mut result = HashMap::new(); + for (k, v) in target_table { + if let toml::Value::Table(t) = v { + result.insert(TargetTriple::from_str(&k), try!(TargetedPackage::from_toml(t, &path))); + } } + Ok(PackageTargets::Targeted(result)) } - - Ok(result) } - fn targets_to_toml(targets: HashMap) -> toml::Table { + fn targets_to_toml(targets: PackageTargets) -> toml::Table { let mut result = toml::Table::new(); - for (k, v) in targets { - result.insert(k.to_string(), toml::Value::Table(v.to_toml())); + match targets { + PackageTargets::Wildcard(tpkg) => { + result.insert("*".to_owned(), toml::Value::Table(tpkg.to_toml())); + }, + PackageTargets::Targeted(tpkgs) => { + for (k, v) in tpkgs { + result.insert(k.to_string(), toml::Value::Table(v.to_toml())); + } + } } result } - pub fn get_target(&self, target: &TargetTriple) -> Result<&TargettedPackage> { - self.targets.get(target).ok_or_else( - || format!("target not found: '{}'", target).into()) + pub fn get_target(&self, target: Option<&TargetTriple>) -> Result<&TargetedPackage> { + match self.targets { + PackageTargets::Wildcard(ref tpkg) => Ok(tpkg), + PackageTargets::Targeted(ref tpkgs) => { + if let Some(t) = target { + tpkgs.get(t).ok_or_else( + || format!("target not found: '{}'", t).into()) + } else { + Err("no target specified".into()) + } + } + } + } +} + +impl PackageTargets { + pub fn get<'a>(&'a self, target: &TargetTriple) -> Option<&'a TargetedPackage> { + match *self { + PackageTargets::Wildcard(ref tpkg) => Some(tpkg), + PackageTargets::Targeted(ref tpkgs) => tpkgs.get(target) + } + } + pub fn get_mut<'a>(&'a mut self, target: &TargetTriple) -> Option<&'a mut TargetedPackage> { + match *self { + PackageTargets::Wildcard(ref mut tpkg) => Some(tpkg), + PackageTargets::Targeted(ref mut tpkgs) => tpkgs.get_mut(target) + } } } -impl TargettedPackage { +impl TargetedPackage { pub fn from_toml(mut table: toml::Table, path: &str) -> Result { let components = try!(get_array(&mut table, "components", path)); let extensions = try!(get_array(&mut table, "extensions", path)); - Ok(TargettedPackage { + Ok(TargetedPackage { available: try!(get_bool(&mut table, "available", path)), url: try!(get_string(&mut table, "url", path)), hash: try!(get_string(&mut table, "hash", path)), @@ -226,16 +277,35 @@ impl Component { pub fn from_toml(mut table: toml::Table, path: &str) -> Result { Ok(Component { pkg: try!(get_string(&mut table, "pkg", path)), - target: try!(get_string(&mut table, "target", path).map(|s| TargetTriple::from_str(&s))), + target: try!(get_string(&mut table, "target", path).map(|s| { + if s == "*" { + None + } else { + Some(TargetTriple::from_str(&s)) + } + })), }) } pub fn to_toml(self) -> toml::Table { let mut result = toml::Table::new(); - result.insert("target".to_owned(), toml::Value::String(self.target.to_string())); + result.insert("target".to_owned(), toml::Value::String( + self.target.map(|t| t.to_string()).unwrap_or_else(||"*".to_owned()) + )); result.insert("pkg".to_owned(), toml::Value::String(self.pkg)); result } pub fn name(&self) -> String { - format!("{}-{}", self.pkg, self.target) + if let Some(ref t) = self.target { + format!("{}-{}", self.pkg, t) + } else { + format!("{}", self.pkg) + } + } + pub fn description(&self) -> String { + if let Some(ref t) = self.target { + format!("'{}' for target '{}'", self.pkg, t) + } else { + format!("'{}'", self.pkg) + } } } diff --git a/src/rustup-dist/src/manifestation.rs b/src/rustup-dist/src/manifestation.rs index f66c997980..c40677d33d 100644 --- a/src/rustup-dist/src/manifestation.rs +++ b/src/rustup-dist/src/manifestation.rs @@ -2,7 +2,7 @@ //! platform components from a distribution server. use config::Config; -use manifest::{Component, Manifest, TargettedPackage}; +use manifest::{Component, Manifest, TargetedPackage}; use dist::{download_and_check, DownloadCfg, TargetTriple, DEFAULT_DIST_SERVER}; use component::{Components, Transaction, TarGzPackage, Package}; use temp; @@ -81,7 +81,7 @@ impl Manifestation { let ref rel_installed_manifest_path = prefix.rel_manifest_file(DIST_MANIFEST); let ref installed_manifest_path = prefix.path().join(rel_installed_manifest_path); let rust_package = try!(new_manifest.get_package("rust")); - let rust_target_package = try!(rust_package.get_target(&self.target_triple)); + let rust_target_package = try!(rust_package.get_target(Some(&self.target_triple))); // Load the previous dist manifest let ref old_manifest = try!(self.load_manifest()); @@ -105,7 +105,7 @@ impl Manifestation { let unavailable_components: Vec = components_to_install.iter().filter(|c| { use manifest::*; let pkg: Option<&Package> = new_manifest.get_package(&c.pkg).ok(); - let target_pkg: Option<&TargettedPackage> = pkg.and_then(|p| p.get_target(&c.target).ok()); + let target_pkg: Option<&TargetedPackage> = pkg.and_then(|p| p.get_target(c.target.as_ref()).ok()); target_pkg.map(|tp| tp.available) != Some(true) }).cloned().collect(); @@ -117,7 +117,7 @@ impl Manifestation { let mut components_urls_and_hashes: Vec<(Component, String, String)> = Vec::new(); for component in components_to_install { let package = try!(new_manifest.get_package(&component.pkg)); - let target_package = try!(package.get_target(&component.target)); + let target_package = try!(package.get_target(component.target.as_ref())); let c_u_h = (component, target_package.url.clone(), target_package.hash.clone()); components_urls_and_hashes.push(c_u_h); } @@ -130,7 +130,7 @@ impl Manifestation { notify_handler(Notification::DownloadingComponent(&component.pkg, &self.target_triple, - &component.target)); + component.target.as_ref())); let url = if altered { url.replace(DEFAULT_DIST_SERVER, temp_cfg.dist_server.as_str()) } else { @@ -182,7 +182,7 @@ impl Manifestation { notify_handler(Notification::InstallingComponent(&component.pkg, &self.target_triple, - &component.target)); + component.target.as_ref())); let package = try!(TarGzPackage::new_file(&installer_file, temp_cfg)); @@ -190,7 +190,7 @@ impl Manifestation { // names are not the same as the dist manifest component // names. Some are just the component name some are the // component name plus the target triple. - let ref name = format!("{}-{}", component.pkg, component.target); + let ref name = component.name(); let ref short_name = format!("{}", component.pkg); // If the package doesn't contain the component that the @@ -254,7 +254,7 @@ impl Manifestation { // names are not the same as the dist manifest component // names. Some are just the component name some are the // component name plus the target triple. - let ref name = format!("{}-{}", component.pkg, component.target); + let ref name = component.name(); let ref short_name = format!("{}", component.pkg); if let Some(c) = try!(self.installation.find(&name)) { tx = try!(c.uninstall(tx)); @@ -313,7 +313,7 @@ impl Manifestation { notify_handler(Notification::DownloadingComponent("rust", &self.target_triple, - &self.target_triple)); + Some(&self.target_triple))); let dlcfg = DownloadCfg { dist_root: "bogus", @@ -331,7 +331,7 @@ impl Manifestation { notify_handler(Notification::InstallingComponent("rust", &self.target_triple, - &self.target_triple)); + Some(&self.target_triple))); // Begin transaction let mut tx = Transaction::new(prefix.clone(), temp_cfg, notify_handler); @@ -383,7 +383,7 @@ fn build_update_component_lists( old_manifest: &Option, config: &Option, changes: Changes, - rust_target_package: &TargettedPackage, + rust_target_package: &TargetedPackage, notify_handler: &Fn(Notification), ) -> Result<(Vec, Vec, Vec)> { diff --git a/src/rustup-dist/src/notifications.rs b/src/rustup-dist/src/notifications.rs index 29eb3d92a4..75fd515d75 100644 --- a/src/rustup-dist/src/notifications.rs +++ b/src/rustup-dist/src/notifications.rs @@ -22,8 +22,8 @@ pub enum Notification<'a> { ExtensionNotInstalled(&'a Component), NonFatalError(&'a Error), MissingInstalledComponent(&'a str), - DownloadingComponent(&'a str, &'a TargetTriple, &'a TargetTriple), - InstallingComponent(&'a str, &'a TargetTriple, &'a TargetTriple), + DownloadingComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>), + InstallingComponent(&'a str, &'a TargetTriple, Option<&'a TargetTriple>), DownloadingManifest(&'a str), DownloadingLegacyManifest, ManifestChecksumFailedHack, @@ -70,8 +70,7 @@ impl<'a> Display for Notification<'a> { Utils(ref n) => n.fmt(f), Extracting(_, _) => write!(f, "extracting..."), ComponentAlreadyInstalled(ref c) => { - write!(f, "component '{}' for target '{}' is up to date", - c.pkg, c.target) + write!(f, "component {} is up to date", c.description()) } CantReadUpdateHash(path) => { write!(f, @@ -83,22 +82,22 @@ impl<'a> Display for Notification<'a> { SignatureValid(_) => write!(f, "signature valid"), RollingBack => write!(f, "rolling back changes"), ExtensionNotInstalled(c) => { - write!(f, "extension '{}-{}' was not installed", c.pkg, c.target) + write!(f, "extension '{}' was not installed", c.name()) } NonFatalError(e) => write!(f, "{}", e), MissingInstalledComponent(c) => write!(f, "during uninstall component {} was not found", c), DownloadingComponent(c, h, t) => { - if h == t { + if Some(h) == t || t.is_none() { write!(f, "downloading component '{}'", c) } else { - write!(f, "downloading component '{}' for '{}'", c, t) + write!(f, "downloading component '{}' for '{}'", c, t.unwrap()) } } InstallingComponent(c, h, t) => { - if h == t { + if Some(h) == t || t.is_none() { write!(f, "installing component '{}'", c) } else { - write!(f, "installing component '{}' for '{}'", c, t) + write!(f, "installing component '{}' for '{}'", c, t.unwrap()) } } DownloadingManifest(t) => write!(f, "syncing channel updates for '{}'", t), diff --git a/src/rustup-dist/tests/dist.rs b/src/rustup-dist/tests/dist.rs index 088549deca..fac01e2a3b 100644 --- a/src/rustup-dist/tests/dist.rs +++ b/src/rustup-dist/tests/dist.rs @@ -53,7 +53,7 @@ pub fn create_mock_channel(channel: &str, date: &str, name: "rust", version: "1.0.0", targets: vec![ - MockTargettedPackage { + MockTargetedPackage { target: "x86_64-apple-darwin".to_string(), available: true, components: vec![ @@ -80,7 +80,7 @@ pub fn create_mock_channel(channel: &str, date: &str, components: vec![] } }, - MockTargettedPackage { + MockTargetedPackage { target: "i686-apple-darwin".to_string(), available: true, components: vec![ @@ -105,7 +105,7 @@ pub fn create_mock_channel(channel: &str, date: &str, name: "rustc", version: "1.0.0", targets: vec![ - MockTargettedPackage { + MockTargetedPackage { target: "x86_64-apple-darwin".to_string(), available: true, components: vec![], @@ -123,7 +123,7 @@ pub fn create_mock_channel(channel: &str, date: &str, ] } }, - MockTargettedPackage { + MockTargetedPackage { target: "i686-apple-darwin".to_string(), available: true, components: vec![], @@ -139,7 +139,7 @@ pub fn create_mock_channel(channel: &str, date: &str, name: "rust-std", version: "1.0.0", targets: vec![ - MockTargettedPackage { + MockTargetedPackage { target: "x86_64-apple-darwin".to_string(), available: true, components: vec![], @@ -157,7 +157,7 @@ pub fn create_mock_channel(channel: &str, date: &str, ] } }, - MockTargettedPackage { + MockTargetedPackage { target: "i686-apple-darwin".to_string(), available: true, components: vec![], @@ -175,7 +175,7 @@ pub fn create_mock_channel(channel: &str, date: &str, ] } }, - MockTargettedPackage { + MockTargetedPackage { target: "i686-unknown-linux-gnu".to_string(), available: true, components: vec![], @@ -202,7 +202,7 @@ pub fn create_mock_channel(channel: &str, date: &str, name: "bonus", version: "1.0.0", targets: vec![ - MockTargettedPackage { + MockTargetedPackage { target: "x86_64-apple-darwin".to_string(), available: true, components: vec![], @@ -399,10 +399,10 @@ fn update_preserves_extensions() { setup(None, &|url, toolchain, prefix, temp_cfg| { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) } ]; @@ -441,7 +441,7 @@ fn update_preserves_extensions_that_became_components() { setup(Some(edit), &|url, toolchain, prefix, temp_cfg| { let ref adds = vec![ Component { - pkg: "bonus".to_string(), target: TargetTriple::from_str("x86_64-apple-darwin") + pkg: "bonus".to_string(), target: Some(TargetTriple::from_str("x86_64-apple-darwin")) }, ]; @@ -499,12 +499,12 @@ fn add_extensions_for_initial_install() { setup(None, &|url, toolchain, prefix, temp_cfg| { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) } - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("lib/i686-apple-darwin/libstd.rlib"))); @@ -519,12 +519,12 @@ fn add_extensions_for_same_manifest() { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) } - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); @@ -544,12 +544,12 @@ fn add_extensions_for_upgrade() { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) } - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); @@ -564,9 +564,9 @@ fn add_extension_not_in_manifest() { setup(None, &|url, toolchain, prefix, temp_cfg| { let ref adds = vec![ Component { - pkg: "rust-bogus".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-bogus".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); }); @@ -578,9 +578,9 @@ fn add_extension_that_is_required_component() { setup(None, &|url, toolchain, prefix, temp_cfg| { let ref adds = vec![ Component { - pkg: "rustc".to_string(), target: TargetTriple::from_str("x86_64-apple-darwin") + pkg: "rustc".to_string(), target: Some(TargetTriple::from_str("x86_64-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); }); @@ -603,9 +603,9 @@ fn add_extensions_does_not_remove_other_components() { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); @@ -620,9 +620,9 @@ fn remove_extensions_for_initial_install() { setup(None, &|url, toolchain, prefix, temp_cfg| { let ref removes = vec![ Component { - pkg: "rustc".to_string(), target: TargetTriple::from_str("x86_64-apple-darwin") + pkg: "rustc".to_string(), target: Some(TargetTriple::from_str("x86_64-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); @@ -633,18 +633,18 @@ fn remove_extensions_for_same_manifest() { setup(None, &|url, toolchain, prefix, temp_cfg| { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) } - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); let ref removes = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, ]; @@ -662,12 +662,12 @@ fn remove_extensions_for_upgrade() { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) } - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); @@ -675,9 +675,9 @@ fn remove_extensions_for_upgrade() { let ref removes = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); @@ -698,9 +698,9 @@ fn remove_extension_not_in_manifest() { let ref removes = vec![ Component { - pkg: "rust-bogus".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-bogus".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); @@ -726,9 +726,9 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { let ref adds = vec![ Component { - pkg: "bonus".to_string(), target: TargetTriple::from_str("x86_64-apple-darwin") + pkg: "bonus".to_string(), target: Some(TargetTriple::from_str("x86_64-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); assert!(utils::path_exists(&prefix.path().join("bin/bonus"))); @@ -736,9 +736,9 @@ fn remove_extension_not_in_manifest_but_is_already_installed() { let ref removes = vec![ Component { - pkg: "bonus".to_string(), target: TargetTriple::from_str("x86_64-apple-darwin") + pkg: "bonus".to_string(), target: Some(TargetTriple::from_str("x86_64-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); } @@ -751,9 +751,9 @@ fn remove_extension_that_is_required_component() { let ref removes = vec![ Component { - pkg: "rustc".to_string(), target: TargetTriple::from_str("x86_64-apple-darwin") + pkg: "rustc".to_string(), target: Some(TargetTriple::from_str("x86_64-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); @@ -767,9 +767,9 @@ fn remove_extension_not_installed() { let ref removes = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); }); @@ -785,17 +785,17 @@ fn remove_extensions_does_not_remove_other_components() { setup(None, &|url, toolchain, prefix, temp_cfg| { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); let ref removes = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, &[], removes, temp_cfg, &|_| ()).unwrap(); @@ -810,9 +810,9 @@ fn add_and_remove_for_upgrade() { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); @@ -820,15 +820,15 @@ fn add_and_remove_for_upgrade() { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; let ref removes = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, &|_| ()).unwrap(); @@ -842,23 +842,23 @@ fn add_and_remove() { setup(None, &|url, toolchain, prefix, temp_cfg| { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, &[], temp_cfg, &|_| ()).unwrap(); let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; let ref removes = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-unknown-linux-gnu") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-unknown-linux-gnu")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, &|_| ()).unwrap(); @@ -875,15 +875,15 @@ fn add_and_remove_same_component() { let ref adds = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple-darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple-darwin")) }, - ]; + ]; let ref removes = vec![ Component { - pkg: "rust-std".to_string(), target: TargetTriple::from_str("i686-apple_darwin") + pkg: "rust-std".to_string(), target: Some(TargetTriple::from_str("i686-apple_darwin")) }, - ]; + ]; update_from_dist(url, toolchain, prefix, adds, removes, temp_cfg, &|_| ()).unwrap(); }); diff --git a/src/rustup-dist/tests/manifest.rs b/src/rustup-dist/tests/manifest.rs index f1ded2ebb0..3608a0ba53 100644 --- a/src/rustup-dist/tests/manifest.rs +++ b/src/rustup-dist/tests/manifest.rs @@ -25,21 +25,21 @@ fn parse_smoke_test() { let rust_pkg = pkg.get_package("rust").unwrap(); assert!(rust_pkg.version.contains("1.3.0")); - let rust_target_pkg = rust_pkg.get_target(&x86_64_unknown_linux_gnu).unwrap(); + let rust_target_pkg = rust_pkg.get_target(Some(&x86_64_unknown_linux_gnu)).unwrap(); assert_eq!(rust_target_pkg.available, true); assert_eq!(rust_target_pkg.url, "example.com"); assert_eq!(rust_target_pkg.hash, "..."); let ref component = rust_target_pkg.components[0]; assert_eq!(component.pkg, "rustc"); - assert_eq!(component.target, x86_64_unknown_linux_gnu); + assert_eq!(component.target.as_ref(), Some(&x86_64_unknown_linux_gnu)); let ref component = rust_target_pkg.extensions[0]; assert_eq!(component.pkg, "rust-std"); - assert_eq!(component.target, x86_64_unknown_linux_musl); + assert_eq!(component.target.as_ref(), Some(&x86_64_unknown_linux_musl)); let docs_pkg = pkg.get_package("rust-docs").unwrap(); - let docs_target_pkg = docs_pkg.get_target(&x86_64_unknown_linux_gnu).unwrap(); + let docs_target_pkg = docs_pkg.get_target(Some(&x86_64_unknown_linux_gnu)).unwrap(); assert_eq!(docs_target_pkg.url, "example.com"); } diff --git a/src/rustup-mock/src/clitools.rs b/src/rustup-mock/src/clitools.rs index 469c8f99b9..70d8ab08f3 100644 --- a/src/rustup-mock/src/clitools.rs +++ b/src/rustup-mock/src/clitools.rs @@ -12,7 +12,7 @@ use std::time::Duration; use tempdir::TempDir; use {MockInstallerBuilder, MockCommand}; use dist::{MockDistServer, MockChannel, MockPackage, - MockTargettedPackage, MockComponent, change_channel_date, + MockTargetedPackage, MockComponent, change_channel_date, ManifestVersion}; use url::Url; use scopeguard; @@ -385,7 +385,7 @@ fn build_mock_channel(s: Scenario, channel: &str, date: &str, let packages = all.into_iter().map(|(name, target_pkgs)| { let target_pkgs = target_pkgs.into_iter().map(|(installer, triple)| { - MockTargettedPackage { + MockTargetedPackage { target: triple, available: true, components: vec![], diff --git a/src/rustup-mock/src/dist.rs b/src/rustup-mock/src/dist.rs index a8d142b0a0..1c8319f095 100644 --- a/src/rustup-mock/src/dist.rs +++ b/src/rustup-mock/src/dist.rs @@ -80,10 +80,10 @@ pub struct MockPackage { // rust, rustc, rust-std-$triple, rust-doc, etc. pub name: &'static str, pub version: &'static str, - pub targets: Vec, + pub targets: Vec, } -pub struct MockTargettedPackage { +pub struct MockTargetedPackage { // Target triple pub target: String, // Whether the file actually exists (could be due to build failure) @@ -142,7 +142,7 @@ impl MockDistServer { fn build_target_package(&self, channel: &MockChannel, package: &MockPackage, - target_package: &MockTargettedPackage) -> String { + target_package: &MockTargetedPackage) -> String { // This is where the tarball, sums and sigs will go let ref dist_dir = self.path.join("dist"); let ref archive_dir = dist_dir.join(&channel.date); diff --git a/src/rustup/errors.rs b/src/rustup/errors.rs index fbeb295e46..33c6ca849b 100644 --- a/src/rustup/errors.rs +++ b/src/rustup/errors.rs @@ -38,20 +38,20 @@ error_chain! { } UnknownComponent(t: String, c: Component) { description("toolchain does not contain component") - display("toolchain '{}' does not contain component '{}' for target '{}'", t, c.pkg, c.target) + display("toolchain '{}' does not contain component {}", t, c.description()) } AddingRequiredComponent(t: String, c: Component) { description("required component cannot be added") - display("component '{}' for target '{}' is required for toolchain '{}' and cannot be re-added", - c.pkg, c.target, t) + display("component {} is required for toolchain '{}' and cannot be re-added", + c.description(), t) } ParsingSettings(e: Vec) { description("error parsing settings") } RemovingRequiredComponent(t: String, c: Component) { description("required component cannot be removed") - display("component '{}' for target '{}' is required for toolchain '{}' and cannot be removed", - c.pkg, c.target, t) + display("component {} is required for toolchain '{}' and cannot be removed", + c.description(), t) } NoExeName { description("couldn't determine self executable name") diff --git a/src/rustup/toolchain.rs b/src/rustup/toolchain.rs index 325c1e9dc9..e8b1e5083f 100644 --- a/src/rustup/toolchain.rs +++ b/src/rustup/toolchain.rs @@ -311,15 +311,15 @@ impl<'a> Toolchain<'a> { pub fn set_ldpath(&self, cmd: &mut Command) { let new_path = self.path.join("lib"); - #[cfg(not(target_os = "macos"))] - mod sysenv { - pub const LOADER_PATH: &'static str = "LD_LIBRARY_PATH"; - } - #[cfg(target_os = "macos")] - mod sysenv { - pub const LOADER_PATH: &'static str = "DYLD_LIBRARY_PATH"; - } - env_var::prepend_path(sysenv::LOADER_PATH, &new_path, cmd); + #[cfg(not(target_os = "macos"))] + mod sysenv { + pub const LOADER_PATH: &'static str = "LD_LIBRARY_PATH"; + } + #[cfg(target_os = "macos")] + mod sysenv { + pub const LOADER_PATH: &'static str = "DYLD_LIBRARY_PATH"; + } + env_var::prepend_path(sysenv::LOADER_PATH, &new_path, cmd); // Append first cargo_home, then toolchain/bin to the PATH let mut path_to_append = Vec::with_capacity(2); diff --git a/www/rustup.css b/www/rustup.css index 429906e65c..e689516c68 100644 --- a/www/rustup.css +++ b/www/rustup.css @@ -1,34 +1,34 @@ @font-face { - font-family: 'Fira Sans'; - font-style: normal; - font-weight: 300; - src: local('Fira Sans Light'), url("fonts/FiraSans-Light.woff") format('woff'); + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 300; + src: local('Fira Sans Light'), url("fonts/FiraSans-Light.woff") format('woff'); } @font-face { - font-family: 'Fira Sans'; - font-style: normal; - font-weight: 400; - src: local('Fira Sans'), url("fonts/FiraSans-Regular.woff") format('woff'); + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 400; + src: local('Fira Sans'), url("fonts/FiraSans-Regular.woff") format('woff'); } @font-face { - font-family: 'Fira Sans'; - font-style: normal; - font-weight: 500; - src: local('Fira Sans Medium'), url("fonts/FiraSans-Medium.woff") format('woff'); + font-family: 'Fira Sans'; + font-style: normal; + font-weight: 500; + src: local('Fira Sans Medium'), url("fonts/FiraSans-Medium.woff") format('woff'); } @font-face { - font-family: 'Work Sans'; - font-style: normal; - font-weight: 500; - src: local('Work Sans Medium'), url("fonts/WorkSans-Medium.ttf") format('ttf'); + font-family: 'Work Sans'; + font-style: normal; + font-weight: 500; + src: local('Work Sans Medium'), url("fonts/WorkSans-Medium.ttf") format('ttf'); } @font-face { - font-family: 'Inconsolata'; - font-style: normal; - font-weight: 400; - src: local('Inconsolata Regular'), url("fonts/Inconsolata-Regular.ttf") format('ttf'); + font-family: 'Inconsolata'; + font-style: normal; + font-weight: 400; + src: local('Inconsolata Regular'), url("fonts/Inconsolata-Regular.ttf") format('ttf'); } body { diff --git a/www/rustup.js b/www/rustup.js index 1de3912e71..97c2b78632 100644 --- a/www/rustup.js +++ b/www/rustup.js @@ -4,7 +4,7 @@ function detect_platform() { "use strict"; if (platform_override) { - return platform_override; + return platform_override; } var os = "unknown"; @@ -20,14 +20,14 @@ function detect_platform() { if (navigator.platform == "FreeBSD amd64") {os = "unix";} if (navigator.platform == "Linux armv7l" - && navigator.appVersion.indexOf("Android") != -1 ) { - os = "android"; + && navigator.appVersion.indexOf("Android") != -1 ) { + os = "android"; } // I wish I knew by now, but I don't. Try harder. if (os == "unknown") { - if (navigator.appVersion.indexOf("Win")!=-1) {os = "win";} - if (navigator.appVersion.indexOf("Mac")!=-1) {os = "unix";} + if (navigator.appVersion.indexOf("Win")!=-1) {os = "win";} + if (navigator.appVersion.indexOf("Mac")!=-1) {os = "unix";} } return os; @@ -51,31 +51,31 @@ function adjust_for_platform() { default_div.style.display = "none"; if (platform == "unix") { - unix_div.style.display = "block"; + unix_div.style.display = "block"; } else if (platform == "win") { - win_div.style.display = "block"; + win_div.style.display = "block"; } else if (platform == "android") { - android_div.style.display = "block"; + android_div.style.display = "block"; } else if (platform == "unknown") { - unknown_div.style.display = "block"; + unknown_div.style.display = "block"; } else { - default_div.style.display = "block"; + default_div.style.display = "block"; } } function cycle_platform() { if (platform_override == null) { - platform_override = "default"; + platform_override = "default"; } else if (platform_override == "default") { - platform_override = "unknown"; + platform_override = "unknown"; } else if (platform_override == "unknown") { - platform_override = "win"; + platform_override = "win"; } else if (platform_override == "win") { - platform_override = "unix"; + platform_override = "unix"; } else if (platform_override == "unix") { - platform_override = "android"; + platform_override = "android"; } else if (platform_override == "android") { - platform_override = "default"; + platform_override = "default"; } adjust_for_platform(); } @@ -89,22 +89,22 @@ function set_up_cycle_button() { var unlocked=false; document.onkeypress = function(event) { - if (event.key == "n" && unlocked) { - cycle_platform(); - } - - if (event.key == key[idx]) { - idx += 1; - - if (idx == key.length) { - cycle_button.style.display = "block"; - unlocked = true; - } - } else if (event.key == key[0]) { - idx = 1; - } else { - idx = 0; - } + if (event.key == "n" && unlocked) { + cycle_platform(); + } + + if (event.key == key[idx]) { + idx += 1; + + if (idx == key.length) { + cycle_button.style.display = "block"; + unlocked = true; + } + } else if (event.key == key[0]) { + idx = 1; + } else { + idx = 0; + } }; }