Skip to content

Commit

Permalink
Add verbose flag to print cargo commands
Browse files Browse the repository at this point in the history
Also fix minor issue with building test crate for doctests.
  • Loading branch information
ian-h-chamberlain committed Aug 6, 2023
1 parent 268c45a commit d374e70
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 33 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ serde = { version = "1.0.139", features = ["derive"] }
tee = "0.1.0"
toml = "0.5.6"
clap = { version = "4.0.15", features = ["derive", "wrap_help"] }
shlex = "1.1.0"
37 changes: 23 additions & 14 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ pub enum Cargo {
pub struct Input {
#[command(subcommand)]
pub cmd: CargoCmd,

/// Print the exact commands `cargo-3ds` is running. Note that this does not
/// set the verbose flag for cargo itself.
#[arg(long, short = 'v')]
pub verbose: bool,
}

/// Run a cargo command. COMMAND will be forwarded to the real
Expand Down Expand Up @@ -153,6 +158,10 @@ impl CargoCmd {
"--doc".to_string(),
"-Z".to_string(),
"doctest-xcompile".to_string(),
// doctests don't automatically build the `test` crate,
// so we manually specify it on the command line
"-Z".to_string(),
"build-std=std,test".to_string(),
]);
} else {
cargo_args.push("--no-run".to_string());
Expand Down Expand Up @@ -278,7 +287,7 @@ impl CargoCmd {
///
/// - `cargo 3ds build` and other "build" commands will use their callbacks to build the final `.3dsx` file and link it.
/// - `cargo 3ds new` and other generic commands will use their callbacks to make 3ds-specific changes to the environment.
pub fn run_callback(&self, messages: &[Message]) {
pub fn run_callback(&self, messages: &[Message], verbose: bool) {
// Process the metadata only for commands that have it/use it
let config = if self.should_build_3dsx() {
eprintln!("Getting metadata");
Expand All @@ -290,9 +299,9 @@ impl CargoCmd {

// Run callback only for commands that use it
match self {
Self::Build(cmd) => cmd.callback(&config),
Self::Run(cmd) => cmd.callback(&config),
Self::Test(cmd) => cmd.callback(&config),
Self::Build(cmd) => cmd.callback(&config, verbose),
Self::Run(cmd) => cmd.callback(&config, verbose),
Self::Test(cmd) => cmd.callback(&config, verbose),
Self::New(cmd) => cmd.callback(),
_ => (),
}
Expand Down Expand Up @@ -327,12 +336,12 @@ impl Build {
/// Callback for `cargo 3ds build`.
///
/// This callback handles building the application as a `.3dsx` file.
fn callback(&self, config: &CTRConfig) {
eprintln!("Building smdh:{}", config.path_smdh().display());
build_smdh(config);
fn callback(&self, config: &CTRConfig, verbose: bool) {
eprintln!("Building smdh: {}", config.path_smdh().display());
build_smdh(config, verbose);

eprintln!("Building 3dsx: {}", config.path_3dsx().display());
build_3dsx(config);
build_3dsx(config, verbose);
}
}

Expand Down Expand Up @@ -381,26 +390,26 @@ impl Run {
/// Callback for `cargo 3ds run`.
///
/// This callback handles launching the application via `3dslink`.
fn callback(&self, config: &CTRConfig) {
fn callback(&self, config: &CTRConfig, verbose: bool) {
// Run the normal "build" callback
self.build_args.callback(config);
self.build_args.callback(config, verbose);

eprintln!("Running 3dslink");
link(config, self);
link(config, self, verbose);
}
}

impl Test {
/// Callback for `cargo 3ds test`.
///
/// This callback handles launching the application via `3dslink`.
fn callback(&self, config: &CTRConfig) {
fn callback(&self, config: &CTRConfig, verbose: bool) {
if self.no_run {
// If the tests don't have to run, use the "build" callback
self.run_args.build_args.callback(config)
self.run_args.build_args.callback(config, verbose)
} else {
// If the tests have to run, use the "run" callback
self.run_args.callback(config)
self.run_args.callback(config, verbose)
}
}
}
Expand Down
69 changes: 52 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub mod command;
use crate::command::{CargoCmd, Run};

use cargo_metadata::{Message, MetadataCommand};
use command::Test;
use command::{Input, Test};
use rustc_version::Channel;
use semver::Version;
use serde::Deserialize;
Expand All @@ -20,16 +20,20 @@ use std::{env, io, process};
///
/// For commands that produce an executable output, this function will build the
/// `.elf` binary that can be used to create other 3ds files.
pub fn run_cargo(cmd: &CargoCmd, message_format: Option<String>) -> (ExitStatus, Vec<Message>) {
let mut command = make_cargo_command(cmd, &message_format);
pub fn run_cargo(input: &Input, message_format: Option<String>) -> (ExitStatus, Vec<Message>) {
let mut command = make_cargo_command(&input.cmd, &message_format);

if input.verbose {
print_command(&command);
}

let mut process = command.spawn().unwrap();
let command_stdout = process.stdout.take().unwrap();

let mut tee_reader;
let mut stdout_reader;

let buf_reader: &mut dyn BufRead = match (message_format, cmd) {
let buf_reader: &mut dyn BufRead = match (message_format, &input.cmd) {
// The user presumably cares about the message format if set, so we should
// copy stuff to stdout like they expect. We can still extract the executable
// information out of it that we need for 3dsxtool etc.
Expand Down Expand Up @@ -112,6 +116,23 @@ pub fn make_cargo_command(cmd: &CargoCmd, message_format: &Option<String>) -> Co
command
}

fn print_command(command: &Command) {
let mut cmd_str = vec![command.get_program().to_string_lossy().to_string()];
cmd_str.extend(command.get_args().map(|s| s.to_string_lossy().to_string()));

eprintln!("Running command:");
for (k, v) in command.get_envs() {
let v = v.map(|v| v.to_string_lossy().to_string());
eprintln!(
" {}={} \\",
k.to_string_lossy(),
v.map_or_else(String::new, |s| shlex::quote(&s).to_string())
);
}
eprintln!(" {}", shlex::join(cmd_str.iter().map(String::as_str)));
eprintln!();
}

/// Finds the sysroot path of the current toolchain
pub fn find_sysroot() -> PathBuf {
let sysroot = env::var("SYSROOT").ok().unwrap_or_else(|| {
Expand Down Expand Up @@ -235,8 +256,9 @@ pub fn get_metadata(messages: &[Message]) -> CTRConfig {

/// Builds the smdh using `smdhtool`.
/// This will fail if `smdhtool` is not within the running directory or in a directory found in $PATH
pub fn build_smdh(config: &CTRConfig) {
let mut process = Command::new("smdhtool")
pub fn build_smdh(config: &CTRConfig, verbose: bool) {
let mut command = Command::new("smdhtool");
command
.arg("--create")
.arg(&config.name)
.arg(&config.description)
Expand All @@ -245,7 +267,13 @@ pub fn build_smdh(config: &CTRConfig) {
.arg(config.path_smdh())
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.stderr(Stdio::inherit());

if verbose {
print_command(&command);
}

let mut process = command
.spawn()
.expect("smdhtool command failed, most likely due to 'smdhtool' not being in $PATH");

Expand All @@ -258,9 +286,9 @@ pub fn build_smdh(config: &CTRConfig) {

/// Builds the 3dsx using `3dsxtool`.
/// This will fail if `3dsxtool` is not within the running directory or in a directory found in $PATH
pub fn build_3dsx(config: &CTRConfig) {
pub fn build_3dsx(config: &CTRConfig, verbose: bool) {
let mut command = Command::new("3dsxtool");
let mut process = command
command
.arg(&config.target_path)
.arg(config.path_3dsx())
.arg(format!("--smdh={}", config.path_smdh().to_string_lossy()));
Expand All @@ -269,7 +297,7 @@ pub fn build_3dsx(config: &CTRConfig) {
let (romfs_path, is_default_romfs) = get_romfs_path(config);
if romfs_path.is_dir() {
eprintln!("Adding RomFS from {}", romfs_path.display());
process = process.arg(format!("--romfs={}", romfs_path.to_string_lossy()));
command.arg(format!("--romfs={}", romfs_path.to_string_lossy()));
} else if !is_default_romfs {
eprintln!(
"Could not find configured RomFS dir: {}",
Expand All @@ -278,7 +306,11 @@ pub fn build_3dsx(config: &CTRConfig) {
process::exit(1);
}

let mut process = process
if verbose {
print_command(&command);
}

let mut process = command
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
Expand All @@ -294,17 +326,20 @@ pub fn build_3dsx(config: &CTRConfig) {

/// Link the generated 3dsx to a 3ds to execute and test using `3dslink`.
/// This will fail if `3dslink` is not within the running directory or in a directory found in $PATH
pub fn link(config: &CTRConfig, run_args: &Run) {
let mut process = Command::new("3dslink")
pub fn link(config: &CTRConfig, run_args: &Run, verbose: bool) {
let mut command = Command::new("3dslink");
command
.arg(config.path_3dsx())
.args(run_args.get_3dslink_args())
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()
.unwrap();
.stderr(Stdio::inherit());

let status = process.wait().unwrap();
if verbose {
print_command(&command);
}

let status = command.spawn().unwrap().wait().unwrap();

if !status.success() {
process::exit(status.code().unwrap_or(1));
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ fn main() {
}
};

let (status, messages) = run_cargo(&input.cmd, message_format);
let (status, messages) = run_cargo(&input, message_format);

if !status.success() {
process::exit(status.code().unwrap_or(1));
}

input.cmd.run_callback(&messages);
input.cmd.run_callback(&messages, input.verbose);
}

0 comments on commit d374e70

Please sign in to comment.