Skip to content

Commit a07ee8c

Browse files
committed
Set up ~/.multirust as a temporary symlink to ~/.rustup
1 parent 418c512 commit a07ee8c

File tree

5 files changed

+134
-18
lines changed

5 files changed

+134
-18
lines changed

src/rustup-cli/self_update.rs

Lines changed: 6 additions & 0 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 54 additions & 1 deletion
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

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ fn remove_component() {
589589
// Run without setting RUSTUP_HOME, with setting HOME and USERPROFILE
590590
fn run_no_home(config: &Config, args: &[&str], env: &[(&str, &str)]) -> process::Output {
591591
let home_dir_str = &format!("{}", config.homedir.display());
592-
let mut cmd = clitools::cmd(config, "rustup", args);
592+
let mut cmd = clitools::cmd(config, args[0], &args[1..]);
593593
clitools::env(config, &mut cmd);
594594
cmd.env_remove("RUSTUP_HOME");
595595
cmd.env("HOME", home_dir_str);
@@ -612,9 +612,9 @@ fn multirust_dir_upgrade_rename_multirust_dir_to_rustup() {
612612
let multirust_dir_str = &format!("{}", multirust_dir.display());
613613

614614
// First write data into ~/.multirust
615-
run_no_home(config, &["default", "stable"],
615+
run_no_home(config, &["rustup", "default", "stable"],
616616
&[("RUSTUP_HOME", multirust_dir_str)]);
617-
let out = run_no_home(config, &["toolchain", "list"],
617+
let out = run_no_home(config, &["rustup", "toolchain", "list"],
618618
&[("RUSTUP_HOME", multirust_dir_str)]);
619619
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
620620

@@ -624,10 +624,11 @@ fn multirust_dir_upgrade_rename_multirust_dir_to_rustup() {
624624
// Next run without RUSTUP_DIR, but with HOME/USERPROFILE set so rustup
625625
// can infer RUSTUP_DIR. It will silently move ~/.multirust to
626626
// ~/.rustup.
627-
let out = run_no_home(config, &["toolchain", "list"], &[]);
627+
let out = run_no_home(config, &["rustup", "toolchain", "list"], &[]);
628628
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
629629

630-
assert!(!multirust_dir.exists());
630+
assert!(multirust_dir.exists());
631+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
631632
assert!(rustup_dir.exists());
632633
});
633634
}
@@ -645,9 +646,9 @@ fn multirust_dir_upgrade_old_rustup_exists() {
645646
let new_rustup_sh_version_file = rustup_sh_dir.join("rustup-version");
646647

647648
// First write data into ~/.multirust
648-
run_no_home(config, &["default", "stable"],
649+
run_no_home(config, &["rustup", "default", "stable"],
649650
&[("RUSTUP_HOME", multirust_dir_str)]);
650-
let out = run_no_home(config, &["toolchain", "list"],
651+
let out = run_no_home(config, &["rustup", "toolchain", "list"],
651652
&[("RUSTUP_HOME", multirust_dir_str)]);
652653
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
653654

@@ -660,10 +661,11 @@ fn multirust_dir_upgrade_old_rustup_exists() {
660661
assert!(old_rustup_sh_version_file.exists());
661662

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

666-
assert!(!multirust_dir.exists());
667+
assert!(multirust_dir.exists());
668+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
667669
assert!(rustup_dir.exists());
668670
assert!(!old_rustup_sh_version_file.exists());
669671
assert!(new_rustup_sh_version_file.exists());
@@ -684,9 +686,9 @@ fn multirust_dir_upgrade_old_rustup_existsand_new_rustup_sh_exists() {
684686
let new_rustup_sh_version_file = rustup_sh_dir.join("rustup-version");
685687

686688
// First write data into ~/.multirust
687-
run_no_home(config, &["default", "stable"],
689+
run_no_home(config, &["rustup", "default", "stable"],
688690
&[("RUSTUP_HOME", multirust_dir_str)]);
689-
let out = run_no_home(config, &["toolchain", "list"],
691+
let out = run_no_home(config, &["rustup", "toolchain", "list"],
690692
&[("RUSTUP_HOME", multirust_dir_str)]);
691693
assert!(String::from_utf8(out.stdout).unwrap().contains("stable"));
692694

@@ -708,12 +710,33 @@ fn multirust_dir_upgrade_old_rustup_existsand_new_rustup_sh_exists() {
708710
assert!(new_rustup_sh_version_file.exists());
709711

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

714-
assert!(!multirust_dir.exists());
716+
// .multirust is now a symlink to .rustup
717+
assert!(multirust_dir.exists());
718+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
719+
715720
assert!(rustup_dir.exists());
716721
assert!(!old_rustup_sh_version_file.exists());
717722
assert!(new_rustup_sh_version_file.exists());
718723
});
719724
}
725+
726+
#[test]
727+
fn multirust_upgrade_works_with_proxy() {
728+
setup(&|config| {
729+
let multirust_dir = config.homedir.join(".multirust");
730+
let rustup_dir = config.homedir.join(".rustup");
731+
732+
// Put data in ~/.multirust
733+
run_no_home(config, &["rustup", "default", "stable"],
734+
&[("RUSTUP_HOME", &format!("{}", multirust_dir.display()))]);
735+
736+
run_no_home(config, &["rustc", "--version"], &[]);
737+
738+
assert!(multirust_dir.exists());
739+
assert!(fs::symlink_metadata(&multirust_dir).unwrap().file_type().is_symlink());
740+
assert!(rustup_dir.exists());
741+
});
742+
}

tests/cli-self-upd.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,9 +802,9 @@ fn install_sets_up_stable_unless_there_is_already_a_default() {
802802
#[cfg(unix)]
803803
fn install_deletes_legacy_multirust_bins() {
804804
setup(&|config| {
805-
let ref multirust_bin_dir = config.rustupdir.join("bin");
805+
let ref multirust_bin_dir = config.homedir.join(".multirust/bin");
806806
fs::create_dir_all(multirust_bin_dir).unwrap();
807-
let ref multirust_bin = multirust_bin_dir.join("rustup");
807+
let ref multirust_bin = multirust_bin_dir.join("multirust");
808808
let ref rustc_bin = multirust_bin_dir.join("rustc");
809809
raw::write_file(multirust_bin, "").unwrap();
810810
raw::write_file(rustc_bin, "").unwrap();
@@ -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)