Browse Source

Add limited support for `cargo 3ds test --doc`

pull/32/head
Ian Chamberlain 2 years ago
parent
commit
e8535a130d
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 13
      README.md
  2. 10
      src/command.rs
  3. 46
      src/lib.rs

13
README.md

@ -95,3 +95,16 @@ executable arguments, *another* `--` can be used. For example:
This works without two `--` instances because `--verbose` begins the set of This works without two `--` instances because `--verbose` begins the set of
`cargo` arguments and ends the set of 3DS-specific arguments. `cargo` arguments and ends the set of 3DS-specific arguments.
### Caveats
Due to the fact that only one executable at a time can be sent with `3dslink`,
by default only the "last" executable built will be used. If a `test` or `run`
command builds more than one binary, you may need to filter it in order to run
the executable you want.
Doc tests sort of work, but `cargo-3ds` uses a number of unstable cargo and
rustdoc features to make them work, so the output won't be as pretty and will
require some manual workarounds to actually run the tests and see output from them.
For now, `cargo 3ds test --doc` will not build a 3dsx file or use `3dslink` at all.

10
src/command.rs

@ -66,6 +66,11 @@ pub struct Test {
#[arg(long)] #[arg(long)]
pub no_run: bool, pub no_run: bool,
/// If set, documentation tests will be built instead of unit tests.
/// This implies `--no-run`.
#[arg(long)]
pub doc: bool,
// The test command uses a superset of the same arguments as Run. // The test command uses a superset of the same arguments as Run.
#[command(flatten)] #[command(flatten)]
pub run_args: Run, pub run_args: Run,
@ -104,7 +109,10 @@ pub struct Run {
impl CargoCmd { impl CargoCmd {
/// Whether or not this command should build a 3DSX executable file. /// Whether or not this command should build a 3DSX executable file.
pub fn should_build_3dsx(&self) -> bool { pub fn should_build_3dsx(&self) -> bool {
matches!(self, Self::Build(_) | Self::Run(_) | Self::Test(_)) matches!(
self,
Self::Build(_) | Self::Run(_) | Self::Test(Test { doc: false, .. })
)
} }
/// Whether or not the resulting executable should be sent to the 3DS with /// Whether or not the resulting executable should be sent to the 3DS with

46
src/lib.rs

@ -3,6 +3,7 @@ pub mod command;
use crate::command::CargoCmd; use crate::command::CargoCmd;
use cargo_metadata::{Message, MetadataCommand}; use cargo_metadata::{Message, MetadataCommand};
use command::Test;
use rustc_version::Channel; use rustc_version::Channel;
use semver::Version; use semver::Version;
use serde::Deserialize; use serde::Deserialize;
@ -26,15 +27,23 @@ pub fn run_cargo(cmd: &CargoCmd, message_format: Option<String>) -> (ExitStatus,
let mut tee_reader; let mut tee_reader;
let mut stdout_reader; let mut stdout_reader;
let buf_reader: &mut dyn BufRead = if message_format.is_none() {
stdout_reader = BufReader::new(command_stdout); let buf_reader: &mut dyn BufRead = match (message_format, cmd) {
&mut stdout_reader // The user presumably cares about the message format if set, so we should
} else {
// The user presumably cares about the message format, so we should
// copy stuff to stdout like they expect. We can still extract the executable // copy stuff to stdout like they expect. We can still extract the executable
// information out of it that we need for 3dsxtool etc. // information out of it that we need for 3dsxtool etc.
(Some(_), _) |
// Rustdoc unfortunately prints to stdout for compile errors, so
// we also use a tee when building doc tests too.
// Possibly related: https://github.com/rust-lang/rust/issues/75135
(None, CargoCmd::Test(Test { doc: true, .. })) => {
tee_reader = BufReader::new(TeeReader::new(command_stdout, io::stdout())); tee_reader = BufReader::new(TeeReader::new(command_stdout, io::stdout()));
&mut tee_reader &mut tee_reader
}
_ => {
stdout_reader = BufReader::new(command_stdout);
&mut stdout_reader
}
}; };
let messages = Message::parse_stream(buf_reader) let messages = Message::parse_stream(buf_reader)
@ -75,7 +84,7 @@ pub fn make_cargo_build_command(cmd: &CargoCmd, message_format: &Option<String>)
); );
if !sysroot.join("lib/rustlib/armv6k-nintendo-3ds").exists() { if !sysroot.join("lib/rustlib/armv6k-nintendo-3ds").exists() {
eprintln!("No pre-build std found, using build-std"); eprintln!("No pre-built std found, using build-std");
command.arg("-Z").arg("build-std"); command.arg("-Z").arg("build-std");
} }
@ -83,9 +92,25 @@ pub fn make_cargo_build_command(cmd: &CargoCmd, message_format: &Option<String>)
CargoCmd::Build(cargo_args) => cargo_args.cargo_args(), CargoCmd::Build(cargo_args) => cargo_args.cargo_args(),
CargoCmd::Run(run) => run.cargo_args.cargo_args(), CargoCmd::Run(run) => run.cargo_args.cargo_args(),
CargoCmd::Test(test) => { CargoCmd::Test(test) => {
// We can't run 3DS executables on the host, so pass --no-run here and // We can't run 3DS executables on the host, so unconditionally pass
// send the executable with 3dslink later, if the user wants // --no-run here and send the executable with 3dslink later, if the
// user wants
if test.doc {
// https://github.com/rust-lang/cargo/issues/7040
command.args(["--doc", "-Z", "doctest-xcompile"]);
// Cargo doesn't like --no-run for doctests:
// https://github.com/rust-lang/rust/issues/87022
let rustdoc_flags = std::env::var("RUSTDOCFLAGS").unwrap_or_default()
// TODO: should we make this output directory depend on profile etc?
+ " --no-run --persist-doctests target/doctests";
command.env("RUSTDOCFLAGS", rustdoc_flags);
} else {
command.arg("--no-run"); command.arg("--no-run");
}
test.run_args.cargo_args.cargo_args() test.run_args.cargo_args.cargo_args()
} }
CargoCmd::Passthrough(other) => &other[1..], CargoCmd::Passthrough(other) => &other[1..],
@ -146,10 +171,7 @@ pub fn check_rust_version() {
}; };
if old_version || old_commit { if old_version || old_commit {
eprintln!( eprintln!("cargo-3ds requires rustc nightly version >= {MINIMUM_COMMIT_DATE}");
"cargo-3ds requires rustc nightly version >= {}",
MINIMUM_COMMIT_DATE,
);
eprintln!("Please run `rustup update nightly` to upgrade your nightly version"); eprintln!("Please run `rustup update nightly` to upgrade your nightly version");
process::exit(1); process::exit(1);

Loading…
Cancel
Save