Skip to content

Commit

Permalink
Merge #719
Browse files Browse the repository at this point in the history
719: Add --list to known subcommands. r=Alexhuszagh a=Alexhuszagh

`cross --list` should list the subcommands present for cargo in the image, rather on the host. This works because any option provided before a subcommand has priority over the subcommand. For example, `cargo build --help` prints the help menu for `cargo build`, but `cargo --help build` ignores `build` and prints the help for `cargo`. Therefore, the options `--help`, `--version`, and `--list` can be treated as pseudo-subcommands.

Fixes #715.

Co-authored-by: Alex Huszagh <ahuszagh@gmail.com>
  • Loading branch information
bors[bot] and Alexhuszagh authored May 28, 2022
2 parents e4d429d + 0938182 commit c8df353
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 11 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- #722 - boolean environment variables are evaluated as truthy or falsey.
- #721 - add support for running doctests on nightly if `CROSS_UNSTABLE_ENABLE_DOCTESTS=true`.
- #719 - add android runner to preload `libc++_shared.so`.
- #720 - add android runner to preload `libc++_shared.so`.
- #719 - add `--list` to known subcommands.
- #718 - remove deb subcommand.
- #714 - use host target directory when falling back to host cargo.
- #713 - convert relative target directories to absolute paths.
Expand Down
9 changes: 8 additions & 1 deletion src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ pub enum Subcommand {
Bench,
Clippy,
Metadata,
List,
}

impl Subcommand {
pub fn needs_docker(self) -> bool {
!matches!(self, Subcommand::Other)
!matches!(self, Subcommand::Other | Subcommand::List)
}

pub fn needs_interpreter(self) -> bool {
Expand All @@ -45,6 +46,7 @@ impl<'a> From<&'a str> for Subcommand {
"bench" => Subcommand::Bench,
"clippy" => Subcommand::Clippy,
"metadata" => Subcommand::Metadata,
"--list" => Subcommand::List,
_ => Subcommand::Other,
}
}
Expand Down Expand Up @@ -88,3 +90,8 @@ pub fn root() -> Result<Option<Root>> {
pub fn run(args: &[String], verbose: bool) -> Result<ExitStatus> {
Command::new("cargo").args(args).run_and_get_status(verbose)
}

/// run cargo and get the output, does not check the exit status
pub fn run_and_get_output(args: &[String], verbose: bool) -> Result<std::process::Output> {
Command::new("cargo").args(args).run_and_get_output(verbose)
}
35 changes: 34 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,39 @@ fn bool_from_envvar(envvar: &str) -> bool {
}
}

pub fn is_subcommand_list(stdout: &str) -> bool {
stdout.starts_with("Installed Commands:")
}

pub fn group_subcommands(stdout: &str) -> (Vec<&str>, Vec<&str>) {
let mut cross = vec![];
let mut host = vec![];
for line in stdout.lines().skip(1) {
// trim all whitespace, then grab the command name
let first = line.trim().split_whitespace().next();
if let Some(command) = first {
match Subcommand::from(command) {
Subcommand::Other => host.push(line),
_ => cross.push(line),
}
}
}

(cross, host)
}

pub fn fmt_subcommands(stdout: &str) {
let (cross, host) = group_subcommands(stdout);
if !cross.is_empty() {
println!("Cross Commands:");
cross.iter().for_each(|line| println!("{}", line));
}
if !host.is_empty() {
println!("Host Commands:");
host.iter().for_each(|line| println!("{}", line));
}
}

pub fn parse(target_list: &TargetList) -> Result<Args> {
let mut channel = None;
let mut target = None;
Expand Down Expand Up @@ -74,7 +107,7 @@ pub fn parse(target_list: &TargetList) -> Result<Args> {
all.push("--target-dir=/target".into());
}
} else {
if !arg.starts_with('-') && sc.is_none() {
if (!arg.starts_with('-') || arg == "--list") && sc.is_none() {
sc = Some(Subcommand::from(arg.as_ref()));
}

Expand Down
29 changes: 24 additions & 5 deletions src/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub trait CommandExt {
fn run(&mut self, verbose: bool) -> Result<()>;
fn run_and_get_status(&mut self, verbose: bool) -> Result<ExitStatus>;
fn run_and_get_stdout(&mut self, verbose: bool) -> Result<String>;
fn run_and_get_output(&mut self, verbose: bool) -> Result<std::process::Output>;
}

impl CommandExt for Command {
Expand Down Expand Up @@ -42,14 +43,32 @@ impl CommandExt for Command {

/// Runs the command to completion and returns its stdout
fn run_and_get_stdout(&mut self, verbose: bool) -> Result<String> {
let out = self.run_and_get_output(verbose)?;
self.status_result(out.status)?;
out.stdout()
}

/// Runs the command to completion and returns the status and its [output](std::process::Output).
///
/// # Notes
///
/// This command does not check the status.
fn run_and_get_output(&mut self, verbose: bool) -> Result<std::process::Output> {
self.print_verbose(verbose);
let out = self
.output()
.wrap_err_with(|| format!("couldn't execute `{:?}`", self))?;
self.output()
.wrap_err_with(|| format!("couldn't execute `{:?}`", self))
.map_err(Into::into)
}
}

self.status_result(out.status)?;
pub trait OutputExt {
fn stdout(&self) -> Result<String>;
}

String::from_utf8(out.stdout).wrap_err_with(|| format!("`{:?}` output was not UTF-8", self))
impl OutputExt for std::process::Output {
fn stdout(&self) -> Result<String> {
String::from_utf8(self.stdout.clone())
.wrap_err_with(|| format!("`{:?}` output was not UTF-8", self))
}
}

Expand Down
22 changes: 19 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mod rustc;
mod rustup;

use std::env;
use std::io::{self, Write};
use std::path::PathBuf;
use std::process::ExitStatus;

Expand All @@ -27,6 +28,7 @@ use serde::Deserialize;
use self::cargo::{Root, Subcommand};
use self::cross_toml::CrossToml;
use self::errors::*;
use self::extensions::OutputExt;
use self::rustc::{TargetList, VersionMetaExt};

#[allow(non_camel_case_types)]
Expand Down Expand Up @@ -420,11 +422,25 @@ fn run() -> Result<ExitStatus> {
}
}

eprintln!("Warning: Falling back to `cargo` on the host.");

// if we fallback to the host cargo, use the same invocation that was made to cross
let argv: Vec<String> = env::args().skip(1).collect();
cargo::run(&argv, verbose)
eprintln!("Warning: Falling back to `cargo` on the host.");
match args.subcommand {
Some(Subcommand::List) => {
// this won't print in order if we have both stdout and stderr.
let out = cargo::run_and_get_output(&argv, verbose)?;
let stdout = out.stdout()?;
if out.status.success() && cli::is_subcommand_list(&stdout) {
cli::fmt_subcommands(&stdout);
} else {
// Not a list subcommand, which can happen with weird edge-cases.
print!("{}", stdout);
io::stdout().flush().unwrap();
}
Ok(out.status)
}
_ => cargo::run(&argv, verbose),
}
}

#[derive(PartialEq, Debug)]
Expand Down

0 comments on commit c8df353

Please sign in to comment.