-
Notifications
You must be signed in to change notification settings - Fork 891
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
Deal cleanly with malformed default-host #1578
Changes from all commits
26972a5
87c36da
5481115
983b5a6
e6a2dc9
239b34a
36ec58f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -223,6 223,7 @@ fn canonical_cargo_home() -> Result<String> { | |
/// and adding `CARGO_HOME`/bin to PATH. | ||
pub fn install(no_prompt: bool, verbose: bool, mut opts: InstallOpts) -> Result<()> { | ||
do_pre_install_sanity_checks()?; | ||
do_pre_install_options_sanity_checks(&opts)?; | ||
check_existence_of_rustc_or_cargo_in_path(no_prompt)?; | ||
do_anti_sudo_check(no_prompt)?; | ||
|
||
|
@@ -454,7 455,7 @@ fn do_pre_install_sanity_checks() -> Result<()> { | |
"delete `{}` to remove rustup.sh", | ||
rustup_sh_path.expect("").display() | ||
); | ||
warn!("or, if you already rustup installed, you can run"); | ||
warn!("or, if you already have rustup installed, you can run"); | ||
warn!("`rustup self update` and `rustup toolchain list` to upgrade"); | ||
warn!("your directory structure"); | ||
return Err("cannot install while rustup.sh is installed".into()); | ||
|
@@ -463,6 464,35 @@ fn do_pre_install_sanity_checks() -> Result<()> { | |
Ok(()) | ||
} | ||
|
||
fn do_pre_install_options_sanity_checks(opts: &InstallOpts) -> Result<()> { | ||
// Verify that the installation options are vaguely sane | ||
(|| { | ||
let host_triple = dist::TargetTriple::from_str(&opts.default_host_triple); | ||
let toolchain_to_use = if opts.default_toolchain == "none" { | ||
"stable" | ||
} else { | ||
&opts.default_toolchain | ||
}; | ||
let partial_channel = dist::PartialToolchainDesc::from_str(toolchain_to_use)?; | ||
let resolved = partial_channel.resolve(&host_triple)?.to_string(); | ||
debug!( | ||
"Successfully resolved installation toolchain as: {}", | ||
resolved | ||
); | ||
Ok(()) | ||
})() | ||
.map_err(|e: Box<std::error::Error>| { | ||
format!( | ||
"Pre-checks for host and toolchain failed: {}\n\ | ||
If you are unsure of suitable values, the 'stable' toolchain is the default.\n\ | ||
Valid host triples look something like: {}", | ||
e, | ||
dist::TargetTriple::from_host_or_build() | ||
) | ||
})?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should move this checking to its own function - There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I've created a function called |
||
Ok(()) | ||
} | ||
|
||
// If the user is trying to install with sudo, on some systems this will | ||
// result in writing root-owned files to the user's home directory, because | ||
// sudo is configured not to change $HOME. Don't let that bogosity happen. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,7 99,7 @@ impl Cfg { | |
); | ||
let dist_root = dist_root_server.clone() "/dist"; | ||
|
||
Ok(Cfg { | ||
let cfg = Cfg { | ||
rustup_dir: rustup_dir, | ||
settings_file: settings_file, | ||
toolchains_dir: toolchains_dir, | ||
|
@@ -111,7 111,15 @@ impl Cfg { | |
env_override: env_override, | ||
dist_root_url: dist_root, | ||
dist_root_server: dist_root_server, | ||
}) | ||
}; | ||
|
||
// Run some basic checks against the constructed configuration | ||
// For now, that means simply checking that 'stable' can resolve | ||
// for the current configuration. | ||
cfg.resolve_toolchain("stable") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand why we need this check. Could you explain please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. By doing this check here we verify that later attempts to resolve the toolchain are more likely to succeed. It means we report the error about bad host types etc earlier in the sequence of operations. This leads to, in my opinion, a slightly better user experience. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the explanation. I wonder if this will ever give a false negatve? If we have some toolchain which is nightly-only perhaps? |
||
.map_err(|e| format!("Unable parse configuration: {}", e))?; | ||
|
||
Ok(cfg) | ||
} | ||
|
||
pub fn set_default(&self, toolchain: &str) -> Result<()> { | ||
|
@@ -470,9 478,11 @@ impl Cfg { | |
} | ||
|
||
pub fn set_default_host_triple(&self, host_triple: &str) -> Result<()> { | ||
if dist::PartialTargetTriple::from_str(host_triple).is_none() { | ||
return Err("Invalid host triple".into()); | ||
} | ||
// Ensure that the provided host_triple is capable of resolving | ||
// against the 'stable' toolchain. This provides early errors | ||
// if the supplied triple is insufficient / bad. | ||
dist::PartialToolchainDesc::from_str("stable")? | ||
.resolve(&dist::TargetTriple::from_str(host_triple))?; | ||
self.settings_file.with_mut(|s| { | ||
s.default_host_triple = Some(host_triple.to_owned()); | ||
Ok(()) | ||
|
@@ -493,7 503,7 @@ impl Cfg { | |
pub fn resolve_toolchain(&self, name: &str) -> Result<String> { | ||
if let Ok(desc) = dist::PartialToolchainDesc::from_str(name) { | ||
let host = self.get_default_host_triple()?; | ||
Ok(desc.resolve(&host).to_string()) | ||
Ok(desc.resolve(&host)?.to_string()) | ||
} else { | ||
Ok(name.to_owned()) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it is duplicating behaviour defined elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To my knowledge it's not per-se. This is simply because using PartialToolchainDesc::resolve needs a valid toolchain name or it won't work (and none isn't valid IIRC).
It looks similar to other checks, but this time we're resolving from options and don't have a
Cfg
struct so I can't just callset_default_host
et al, and deal with things that way. Also thedebug!()
is meant to be useful to tell us that it's behaving right and picking the correct fully qualified toolchain name.If I've missed something you know of, please do let me know, but I've had a fairly good grep around I think.