diff --git a/src/rustup-utils/src/utils.rs b/src/rustup-utils/src/utils.rs index ffbf69164a..af94a14530 100644 --- a/src/rustup-utils/src/utils.rs +++ b/src/rustup-utils/src/utils.rs @@ -618,6 +618,9 @@ pub fn do_rustup_home_upgrade() -> bool { // Creates a ~/.rustup folder and a ~/.multirust symlink pub fn create_rustup_home() -> Result<()> { + // If there's an existing install, then try to upgrade + do_rustup_home_upgrade(); + // If RUSTUP_HOME is set then don't make any assumptions about where it's // ok to put ~/.multirust if env::var_os("RUSTUP_HOME").is_some() { return Ok(()) } @@ -638,6 +641,10 @@ fn create_legacy_multirust_symlink() -> Result<()> { let newhome = rustup_home_in_user_dir()?; let oldhome = legacy_multirust_home()?; + if oldhome.exists() { + return Ok(()); + } + raw::symlink_dir(&newhome, &oldhome) .chain_err(|| format!("unable to symlink {} from {}", newhome.display(), oldhome.display()))?; diff --git a/tests/cli-self-upd.rs b/tests/cli-self-upd.rs index e3013cff07..ae70999ca3 100644 --- a/tests/cli-self-upd.rs +++ b/tests/cli-self-upd.rs @@ -1084,9 +1084,13 @@ fn install_creates_legacy_home_symlink() { let mut cmd = clitools::cmd(config, "rustup-init", &["-y"]); // It'll only do this behavior when RUSTUP_HOME isn't set cmd.env_remove("RUSTUP_HOME"); - assert!(cmd.output().unwrap().status.success()); + let mut cmd = clitools::cmd(config, "rustc", &["--version"]); + cmd.env_remove("RUSTUP_HOME"); + let out = String::from_utf8(cmd.output().unwrap().stdout).unwrap(); + assert!(out.contains("hash-s-2")); + let rustup_dir = config.homedir.join(".rustup"); assert!(rustup_dir.exists()); let multirust_dir = config.homedir.join(".multirust"); @@ -1095,6 +1099,48 @@ fn install_creates_legacy_home_symlink() { }); } +// Do upgrade over multirust. #848 +#[test] +fn install_over_unupgraded_multirust_dir() { + setup(&|config| { + let rustup_dir = config.homedir.join(".rustup"); + let multirust_dir = config.homedir.join(".multirust"); + + // Install rustup + let mut cmd = clitools::cmd(config, "rustup-init", &["-y", "--default-toolchain=nightly"]); + cmd.env_remove("RUSTUP_HOME"); + assert!(cmd.output().unwrap().status.success()); + + let mut cmd = clitools::cmd(config, "rustc", &["--version"]); + cmd.env_remove("RUSTUP_HOME"); + let out = String::from_utf8(cmd.output().unwrap().stdout).unwrap(); + assert!(out.contains("hash-n-2")); + + // Move .rustup to .multirust so the next rustup-init will be + // an upgrade from ~/.multirust to ~/.rustup + raw::remove_dir(&multirust_dir).unwrap(); + fs::rename(&rustup_dir, &multirust_dir).unwrap(); + assert!(!rustup_dir.exists()); + assert!(multirust_dir.exists()); + + // Do the upgrade + let mut cmd = clitools::cmd(config, "rustup-init", &["-y"]); + cmd.env_remove("RUSTUP_HOME"); + assert!(cmd.output().unwrap().status.success()); + + // Directories should be set up correctly + assert!(rustup_dir.exists()); + assert!(multirust_dir.exists()); + assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink()); + + // We should still be on nightly + let mut cmd = clitools::cmd(config, "rustc", &["--version"]); + cmd.env_remove("RUSTUP_HOME"); + let out = String::from_utf8(cmd.output().unwrap().stdout).unwrap(); + assert!(out.contains("hash-n-2")); + }); +} + #[test] fn uninstall_removes_legacy_home_symlink() { setup(&|config| {