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. 52
      src/lib.rs

13
README.md

@ -95,3 +95,16 @@ executable arguments, *another* `--` can be used. For example: @@ -95,3 +95,16 @@ executable arguments, *another* `--` can be used. For example:
This works without two `--` instances because `--verbose` begins the set of
`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 { @@ -66,6 +66,11 @@ pub struct Test {
#[arg(long)]
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.
#[command(flatten)]
pub run_args: Run,
@ -104,7 +109,10 @@ pub struct Run { @@ -104,7 +109,10 @@ pub struct Run {
impl CargoCmd {
/// Whether or not this command should build a 3DSX executable file.
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

52
src/lib.rs

@ -3,6 +3,7 @@ pub mod command; @@ -3,6 +3,7 @@ pub mod command;
use crate::command::CargoCmd;
use cargo_metadata::{Message, MetadataCommand};
use command::Test;
use rustc_version::Channel;
use semver::Version;
use serde::Deserialize;
@ -26,15 +27,23 @@ pub fn run_cargo(cmd: &CargoCmd, message_format: Option<String>) -> (ExitStatus, @@ -26,15 +27,23 @@ pub fn run_cargo(cmd: &CargoCmd, message_format: Option<String>) -> (ExitStatus,
let mut tee_reader;
let mut stdout_reader;
let buf_reader: &mut dyn BufRead = if message_format.is_none() {
stdout_reader = BufReader::new(command_stdout);
&mut stdout_reader
} else {
// The user presumably cares about the message format, so we should
let buf_reader: &mut dyn BufRead = match (message_format, 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.
tee_reader = BufReader::new(TeeReader::new(command_stdout, io::stdout()));
&mut tee_reader
(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()));
&mut tee_reader
}
_ => {
stdout_reader = BufReader::new(command_stdout);
&mut stdout_reader
}
};
let messages = Message::parse_stream(buf_reader)
@ -75,7 +84,7 @@ pub fn make_cargo_build_command(cmd: &CargoCmd, message_format: &Option<String>) @@ -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() {
eprintln!("No pre-build std found, using build-std");
eprintln!("No pre-built std found, using build-std");
command.arg("-Z").arg("build-std");
}
@ -83,9 +92,25 @@ pub fn make_cargo_build_command(cmd: &CargoCmd, message_format: &Option<String>) @@ -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::Run(run) => run.cargo_args.cargo_args(),
CargoCmd::Test(test) => {
// We can't run 3DS executables on the host, so pass --no-run here and
// send the executable with 3dslink later, if the user wants
command.arg("--no-run");
// We can't run 3DS executables on the host, so unconditionally pass
// --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");
}
test.run_args.cargo_args.cargo_args()
}
CargoCmd::Passthrough(other) => &other[1..],
@ -146,10 +171,7 @@ pub fn check_rust_version() { @@ -146,10 +171,7 @@ pub fn check_rust_version() {
};
if old_version || old_commit {
eprintln!(
"cargo-3ds requires rustc nightly version >= {}",
MINIMUM_COMMIT_DATE,
);
eprintln!("cargo-3ds requires rustc nightly version >= {MINIMUM_COMMIT_DATE}");
eprintln!("Please run `rustup update nightly` to upgrade your nightly version");
process::exit(1);

Loading…
Cancel
Save