Skip to content

Commit 679abdd

Browse files
committed
Set up ~/.multirust as a temporary symlink to ~/.rustup
1 parent de64c9c commit 679abdd

File tree

5 files changed

+134
-18
lines changed

5 files changed

+134
-18
lines changed

src/rustup-cli/self_update.rs

+6
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ pub fn install(no_prompt: bool, verbose: bool,
228228
if !opts.no_modify_path {
229229
try!(do_add_to_path(&get_add_path_methods()));
230230
}
231+
// Create ~/.rustup and a compatibility ~/.multirust symlink.
232+
// FIXME: Someday we can stop setting up the symlink, and when
233+
// we do that we can stop creating ~/.rustup as well.
234+
try!(utils::create_rustup_home());
231235
try!(maybe_install_rust(&opts.default_toolchain, &opts.default_host_triple, verbose));
232236

233237
if cfg!(unix) {
@@ -607,6 +611,8 @@ pub fn uninstall(no_prompt: bool) -> Result<()> {
607611

608612
info!("removing rustup home");
609613

614+
try!(utils::delete_legacy_multirust_symlink());
615+
610616
// Delete RUSTUP_HOME
611617
let ref rustup_dir = try!(utils::multirust_home());
612618
if rustup_dir.exists() {

src/rustup-mock/src/clitools.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,9 @@ pub fn env(config: &Config, cmd: &mut Command) {
259259
cmd.env("CARGO_HOME", config.cargodir.to_string_lossy().to_string());
260260
cmd.env("RUSTUP_OVERRIDE_HOST_TRIPLE", this_host_triple());
261261

262-
// This is only used for some installation tests on unix where CARGO_HOME
263-
// above is unset
262+
// These are used in some installation tests that unset RUSTUP_HOME/CARGO_HOME
264263
cmd.env("HOME", config.homedir.to_string_lossy().to_string());
264+
cmd.env("USERPROFILE", config.homedir.to_string_lossy().to_string());
265265

266266
// Setting HOME will confuse the sudo check for rustup-init. Override it
267267
cmd.env("RUSTUP_INIT_SKIP_SUDO_CHECK", "yes");

src/rustup-utils/src/utils.rs

+54-1
Original file line numberDiff line numberDiff line change
@@ -598,10 +598,14 @@ pub fn do_rustup_home_upgrade() -> bool {
598598
old_rustup_dir_removed && if multirust_dir_exists() {
599599
if rustup_dir_exists() {
600600
// There appears to be both a ~/.multirust dir and a valid ~/.rustup
601-
// dir. Weird situation. Pick ~/.rustup.
601+
// dir. Most likely because one is a symlink to the other, as configured
602+
// below.
602603
true
603604
} else {
604605
if rename_multirust_dir_to_rustup().is_ok() {
606+
// Finally, making the hardlink from ~/.multirust back to
607+
// ~/.rustup, for temporary compatibility.
608+
let _ = create_legacy_multirust_symlink();
605609
true
606610
} else {
607611
false
@@ -612,6 +616,51 @@ pub fn do_rustup_home_upgrade() -> bool {
612616
}
613617
}
614618

619+
// Creates a ~/.rustup folder and a ~/.multirust symlink
620+
pub fn create_rustup_home() -> Result<()> {
621+
// If RUSTUP_HOME is set then don't make any assumptions about where it's
622+
// ok to put ~/.multirust
623+
if env::var_os("RUSTUP_HOME").is_some() { return Ok(()) }
624+
625+
let home = rustup_home_in_user_dir()?;
626+
fs::create_dir_all(&home)
627+
.chain_err(|| "unable to create ~/.rustup")?;
628+
629+
// This is a temporary compatibility symlink
630+
create_legacy_multirust_symlink()?;
631+
632+
Ok(())
633+
}
634+
635+
// Create a symlink from ~/.multirust to ~/.rustup to temporarily
636+
// accomodate old tools that are expecting that directory
637+
fn create_legacy_multirust_symlink() -> Result<()> {
638+
let newhome = rustup_home_in_user_dir()?;
639+
let oldhome = legacy_multirust_home()?;
640+
641+
raw::symlink_dir(&newhome, &oldhome)
642+
.chain_err(|| format!("unable to symlink {} from {}",
643+
newhome.display(), oldhome.display()))?;
644+
645+
Ok(())
646+
}
647+
648+
pub fn delete_legacy_multirust_symlink() -> Result<()> {
649+
let oldhome = legacy_multirust_home()?;
650+
651+
if oldhome.exists() {
652+
let meta = fs::symlink_metadata(&oldhome)
653+
.chain_err(|| "unable to get metadata for ~/.multirust")?;
654+
if meta.file_type().is_symlink() {
655+
// remove_dir handles unlinking symlinks
656+
raw::remove_dir(&oldhome)
657+
.chain_err(|| format!("unable to delete legacy symlink {}", oldhome.display()))?;
658+
}
659+
}
660+
661+
Ok(())
662+
}
663+
615664
fn dot_dir(name: &str) -> Option<PathBuf> {
616665
home_dir().map(|p| p.join(name))
617666
}
@@ -620,6 +669,10 @@ pub fn legacy_multirust_home() -> Result<PathBuf> {
620669
dot_dir(".multirust").ok_or(ErrorKind::MultirustHome.into())
621670
}
622671

672+
pub fn rustup_home_in_user_dir() -> Result<PathBuf> {
673+
dot_dir(".rustup").ok_or(ErrorKind::MultirustHome.into())
674+
}
675+
623676
pub fn multirust_home() -> Result<PathBuf> {
624677
let use_rustup_dir = do_rustup_home_upgrade();
625678

tests/cli-rustup.rs

+36-13
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ fn remove_component() {
551551
// Run without setting RUSTUP_HOME, with setting HOME and USERPROFILE
552552
fn run_no_home(config: &Config, args: &[&str], env: &[(&str, &str)]) -> process::Output {
553553
let home_dir_str = &format!("{}", config.homedir.display());
554-
let mut cmd = clitools::cmd(config, "rustup", args);
554+
let mut cmd = clitools::cmd(config, args[0], &args[1..]);
555555
clitools::env(config, &mut cmd);
556556
cmd.env_remove("RUSTUP_HOME");
557557
cmd.env("HOME", home_dir_str);
@@ -574,9 +574,9 @@ fn multirust_dir_upgrade_rename_multirust_dir_to_rustup() {
574574
let multirust_dir_str = &format!("{}", multirust_dir.display());
575575

576576
// First write data into ~/.multirust
577-
run_no_home(config, &["default", "stable"],
577+
run_no_home(config, &["rustup", "default", "stable"],
578578
&[("RUSTUP_HOME", multirust_dir_str)]);
579-
let out = run_no_home(config, &["toolchain", "list"],
579+
let out = run_no_home(config, &["rustup", "toolchain", "list"],
580580
&[("RUSTUP_HOME", multirust_dir_str)]);
581581
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
582582

@@ -586,10 +586,11 @@ fn multirust_dir_upgrade_rename_multirust_dir_to_rustup() {
586586
// Next run without RUSTUP_DIR, but with HOME/USERPROFILE set so rustup
587587
// can infer RUSTUP_DIR. It will silently move ~/.multirust to
588588
// ~/.rustup.
589-
let out = run_no_home(config, &["toolchain", "list"], &[]);
589+
let out = run_no_home(config, &["rustup", "toolchain", "list"], &[]);
590590
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
591591

592-
assert!(!multirust_dir.exists());
592+
assert!(multirust_dir.exists());
593+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
593594
assert!(rustup_dir.exists());
594595
});
595596
}
@@ -607,9 +608,9 @@ fn multirust_dir_upgrade_old_rustup_exists() {
607608
let new_rustup_sh_version_file = rustup_sh_dir.join("rustup-version");
608609

609610
// First write data into ~/.multirust
610-
run_no_home(config, &["default", "stable"],
611+
run_no_home(config, &["rustup", "default", "stable"],
611612
&[("RUSTUP_HOME", multirust_dir_str)]);
612-
let out = run_no_home(config, &["toolchain", "list"],
613+
let out = run_no_home(config, &["rustup", "toolchain", "list"],
613614
&[("RUSTUP_HOME", multirust_dir_str)]);
614615
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
615616

@@ -622,10 +623,11 @@ fn multirust_dir_upgrade_old_rustup_exists() {
622623
assert!(old_rustup_sh_version_file.exists());
623624

624625
// Now do the upgrade, and ~/.rustup will be moved to ~/.rustup.sh
625-
let out = run_no_home(config, &["toolchain", "list"], &[]);
626+
let out = run_no_home(config, &["rustup", "toolchain", "list"], &[]);
626627
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
627628

628-
assert!(!multirust_dir.exists());
629+
assert!(multirust_dir.exists());
630+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
629631
assert!(rustup_dir.exists());
630632
assert!(!old_rustup_sh_version_file.exists());
631633
assert!(new_rustup_sh_version_file.exists());
@@ -646,9 +648,9 @@ fn multirust_dir_upgrade_old_rustup_existsand_new_rustup_sh_exists() {
646648
let new_rustup_sh_version_file = rustup_sh_dir.join("rustup-version");
647649

648650
// First write data into ~/.multirust
649-
run_no_home(config, &["default", "stable"],
651+
run_no_home(config, &["rustup", "default", "stable"],
650652
&[("RUSTUP_HOME", multirust_dir_str)]);
651-
let out = run_no_home(config, &["toolchain", "list"],
653+
let out = run_no_home(config, &["rustup", "toolchain", "list"],
652654
&[("RUSTUP_HOME", multirust_dir_str)]);
653655
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
654656

@@ -670,12 +672,33 @@ fn multirust_dir_upgrade_old_rustup_existsand_new_rustup_sh_exists() {
670672
assert!(new_rustup_sh_version_file.exists());
671673

672674
// Now do the upgrade, and ~/.rustup will be moved to ~/.rustup.sh
673-
let out = run_no_home(config, &["toolchain", "list"], &[]);
675+
let out = run_no_home(config, &["rustup", "toolchain", "list"], &[]);
674676
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
675677

676-
assert!(!multirust_dir.exists());
678+
// .multirust is now a symlink to .rustup
679+
assert!(multirust_dir.exists());
680+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
681+
677682
assert!(rustup_dir.exists());
678683
assert!(!old_rustup_sh_version_file.exists());
679684
assert!(new_rustup_sh_version_file.exists());
680685
});
681686
}
687+
688+
#[test]
689+
fn multirust_upgrade_works_with_proxy() {
690+
setup(&|config| {
691+
let multirust_dir = config.homedir.join(".multirust");
692+
let rustup_dir = config.homedir.join(".rustup");
693+
694+
// Put data in ~/.multirust
695+
run_no_home(config, &["rustup", "default", "stable"],
696+
&[("RUSTUP_HOME", &format!("{}", multirust_dir.display()))]);
697+
698+
run_no_home(config, &["rustc", "--version"], &[]);
699+
700+
assert!(multirust_dir.exists());
701+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
702+
assert!(rustup_dir.exists());
703+
});
704+
}

tests/cli-self-upd.rs

+36-2
Original file line numberDiff line numberDiff line change
@@ -804,8 +804,8 @@ fn install_deletes_legacy_multirust_bins() {
804804
setup(&|config| {
805805
let ref multirust_bin_dir = config.rustupdir.join("bin");
806806
fs::create_dir_all(multirust_bin_dir).unwrap();
807-
let ref multirust_bin = multirust_bin_dir.join("rustup");
808-
let ref rustc_bin = multirust_bin_dir.join("rustc");
807+
let ref multirust_bin = multirust_bin_dir.join("old-mutirust");
808+
let ref rustc_bin = multirust_bin_dir.join("old-rustc");
809809
raw::write_file(multirust_bin, "").unwrap();
810810
raw::write_file(rustc_bin, "").unwrap();
811811
assert!(multirust_bin.exists());
@@ -1076,3 +1076,37 @@ fn legacy_upgrade_removes_multirust_bin() {
10761076
assert!(!multirust_bin.exists());
10771077
});
10781078
}
1079+
1080+
// Create a ~/.multirust symlink to ~/.rustup
1081+
#[test]
1082+
fn install_creates_legacy_home_symlink() {
1083+
setup(&|config| {
1084+
let mut cmd = clitools::cmd(config, "rustup-init", &["-y"]);
1085+
// It'll only do this behavior when RUSTUP_HOME isn't set
1086+
cmd.env_remove("RUSTUP_HOME");
1087+
1088+
assert!(cmd.output().unwrap().status.success());
1089+
1090+
let rustup_dir = config.homedir.join(".rustup");
1091+
assert!(rustup_dir.exists());
1092+
let multirust_dir = config.homedir.join(".multirust");
1093+
assert!(multirust_dir.exists());
1094+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
1095+
});
1096+
}
1097+
1098+
#[test]
1099+
fn uninstall_removes_legacy_home_symlink() {
1100+
setup(&|config| {
1101+
let mut cmd = clitools::cmd(config, "rustup-init", &["-y"]);
1102+
// It'll only do this behavior when RUSTUP_HOME isn't set
1103+
cmd.env_remove("RUSTUP_HOME");
1104+
assert!(cmd.output().unwrap().status.success());
1105+
1106+
let multirust_dir = config.homedir.join(".multirust");
1107+
assert!(multirust_dir.exists());
1108+
1109+
expect_ok(config, &["rustup", "self", "uninstall", "-y"]);
1110+
assert!(!multirust_dir.exists());
1111+
});
1112+
}

0 commit comments

Comments
 (0)