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

Installation profiles #1673

Merged
merged 3 commits into from
Sep 11, 2019
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
1 change: 1 addition & 0 deletions rustup-init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ OPTIONS:
--default-host <default-host> Choose a default host triple
--default-toolchain <default-toolchain> Choose a default toolchain to install
--default-toolchain none Do not install any toolchains
--profile [minimal|default|complete] Choose a profile
EOF
}

Expand Down
12 changes: 2 additions & 10 deletions src/cli/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,7 @@ pub fn list_targets(toolchain: &Toolchain<'_>) -> Result<()> {
.target
.as_ref()
.expect("rust-std should have a target");
if component.required {
let _ = t.attr(term2::Attr::Bold);
let _ = writeln!(t, "{} (default)", target);
let _ = t.reset();
} else if component.installed {
if component.installed {
let _ = t.attr(term2::Attr::Bold);
let _ = writeln!(t, "{} (installed)", target);
let _ = t.reset();
Expand Down Expand Up @@ -406,11 +402,7 @@ pub fn list_components(toolchain: &Toolchain<'_>) -> Result<()> {
let mut t = term2::stdout();
for component in toolchain.list_components()? {
let name = component.name;
if component.required {
t.attr(term2::Attr::Bold)?;
writeln!(t, "{} (default)", name)?;
t.reset()?;
} else if component.installed {
if component.installed {
t.attr(term2::Attr::Bold)?;
writeln!(t, "{} (installed)", name)?;
t.reset()?;
Expand Down
2 changes: 0 additions & 2 deletions src/cli/download_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ impl<'a> fmt::Display for Size<'a> {

#[cfg(test)]
mod tests {

#[test]
fn download_tracker_from_seconds_test() {
use crate::download_tracker::DownloadTracker;
Expand All @@ -267,5 +266,4 @@ mod tests {

assert_eq!(DownloadTracker::from_seconds(222_292), (2, 13, 44, 52));
}

nrc marked this conversation as resolved.
Show resolved Hide resolved
}
46 changes: 40 additions & 6 deletions src/cli/rustup_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::self_update;
use crate::term2;
use crate::term2::Terminal;
use clap::{App, AppSettings, Arg, ArgGroup, ArgMatches, Shell, SubCommand};
use rustup::dist::dist::{PartialTargetTriple, PartialToolchainDesc, TargetTriple};
use rustup::dist::dist::{PartialTargetTriple, PartialToolchainDesc, Profile, TargetTriple};
use rustup::dist::manifest::Component;
use rustup::utils::utils::{self, ExitCode};
use rustup::{command, Cfg, Toolchain};
Expand Down Expand Up @@ -44,6 +44,7 @@ pub fn main() -> Result<()> {
("show", Some(c)) => match c.subcommand() {
("active-toolchain", Some(_)) => handle_epipe(show_active_toolchain(cfg))?,
("home", Some(_)) => handle_epipe(show_rustup_home(cfg))?,
("profile", Some(_)) => handle_epipe(show_profile(cfg))?,
(_, _) => handle_epipe(show(cfg))?,
},
("install", Some(m)) => update(cfg, m)?,
Expand Down Expand Up @@ -86,6 +87,7 @@ pub fn main() -> Result<()> {
},
("set", Some(c)) => match c.subcommand() {
("default-host", Some(m)) => set_default_host_triple(&cfg, m)?,
("profile", Some(m)) => set_profile(&cfg, m)?,
(_, _) => unreachable!(),
},
("completions", Some(c)) => {
Expand Down Expand Up @@ -125,7 +127,7 @@ pub fn cli() -> App<'static, 'static> {
)
.subcommand(
SubCommand::with_name("show")
.about("Show the active and installed toolchains")
.about("Show the active and installed toolchains or profiles")
.after_help(SHOW_HELP)
.setting(AppSettings::VersionlessSubcommands)
.setting(AppSettings::DeriveDisplayOrder)
Expand All @@ -138,6 +140,7 @@ pub fn cli() -> App<'static, 'static> {
SubCommand::with_name("home")
.about("Display the computed value of RUSTUP_HOME"),
)
.subcommand(SubCommand::with_name("profile").about("Show the current profile")),
)
.subcommand(
SubCommand::with_name("install")
Expand Down Expand Up @@ -501,6 +504,16 @@ pub fn cli() -> App<'static, 'static> {
SubCommand::with_name("default-host")
.about("The triple used to identify toolchains when not specified")
.arg(Arg::with_name("host_triple").required(true)),
)
.subcommand(
SubCommand::with_name("profile")
.about("The default components installed")
.arg(
Arg::with_name("profile-name")
.required(true)
.possible_values(Profile::names())
.default_value(Profile::default_name()),
),
),
);

Expand Down Expand Up @@ -919,7 +932,11 @@ fn target_add(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
}

for target in &targets {
let new_component = Component::new("rust-std".to_string(), Some(TargetTriple::new(target)));
let new_component = Component::new(
"rust-std".to_string(),
Some(TargetTriple::new(target)),
false,
);
toolchain.add_component(new_component)?;
}

Expand All @@ -930,7 +947,11 @@ fn target_remove(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
let toolchain = explicit_or_dir_toolchain(cfg, m)?;

for target in m.values_of("target").expect("") {
let new_component = Component::new("rust-std".to_string(), Some(TargetTriple::new(target)));
let new_component = Component::new(
"rust-std".to_string(),
Some(TargetTriple::new(target)),
false,
);

toolchain.remove_component(new_component)?;
}
Expand Down Expand Up @@ -959,7 +980,7 @@ fn component_add(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
});

for component in m.values_of("component").expect("") {
let new_component = Component::new(component.to_string(), target.clone());
let new_component = Component::new(component.to_string(), target.clone(), true);

toolchain.add_component(new_component)?;
}
Expand All @@ -978,7 +999,7 @@ fn component_remove(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
});

for component in m.values_of("component").expect("") {
let new_component = Component::new(component.to_string(), target.clone());
let new_component = Component::new(component.to_string(), target.clone(), true);

toolchain.remove_component(new_component)?;
}
Expand Down Expand Up @@ -1159,6 +1180,19 @@ fn set_default_host_triple(cfg: &Cfg, m: &ArgMatches<'_>) -> Result<()> {
Ok(())
}

fn set_profile(cfg: &Cfg, m: &ArgMatches) -> Result<()> {
cfg.set_profile(&m.value_of("profile-name").unwrap())?;
Ok(())
}

fn show_profile(cfg: &Cfg) -> Result<()> {
match cfg.get_profile()? {
Some(p) => println!("{}", p),
None => println!("No profile set"),
}
Ok(())
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum CompletionCommand {
Rustup,
Expand Down
34 changes: 29 additions & 5 deletions src/cli/self_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::common::{self, Confirm};
use crate::errors::*;
use crate::markdown::md;
use crate::term2;
use rustup::dist::dist;
use rustup::dist::dist::{self, Profile};
use rustup::utils::utils;
use rustup::utils::Notification;
use rustup::{DUP_TOOLS, TOOLS};
Expand All @@ -48,6 +48,7 @@ use std::process::{self, Command};
pub struct InstallOpts {
pub default_host_triple: String,
pub default_toolchain: String,
pub profile: String,
pub no_modify_path: bool,
}

Expand Down Expand Up @@ -278,7 +279,12 @@ pub fn install(no_prompt: bool, verbose: bool, mut opts: InstallOpts) -> Result<
do_add_to_path(&get_add_path_methods())?;
}
utils::create_rustup_home()?;
maybe_install_rust(&opts.default_toolchain, &opts.default_host_triple, verbose)?;
maybe_install_rust(
&opts.default_toolchain,
&opts.profile,
&opts.default_host_triple,
verbose,
)?;

if cfg!(unix) {
let env_file = utils::cargo_home()?.join("env");
Expand Down Expand Up @@ -590,10 +596,12 @@ fn current_install_opts(opts: &InstallOpts) -> String {

- ` `default host triple: `{}`
- ` `default toolchain: `{}`
- ` `profile: `{}`
- modify PATH variable: `{}`
",
opts.default_host_triple,
opts.default_toolchain,
opts.profile,
if !opts.no_modify_path { "yes" } else { "no" }
)
}
Expand All @@ -615,6 +623,14 @@ fn customize_install(mut opts: InstallOpts) -> Result<InstallOpts> {
&opts.default_toolchain,
)?;

opts.profile = common::question_str(
&format!(
"Profile (which tools and data to install)? ({})",
Profile::names().join("/")
),
&opts.profile,
)?;

opts.no_modify_path =
!common::question_bool("Modify PATH variable? (y/n)", !opts.no_modify_path)?;

Expand Down Expand Up @@ -716,8 +732,14 @@ pub fn install_proxies() -> Result<()> {
Ok(())
}

fn maybe_install_rust(toolchain_str: &str, default_host_triple: &str, verbose: bool) -> Result<()> {
fn maybe_install_rust(
toolchain_str: &str,
profile_str: &str,
default_host_triple: &str,
verbose: bool,
) -> Result<()> {
let cfg = common::set_globals(verbose)?;
cfg.set_profile(profile_str)?;

// If there is already an install, then `toolchain_str` may not be
// a toolchain the user actually wants. Don't do anything. FIXME:
Expand Down Expand Up @@ -787,7 +809,8 @@ pub fn uninstall(no_prompt: bool) -> Result<()> {
// Delete everything in CARGO_HOME *except* the rustup bin

// First everything except the bin directory
for dirent in fs::read_dir(&cargo_home).chain_err(|| read_dir_err)? {
let diriter = fs::read_dir(&cargo_home).chain_err(|| read_dir_err)?;
for dirent in diriter {
let dirent = dirent.chain_err(|| read_dir_err)?;
if dirent.file_name().to_str() != Some("bin") {
if dirent.path().is_dir() {
Expand All @@ -805,7 +828,8 @@ pub fn uninstall(no_prompt: bool) -> Result<()> {
.chain(DUP_TOOLS.iter())
.map(|t| format!("{}{}", t, EXE_SUFFIX));
let tools: Vec<_> = tools.chain(vec![format!("rustup{}", EXE_SUFFIX)]).collect();
for dirent in fs::read_dir(&cargo_home.join("bin")).chain_err(|| read_dir_err)? {
let diriter = fs::read_dir(&cargo_home.join("bin")).chain_err(|| read_dir_err)?;
for dirent in diriter {
let dirent = dirent.chain_err(|| read_dir_err)?;
let name = dirent.file_name();
let file_is_tool = name.to_str().map(|n| tools.iter().any(|t| *t == n));
Expand Down
12 changes: 11 additions & 1 deletion src/cli/setup_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::common;
use crate::errors::*;
use crate::self_update::{self, InstallOpts};
use clap::{App, AppSettings, Arg};
use rustup::dist::dist::TargetTriple;
use rustup::dist::dist::{Profile, TargetTriple};
use std::env;

pub fn main() -> Result<()> {
Expand Down Expand Up @@ -48,6 +48,12 @@ pub fn main() -> Result<()> {
.takes_value(true)
.help("Choose a default toolchain to install"),
)
.arg(
Arg::with_name("profile")
.long("profile")
.possible_values(Profile::names())
.default_value(Profile::default_name()),
)
.arg(
Arg::with_name("no-modify-path")
.long("no-modify-path")
Expand All @@ -62,11 +68,15 @@ pub fn main() -> Result<()> {
.map(std::borrow::ToOwned::to_owned)
.unwrap_or_else(|| TargetTriple::from_host_or_build().to_string());
let default_toolchain = matches.value_of("default-toolchain").unwrap_or("stable");
let profile = matches
.value_of("profile")
.expect("Unreachable: Clap should supply a default");
let no_modify_path = matches.is_present("no-modify-path");

let opts = InstallOpts {
default_host_triple: default_host,
default_toolchain: default_toolchain.to_owned(),
profile: profile.to_owned(),
no_modify_path,
};

Expand Down
30 changes: 30 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,36 @@ impl Cfg {
Ok(())
}

pub fn set_profile(&self, profile: &str) -> Result<()> {
if !dist::Profile::names().contains(&profile) {
kinnison marked this conversation as resolved.
Show resolved Hide resolved
return Err(ErrorKind::UnknownProfile(profile.to_owned()).into());
}
self.settings_file.with_mut(|s| {
s.profile = Some(profile.to_owned());
Ok(())
})?;
(self.notify_handler)(Notification::SetProfile(profile));
Ok(())
}

// Returns a profile, if one exists in the settings file.
//
// Returns `Err` if the settings file could not be read or the profile is
// invalid. Returns `Ok(Some(...))` if there is a valid profile, and `Ok(None)`
// if there is no profile in the settings file. The last variant happens when
// a user upgrades from a version of Rustup without profiles to a version of
// Rustup with profiles.
pub fn get_profile(&self) -> Result<Option<dist::Profile>> {
self.settings_file.with(|s| {
let p = match &s.profile {
Some(p) => p,
None => return Ok(None),
kinnison marked this conversation as resolved.
Show resolved Hide resolved
};
let p = dist::Profile::from_str(p)?;
Ok(Some(p))
})
}

pub fn get_toolchain(&self, name: &str, create_parent: bool) -> Result<Toolchain<'_>> {
if create_parent {
utils::ensure_dir_exists("toolchains", &self.toolchains_dir, &|n| {
Expand Down
10 changes: 5 additions & 5 deletions src/dist/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ pub struct Config {

impl Config {
pub fn from_toml(mut table: toml::value::Table, path: &str) -> Result<Self> {
let version = get_string(&mut table, "config_version", path)?;
if !SUPPORTED_CONFIG_VERSIONS.contains(&&*version) {
return Err(ErrorKind::UnsupportedVersion(version).into());
let config_version = get_string(&mut table, "config_version", path)?;
if !SUPPORTED_CONFIG_VERSIONS.contains(&&*config_version) {
return Err(ErrorKind::UnsupportedVersion(config_version).into());
}

let components = get_array(&mut table, "components", path)?;
let components =
Self::toml_to_components(components, &format!("{}{}.", path, "components"))?;

Ok(Self {
config_version: version,
config_version,
components,
})
}
Expand Down Expand Up @@ -55,7 +55,7 @@ impl Config {
for (i, v) in arr.into_iter().enumerate() {
if let toml::Value::Table(t) = v {
let path = format!("{}[{}]", path, i);
result.push(Component::from_toml(t, &path)?);
result.push(Component::from_toml(t, &path, false)?);
}
}

Expand Down
Loading