Add metadata upgrade from version 2 to 12
This commit is contained in:
@@ -2,7 +2,6 @@ use std::path::{Path, PathBuf};
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
@@ -155,9 +154,9 @@ impl Cfg {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn upgrade_data(&self) -> Result<bool> {
|
||||
pub fn upgrade_data(&self) -> Result<()> {
|
||||
if !utils::is_file(&self.version_file) {
|
||||
return Ok(false);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut current_version = try!(utils::read_file("version", &self.version_file));
|
||||
@@ -167,7 +166,7 @@ impl Cfg {
|
||||
if current_version == METADATA_VERSION {
|
||||
self.notify_handler
|
||||
.call(Notification::MetadataUpgradeNotNeeded(METADATA_VERSION));
|
||||
return Ok(false);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.notify_handler
|
||||
@@ -175,15 +174,28 @@ impl Cfg {
|
||||
|
||||
match &*current_version {
|
||||
"1" => {
|
||||
// Ignore errors. These files may not exist.
|
||||
let _ = fs::remove_dir_all(self.multirust_dir.join("available-updates"));
|
||||
let _ = fs::remove_dir_all(self.multirust_dir.join("update-sums"));
|
||||
let _ = fs::remove_dir_all(self.multirust_dir.join("channel-sums"));
|
||||
let _ = fs::remove_dir_all(self.multirust_dir.join("manifests"));
|
||||
// This corresponds to an old version of multirust.sh.
|
||||
Err(Error::UnknownMetadataVersion(current_version))
|
||||
}
|
||||
"2" => {
|
||||
// The toolchain installation format changed. Just delete them all.
|
||||
let dirs = try!(utils::read_dir("toolchains", &self.toolchains_dir));
|
||||
for dir in dirs {
|
||||
let dir = try!(dir.map_err(|e| Error::UpgradeIoError(e)));
|
||||
try!(utils::remove_dir("toolchain", &dir.path(),
|
||||
utils::NotifyHandler::some(&self.notify_handler)));
|
||||
}
|
||||
|
||||
// Also delete the update hashes
|
||||
let files = try!(utils::read_dir("update hashes", &self.update_hash_dir));
|
||||
for file in files {
|
||||
let file = try!(file.map_err(|e| Error::UpgradeIoError(e)));
|
||||
try!(utils::remove_file("update hash", &file.path()));
|
||||
}
|
||||
|
||||
try!(utils::write_file("version", &self.version_file, METADATA_VERSION));
|
||||
|
||||
Ok(true)
|
||||
Ok(())
|
||||
}
|
||||
_ => Err(Error::UnknownMetadataVersion(current_version)),
|
||||
}
|
||||
@@ -273,7 +285,7 @@ impl Cfg {
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub fn check_metadata_version(&self) -> Result<bool> {
|
||||
pub fn check_metadata_version(&self) -> Result<()> {
|
||||
try!(utils::assert_is_directory(&self.multirust_dir));
|
||||
|
||||
if !utils::is_file(&self.version_file) {
|
||||
@@ -281,13 +293,17 @@ impl Cfg {
|
||||
|
||||
try!(utils::write_file("metadata version", &self.version_file, METADATA_VERSION));
|
||||
|
||||
Ok(true)
|
||||
Ok(())
|
||||
} else {
|
||||
let current_version = try!(utils::read_file("metadata version", &self.version_file));
|
||||
|
||||
self.notify_handler.call(Notification::ReadMetadataVersion(¤t_version));
|
||||
|
||||
Ok(&*current_version == METADATA_VERSION)
|
||||
if &*current_version == METADATA_VERSION {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::NeedMetadataUpgrade)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::path::Path;
|
||||
use std::error;
|
||||
use std::fmt::{self, Display};
|
||||
use std::io;
|
||||
|
||||
use rust_install::{self, utils, temp};
|
||||
use rust_install::notify::{self, NotificationLevel, Notifyable};
|
||||
@@ -42,6 +43,8 @@ pub enum Error {
|
||||
ToolchainNotInstalled(String),
|
||||
UnknownHostTriple,
|
||||
InfiniteRecursion,
|
||||
NeedMetadataUpgrade,
|
||||
UpgradeIoError(io::Error),
|
||||
Custom {
|
||||
id: String,
|
||||
desc: String,
|
||||
@@ -138,6 +141,8 @@ impl error::Error for Error {
|
||||
ToolchainNotInstalled(_) => "toolchain is not installed",
|
||||
UnknownHostTriple => "unknown host triple",
|
||||
InfiniteRecursion => "infinite recursion detected",
|
||||
NeedMetadataUpgrade => "multirust's metadata is out of date. run multirust upgrade-data.",
|
||||
UpgradeIoError(_) => "I/O error during upgrade",
|
||||
Custom { ref desc, .. } => desc,
|
||||
}
|
||||
}
|
||||
@@ -148,6 +153,7 @@ impl error::Error for Error {
|
||||
Install(ref e) => Some(e),
|
||||
Utils(ref e) => Some(e),
|
||||
Temp(ref e) => Some(e),
|
||||
UpgradeIoError(ref e) => Some(e),
|
||||
UnknownMetadataVersion(_) |
|
||||
InvalidEnvironment |
|
||||
NoDefaultToolchain |
|
||||
@@ -155,6 +161,7 @@ impl error::Error for Error {
|
||||
ToolchainNotInstalled(_) |
|
||||
UnknownHostTriple |
|
||||
InfiniteRecursion |
|
||||
NeedMetadataUpgrade |
|
||||
Custom {..} => None,
|
||||
}
|
||||
}
|
||||
@@ -162,6 +169,7 @@ impl error::Error for Error {
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
|
||||
use std::error::Error;
|
||||
use self::Error::*;
|
||||
match *self {
|
||||
Install(ref n) => n.fmt(f),
|
||||
@@ -177,6 +185,10 @@ impl Display for Error {
|
||||
write!(f,
|
||||
"infinite recursion detected: the command may not exist for this toolchain")
|
||||
}
|
||||
NeedMetadataUpgrade => write!(f, "{}", self.description()),
|
||||
UpgradeIoError(ref e) => {
|
||||
write!(f, "I/O error during upgrade: {}", e.description())
|
||||
}
|
||||
Custom { ref desc, .. } => write!(f, "{}", desc),
|
||||
}
|
||||
}
|
||||
|
||||
60
src/main.rs
60
src/main.rs
@@ -243,6 +243,12 @@ fn run_multirust() -> Result<()> {
|
||||
return Err(Error::InfiniteRecursion);
|
||||
}
|
||||
|
||||
let need_metadata = try!(command_requires_metadata());
|
||||
if need_metadata {
|
||||
let cfg = try!(Cfg::from_env(shared_ntfy!(move |_: Notification| { })));
|
||||
try!(cfg.check_metadata_version());
|
||||
}
|
||||
|
||||
// If the executable name is not multirust*, then go straight
|
||||
// to proxying
|
||||
if try!(maybe_direct_proxy()) {
|
||||
@@ -250,31 +256,24 @@ fn run_multirust() -> Result<()> {
|
||||
}
|
||||
|
||||
let app_matches = cli::get().get_matches();
|
||||
|
||||
let cfg = try!(set_globals(Some(&app_matches)));
|
||||
|
||||
match app_matches.subcommand_name() {
|
||||
Some("upgrade-data") | Some("delete-data") | Some("install") |
|
||||
Some("uninstall") | None => {} // Don't need consistent metadata
|
||||
Some(_) => {
|
||||
try!(cfg.check_metadata_version());
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure everything is set-up correctly
|
||||
match app_matches.subcommand_name() {
|
||||
Some("self") | Some("proxy") => {}
|
||||
_ => {
|
||||
if !test_proxies() {
|
||||
if !test_installed(&cfg) {
|
||||
warn!("multirust is not installed for the current user: `rustc` invocations \
|
||||
will not be proxied.\n\nFor more information, run `multirust install \
|
||||
--help`\n");
|
||||
} else {
|
||||
warn!("multirust is installed but is not set up correctly: `rustc` \
|
||||
invocations will not be proxied.\n\nEnsure '{}' is on your PATH, and \
|
||||
has priority.\n",
|
||||
cfg.multirust_dir.join("bin").display());
|
||||
if need_metadata {
|
||||
match app_matches.subcommand_name() {
|
||||
Some("self") | Some("proxy") => {}
|
||||
_ => {
|
||||
if !test_proxies() {
|
||||
if !test_installed(&cfg) {
|
||||
warn!("multirust is not installed for the current user: `rustc` invocations \
|
||||
will not be proxied.\n\nFor more information, run `multirust install \
|
||||
--help`\n");
|
||||
} else {
|
||||
warn!("multirust is installed but is not set up correctly: `rustc` \
|
||||
invocations will not be proxied.\n\nEnsure '{}' is on your PATH, and \
|
||||
has priority.\n",
|
||||
cfg.multirust_dir.join("bin").display());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,6 +325,23 @@ fn run_multirust() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
fn command_requires_metadata() -> Result<bool> {
|
||||
let args = env::args().collect::<Vec<_>>();
|
||||
let arg1 = args.get(1).map(|s| &**s);
|
||||
let arg2 = args.get(2).map(|s| &**s);
|
||||
|
||||
match (arg1, arg2) {
|
||||
(Some("upgrade-data"), _) |
|
||||
(Some("delete-data"), _) |
|
||||
(Some("self"), Some("install")) => {
|
||||
Ok(false)
|
||||
}
|
||||
(_, _) => {
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_install(cfg: &Cfg) -> Result<()> {
|
||||
let exe_path = try!(utils::current_exe());
|
||||
if !test_installed(&cfg) {
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
extern crate rust_install;
|
||||
|
||||
use rust_install::mock::dist::ManifestVersion;
|
||||
use rust_install::mock::clitools::{self, Config,
|
||||
expect_ok, run};
|
||||
use rust_install::mock::clitools::{self, Config, expect_stdout_ok,
|
||||
expect_ok, expect_err, run};
|
||||
use rust_install::utils;
|
||||
|
||||
pub fn setup(f: &Fn(&Config)) {
|
||||
clitools::setup(&[ManifestVersion::V2], f);
|
||||
@@ -171,3 +172,38 @@ fn custom_dir_invalid_name() {
|
||||
fn custom_without_rustc() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn running_with_v2_metadata() {
|
||||
setup(&|config| {
|
||||
expect_ok(config, &["multirust", "default", "nightly"]);
|
||||
// Replace the metadata version
|
||||
utils::raw::write_file(&config.homedir.path().join("version"),
|
||||
"2").unwrap();
|
||||
expect_err(config, &["multirust", "default", "nightly"],
|
||||
"multirust's metadata is out of date. run multirust upgrade-data");
|
||||
expect_err(config, &["rustc", "--version"],
|
||||
"multirust's metadata is out of date. run multirust upgrade-data");
|
||||
});
|
||||
}
|
||||
|
||||
// The thing that changed in the version bump from 2 -> 12 was the
|
||||
// toolchain format. Check that on the upgrade all the toolchains.
|
||||
// are deleted.
|
||||
#[test]
|
||||
fn upgrade_v2_metadata_to_v12() {
|
||||
setup(&|config| {
|
||||
expect_ok(config, &["multirust", "default", "nightly"]);
|
||||
// Replace the metadata version
|
||||
utils::raw::write_file(&config.homedir.path().join("version"),
|
||||
"2").unwrap();
|
||||
expect_ok(config, &["multirust", "upgrade-data"]);
|
||||
expect_err(config, &["multirust", "show-default"],
|
||||
"toolchain 'nightly' is not installed");
|
||||
expect_err(config, &["rustc", "--version"],
|
||||
"toolchain 'nightly' is not installed");
|
||||
expect_ok(config, &["multirust", "update", "nightly"]);
|
||||
expect_stdout_ok(config, &["rustc", "--version"],
|
||||
"hash-n-2");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user