Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename ~/.multirust to ~/.rustup #830

Merged
merged 2 commits into from
Dec 2, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/rustup-cli/self_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ pub fn install(no_prompt: bool, verbose: bool,
if !opts.no_modify_path {
try!(do_add_to_path(&get_add_path_methods()));
}
// Create ~/.rustup and a compatibility ~/.multirust symlink.
// FIXME: Someday we can stop setting up the symlink, and when
// we do that we can stop creating ~/.rustup as well.
try!(utils::create_rustup_home());
try!(maybe_install_rust(&opts.default_toolchain, &opts.default_host_triple, verbose));

if cfg!(unix) {
Expand Down Expand Up @@ -508,7 +512,7 @@ fn cleanup_legacy() -> Result<()> {

#[cfg(unix)]
fn legacy_multirust_home_dir() -> Result<PathBuf> {
Ok(try!(utils::multirust_home()))
Ok(try!(utils::legacy_multirust_home()))
}

#[cfg(windows)]
Expand Down Expand Up @@ -607,6 +611,8 @@ pub fn uninstall(no_prompt: bool) -> Result<()> {

info!("removing rustup home");

try!(utils::delete_legacy_multirust_symlink());

// Delete RUSTUP_HOME
let ref rustup_dir = try!(utils::multirust_home());
if rustup_dir.exists() {
Expand Down
4 changes: 2 additions & 2 deletions src/rustup-mock/src/clitools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ pub fn env(config: &Config, cmd: &mut Command) {
cmd.env("CARGO_HOME", config.cargodir.to_string_lossy().to_string());
cmd.env("RUSTUP_OVERRIDE_HOST_TRIPLE", this_host_triple());

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

// Setting HOME will confuse the sudo check for rustup-init. Override it
cmd.env("RUSTUP_INIT_SKIP_SUDO_CHECK", "yes");
Expand Down
184 changes: 183 additions & 1 deletion src/rustup-utils/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,12 +497,194 @@ pub fn cargo_home() -> Result<PathBuf> {
cargo_home.or(user_home).ok_or(ErrorKind::CargoHome.into())
}

// Convert the ~/.multirust folder to ~/.rustup while dealing with rustup.sh
// metadata, which used to also live in ~/.rustup, but now lives in ~/rustup.sh.
pub fn do_rustup_home_upgrade() -> bool {

fn rustup_home_is_set() -> bool {
env::var_os("RUSTUP_HOME").is_some()
}

fn rustup_dir() -> Option<PathBuf> {
dot_dir(".rustup")
}

fn rustup_sh_dir() -> Option<PathBuf> {
dot_dir(".rustup.sh")
}

fn multirust_dir() -> Option<PathBuf> {
dot_dir(".multirust")
}

fn rustup_dir_exists() -> bool {
rustup_dir().map(|p| p.exists()).unwrap_or(false)
}

fn rustup_sh_dir_exists() -> bool {
rustup_sh_dir().map(|p| p.exists()).unwrap_or(false)
}

fn multirust_dir_exists() -> bool {
multirust_dir().map(|p| p.exists()).unwrap_or(false)
}

fn rustup_old_version_exists() -> bool {
rustup_dir()
.map(|p| p.join("rustup-version").exists())
.unwrap_or(false)
}

fn delete_rustup_dir() -> Result<()> {
if let Some(dir) = rustup_dir() {
raw::remove_dir(&dir)
.chain_err(|| "unable to delete rustup dir")?;
}

Ok(())
}

fn rename_rustup_dir_to_rustup_sh() -> Result<()> {
let dirs = (rustup_dir(), rustup_sh_dir());
if let (Some(rustup), Some(rustup_sh)) = dirs {
fs::rename(&rustup, &rustup_sh)
.chain_err(|| "unable to rename rustup dir")?;
}

Ok(())
}

fn rename_multirust_dir_to_rustup() -> Result<()> {
let dirs = (multirust_dir(), rustup_dir());
if let (Some(rustup), Some(rustup_sh)) = dirs {
fs::rename(&rustup, &rustup_sh)
.chain_err(|| "unable to rename multirust dir")?;
}

Ok(())
}

// If RUSTUP_HOME is set then its default path doesn't matter, so we're
// not going to risk doing any I/O work and making a mess.
if rustup_home_is_set() { return true }

// Now we are just trying to get a bogus, rustup.sh-created ~/.rustup out
// of the way in the manner that is least likely to take time and generate
// errors. First try to rename it to ~/.rustup.sh, then try to delete it.
// If that doesn't work we can't use the ~/.rustup name.
let old_rustup_dir_removed = if rustup_old_version_exists() {
if !rustup_sh_dir_exists() {
if rename_rustup_dir_to_rustup_sh().is_ok() {
true
} else {
if delete_rustup_dir().is_ok() {
true
} else {
false
}
}
} else {
if delete_rustup_dir().is_ok() {
true
} else {
false
}
}
} else {
true
};

// Now we're trying to move ~/.multirust to ~/.rustup
old_rustup_dir_removed && if multirust_dir_exists() {
if rustup_dir_exists() {
// There appears to be both a ~/.multirust dir and a valid ~/.rustup
// dir. Most likely because one is a symlink to the other, as configured
// below.
true
} else {
if rename_multirust_dir_to_rustup().is_ok() {
// Finally, making the hardlink from ~/.multirust back to
// ~/.rustup, for temporary compatibility.
let _ = create_legacy_multirust_symlink();
true
} else {
false
}
}
} else {
true
}
}

// Creates a ~/.rustup folder and a ~/.multirust symlink
pub fn create_rustup_home() -> Result<()> {
// 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(()) }

let home = rustup_home_in_user_dir()?;
fs::create_dir_all(&home)
.chain_err(|| "unable to create ~/.rustup")?;

// This is a temporary compatibility symlink
create_legacy_multirust_symlink()?;

Ok(())
}

// Create a symlink from ~/.multirust to ~/.rustup to temporarily
// accomodate old tools that are expecting that directory
fn create_legacy_multirust_symlink() -> Result<()> {
let newhome = rustup_home_in_user_dir()?;
let oldhome = legacy_multirust_home()?;

raw::symlink_dir(&newhome, &oldhome)
.chain_err(|| format!("unable to symlink {} from {}",
newhome.display(), oldhome.display()))?;

Ok(())
}

pub fn delete_legacy_multirust_symlink() -> Result<()> {
let oldhome = legacy_multirust_home()?;

if oldhome.exists() {
let meta = fs::symlink_metadata(&oldhome)
.chain_err(|| "unable to get metadata for ~/.multirust")?;
if meta.file_type().is_symlink() {
// remove_dir handles unlinking symlinks
raw::remove_dir(&oldhome)
.chain_err(|| format!("unable to delete legacy symlink {}", oldhome.display()))?;
}
}

Ok(())
}

fn dot_dir(name: &str) -> Option<PathBuf> {
home_dir().map(|p| p.join(name))
}

pub fn legacy_multirust_home() -> Result<PathBuf> {
dot_dir(".multirust").ok_or(ErrorKind::MultirustHome.into())
}

pub fn rustup_home_in_user_dir() -> Result<PathBuf> {
dot_dir(".rustup").ok_or(ErrorKind::MultirustHome.into())
}

pub fn multirust_home() -> Result<PathBuf> {
let use_rustup_dir = do_rustup_home_upgrade();

let cwd = try!(env::current_dir().chain_err(|| ErrorKind::MultirustHome));
let multirust_home = env::var_os("RUSTUP_HOME").map(|home| {
cwd.join(home)
});
let user_home = home_dir().map(|p| p.join(".multirust"));
let user_home = if use_rustup_dir {
dot_dir(".rustup")
} else {
dot_dir(".multirust")
};
multirust_home.or(user_home).ok_or(ErrorKind::MultirustHome.into())
}

Expand Down
Loading