Skip to content
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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ Command | Description
`rustup target add arm-linux-androideabi` | Install the Android target
`rustup target remove arm-linux-androideabi` | Remove the Android target
`rustup run nightly rustc foo.rs` | Run the nightly regardless of the active toolchain
`rustc +nightly foo.rs` | Shorthand way to run a nightly compiler
`rustup run nightly bash` | Run a shell configured for the nightly compiler
`rustup default stable-msvc` | On Windows, use the MSVC toolchain instead of GNU
`rustup override nightly-2015-04-01` | For the current directory, use a nightly from a specific date
Expand Down
10 changes: 9 additions & 1 deletion src/rustup-cli/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,15 @@ r"
Configures an environment to use the given toolchain and then runs
the specified program. The command may be any program, not just
rustc or cargo. This can be used for testing arbitrary toolchains
without setting an override.";
without setting an override.

Commands explicitly proxied by `rustup` (such as `rustc` and `cargo`)
also have a shorthand for this available. The toolchain can be set by
using `+toolchain` as the first argument. These are equivalent:

cargo +nightly build

rustup run nightly cargo build";

pub static DOC_HELP: &'static str =
r"
Expand Down
34 changes: 28 additions & 6 deletions src/rustup-cli/proxy_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use errors::*;
use rustup_utils::utils;
use rustup::command::run_command_for_dir;
use std::env;
use std::ffi::OsString;
use std::path::PathBuf;
use job;

Expand All @@ -12,23 +13,44 @@ pub fn main() -> Result<()> {

job::setup();

let arg0 = env::args().next().map(|a| PathBuf::from(a));
let mut args = env::args();

let arg0 = args.next().map(|a| PathBuf::from(a));
let arg0 = arg0.as_ref()
.and_then(|a| a.file_name())
.and_then(|a| a.to_str());
let ref arg0 = try!(arg0.ok_or(ErrorKind::NoExeName));

// Check for a toolchain specifier.
let arg1 = args.next();
let toolchain = arg1.as_ref()
.and_then(|arg1| {
if arg1.starts_with("+") {
Some(&arg1[1..])
} else {
None
}
});

// Build command args now while we know whether or not to skip arg 1.
let cmd_args: Vec<_> = if toolchain.is_none() {
env::args_os().collect()
} else {
env::args_os().take(1).chain(env::args_os().skip(2)).collect()
};

let cfg = try!(set_globals(false));
try!(cfg.check_metadata_version());
try!(direct_proxy(&cfg, arg0));
try!(direct_proxy(&cfg, arg0, toolchain, &cmd_args));

Ok(())
}

fn direct_proxy(cfg: &Cfg, arg0: &str) -> Result<()> {
let cmd = try!(cfg.create_command_for_dir(&try!(utils::current_dir()), arg0));
let args: Vec<_> = env::args_os().collect();

fn direct_proxy(cfg: &Cfg, arg0: &str, toolchain: Option<&str>, args: &[OsString]) -> Result<()> {
let cmd = match toolchain {
None => try!(cfg.create_command_for_dir(&try!(utils::current_dir()), arg0)),
Some(tc) => try!(cfg.create_command_for_toolchain(tc, arg0)),
};
Ok(try!(run_command_for_dir(cmd, &args, &cfg)))
}

11 changes: 11 additions & 0 deletions tests/cli-rustup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,3 +501,14 @@ fn toolchain_update_is_like_update_except_that_bare_install_is_an_error() {
"arguments were not provided");
});
}

#[test]
fn proxy_toolchain_shorthand() {
setup(&|config| {
expect_ok(config, &["rustup", "default", "stable"]);
expect_ok(config, &["rustup", "toolchain", "update" , "nightly"]);
expect_stdout_ok(config, &["rustc", "--version"], "hash-s-2");
expect_stdout_ok(config, &["rustc", "+stable", "--version"], "hash-s-2");
expect_stdout_ok(config, &["rustc", "+nightly", "--version"], "hash-n-2");
});
}