From 5a9135961f34505714e23f12e4cf4bacfa492dcd Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 14 Apr 2023 21:53:56 +0200 Subject: [PATCH 01/31] Split remove old examples --- examples/README.md | 42 +++++++ .../rp2040_local_i2c_init/.cargo/config.toml | 45 +++++++ examples/rp2040_local_i2c_init/Cargo.toml | 32 +++++ examples/rp2040_local_i2c_init/Embed.toml | 39 ++++++ examples/rp2040_local_i2c_init/build.rs | 31 +++++ examples/rp2040_local_i2c_init/memory.x | 15 +++ examples/rp2040_local_i2c_init/src/main.rs | 114 ++++++++++++++++++ examples/stm32f3_blinky/.cargo/config.toml | 45 +++++++ examples/stm32f3_blinky/Cargo.toml | 35 ++++++ examples/stm32f3_blinky/Embed.toml | 9 ++ examples/stm32f3_blinky/README.md | 19 +++ examples/stm32f3_blinky/memory.x | 5 + examples/stm32f3_blinky/src/main.rs | 74 ++++++++++++ 13 files changed, 505 insertions(+) create mode 100644 examples/README.md create mode 100644 examples/rp2040_local_i2c_init/.cargo/config.toml create mode 100644 examples/rp2040_local_i2c_init/Cargo.toml create mode 100644 examples/rp2040_local_i2c_init/Embed.toml create mode 100644 examples/rp2040_local_i2c_init/build.rs create mode 100644 examples/rp2040_local_i2c_init/memory.x create mode 100644 examples/rp2040_local_i2c_init/src/main.rs create mode 100644 examples/stm32f3_blinky/.cargo/config.toml create mode 100644 examples/stm32f3_blinky/Cargo.toml create mode 100644 examples/stm32f3_blinky/Embed.toml create mode 100644 examples/stm32f3_blinky/README.md create mode 100644 examples/stm32f3_blinky/memory.x create mode 100644 examples/stm32f3_blinky/src/main.rs diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000000..929d3f20d7 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,42 @@ +# `RTIC examples` + +> Here you can find examples on different aspects of the RTIC scheduler. + +## Structure + +This repo does have example applications based on RTIC framework for popular hardware platforms (for example nRF series and Bluepill). + +## Requirements + +To run these examples, you need to have working environment as described in [Installing the tools](https://rust-embedded.github.io/book/intro/install.html) chapter of **The Embedded Rust Book**. + +Short list: + +* Rust and cargo +* Toolchain for your microcontroller +* OpenOCD + +## Contributing +New examples are always welcome! + +## External examples + +Some projects maintain RTIC examples in their own repository. Follow these links to find more RTIC examples. + +- The [`teensy4-rs` project](https://github.com/mciantyre/teensy4-rs) maintains `RTIC v1.0` examples that run on the Teensy 4.0 and 4.1. + +## License + +Licensed under either of + +* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or + [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)) +* MIT license ([LICENSE-MIT](LICENSE-MIT) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT)) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the +work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any +additional terms or conditions. diff --git a/examples/rp2040_local_i2c_init/.cargo/config.toml b/examples/rp2040_local_i2c_init/.cargo/config.toml new file mode 100644 index 0000000000..c6e086aa50 --- /dev/null +++ b/examples/rp2040_local_i2c_init/.cargo/config.toml @@ -0,0 +1,45 @@ +[target.thumbv6m-none-eabi] +# uncomment this to make `cargo run` execute programs on QEMU +# runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# uncomment ONE of these three option to make `cargo run` start a GDB session +# which option to pick depends on your system +# runner = "arm-none-eabi-gdb -q -x openocd.gdb" +# runner = "gdb-multiarch -q -x openocd.gdb" +# runner = "gdb -q -x openocd.gdb" + +rustflags = [ + # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x + # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 + "-C", "link-arg=--nmagic", + + # LLD (shipped with the Rust toolchain) is used as the default linker + "-C", "link-arg=-Tlink.x", + + # if you run into problems with LLD switch to the GNU linker by commenting out + # this line + # "-C", "linker=arm-none-eabi-ld", + + # if you need to link to pre-compiled C libraries provided by a C toolchain + # use GCC as the linker by commenting out both lines above and then + # uncommenting the three lines below + # "-C", "linker=arm-none-eabi-gcc", + # "-C", "link-arg=-Wl,-Tlink.x", + # "-C", "link-arg=-nostartfiles", +] + +[build] +# Pick ONE of these compilation targets +target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +# target = "thumbv7m-none-eabi" # Cortex-M3 +# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) +# target = "thumbv8m.base-none-eabi" # Cortex-M23 +# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU) +# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU) + +# thumbv7m-none-eabi is not coming with core and alloc, compile myself +[unstable] +mtime-on-use = true +build-std = ["core", "alloc"] diff --git a/examples/rp2040_local_i2c_init/Cargo.toml b/examples/rp2040_local_i2c_init/Cargo.toml new file mode 100644 index 0000000000..4aed0b83ac --- /dev/null +++ b/examples/rp2040_local_i2c_init/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "rp2040_local_i2c_init" +categories = ["embedded", "no-std"] +description = "Example task local initialized resources for Raspberry Pi Pico" +license = "MIT OR Apache-2.0" +version = "0.1.0" +edition = "2021" + +[dependencies] +cortex-m = "0.7" +rtic = { git = "https://github.com/rtic-rs/rtic", features = [ + "thumbv6-backend", +] } +rtic-monotonics = { git = "https://github.com/rtic-rs/rtic", features = [ + "rp2040", +] } +embedded-hal = { version = "0.2.7", features = ["unproven"] } +fugit = "0.3" +rp-pico = "0.7.0" +panic-probe = "0.3" + +[profile.dev] +opt-level = 1 +codegen-units = 16 +debug = true +lto = false + +[profile.release] +opt-level = "s" # optimize for size +codegen-units = 1 # better optimizations +debug = true # symbols are nice and they don't increase the size on Flash +lto = true # better optimzations diff --git a/examples/rp2040_local_i2c_init/Embed.toml b/examples/rp2040_local_i2c_init/Embed.toml new file mode 100644 index 0000000000..0e6edc09f2 --- /dev/null +++ b/examples/rp2040_local_i2c_init/Embed.toml @@ -0,0 +1,39 @@ +[default.probe] +protocol = "Swd" +speed = 20000 +# If you only have one probe cargo embed will pick automatically +# Otherwise: add your probe's VID/PID/serial to filter + +## rust-dap +# usb_vid = "6666" +# usb_pid = "4444" +# serial = "test" + + +[default.flashing] +enabled = true + +[default.reset] +enabled = true +halt_afterwards = false + +[default.general] +chip = "RP2040" +log_level = "WARN" +# RP2040 does not support connect_under_reset +connect_under_reset = false + +[default.rtt] +enabled = true +up_mode = "NoBlockSkip" +channels = [ + { up = 0, down = 0, name = "name", up_mode = "NoBlockSkip", format = "Defmt" }, +] +timeout = 3000 +show_timestamps = true +log_enabled = false +log_path = "./logs" + +[default.gdb] +enabled = true +gdb_connection_string = "127.0.0.1:2345" diff --git a/examples/rp2040_local_i2c_init/build.rs b/examples/rp2040_local_i2c_init/build.rs new file mode 100644 index 0000000000..d534cc3df6 --- /dev/null +++ b/examples/rp2040_local_i2c_init/build.rs @@ -0,0 +1,31 @@ +//! This build script copies the `memory.x` file from the crate root into +//! a directory where the linker can always find it at build time. +//! For many projects this is optional, as the linker always searches the +//! project root directory -- wherever `Cargo.toml` is. However, if you +//! are using a workspace or have a more complicated build setup, this +//! build script becomes required. Additionally, by requesting that +//! Cargo re-run the build script whenever `memory.x` is changed, +//! updating `memory.x` ensures a rebuild of the application with the +//! new memory settings. + +use std::env; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + // Put `memory.x` in our output directory and ensure it's + // on the linker search path. + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + // By default, Cargo will re-run a build script whenever + // any file in the project changes. By specifying `memory.x` + // here, we ensure the build script is only re-run when + // `memory.x` is changed. + println!("cargo:rerun-if-changed=memory.x"); +} diff --git a/examples/rp2040_local_i2c_init/memory.x b/examples/rp2040_local_i2c_init/memory.x new file mode 100644 index 0000000000..4077aab279 --- /dev/null +++ b/examples/rp2040_local_i2c_init/memory.x @@ -0,0 +1,15 @@ +MEMORY { + BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 + FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} + +EXTERN(BOOT2_FIRMWARE) + +SECTIONS { + /* ### Boot loader */ + .boot2 ORIGIN(BOOT2) : + { + KEEP(*(.boot2)); + } > BOOT2 +} INSERT BEFORE .text; diff --git a/examples/rp2040_local_i2c_init/src/main.rs b/examples/rp2040_local_i2c_init/src/main.rs new file mode 100644 index 0000000000..3d881aa0d8 --- /dev/null +++ b/examples/rp2040_local_i2c_init/src/main.rs @@ -0,0 +1,114 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[rtic::app( + device = rp_pico::hal::pac, + dispatchers = [TIMER_IRQ_1] +)] +mod app { + use rp_pico::hal::{ + clocks, gpio, + gpio::pin::bank0::{Gpio2, Gpio25, Gpio3}, + gpio::pin::PushPullOutput, + pac, + sio::Sio, + watchdog::Watchdog, + I2C, + }; + use rp_pico::XOSC_CRYSTAL_FREQ; + + use core::mem::MaybeUninit; + use embedded_hal::digital::v2::{OutputPin, ToggleableOutputPin}; + use fugit::RateExtU32; + use rtic_monotonics::rp2040::*; + + use panic_probe as _; + + rtic_monotonics::make_rp2040_monotonic_handler!(); + + type I2CBus = I2C< + pac::I2C1, + ( + gpio::Pin, + gpio::Pin, + ), + >; + + #[shared] + struct Shared {} + + #[local] + struct Local { + led: gpio::Pin, + i2c: &'static mut I2CBus, + } + + #[init(local=[ + // Task local initialized resources are static + // Here we use MaybeUninit to allow for initialization in init() + // This enables its usage in driver initialization + i2c_ctx: MaybeUninit = MaybeUninit::uninit() + ])] + fn init(mut ctx: init::Context) -> (Shared, Local) { + // Configure the clocks, watchdog - The default is to generate a 125 MHz system clock + Timer::start(ctx.device.TIMER, &mut ctx.device.RESETS); // default rp2040 clock-rate is 125MHz + let mut watchdog = Watchdog::new(ctx.device.WATCHDOG); + let clocks = clocks::init_clocks_and_plls( + XOSC_CRYSTAL_FREQ, + ctx.device.XOSC, + ctx.device.CLOCKS, + ctx.device.PLL_SYS, + ctx.device.PLL_USB, + &mut ctx.device.RESETS, + &mut watchdog, + ) + .ok() + .unwrap(); + + // Init LED pin + let sio = Sio::new(ctx.device.SIO); + let gpioa = rp_pico::Pins::new( + ctx.device.IO_BANK0, + ctx.device.PADS_BANK0, + sio.gpio_bank0, + &mut ctx.device.RESETS, + ); + let mut led = gpioa.led.into_push_pull_output(); + led.set_low().unwrap(); + + // Init I2C pins + let sda_pin = gpioa.gpio2.into_mode::(); + let scl_pin = gpioa.gpio3.into_mode::(); + + // Init I2C itself, using MaybeUninit to overwrite the previously + // uninitialized i2c_ctx variable without dropping its value + // (i2c_ctx definined in init local resources above) + let i2c_tmp: &'static mut _ = ctx.local.i2c_ctx.write(I2C::i2c1( + ctx.device.I2C1, + sda_pin, + scl_pin, + 100.kHz(), + &mut ctx.device.RESETS, + &clocks.system_clock, + )); + + // Spawn heartbeat task + heartbeat::spawn().ok(); + + // Return resources and timer + (Shared {}, Local { led, i2c: i2c_tmp }) + } + + #[task(local = [i2c, led])] + async fn heartbeat(ctx: heartbeat::Context) { + // Flicker the built-in LED + _ = ctx.local.led.toggle(); + + // Congrats, you can use your i2c and have access to it here, + // now to do something with it! + + // Re-spawn this task after 1 second + Timer::delay(1000.millis()).await; + } +} diff --git a/examples/stm32f3_blinky/.cargo/config.toml b/examples/stm32f3_blinky/.cargo/config.toml new file mode 100644 index 0000000000..05a5069a70 --- /dev/null +++ b/examples/stm32f3_blinky/.cargo/config.toml @@ -0,0 +1,45 @@ +[target.thumbv7m-none-eabi] +# uncomment this to make `cargo run` execute programs on QEMU +# runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# uncomment ONE of these three option to make `cargo run` start a GDB session +# which option to pick depends on your system +# runner = "arm-none-eabi-gdb -q -x openocd.gdb" +# runner = "gdb-multiarch -q -x openocd.gdb" +# runner = "gdb -q -x openocd.gdb" + +rustflags = [ + # This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x + # See https://github.com/rust-embedded/cortex-m-quickstart/pull/95 + "-C", "link-arg=--nmagic", + + # LLD (shipped with the Rust toolchain) is used as the default linker + "-C", "link-arg=-Tlink.x", + + # if you run into problems with LLD switch to the GNU linker by commenting out + # this line + # "-C", "linker=arm-none-eabi-ld", + + # if you need to link to pre-compiled C libraries provided by a C toolchain + # use GCC as the linker by commenting out both lines above and then + # uncommenting the three lines below + # "-C", "linker=arm-none-eabi-gcc", + # "-C", "link-arg=-Wl,-Tlink.x", + # "-C", "link-arg=-nostartfiles", +] + +[build] +# Pick ONE of these compilation targets +# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+ +target = "thumbv7m-none-eabi" # Cortex-M3 +# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU) +# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) +# target = "thumbv8m.base-none-eabi" # Cortex-M23 +# target = "thumbv8m.main-none-eabi" # Cortex-M33 (no FPU) +# target = "thumbv8m.main-none-eabihf" # Cortex-M33 (with FPU) + +# thumbv7m-none-eabi is not coming with core and alloc, compile myself +[unstable] +mtime-on-use = true +build-std = ["core", "alloc"] diff --git a/examples/stm32f3_blinky/Cargo.toml b/examples/stm32f3_blinky/Cargo.toml new file mode 100644 index 0000000000..4cd21fc046 --- /dev/null +++ b/examples/stm32f3_blinky/Cargo.toml @@ -0,0 +1,35 @@ +[package] +authors = ["Simsys "] +edition = "2021" +readme = "README.md" +name = "stm32f3-blinky" +version = "0.1.0" + +[dependencies] +embedded-hal = "0.2.7" +rtic = { git = "https://github.com/rtic-rs/rtic", features = ["thumbv7-backend"] } +rtic-monotonics = { git = "https://github.com/rtic-rs/rtic", features = ["cortex-m-systick"] } +panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] } +rtt-target = { version = "0.3.1", features = ["cortex-m"] } + +[dependencies.stm32f3xx-hal] +features = ["stm32f303xc", "rt"] +version = "0.9.2" + +# this lets you use `cargo fix`! +[[bin]] +name = "stm32f3-blinky" +test = false +bench = false + +[profile.dev] +opt-level = 1 +codegen-units = 16 +debug = true +lto = false + +[profile.release] +opt-level = "s" # optimize for size +codegen-units = 1 # better optimizations +debug = true # symbols are nice and they don't increase the size on Flash +lto = true # better optimizations diff --git a/examples/stm32f3_blinky/Embed.toml b/examples/stm32f3_blinky/Embed.toml new file mode 100644 index 0000000000..6dffe3f073 --- /dev/null +++ b/examples/stm32f3_blinky/Embed.toml @@ -0,0 +1,9 @@ +[default.general] +chip = "stm32f303re" + + +[default.rtt] +enabled = true + +[default.gdb] +enabled = false diff --git a/examples/stm32f3_blinky/README.md b/examples/stm32f3_blinky/README.md new file mode 100644 index 0000000000..51526612dd --- /dev/null +++ b/examples/stm32f3_blinky/README.md @@ -0,0 +1,19 @@ +# STM32F3 RTIC Blink example + +Working example of simple LED blinking application for STM32 F303 Nucleo-64 board based on the STM32F303RE chip. Example uses schedule API and peripherials access. This example is based on blue-pill blinky example. + +## How-to + +### Build + +Run `cargo +nightly build` to compile the code. If you run it for the first time, it will take some time to download and compile dependencies. + +After that, you can use for example the cargo-embed tool to flash and run it + +```bash +$ cargo +nightly embed +``` + +### Setup environment, flash and run program + +In the [Discovery Book](https://rust-embedded.github.io/discovery) you find all needed informations to setup the environment, flash the controler and run the program. diff --git a/examples/stm32f3_blinky/memory.x b/examples/stm32f3_blinky/memory.x new file mode 100644 index 0000000000..d3693453f2 --- /dev/null +++ b/examples/stm32f3_blinky/memory.x @@ -0,0 +1,5 @@ +MEMORY +{ + FLASH : ORIGIN = 0x08000000, LENGTH = 256K + RAM : ORIGIN = 0x20000000, LENGTH = 40K +} diff --git a/examples/stm32f3_blinky/src/main.rs b/examples/stm32f3_blinky/src/main.rs new file mode 100644 index 0000000000..e208d09de3 --- /dev/null +++ b/examples/stm32f3_blinky/src/main.rs @@ -0,0 +1,74 @@ +#![deny(unsafe_code)] +#![deny(warnings)] +#![no_main] +#![no_std] +#![feature(type_alias_impl_trait)] + +use panic_rtt_target as _; +use rtic::app; +use rtic_monotonics::systick::*; +use rtt_target::{rprintln, rtt_init_print}; +use stm32f3xx_hal::gpio::{Output, PushPull, PA5}; +use stm32f3xx_hal::prelude::*; + +#[app(device = stm32f3xx_hal::pac, peripherals = true, dispatchers = [SPI1])] +mod app { + use super::*; + + rtic_monotonics::make_systick_handler!(); + + #[shared] + struct Shared {} + + #[local] + struct Local { + led: PA5>, + state: bool, + } + + #[init] + fn init(cx: init::Context) -> (Shared, Local) { + // Setup clocks + let mut flash = cx.device.FLASH.constrain(); + let mut rcc = cx.device.RCC.constrain(); + + Systick::start(cx.core.SYST, 36_000_000); // default STM32F303 clock-rate is 36MHz + + rtt_init_print!(); + rprintln!("init"); + + let _clocks = rcc + .cfgr + .use_hse(8.MHz()) + .sysclk(36.MHz()) + .pclk1(36.MHz()) + .freeze(&mut flash.acr); + + // Setup LED + let mut gpioa = cx.device.GPIOA.split(&mut rcc.ahb); + let mut led = gpioa + .pa5 + .into_push_pull_output(&mut gpioa.moder, &mut gpioa.otyper); + led.set_high().unwrap(); + + // Schedule the blinking task + blink::spawn().ok(); + + (Shared {}, Local { led, state: false }) + } + + #[task(local = [led, state])] + async fn blink(cx: blink::Context) { + loop { + rprintln!("blink"); + if *cx.local.state { + cx.local.led.set_high().unwrap(); + *cx.local.state = false; + } else { + cx.local.led.set_low().unwrap(); + *cx.local.state = true; + } + Systick::delay(1000.millis()).await; + } + } +} From dc02818ef1abe74b4d089dd7212984ef7e0654fe Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 14 Apr 2023 21:59:37 +0200 Subject: [PATCH 02/31] rp2040_local_i2c_init: update to latest version --- examples/rp2040_local_i2c_init/Cargo.toml | 18 ++++++++++++------ examples/rp2040_local_i2c_init/src/main.rs | 7 ++++--- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/examples/rp2040_local_i2c_init/Cargo.toml b/examples/rp2040_local_i2c_init/Cargo.toml index 4aed0b83ac..9029b6e70b 100644 --- a/examples/rp2040_local_i2c_init/Cargo.toml +++ b/examples/rp2040_local_i2c_init/Cargo.toml @@ -6,14 +6,20 @@ license = "MIT OR Apache-2.0" version = "0.1.0" edition = "2021" +[workspace] + +[dependencies.rtic] +path = "../../rtic" +version = "2.0.0-alpha.1" +features = ["thumbv6-backend"] + +[dependencies.rtic-monotonics] +path = "../../rtic-monotonics" +version = "1.0.0-alpha.1" +features = ["rp2040"] + [dependencies] cortex-m = "0.7" -rtic = { git = "https://github.com/rtic-rs/rtic", features = [ - "thumbv6-backend", -] } -rtic-monotonics = { git = "https://github.com/rtic-rs/rtic", features = [ - "rp2040", -] } embedded-hal = { version = "0.2.7", features = ["unproven"] } fugit = "0.3" rp-pico = "0.7.0" diff --git a/examples/rp2040_local_i2c_init/src/main.rs b/examples/rp2040_local_i2c_init/src/main.rs index 3d881aa0d8..67768927e9 100644 --- a/examples/rp2040_local_i2c_init/src/main.rs +++ b/examples/rp2040_local_i2c_init/src/main.rs @@ -25,8 +25,6 @@ mod app { use panic_probe as _; - rtic_monotonics::make_rp2040_monotonic_handler!(); - type I2CBus = I2C< pac::I2C1, ( @@ -51,8 +49,11 @@ mod app { i2c_ctx: MaybeUninit = MaybeUninit::uninit() ])] fn init(mut ctx: init::Context) -> (Shared, Local) { + // Initialize the interrupt for the RP2040 timer and obtain the token + // proving that we have. + let rp2040_timer_token = rtic_monotonics::create_rp2040_monotonic_token!(); // Configure the clocks, watchdog - The default is to generate a 125 MHz system clock - Timer::start(ctx.device.TIMER, &mut ctx.device.RESETS); // default rp2040 clock-rate is 125MHz + Timer::start(ctx.device.TIMER, &mut ctx.device.RESETS, rp2040_timer_token); // default rp2040 clock-rate is 125MHz let mut watchdog = Watchdog::new(ctx.device.WATCHDOG); let clocks = clocks::init_clocks_and_plls( XOSC_CRYSTAL_FREQ, From 0411ed10b19433a7ea969436afd4bc705ade538c Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 14 Apr 2023 22:05:31 +0200 Subject: [PATCH 03/31] stm32f3_blinky: update to latest version --- examples/stm32f3_blinky/Cargo.toml | 14 ++++++++++++-- examples/stm32f3_blinky/src/main.rs | 6 +++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/examples/stm32f3_blinky/Cargo.toml b/examples/stm32f3_blinky/Cargo.toml index 4cd21fc046..60c21a917b 100644 --- a/examples/stm32f3_blinky/Cargo.toml +++ b/examples/stm32f3_blinky/Cargo.toml @@ -5,10 +5,20 @@ readme = "README.md" name = "stm32f3-blinky" version = "0.1.0" +[workspace] + +[dependencies.rtic] +path = "../../rtic" +version = "2.0.0-alhpa.1" +features = ["thumbv7-backend"] + +[dependencies.rtic-monotonics] +path = "../../rtic-monotonics" +version = "1.0.0-alhpa.1" +features = ["cortex-m-systick"] + [dependencies] embedded-hal = "0.2.7" -rtic = { git = "https://github.com/rtic-rs/rtic", features = ["thumbv7-backend"] } -rtic-monotonics = { git = "https://github.com/rtic-rs/rtic", features = ["cortex-m-systick"] } panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] } rtt-target = { version = "0.3.1", features = ["cortex-m"] } diff --git a/examples/stm32f3_blinky/src/main.rs b/examples/stm32f3_blinky/src/main.rs index e208d09de3..b6da714b93 100644 --- a/examples/stm32f3_blinky/src/main.rs +++ b/examples/stm32f3_blinky/src/main.rs @@ -15,8 +15,6 @@ use stm32f3xx_hal::prelude::*; mod app { use super::*; - rtic_monotonics::make_systick_handler!(); - #[shared] struct Shared {} @@ -32,7 +30,9 @@ mod app { let mut flash = cx.device.FLASH.constrain(); let mut rcc = cx.device.RCC.constrain(); - Systick::start(cx.core.SYST, 36_000_000); // default STM32F303 clock-rate is 36MHz + // Initialize the systick interrupt & obtain the token to prove that we did + let systick_mono_token = rtic_monotonics::create_systick_token!(); + Systick::start(cx.core.SYST, 36_000_000, systick_mono_token); // default STM32F303 clock-rate is 36MHz rtt_init_print!(); rprintln!("init"); From 093d64500d1822153fa29d397bcd726890ee6dd5 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 14 Apr 2023 22:05:42 +0200 Subject: [PATCH 04/31] examples: commit Cargo.lock files --- examples/.gitignore | 2 + examples/rp2040_local_i2c_init/Cargo.lock | 533 ++++++++++++++++++ examples/stm32f3_blinky/Cargo.lock | 635 ++++++++++++++++++++++ 3 files changed, 1170 insertions(+) create mode 100644 examples/.gitignore create mode 100644 examples/rp2040_local_i2c_init/Cargo.lock create mode 100644 examples/stm32f3_blinky/Cargo.lock diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000000..1520f46c57 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,2 @@ +/**/*/target +!Cargo.lock diff --git a/examples/rp2040_local_i2c_init/Cargo.lock b/examples/rp2040_local_i2c_init/Cargo.lock new file mode 100644 index 0000000000..db8191608a --- /dev/null +++ b/examples/rp2040_local_i2c_init/Cargo.lock @@ -0,0 +1,533 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "atomic-polyfill" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c314e70d181aa6053b26e3f7fbf86d1dfff84f816a6175b967666b3506ef7289" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal 0.2.5", + "bitfield", + "embedded-hal", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "crc-any" +version = "2.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774646b687f63643eb0f4bf13dc263cb581c8c9e57973b6ddf78bda3994d88df" +dependencies = [ + "debug-helper", +] + +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + +[[package]] +name = "debug-helper" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "embedded-dma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "fugit" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab17bb279def6720d058cb6c052249938e7f99260ab534879281a95367a87e5" +dependencies = [ + "gcd", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "panic-probe" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa6fa5645ef5a760cd340eaa92af9c1ce131c8c09e7f8926d8a24b59d26652b9" +dependencies = [ + "cortex-m", +] + +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pio" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e09694b50f89f302ed531c1f2a7569f0be5867aee4ab4f8f729bbeec0078e3" +dependencies = [ + "arrayvec", + "num_enum", + "paste", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rp-pico" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aab28f6f4e19cec2d61b64cdd685e69794b81c579fd3b765579c46018fe616d0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "fugit", + "rp2040-boot2", + "rp2040-hal", + "usb-device", +] + +[[package]] +name = "rp2040-boot2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c773ec49b836077aa144b58dc7654a243e1eecdb6cf0d25361ae7c7600fabd8" +dependencies = [ + "crc-any", +] + +[[package]] +name = "rp2040-hal" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd64ea14218eaa350e5cf1023b7a84c267f092e4a64b69129dc460e53412bed8" +dependencies = [ + "cortex-m", + "critical-section", + "embedded-dma", + "embedded-hal", + "fugit", + "itertools", + "nb 1.1.0", + "paste", + "pio", + "rand_core", + "rp2040-hal-macros", + "rp2040-pac", + "usb-device", + "vcell", + "void", +] + +[[package]] +name = "rp2040-hal-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86479063e497efe1ae81995ef9071f54fd1c7427e04d6c5b84cde545ff672a5e" +dependencies = [ + "cortex-m-rt", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rp2040-pac" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9192cafbb40d717c9e0ddf767aaf9c69fee1b4e48d22ed853b57b11f6d9f3d7e" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "rp2040_local_i2c_init" +version = "0.1.0" +dependencies = [ + "cortex-m", + "embedded-hal", + "fugit", + "panic-probe", + "rp-pico", + "rtic", + "rtic-monotonics", +] + +[[package]] +name = "rtic" +version = "2.0.0-alpha.1" +dependencies = [ + "atomic-polyfill", + "bare-metal 1.0.0", + "cortex-m", + "critical-section", + "rtic-core", + "rtic-macros", +] + +[[package]] +name = "rtic-common" +version = "1.0.0-alpha.0" +dependencies = [ + "critical-section", +] + +[[package]] +name = "rtic-core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42" + +[[package]] +name = "rtic-macros" +version = "2.0.0-alpha.0" +dependencies = [ + "indexmap", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rtic-monotonics" +version = "1.0.0-alpha.1" +dependencies = [ + "atomic-polyfill", + "cfg-if", + "cortex-m", + "fugit", + "rp2040-pac", + "rtic-time", +] + +[[package]] +name = "rtic-time" +version = "1.0.0-alpha.1" +dependencies = [ + "critical-section", + "futures-util", + "rtic-common", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "usb-device" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" +dependencies = [ + "vcell", +] diff --git a/examples/stm32f3_blinky/Cargo.lock b/examples/stm32f3_blinky/Cargo.lock new file mode 100644 index 0000000000..48b520be0b --- /dev/null +++ b/examples/stm32f3_blinky/Cargo.lock @@ -0,0 +1,635 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "atomic-polyfill" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d299f547288d6db8d5c3a2916f7b2f66134b15b8c1ac1c4357dd3b8752af7bb2" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bxcan" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b13b4b2ea9ab2ba924063ebb86ad895cb79f4a79bf90f27949eb20c335b30f9" +dependencies = [ + "bitflags", + "nb 1.0.0", + "vcell", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal 0.2.5", + "bitfield", + "critical-section", + "embedded-hal", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + +[[package]] +name = "darling" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "embedded-dma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-time" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a4b4d10ac48d08bfe3db7688c402baadb244721f30a77ce360bd24c3dffe58" +dependencies = [ + "num", +] + +[[package]] +name = "enumset" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fugit" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab17bb279def6720d058cb6c052249938e7f99260ab534879281a95367a87e5" +dependencies = [ + "gcd", +] + +[[package]] +name = "futures-core" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" + +[[package]] +name = "futures-task" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" + +[[package]] +name = "futures-util" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" + +[[package]] +name = "num" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" +dependencies = [ + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "panic-rtt-target" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ab67bc881453e4c90f958c657c1303670ea87bc1a16e87fd71a40f656dce9" +dependencies = [ + "cortex-m", + "rtt-target", +] + +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rtcc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3623619ce77c09a7d87cf7c61c5c887b9c7dee8805f66af6c4aa5824be4d9930" +dependencies = [ + "chrono", +] + +[[package]] +name = "rtic" +version = "2.0.0-alpha.1" +dependencies = [ + "atomic-polyfill", + "bare-metal 1.0.0", + "cortex-m", + "critical-section", + "rtic-core", + "rtic-macros", +] + +[[package]] +name = "rtic-common" +version = "1.0.0-alpha.0" +dependencies = [ + "critical-section", +] + +[[package]] +name = "rtic-core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42" + +[[package]] +name = "rtic-macros" +version = "2.0.0-alpha.0" +dependencies = [ + "indexmap", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rtic-monotonics" +version = "1.0.0-alpha.1" +dependencies = [ + "atomic-polyfill", + "cfg-if", + "cortex-m", + "fugit", + "rtic-time", +] + +[[package]] +name = "rtic-time" +version = "1.0.0-alpha.1" +dependencies = [ + "critical-section", + "futures-util", + "rtic-common", +] + +[[package]] +name = "rtt-target" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065d6058bb1204f51a562a67209e1817cf714759d5cf845aa45c75fa7b0b9d9b" +dependencies = [ + "cortex-m", + "ufmt-write", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "slice-group-by" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stm32-usbd" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c94998f166d66b210a164648a0b7866428d8f1e0740bf8a4c5edd89d4750c1" +dependencies = [ + "cortex-m", + "usb-device", + "vcell", +] + +[[package]] +name = "stm32f3" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "265cda62ac13307414de4aca58dbbbd8038ddba85cffbb335823aa216f2e3200" +dependencies = [ + "bare-metal 1.0.0", + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "stm32f3-blinky" +version = "0.1.0" +dependencies = [ + "embedded-hal", + "panic-rtt-target", + "rtic", + "rtic-monotonics", + "rtt-target", + "stm32f3xx-hal", +] + +[[package]] +name = "stm32f3xx-hal" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c9d827f02df3826371c897404dfbea8a1abd544eed9d6cdc3e5f6e9f04b9e06" +dependencies = [ + "bare-metal 1.0.0", + "bxcan", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "embedded-dma", + "embedded-hal", + "embedded-time", + "enumset", + "nb 1.0.0", + "paste", + "rtcc", + "slice-group-by", + "stm32-usbd", + "stm32f3", + "void", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "ufmt-write" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "usb-device" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6cc3adc849b5292b4075fc0d5fdcf2f24866e88e336dd27a8943090a520508" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6" +dependencies = [ + "vcell", +] From cba786529a7e34ed623df5f7cde5aae762a8c55c Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 14 Apr 2023 23:50:05 +0200 Subject: [PATCH 05/31] examples: pin to specific version --- examples/rp2040_local_i2c_init/Cargo.toml | 4 ++-- examples/stm32f3_blinky/Cargo.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/rp2040_local_i2c_init/Cargo.toml b/examples/rp2040_local_i2c_init/Cargo.toml index 9029b6e70b..c8e475ab71 100644 --- a/examples/rp2040_local_i2c_init/Cargo.toml +++ b/examples/rp2040_local_i2c_init/Cargo.toml @@ -10,12 +10,12 @@ edition = "2021" [dependencies.rtic] path = "../../rtic" -version = "2.0.0-alpha.1" +version = "=2.0.0-alpha.1" features = ["thumbv6-backend"] [dependencies.rtic-monotonics] path = "../../rtic-monotonics" -version = "1.0.0-alpha.1" +version = "=1.0.0-alpha.1" features = ["rp2040"] [dependencies] diff --git a/examples/stm32f3_blinky/Cargo.toml b/examples/stm32f3_blinky/Cargo.toml index 60c21a917b..02937e869c 100644 --- a/examples/stm32f3_blinky/Cargo.toml +++ b/examples/stm32f3_blinky/Cargo.toml @@ -9,12 +9,12 @@ version = "0.1.0" [dependencies.rtic] path = "../../rtic" -version = "2.0.0-alhpa.1" +version = "=2.0.0-alpha.1" features = ["thumbv7-backend"] [dependencies.rtic-monotonics] path = "../../rtic-monotonics" -version = "1.0.0-alhpa.1" +version = "=1.0.0-alpha.1" features = ["cortex-m-systick"] [dependencies] From 63b7024cb98717dd785ae888f419002b9835c6b1 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Fri, 14 Apr 2023 23:59:23 +0200 Subject: [PATCH 06/31] xtask: build usage examples and general improvements --- xtask/src/argument_parsing.rs | 53 +++++++++++++++++++- xtask/src/cargo_commands.rs | 27 ++++++++++ xtask/src/command.rs | 94 ++++++++++++++++++++++++++++++----- xtask/src/main.rs | 23 +++++++-- 4 files changed, 178 insertions(+), 19 deletions(-) diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 3ee9e34ce5..d74ba69f8f 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -190,8 +190,8 @@ pub enum BuildOrCheck { #[derive(Parser, Clone)] pub struct Globals { - /// For which backend to build (defaults to thumbv7) - #[arg(value_enum, short, long, global = true)] + /// For which backend to build. + #[arg(value_enum, short, default_value = "thumbv7", long, global = true)] pub backend: Option, /// List of comma separated examples to include, all others are excluded @@ -300,6 +300,55 @@ pub enum Commands { /// Build books with mdbook Book(Arg), + + /// Check one or more usage examples. + /// + /// Usage examples are located in ./examples + UsageExamplesCheck(UsageExamples), + + /// Build one or more usage examples. + /// + /// Usage examples are located in ./examples + #[clap(alias = "./examples")] + UsageExampleBuild(UsageExamples), +} + +#[derive(Args, Clone, Debug)] +pub struct UsageExamples { + /// The usage examples to build. All usage examples are selected if this argument is not provided. + /// + /// Example: `rp2040_local_i2c_init,stm32f3_blinky`. + examples: Option, +} + +impl UsageExamples { + pub fn examples(&self) -> anyhow::Result> { + let usage_examples: Vec<_> = std::fs::read_dir("./examples")? + .filter_map(Result::ok) + .filter(|p| p.metadata().ok().map(|p| p.is_dir()).unwrap_or(false)) + .filter_map(|p| p.file_name().as_os_str().to_str().map(ToString::to_string)) + .collect(); + + let selected_examples: Option> = self + .examples + .clone() + .map(|s| s.split(",").map(ToString::to_string).collect()); + + if let Some(selected_examples) = selected_examples { + if let Some(unfound_example) = selected_examples + .iter() + .find(|e| !usage_examples.contains(e)) + { + Err(anyhow::anyhow!( + "Usage example {unfound_example} does not exist" + )) + } else { + Ok(selected_examples) + } + } else { + Ok(usage_examples) + } + } } #[derive(Args, Debug, Clone)] diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index 9cbdaefd75..9b07088c34 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -126,6 +126,33 @@ pub fn cargo<'c>( runner.run_and_coalesce() } +/// Cargo command to build a usage example. +/// +/// The usage examples are in examples/ +pub fn cargo_usage_example( + globals: &Globals, + operation: BuildOrCheck, + usage_examples: Vec, +) -> Vec> { + examples_iter(&usage_examples) + .map(|example| { + let path = format!("examples/{example}"); + + let command = match operation { + BuildOrCheck::Check => CargoCommand::CheckInDir { + mode: BuildMode::Release, + dir: path.into(), + }, + BuildOrCheck::Build => CargoCommand::BuildInDir { + mode: BuildMode::Release, + dir: path.into(), + }, + }; + (globals, command, false) + }) + .run_and_coalesce() +} + /// Cargo command to either build or check all examples /// /// The examples are in rtic/examples diff --git a/xtask/src/command.rs b/xtask/src/command.rs index b62724ab73..93de9cf65a 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -8,6 +8,7 @@ use core::fmt; use std::{ fs::File, io::Read, + path::PathBuf, process::{Command, Stdio}, }; @@ -111,6 +112,14 @@ pub enum CargoCommand<'a> { mode: BuildMode, arguments: Option, }, + CheckInDir { + mode: BuildMode, + dir: PathBuf, + }, + BuildInDir { + mode: BuildMode, + dir: PathBuf, + }, } impl core::fmt::Display for CargoCommand<'_> { @@ -211,6 +220,10 @@ impl core::fmt::Display for CargoCommand<'_> { details(target, mode, features, cargoarg) ) } + CargoCommand::BuildInDir { mode, dir } => { + let dir = dir.as_os_str().to_str().unwrap_or("Not displayable"); + write!(f, "Build {dir} ({mode})") + } CargoCommand::Check { cargoarg, package, @@ -225,6 +238,10 @@ impl core::fmt::Display for CargoCommand<'_> { details(target, mode, features, cargoarg) ) } + CargoCommand::CheckInDir { mode, dir } => { + let dir = dir.as_os_str().to_str().unwrap_or("Not displayable"); + write!(f, "Check {dir} ({mode})") + } CargoCommand::Clippy { cargoarg, package, @@ -316,11 +333,15 @@ impl<'a> CargoCommand<'a> { format!("{executable} {args}") } - fn command(&self) -> &str { + fn command(&self) -> &'static str { match self { CargoCommand::Run { .. } | CargoCommand::Qemu { .. } => "run", - CargoCommand::ExampleCheck { .. } | CargoCommand::Check { .. } => "check", - CargoCommand::ExampleBuild { .. } | CargoCommand::Build { .. } => "build", + CargoCommand::ExampleCheck { .. } + | CargoCommand::Check { .. } + | CargoCommand::CheckInDir { .. } => "check", + CargoCommand::ExampleBuild { .. } + | CargoCommand::Build { .. } + | CargoCommand::BuildInDir { .. } => "build", CargoCommand::ExampleSize { .. } => "size", CargoCommand::Clippy { .. } => "clippy", CargoCommand::Format { .. } => "fmt", @@ -329,7 +350,7 @@ impl<'a> CargoCommand<'a> { CargoCommand::Test { .. } => "test", } } - pub fn executable(&self) -> &str { + pub fn executable(&self) -> &'static str { match self { CargoCommand::Run { .. } | CargoCommand::Qemu { .. } @@ -341,7 +362,9 @@ impl<'a> CargoCommand<'a> { | CargoCommand::Clippy { .. } | CargoCommand::Format { .. } | CargoCommand::Test { .. } - | CargoCommand::Doc { .. } => "cargo", + | CargoCommand::Doc { .. } + | CargoCommand::CheckInDir { .. } + | CargoCommand::BuildInDir { .. } => "cargo", CargoCommand::Book { .. } => "mdbook", } } @@ -641,6 +664,34 @@ impl<'a> CargoCommand<'a> { } args } + CargoCommand::CheckInDir { mode, dir: _ } => { + let mut args = vec!["+nightly"]; + args.push(self.command()); + + if let Some(mode) = mode.to_flag() { + args.push(mode); + } + + args + } + CargoCommand::BuildInDir { mode, dir: _ } => { + let mut args = vec!["+nightly", self.command()]; + + if let Some(mode) = mode.to_flag() { + args.push(mode); + } + + args + } + } + } + + fn chdir(&self) -> Option<&PathBuf> { + match self { + CargoCommand::CheckInDir { dir, .. } | CargoCommand::BuildInDir { dir, .. } => { + Some(dir) + } + _ => None, } } } @@ -669,11 +720,18 @@ impl fmt::Display for BuildMode { pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result { log::info!("👟 {command}"); - let result = Command::new(command.executable()) + let mut process = Command::new(command.executable()); + + process .args(command.args()) .stdout(Stdio::piped()) - .stderr(stderr_mode) - .output()?; + .stderr(stderr_mode); + + if let Some(dir) = command.chdir() { + process.current_dir(dir); + } + + let result = process.output()?; let exit_status = result.status; let stderr = String::from_utf8(result.stderr).unwrap_or("Not displayable".into()); @@ -759,15 +817,27 @@ pub fn handle_results(globals: &Globals, results: Vec) -> anyhow errors.clone().for_each(log_stdout_stderr(Level::Error)); successes.for_each(|(cmd, _)| { - if globals.verbose > 0 { - info!("✅ Success: {cmd}\n {}", cmd.as_cmd_string()); + let path = if let Some(dir) = cmd.chdir() { + let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); + format!(" (in {path}") } else { - info!("✅ Success: {cmd}"); + format!("") + }; + + if globals.verbose > 0 { + info!("✅ Success:{path} {cmd}\n {}", cmd.as_cmd_string()); + } else { + info!("✅ Success:{path} {cmd}"); } }); errors.clone().for_each(|(cmd, _)| { - error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); + if let Some(dir) = cmd.chdir() { + let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); + error!("❌ Failed: (in {path}) {cmd}\n {}", cmd.as_cmd_string()); + } else { + error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); + } }); let ecount = errors.count(); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2bfe851f93..2b45f23793 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -23,10 +23,7 @@ use log::{error, info, log_enabled, trace, Level}; use crate::{ argument_parsing::{Backends, BuildOrCheck, Cli, Commands}, build::init_build_dir, - cargo_commands::{ - build_and_check_size, cargo, cargo_book, cargo_clippy, cargo_doc, cargo_example, - cargo_format, cargo_test, run_test, - }, + cargo_commands::*, command::{handle_results, run_command, run_successful, CargoCommand}, }; @@ -152,6 +149,12 @@ fn main() -> anyhow::Result<()> { trace!("default logging level: {0}", globals.verbose); + log::debug!( + "Stderr of child processes is inherited: {}", + globals.stderr_inherited + ); + log::debug!("Partial features: {}", globals.partial); + let backend = if let Some(backend) = globals.backend { backend } else { @@ -285,6 +288,14 @@ fn main() -> anyhow::Result<()> { info!("Running mdbook"); cargo_book(globals, &args.arguments) } + Commands::UsageExamplesCheck(examples) => { + info!("Checking usage examples"); + cargo_usage_example(globals, BuildOrCheck::Check, examples.examples()?) + } + Commands::UsageExampleBuild(examples) => { + info!("Building usage examples"); + cargo_usage_example(globals, BuildOrCheck::Build, examples.examples()?) + } }; handle_results(globals, final_run_results) @@ -347,7 +358,9 @@ fn command_parser( | CargoCommand::Doc { .. } | CargoCommand::Test { .. } | CargoCommand::Book { .. } - | CargoCommand::ExampleSize { .. } => { + | CargoCommand::ExampleSize { .. } + | CargoCommand::BuildInDir { .. } + | CargoCommand::CheckInDir { .. } => { let cargo_result = run_command(command, output_mode)?; Ok(cargo_result) } From eac593e300832c3f7b0440134a8a3e810dd08ee3 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sat, 15 Apr 2023 19:40:21 +0200 Subject: [PATCH 07/31] Check usage examples in CI --- .github/workflows/build.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2bec7dce4..4fa2b8079d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -148,6 +148,35 @@ jobs: if: ${{ matrix.backend != 'thumbv8-base' }} run: cargo xtask --backend ${{ matrix.backend }} example-check + # Check that the usage examples build + usageexamples: + name: Build usage examples + runs-on: ubuntu-22.04 + strategy: + matrix: + toolchain: + - nightly + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install rust ${{ matrix.toolchain }} + run: | + rustup set profile minimal + rustup override set ${{ matrix.toolchain }} + + - name: Configure rust target (v6, v7) + run: | + rustup target add thumbv7m-none-eabi + rustup target add thumbv6m-none-eabi + rustup component add rust-src + + - name: Cache Dependencies + uses: Swatinem/rust-cache@v2 + + - name: Check the examples + run: cargo xtask usage-example-build + # Verify the example output with run-pass tests testexamples: name: QEMU run From fa8af4cbcffbedec1504ed464bd02b6ee6e3fb4b Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sat, 15 Apr 2023 20:19:37 +0200 Subject: [PATCH 08/31] Add the most important message --- xtask/src/command.rs | 6 ++++-- xtask/src/main.rs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 93de9cf65a..186836b201 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -771,7 +771,7 @@ pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), } } -pub fn handle_results(globals: &Globals, results: Vec) -> anyhow::Result<()> { +pub fn handle_results(globals: &Globals, results: Vec) -> Result<(), ()> { let errors = results.iter().filter_map(|r| { if let FinalRunResult::Failed(c, r) = r { Some((c, r)) @@ -842,8 +842,10 @@ pub fn handle_results(globals: &Globals, results: Vec) -> anyhow let ecount = errors.count(); if ecount != 0 { - Err(anyhow::anyhow!("{ecount} commands failed.")) + log::error!("{ecount} commands failed."); + Err(()) } else { + info!("🚀🚀🚀 All tasks succeeded 🚀🚀🚀"); Ok(()) } } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2b45f23793..1cc01850dc 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -298,7 +298,7 @@ fn main() -> anyhow::Result<()> { } }; - handle_results(globals, final_run_results) + handle_results(globals, final_run_results).map_err(|_| anyhow::anyhow!("Commands failed")) } // run example binary `example` From 6517a4bec2e909b40eb9974e063f95e44e4d9a31 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sat, 15 Apr 2023 20:44:06 +0200 Subject: [PATCH 09/31] Also check for CommandErrors in error checking --- xtask/src/cargo_commands.rs | 14 ++++++++++---- xtask/src/command.rs | 27 +++++++++++++++++++-------- xtask/src/main.rs | 2 -- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index 9b07088c34..ead6eaa9a0 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -10,10 +10,11 @@ use rayon::prelude::*; use iters::*; +#[derive(Debug)] pub enum FinalRunResult<'c> { Success(CargoCommand<'c>, RunResult), Failed(CargoCommand<'c>, RunResult), - CommandError(anyhow::Error), + CommandError(CargoCommand<'c>, anyhow::Error), } fn run_and_convert<'a>( @@ -21,7 +22,8 @@ fn run_and_convert<'a>( ) -> FinalRunResult<'a> { // Run the command let result = command_parser(global, &command, overwrite); - match result { + + let output = match result { // If running the command succeeded without looking at any of the results, // log the data and see if the actual execution was succesfull too. Ok(result) => { @@ -32,8 +34,12 @@ fn run_and_convert<'a>( } } // If it didn't and some IO error occured, just panic - Err(e) => FinalRunResult::CommandError(e), - } + Err(e) => FinalRunResult::CommandError(command, e), + }; + + log::trace!("Final result: {output:?}"); + + output } pub trait CoalescingRunner<'c> { diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 186836b201..93ea824551 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -774,7 +774,7 @@ pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), pub fn handle_results(globals: &Globals, results: Vec) -> Result<(), ()> { let errors = results.iter().filter_map(|r| { if let FinalRunResult::Failed(c, r) = r { - Some((c, r)) + Some((c, &r.stdout, &r.stderr)) } else { None } @@ -782,16 +782,22 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result let successes = results.iter().filter_map(|r| { if let FinalRunResult::Success(c, r) = r { - Some((c, r)) + Some((c, &r.stdout, &r.stderr)) + } else { + None + } + }); + + let command_errors = results.iter().filter_map(|r| { + if let FinalRunResult::CommandError(c, e) = r { + Some((c, e)) } else { None } }); let log_stdout_stderr = |level: Level| { - move |(command, result): (&CargoCommand, &RunResult)| { - let stdout = &result.stdout; - let stderr = &result.stderr; + move |(command, stdout, stderr): (&CargoCommand, &String, &String)| { if !stdout.is_empty() && !stderr.is_empty() { log::log!( level, @@ -816,7 +822,7 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result successes.clone().for_each(log_stdout_stderr(Level::Debug)); errors.clone().for_each(log_stdout_stderr(Level::Error)); - successes.for_each(|(cmd, _)| { + successes.for_each(|(cmd, _, _)| { let path = if let Some(dir) = cmd.chdir() { let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); format!(" (in {path}") @@ -831,7 +837,7 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result } }); - errors.clone().for_each(|(cmd, _)| { + errors.clone().for_each(|(cmd, _, _)| { if let Some(dir) = cmd.chdir() { let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); error!("❌ Failed: (in {path}) {cmd}\n {}", cmd.as_cmd_string()); @@ -840,8 +846,13 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result } }); + command_errors + .clone() + .for_each(|(cmd, error)| error!("❌ Failed: {cmd}\n {}\n{error}", cmd.as_cmd_string())); + let ecount = errors.count(); - if ecount != 0 { + let cecount = command_errors.count(); + if ecount != 0 || cecount != 0 { log::error!("{ecount} commands failed."); Err(()) } else { diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 1cc01850dc..4cf6db8aae 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -324,9 +324,7 @@ fn command_parser( .map_err(TestRunError::PathConversionError)?; // cargo run <..> - info!("Running example: {example}"); let cargo_run_result = run_command(command, output_mode)?; - info!("{}", cargo_run_result.stdout); // Create a file for the expected output if it does not exist or mismatches if overwrite { From 859cd418f063590a9928b3e43caeea0b53dc0823 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sat, 15 Apr 2023 20:57:27 +0200 Subject: [PATCH 10/31] Rename some things --- xtask/src/argument_parsing.rs | 8 ++++---- xtask/src/command.rs | 6 +++--- xtask/src/main.rs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index d74ba69f8f..6cae186edc 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -304,24 +304,24 @@ pub enum Commands { /// Check one or more usage examples. /// /// Usage examples are located in ./examples - UsageExamplesCheck(UsageExamples), + UsageExampleCheck(UsageExamplesOpt), /// Build one or more usage examples. /// /// Usage examples are located in ./examples #[clap(alias = "./examples")] - UsageExampleBuild(UsageExamples), + UsageExampleBuild(UsageExamplesOpt), } #[derive(Args, Clone, Debug)] -pub struct UsageExamples { +pub struct UsageExamplesOpt { /// The usage examples to build. All usage examples are selected if this argument is not provided. /// /// Example: `rp2040_local_i2c_init,stm32f3_blinky`. examples: Option, } -impl UsageExamples { +impl UsageExamplesOpt { pub fn examples(&self) -> anyhow::Result> { let usage_examples: Vec<_> = std::fs::read_dir("./examples")? .filter_map(Result::ok) diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 93ea824551..a1c4d2533b 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -831,16 +831,16 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result }; if globals.verbose > 0 { - info!("✅ Success:{path} {cmd}\n {}", cmd.as_cmd_string()); + info!("✅ Success: {cmd}{path}\n {}", cmd.as_cmd_string()); } else { - info!("✅ Success:{path} {cmd}"); + info!("✅ Success:{cmd}{path}"); } }); errors.clone().for_each(|(cmd, _, _)| { if let Some(dir) = cmd.chdir() { let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); - error!("❌ Failed: (in {path}) {cmd}\n {}", cmd.as_cmd_string()); + error!("❌ Failed: {cmd} (in {path}) \n {}", cmd.as_cmd_string()); } else { error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 4cf6db8aae..10499c022c 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -288,7 +288,7 @@ fn main() -> anyhow::Result<()> { info!("Running mdbook"); cargo_book(globals, &args.arguments) } - Commands::UsageExamplesCheck(examples) => { + Commands::UsageExampleCheck(examples) => { info!("Checking usage examples"); cargo_usage_example(globals, BuildOrCheck::Check, examples.examples()?) } From d838286de679a1ac35ea79999816418cd02b7259 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sat, 15 Apr 2023 21:16:45 +0200 Subject: [PATCH 11/31] Fix config pickup behaviour so that both examples and usage-examples build correctly --- .cargo/config.toml | 12 ++---------- rtic/.cargo/config.toml | 10 ++++++++++ xtask/src/command.rs | 28 +++++++++++++++++++++++++--- xtask/src/main.rs | 4 ++-- 4 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 rtic/.cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml index 0a62466ad2..ea1655c19d 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,13 +2,5 @@ xtask = "run --package xtask --" pxtask = "run --package xtask --features rayon --" -[target.thumbv6m-none-eabi] -runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" - -[target.thumbv7m-none-eabi] -runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" - -[target.'cfg(all(target_arch = "arm", target_os = "none"))'] -rustflags = [ - "-C", "link-arg=-Tlink.x", -] +# Don't define the RUSTFLAGS link.x thing here: it messes +# up compilation of the usage examples. diff --git a/rtic/.cargo/config.toml b/rtic/.cargo/config.toml new file mode 100644 index 0000000000..ddec65047b --- /dev/null +++ b/rtic/.cargo/config.toml @@ -0,0 +1,10 @@ +[target.thumbv6m-none-eabi] +runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.thumbv7m-none-eabi] +runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel" + +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +rustflags = [ + "-C", "link-arg=-Tlink.x", +] diff --git a/xtask/src/command.rs b/xtask/src/command.rs index a1c4d2533b..a45cb8ac8b 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -383,6 +383,7 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } + args.extend_from_slice(&[ self.command(), "--example", @@ -407,9 +408,15 @@ impl<'a> CargoCommand<'a> { mode, } => { let mut args = vec!["+nightly"]; + if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } + + // We need to be in the `rtic` directory to pick up + // the correct .cargo/config.toml file + args.extend_from_slice(&["-Z", "unstable-options", "-C", "rtic"]); + args.extend_from_slice(&[ self.command(), "--example", @@ -641,6 +648,11 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } + + // We need to be in the `rtic` directory to pick up + // the correct .cargo/config.toml file + args.extend_from_slice(&["-Z", "unstable-options", "-C", "rtic"]); + args.extend_from_slice(&[ self.command(), "--example", @@ -694,6 +706,13 @@ impl<'a> CargoCommand<'a> { _ => None, } } + + pub fn print_stdout_intermediate(&self) -> bool { + match self { + Self::ExampleSize { .. } => true, + _ => false, + } + } } impl BuildMode { @@ -737,6 +756,10 @@ pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::R let stderr = String::from_utf8(result.stderr).unwrap_or("Not displayable".into()); let stdout = String::from_utf8(result.stdout).unwrap_or("Not displayable".into()); + if command.print_stdout_intermediate() && exit_status.success() { + log::info!("\n{}", stdout); + } + Ok(RunResult { exit_status, stdout, @@ -850,9 +873,8 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result .clone() .for_each(|(cmd, error)| error!("❌ Failed: {cmd}\n {}\n{error}", cmd.as_cmd_string())); - let ecount = errors.count(); - let cecount = command_errors.count(); - if ecount != 0 || cecount != 0 { + let ecount = errors.count() + command_errors.count(); + if ecount != 0 { log::error!("{ecount} commands failed."); Err(()) } else { diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 10499c022c..7077d552bd 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -100,8 +100,8 @@ impl fmt::Display for TestRunError { TestRunError::CommandError(e) => { write!( f, - "Command failed with exit status {}: {}", - e.exit_status, e.stdout + "Command failed with exit status {}: {} {}", + e.exit_status, e.stdout, e.stderr ) } TestRunError::PathConversionError(p) => { From 1c84ccf6e4169b4b45f0e22e709e4265a10324a5 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sat, 15 Apr 2023 22:19:13 +0200 Subject: [PATCH 12/31] Fix running of tests --- xtask/src/cargo_commands.rs | 47 ++++++++++++++++++------------------- xtask/src/command.rs | 7 +++++- xtask/src/main.rs | 2 +- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index ead6eaa9a0..42895d810b 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -302,7 +302,7 @@ pub fn cargo_book<'c>( /// Run examples /// /// Supports updating the expected output via the overwrite argument -pub fn run_test<'c>( +pub fn qemu_run_examples<'c>( globals: &Globals, cargoarg: &'c Option<&'c str>, backend: Backends, @@ -312,31 +312,30 @@ pub fn run_test<'c>( let target = backend.to_target(); let features = Some(target.and_features(backend.to_rtic_feature())); - examples_iter(examples) - .map(|example| { - let cmd = CargoCommand::ExampleBuild { - cargoarg: &Some("--quiet"), - example, - target, - features: features.clone(), - mode: BuildMode::Release, - }; + let build = examples_iter(examples).map(|example| { + let cmd_build = CargoCommand::ExampleBuild { + // We need to be in the correct + cargoarg: &None, + example, + target, + features: features.clone(), + mode: BuildMode::Release, + }; + (globals, cmd_build, overwrite) + }); - if let Err(err) = command_parser(globals, &cmd, false) { - error!("{err}"); - } + let run = examples_iter(examples).map(|example| { + let cmd_qemu = CargoCommand::Qemu { + cargoarg, + example, + target, + features: features.clone(), + mode: BuildMode::Release, + }; + (globals, cmd_qemu, overwrite) + }); - let cmd = CargoCommand::Qemu { - cargoarg, - example, - target, - features: features.clone(), - mode: BuildMode::Release, - }; - - (globals, cmd, overwrite) - }) - .run_and_coalesce() + build.chain(run).run_and_coalesce() } /// Check the binary sizes of examples diff --git a/xtask/src/command.rs b/xtask/src/command.rs index a45cb8ac8b..187a3ddccd 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -593,6 +593,11 @@ impl<'a> CargoCommand<'a> { if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } + + // We need to be in the `rtic` directory to pick up + // the correct .cargo/config.toml file + args.extend_from_slice(&["-Z", "unstable-options", "-C", "rtic"]); + args.extend_from_slice(&[ self.command(), "--example", @@ -856,7 +861,7 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result if globals.verbose > 0 { info!("✅ Success: {cmd}{path}\n {}", cmd.as_cmd_string()); } else { - info!("✅ Success:{cmd}{path}"); + info!("✅ Success: {cmd}{path}"); } }); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 7077d552bd..853dbe783c 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -268,7 +268,7 @@ fn main() -> anyhow::Result<()> { Commands::Qemu(args) | Commands::Run(args) => { // x86_64 target not valid info!("Testing for backend: {backend:?}"); - run_test( + qemu_run_examples( globals, &cargologlevel, backend, From deeb3877f061fb71389ec7730c6c21e81e9e3050 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sat, 15 Apr 2023 22:40:25 +0200 Subject: [PATCH 13/31] Improve locality of error messages & ExampleBuild + Qemu commands, and indicate failure earlier --- xtask/src/cargo_commands.rs | 50 +++++++++++++++++++++---------------- xtask/src/command.rs | 34 +++++++++++-------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index 42895d810b..2e3099749b 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -312,30 +312,36 @@ pub fn qemu_run_examples<'c>( let target = backend.to_target(); let features = Some(target.and_features(backend.to_rtic_feature())); - let build = examples_iter(examples).map(|example| { - let cmd_build = CargoCommand::ExampleBuild { - // We need to be in the correct - cargoarg: &None, - example, - target, - features: features.clone(), - mode: BuildMode::Release, - }; - (globals, cmd_build, overwrite) - }); + examples_iter(examples) + .flat_map(|example| { + let cmd_build = CargoCommand::ExampleBuild { + cargoarg: &None, + example, + target, + features: features.clone(), + mode: BuildMode::Release, + }; - let run = examples_iter(examples).map(|example| { - let cmd_qemu = CargoCommand::Qemu { - cargoarg, - example, - target, - features: features.clone(), - mode: BuildMode::Release, - }; - (globals, cmd_qemu, overwrite) - }); + let cmd_qemu = CargoCommand::Qemu { + cargoarg, + example, + target, + features: features.clone(), + mode: BuildMode::Release, + }; - build.chain(run).run_and_coalesce() + #[cfg(not(feature = "rayon"))] + { + [cmd_build, cmd_qemu].into_iter() + } + + #[cfg(feature = "rayon")] + { + [cmd_build, cmd_qemu].into_par_iter() + } + }) + .map(|cmd| (globals, cmd, overwrite)) + .run_and_coalesce() } /// Check the binary sizes of examples diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 187a3ddccd..3596897e30 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -765,6 +765,10 @@ pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::R log::info!("\n{}", stdout); } + if !exit_status.success() { + log::error!("❌ Command failed. Run to completion for the summary."); + } + Ok(RunResult { exit_status, stdout, @@ -825,32 +829,19 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result }); let log_stdout_stderr = |level: Level| { - move |(command, stdout, stderr): (&CargoCommand, &String, &String)| { + move |(cmd, stdout, stderr): (&CargoCommand, &String, &String)| { + let cmd = cmd.as_cmd_string(); if !stdout.is_empty() && !stderr.is_empty() { - log::log!( - level, - "Output for \"{command}\"\nStdout:\n{stdout}\nStderr:\n{stderr}" - ); + log::log!(level, "\n{cmd}\nStdout:\n{stdout}\nStderr:\n{stderr}"); } else if !stdout.is_empty() { - log::log!( - level, - "Output for \"{command}\":\nStdout:\n{}", - stdout.trim_end() - ); + log::log!(level, "\n{cmd}\nStdout:\n{}", stdout.trim_end()); } else if !stderr.is_empty() { - log::log!( - level, - "Output for \"{command}\"\nStderr:\n{}", - stderr.trim_end() - ); + log::log!(level, "\n{cmd}\nStderr:\n{}", stderr.trim_end()); } } }; - successes.clone().for_each(log_stdout_stderr(Level::Debug)); - errors.clone().for_each(log_stdout_stderr(Level::Error)); - - successes.for_each(|(cmd, _, _)| { + successes.for_each(|(cmd, stdout, stderr)| { let path = if let Some(dir) = cmd.chdir() { let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); format!(" (in {path}") @@ -863,15 +854,18 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result } else { info!("✅ Success: {cmd}{path}"); } + + log_stdout_stderr(Level::Debug)((cmd, stdout, stderr)); }); - errors.clone().for_each(|(cmd, _, _)| { + errors.clone().for_each(|(cmd, stdout, stderr)| { if let Some(dir) = cmd.chdir() { let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); error!("❌ Failed: {cmd} (in {path}) \n {}", cmd.as_cmd_string()); } else { error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); } + log_stdout_stderr(Level::Error)((cmd, stdout, stderr)); }); command_errors From 9dc9f492639daace5222562c124846fb0d3cb154 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sat, 15 Apr 2023 23:22:00 +0200 Subject: [PATCH 14/31] Use chdir() instead of unstable option, also confirm whenver a command succeeds because why not --- xtask/src/argument_parsing.rs | 2 +- xtask/src/cargo_commands.rs | 7 +++ xtask/src/command.rs | 89 ++++++++++++++++++++++------------- 3 files changed, 63 insertions(+), 35 deletions(-) diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 6cae186edc..69275eb338 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -326,7 +326,7 @@ impl UsageExamplesOpt { let usage_examples: Vec<_> = std::fs::read_dir("./examples")? .filter_map(Result::ok) .filter(|p| p.metadata().ok().map(|p| p.is_dir()).unwrap_or(false)) - .filter_map(|p| p.file_name().as_os_str().to_str().map(ToString::to_string)) + .filter_map(|p| p.file_name().to_str().map(ToString::to_string)) .collect(); let selected_examples: Option> = self diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index 2e3099749b..ec91eae0da 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -1,3 +1,5 @@ +use std::path::PathBuf; + use crate::{ argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, TestMetadata}, command::{BuildMode, CargoCommand}, @@ -186,6 +188,7 @@ pub fn cargo_example<'c>( target: backend.to_target(), features, mode: BuildMode::Release, + dir: Some(PathBuf::from("./rtic")), }, }; (globals, command, false) @@ -320,6 +323,7 @@ pub fn qemu_run_examples<'c>( target, features: features.clone(), mode: BuildMode::Release, + dir: Some(PathBuf::from("./rtic")), }; let cmd_qemu = CargoCommand::Qemu { @@ -328,6 +332,7 @@ pub fn qemu_run_examples<'c>( target, features: features.clone(), mode: BuildMode::Release, + dir: Some(PathBuf::from("./rtic")), }; #[cfg(not(feature = "rayon"))] @@ -363,6 +368,7 @@ pub fn build_and_check_size<'c>( target, features: features.clone(), mode: BuildMode::Release, + dir: Some(PathBuf::from("./rtic")), }; if let Err(err) = command_parser(globals, &cmd, false) { error!("{err}"); @@ -375,6 +381,7 @@ pub fn build_and_check_size<'c>( features: features.clone(), mode: BuildMode::Release, arguments: arguments.clone(), + dir: Some(PathBuf::from("./rtic")), }; (globals, cmd, false) }); diff --git a/xtask/src/command.rs b/xtask/src/command.rs index 3596897e30..e06c89ea0c 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -51,6 +51,7 @@ pub enum CargoCommand<'a> { target: Target<'a>, features: Option, mode: BuildMode, + dir: Option, }, ExampleBuild { cargoarg: &'a Option<&'a str>, @@ -58,6 +59,7 @@ pub enum CargoCommand<'a> { target: Target<'a>, features: Option, mode: BuildMode, + dir: Option, }, ExampleCheck { cargoarg: &'a Option<&'a str>, @@ -111,6 +113,7 @@ pub enum CargoCommand<'a> { features: Option, mode: BuildMode, arguments: Option, + dir: Option, }, CheckInDir { mode: BuildMode, @@ -179,22 +182,32 @@ impl core::fmt::Display for CargoCommand<'_> { target, features, mode, - } => write!( - f, - "Run example {example} in QEMU {}", - details(target, mode, features, cargoarg) - ), + dir, + } => { + let details = details(target, mode, features, cargoarg); + if let Some(dir) = dir { + let dir = dir.to_str().unwrap_or("Not displayable"); + write!(f, "Run example {example} in QEMU from {dir} {details}",) + } else { + write!(f, "Run example {example} in QEMU {details}",) + } + } CargoCommand::ExampleBuild { cargoarg, example, target, features, mode, - } => write!( - f, - "Build example {example} {}", - details(target, mode, features, cargoarg) - ), + dir, + } => { + let details = details(target, mode, features, cargoarg); + if let Some(dir) = dir { + let dir = dir.to_str().unwrap_or("Not displayable"); + write!(f, "Build example {example} in {dir} {details}") + } else { + write!(f, "Build example {example} {details}",) + } + } CargoCommand::ExampleCheck { cargoarg, example, @@ -221,7 +234,7 @@ impl core::fmt::Display for CargoCommand<'_> { ) } CargoCommand::BuildInDir { mode, dir } => { - let dir = dir.as_os_str().to_str().unwrap_or("Not displayable"); + let dir = dir.to_str().unwrap_or("Not displayable"); write!(f, "Build {dir} ({mode})") } CargoCommand::Check { @@ -239,7 +252,7 @@ impl core::fmt::Display for CargoCommand<'_> { ) } CargoCommand::CheckInDir { mode, dir } => { - let dir = dir.as_os_str().to_str().unwrap_or("Not displayable"); + let dir = dir.to_str().unwrap_or("Not displayable"); write!(f, "Check {dir} ({mode})") } CargoCommand::Clippy { @@ -315,12 +328,15 @@ impl core::fmt::Display for CargoCommand<'_> { features, mode, arguments: _, + dir, } => { - write!( - f, - "Compute size of example {example} {}", - details(target, mode, features, cargoarg) - ) + let details = details(target, mode, features, cargoarg); + if let Some(dir) = dir { + let dir = dir.to_str().unwrap_or("Not displayable"); + write!(f, "Compute size of example {example} from {dir} {details}",) + } else { + write!(f, "Compute size of example {example} {details}") + } } } } @@ -328,9 +344,15 @@ impl core::fmt::Display for CargoCommand<'_> { impl<'a> CargoCommand<'a> { pub fn as_cmd_string(&self) -> String { + let cd = if let Some(Some(chdir)) = self.chdir().map(|p| p.to_str()) { + format!("cd {chdir} && ") + } else { + format!("") + }; + let executable = self.executable(); let args = self.args().join(" "); - format!("{executable} {args}") + format!("{cd}{executable} {args}") } fn command(&self) -> &'static str { @@ -406,6 +428,8 @@ impl<'a> CargoCommand<'a> { target, features, mode, + // Dir is exposed through chdir instead + dir: _, } => { let mut args = vec!["+nightly"]; @@ -413,10 +437,6 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[cargoarg]); } - // We need to be in the `rtic` directory to pick up - // the correct .cargo/config.toml file - args.extend_from_slice(&["-Z", "unstable-options", "-C", "rtic"]); - args.extend_from_slice(&[ self.command(), "--example", @@ -588,16 +608,14 @@ impl<'a> CargoCommand<'a> { target, features, mode, + // Dir is exposed through chdir instead + dir: _, } => { let mut args = vec!["+nightly"]; if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - // We need to be in the `rtic` directory to pick up - // the correct .cargo/config.toml file - args.extend_from_slice(&["-Z", "unstable-options", "-C", "rtic"]); - args.extend_from_slice(&[ self.command(), "--example", @@ -648,16 +666,14 @@ impl<'a> CargoCommand<'a> { features, mode, arguments, + // Dir is exposed through chdir instead + dir: _, } => { let mut args = vec!["+nightly"]; if let Some(cargoarg) = cargoarg { args.extend_from_slice(&[cargoarg]); } - // We need to be in the `rtic` directory to pick up - // the correct .cargo/config.toml file - args.extend_from_slice(&["-Z", "unstable-options", "-C", "rtic"]); - args.extend_from_slice(&[ self.command(), "--example", @@ -708,6 +724,9 @@ impl<'a> CargoCommand<'a> { CargoCommand::CheckInDir { dir, .. } | CargoCommand::BuildInDir { dir, .. } => { Some(dir) } + CargoCommand::Qemu { dir, .. } + | CargoCommand::ExampleBuild { dir, .. } + | CargoCommand::ExampleSize { dir, .. } => dir.as_ref(), _ => None, } } @@ -752,7 +771,7 @@ pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::R .stderr(stderr_mode); if let Some(dir) = command.chdir() { - process.current_dir(dir); + process.current_dir(dir.canonicalize()?); } let result = process.output()?; @@ -765,7 +784,9 @@ pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::R log::info!("\n{}", stdout); } - if !exit_status.success() { + if exit_status.success() { + log::info!("✅ Success.") + } else { log::error!("❌ Command failed. Run to completion for the summary."); } @@ -843,7 +864,7 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result successes.for_each(|(cmd, stdout, stderr)| { let path = if let Some(dir) = cmd.chdir() { - let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); + let path = dir.to_str().unwrap_or("Not displayable"); format!(" (in {path}") } else { format!("") @@ -860,7 +881,7 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result errors.clone().for_each(|(cmd, stdout, stderr)| { if let Some(dir) = cmd.chdir() { - let path = dir.as_os_str().to_str().unwrap_or("Not displayable"); + let path = dir.to_str().unwrap_or("Not displayable"); error!("❌ Failed: {cmd} (in {path}) \n {}", cmd.as_cmd_string()); } else { error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); From 404867cdf92990cb0aba415dfbee97c7fef78b60 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 09:44:30 +0200 Subject: [PATCH 15/31] CargoCommand can take any package --- xtask/src/argument_parsing.rs | 20 +++++++++++--------- xtask/src/cargo_commands.rs | 8 ++++---- xtask/src/command.rs | 26 +++++++++++++------------- xtask/src/main.rs | 2 +- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 69275eb338..738168e16a 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -19,15 +19,17 @@ impl fmt::Display for Package { } impl Package { - pub fn name(&self) -> &str { - match self { + pub fn name(&self) -> String { + let name = match self { Package::Rtic => "rtic", Package::RticCommon => "rtic-common", Package::RticMacros => "rtic-macros", Package::RticMonotonics => "rtic-monotonics", Package::RticSync => "rtic-sync", Package::RticTime => "rtic-time", - } + }; + + name.to_string() } pub fn all() -> Vec { @@ -102,33 +104,33 @@ impl TestMetadata { ); let features = Some(backend.to_target().and_features(&features)); CargoCommand::Test { - package: Some(package), + package: Some(package.name()), features, test: Some("ui".to_owned()), } } Package::RticMacros => CargoCommand::Test { - package: Some(package), + package: Some(package.name()), features: Some(backend.to_rtic_macros_feature().to_owned()), test: None, }, Package::RticSync => CargoCommand::Test { - package: Some(package), + package: Some(package.name()), features: Some("testing".to_owned()), test: None, }, Package::RticCommon => CargoCommand::Test { - package: Some(package), + package: Some(package.name()), features: Some("testing".to_owned()), test: None, }, Package::RticMonotonics => CargoCommand::Test { - package: Some(package), + package: Some(package.name()), features: None, test: None, }, Package::RticTime => CargoCommand::Test { - package: Some(package), + package: Some(package.name()), features: Some("critical-section/std".into()), test: None, }, diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index ec91eae0da..c290e95742 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -114,14 +114,14 @@ pub fn cargo<'c>( let command = match operation { BuildOrCheck::Check => CargoCommand::Check { cargoarg, - package: Some(package), + package: Some(package.name()), target, features, mode: BuildMode::Release, }, BuildOrCheck::Build => CargoCommand::Build { cargoarg, - package: Some(package), + package: Some(package.name()), target, features, mode: BuildMode::Release, @@ -224,7 +224,7 @@ pub fn cargo_clippy<'c>( globals, CargoCommand::Clippy { cargoarg, - package: Some(package), + package: Some(package.name()), target, features, }, @@ -247,7 +247,7 @@ pub fn cargo_format<'c>( globals, CargoCommand::Format { cargoarg, - package: Some(p), + package: Some(p.name()), check_only, }, false, diff --git a/xtask/src/command.rs b/xtask/src/command.rs index e06c89ea0c..da6d9074b6 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -1,8 +1,8 @@ use log::{error, info, Level}; use crate::{ - argument_parsing::Globals, cargo_commands::FinalRunResult, ExtraArguments, Package, RunResult, - Target, TestRunError, + argument_parsing::Globals, cargo_commands::FinalRunResult, ExtraArguments, RunResult, Target, + TestRunError, }; use core::fmt; use std::{ @@ -70,27 +70,27 @@ pub enum CargoCommand<'a> { }, Build { cargoarg: &'a Option<&'a str>, - package: Option, + package: Option, target: Target<'a>, features: Option, mode: BuildMode, }, Check { cargoarg: &'a Option<&'a str>, - package: Option, + package: Option, target: Target<'a>, features: Option, mode: BuildMode, }, Clippy { cargoarg: &'a Option<&'a str>, - package: Option, + package: Option, target: Target<'a>, features: Option, }, Format { cargoarg: &'a Option<&'a str>, - package: Option, + package: Option, check_only: bool, }, Doc { @@ -99,7 +99,7 @@ pub enum CargoCommand<'a> { arguments: Option, }, Test { - package: Option, + package: Option, features: Option, test: Option, }, @@ -127,7 +127,7 @@ pub enum CargoCommand<'a> { impl core::fmt::Display for CargoCommand<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let p = |p: &Option| { + let p = |p: &Option| { if let Some(package) = p { format!("package {package}") } else { @@ -468,7 +468,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[self.command(), "--target", target.triple()]); if let Some(package) = package { - args.extend_from_slice(&["--package", package.name()]); + args.extend_from_slice(&["--package", package]); } if let Some(feature) = features { @@ -493,7 +493,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[self.command()]); if let Some(package) = package { - args.extend_from_slice(&["--package", package.name()]); + args.extend_from_slice(&["--package", package]); } if let Some(feature) = features { @@ -518,7 +518,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[self.command()]); if let Some(package) = package { - args.extend_from_slice(&["--package", package.name()]); + args.extend_from_slice(&["--package", package]); } if let Some(feature) = features { @@ -557,7 +557,7 @@ impl<'a> CargoCommand<'a> { args.extend_from_slice(&[self.command()]); if let Some(package) = package { - args.extend_from_slice(&["--package", package.name()]); + args.extend_from_slice(&["--package", package]); } if let Some(feature) = features { @@ -594,7 +594,7 @@ impl<'a> CargoCommand<'a> { } if let Some(package) = package { - args.extend_from_slice(&["--package", package.name()]); + args.extend_from_slice(&["--package", package]); } if *check_only { args.extend_from_slice(&["--check"]); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 853dbe783c..0043474ab2 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -3,7 +3,7 @@ mod build; mod cargo_commands; mod command; -use argument_parsing::{ExtraArguments, Globals, Package}; +use argument_parsing::{ExtraArguments, Globals}; use clap::Parser; use command::OutputMode; use core::fmt; From b59bf686c1e10bb8068d89e43779d7777f553c48 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 11:00:39 +0200 Subject: [PATCH 16/31] Redo command building so that we don't repeat as much, and to make it easier to add new ones --- xtask/src/cargo_commands.rs | 46 +-- xtask/src/command.rs | 583 +++++++++++++++--------------------- xtask/src/main.rs | 4 +- 3 files changed, 270 insertions(+), 363 deletions(-) diff --git a/xtask/src/cargo_commands.rs b/xtask/src/cargo_commands.rs index c290e95742..e2982e4f75 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/cargo_commands.rs @@ -111,6 +111,7 @@ pub fn cargo<'c>( } }) .map(move |(package, target, features)| { + let target = target.into(); let command = match operation { BuildOrCheck::Check => CargoCommand::Check { cargoarg, @@ -118,6 +119,7 @@ pub fn cargo<'c>( target, features, mode: BuildMode::Release, + dir: None, }, BuildOrCheck::Build => CargoCommand::Build { cargoarg, @@ -125,6 +127,7 @@ pub fn cargo<'c>( target, features, mode: BuildMode::Release, + dir: None, }, }; @@ -147,13 +150,21 @@ pub fn cargo_usage_example( let path = format!("examples/{example}"); let command = match operation { - BuildOrCheck::Check => CargoCommand::CheckInDir { + BuildOrCheck::Check => CargoCommand::Check { + cargoarg: &None, mode: BuildMode::Release, - dir: path.into(), + dir: Some(path.into()), + package: None, + target: None, + features: None, }, - BuildOrCheck::Build => CargoCommand::BuildInDir { + BuildOrCheck::Build => CargoCommand::Build { + cargoarg: &None, + package: None, + target: None, + features: None, mode: BuildMode::Release, - dir: path.into(), + dir: Some(path.into()), }, }; (globals, command, false) @@ -178,14 +189,14 @@ pub fn cargo_example<'c>( BuildOrCheck::Check => CargoCommand::ExampleCheck { cargoarg, example, - target: backend.to_target(), + target: Some(backend.to_target()), features, mode: BuildMode::Release, }, BuildOrCheck::Build => CargoCommand::ExampleBuild { cargoarg, example, - target: backend.to_target(), + target: Some(backend.to_target()), features, mode: BuildMode::Release, dir: Some(PathBuf::from("./rtic")), @@ -220,16 +231,14 @@ pub fn cargo_clippy<'c>( } }) .map(move |(package, target, features)| { - ( - globals, - CargoCommand::Clippy { - cargoarg, - package: Some(package.name()), - target, - features, - }, - false, - ) + let command = CargoCommand::Clippy { + cargoarg, + package: Some(package.name()), + target: target.into(), + features, + }; + + (globals, command, false) }); runner.run_and_coalesce() @@ -317,6 +326,7 @@ pub fn qemu_run_examples<'c>( examples_iter(examples) .flat_map(|example| { + let target = target.into(); let cmd_build = CargoCommand::ExampleBuild { cargoarg: &None, example, @@ -361,6 +371,8 @@ pub fn build_and_check_size<'c>( let features = Some(target.and_features(backend.to_rtic_feature())); let runner = examples_iter(examples).map(|example| { + let target = target.into(); + // Make sure the requested example(s) are built let cmd = CargoCommand::ExampleBuild { cargoarg: &Some("--quiet"), @@ -377,7 +389,7 @@ pub fn build_and_check_size<'c>( let cmd = CargoCommand::ExampleSize { cargoarg, example, - target: backend.to_target(), + target, features: features.clone(), mode: BuildMode::Release, arguments: arguments.clone(), diff --git a/xtask/src/command.rs b/xtask/src/command.rs index da6d9074b6..33d0703031 100644 --- a/xtask/src/command.rs +++ b/xtask/src/command.rs @@ -41,14 +41,15 @@ pub enum CargoCommand<'a> { Run { cargoarg: &'a Option<&'a str>, example: &'a str, - target: Target<'a>, + target: Option>, features: Option, mode: BuildMode, + dir: Option, }, Qemu { cargoarg: &'a Option<&'a str>, example: &'a str, - target: Target<'a>, + target: Option>, features: Option, mode: BuildMode, dir: Option, @@ -56,7 +57,7 @@ pub enum CargoCommand<'a> { ExampleBuild { cargoarg: &'a Option<&'a str>, example: &'a str, - target: Target<'a>, + target: Option>, features: Option, mode: BuildMode, dir: Option, @@ -64,28 +65,30 @@ pub enum CargoCommand<'a> { ExampleCheck { cargoarg: &'a Option<&'a str>, example: &'a str, - target: Target<'a>, + target: Option>, features: Option, mode: BuildMode, }, Build { cargoarg: &'a Option<&'a str>, package: Option, - target: Target<'a>, + target: Option>, features: Option, mode: BuildMode, + dir: Option, }, Check { cargoarg: &'a Option<&'a str>, package: Option, - target: Target<'a>, + target: Option>, features: Option, mode: BuildMode, + dir: Option, }, Clippy { cargoarg: &'a Option<&'a str>, package: Option, - target: Target<'a>, + target: Option>, features: Option, }, Format { @@ -109,60 +112,78 @@ pub enum CargoCommand<'a> { ExampleSize { cargoarg: &'a Option<&'a str>, example: &'a str, - target: Target<'a>, + target: Option>, features: Option, mode: BuildMode, arguments: Option, dir: Option, }, - CheckInDir { - mode: BuildMode, - dir: PathBuf, - }, - BuildInDir { - mode: BuildMode, - dir: PathBuf, - }, } impl core::fmt::Display for CargoCommand<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let p = |p: &Option| { + fn p(p: &Option) -> String { if let Some(package) = p { format!("package {package}") } else { format!("default package") } - }; + } - let feat = |f: &Option| { + fn feat(f: &Option) -> String { if let Some(features) = f { format!("\"{features}\"") } else { format!("no features") } - }; + } - let carg = |f: &&Option<&str>| { + fn carg(f: &&Option<&str>) -> String { if let Some(cargoarg) = f { format!("{cargoarg}") } else { format!("no cargo args") } - }; + } - let details = |target: &Target, - mode: &BuildMode, - features: &Option, - cargoarg: &&Option<&str>| { + fn details( + target: &Option, + mode: Option<&BuildMode>, + features: &Option, + cargoarg: &&Option<&str>, + path: Option<&PathBuf>, + ) -> String { let feat = feat(features); let carg = carg(cargoarg); - if cargoarg.is_some() { + let in_dir = if let Some(path) = path { + let path = path.to_str().unwrap_or(""); + format!("in {path}") + } else { + format!("") + }; + + let target = if let Some(target) = target { + format!("{target}") + } else { + format!("") + }; + + let mode = if let Some(mode) = mode { + format!("{mode}") + } else { + format!("debug") + }; + + if cargoarg.is_some() && path.is_some() { + format!("({target}, {mode}, {feat}, {carg}, {in_dir})") + } else if cargoarg.is_some() { format!("({target}, {mode}, {feat}, {carg})") + } else if path.is_some() { + format!("({target}, {mode}, {feat}, {in_dir})") } else { format!("({target}, {mode}, {feat})") } - }; + } match self { CargoCommand::Run { @@ -171,11 +192,14 @@ impl core::fmt::Display for CargoCommand<'_> { target, features, mode, - } => write!( - f, - "Run example {example} {}", - details(target, mode, features, cargoarg) - ), + dir, + } => { + write!( + f, + "Run example {example} {}", + details(target, Some(mode), features, cargoarg, dir.as_ref()) + ) + } CargoCommand::Qemu { cargoarg, example, @@ -184,13 +208,8 @@ impl core::fmt::Display for CargoCommand<'_> { mode, dir, } => { - let details = details(target, mode, features, cargoarg); - if let Some(dir) = dir { - let dir = dir.to_str().unwrap_or("Not displayable"); - write!(f, "Run example {example} in QEMU from {dir} {details}",) - } else { - write!(f, "Run example {example} in QEMU {details}",) - } + let details = details(target, Some(mode), features, cargoarg, dir.as_ref()); + write!(f, "Run example {example} in QEMU {details}",) } CargoCommand::ExampleBuild { cargoarg, @@ -200,13 +219,8 @@ impl core::fmt::Display for CargoCommand<'_> { mode, dir, } => { - let details = details(target, mode, features, cargoarg); - if let Some(dir) = dir { - let dir = dir.to_str().unwrap_or("Not displayable"); - write!(f, "Build example {example} in {dir} {details}") - } else { - write!(f, "Build example {example} {details}",) - } + let details = details(target, Some(mode), features, cargoarg, dir.as_ref()); + write!(f, "Build example {example} {details}",) } CargoCommand::ExampleCheck { cargoarg, @@ -217,7 +231,7 @@ impl core::fmt::Display for CargoCommand<'_> { } => write!( f, "Check example {example} {}", - details(target, mode, features, cargoarg) + details(target, Some(mode), features, cargoarg, None) ), CargoCommand::Build { cargoarg, @@ -225,50 +239,40 @@ impl core::fmt::Display for CargoCommand<'_> { target, features, mode, + dir, } => { let package = p(package); write!( f, "Build {package} {}", - details(target, mode, features, cargoarg) + details(target, Some(mode), features, cargoarg, dir.as_ref()) ) } - CargoCommand::BuildInDir { mode, dir } => { - let dir = dir.to_str().unwrap_or("Not displayable"); - write!(f, "Build {dir} ({mode})") - } + CargoCommand::Check { cargoarg, package, target, features, mode, + dir, } => { let package = p(package); write!( f, "Check {package} {}", - details(target, mode, features, cargoarg) + details(target, Some(mode), features, cargoarg, dir.as_ref()) ) } - CargoCommand::CheckInDir { mode, dir } => { - let dir = dir.to_str().unwrap_or("Not displayable"); - write!(f, "Check {dir} ({mode})") - } CargoCommand::Clippy { cargoarg, package, target, features, } => { + let details = details(target, None, features, cargoarg, None); let package = p(package); - let features = feat(features); - let carg = carg(cargoarg); - if cargoarg.is_some() { - write!(f, "Clippy {package} ({target}, {features}, {carg})") - } else { - write!(f, "Clippy {package} ({target}, {features})") - } + write!(f, "Clippy {package} {details}") } CargoCommand::Format { cargoarg, @@ -330,13 +334,8 @@ impl core::fmt::Display for CargoCommand<'_> { arguments: _, dir, } => { - let details = details(target, mode, features, cargoarg); - if let Some(dir) = dir { - let dir = dir.to_str().unwrap_or("Not displayable"); - write!(f, "Compute size of example {example} from {dir} {details}",) - } else { - write!(f, "Compute size of example {example} {details}") - } + let details = details(target, Some(mode), features, cargoarg, dir.as_ref()); + write!(f, "Compute size of example {example} {details}") } } } @@ -358,12 +357,8 @@ impl<'a> CargoCommand<'a> { fn command(&self) -> &'static str { match self { CargoCommand::Run { .. } | CargoCommand::Qemu { .. } => "run", - CargoCommand::ExampleCheck { .. } - | CargoCommand::Check { .. } - | CargoCommand::CheckInDir { .. } => "check", - CargoCommand::ExampleBuild { .. } - | CargoCommand::Build { .. } - | CargoCommand::BuildInDir { .. } => "build", + CargoCommand::ExampleCheck { .. } | CargoCommand::Check { .. } => "check", + CargoCommand::ExampleBuild { .. } | CargoCommand::Build { .. } => "build", CargoCommand::ExampleSize { .. } => "size", CargoCommand::Clippy { .. } => "clippy", CargoCommand::Format { .. } => "fmt", @@ -384,189 +379,159 @@ impl<'a> CargoCommand<'a> { | CargoCommand::Clippy { .. } | CargoCommand::Format { .. } | CargoCommand::Test { .. } - | CargoCommand::Doc { .. } - | CargoCommand::CheckInDir { .. } - | CargoCommand::BuildInDir { .. } => "cargo", + | CargoCommand::Doc { .. } => "cargo", CargoCommand::Book { .. } => "mdbook", } } + /// Build args using common arguments for all commands, and the + /// specific information provided + fn build_args<'i, T: Iterator>( + &'i self, + nightly: bool, + cargoarg: &'i Option<&'i str>, + features: &'i Option, + mode: Option<&'i BuildMode>, + extra: T, + ) -> Vec<&str> { + let mut args: Vec<&str> = Vec::new(); + + if nightly { + args.push("+nightly"); + } + + if let Some(cargoarg) = cargoarg.as_deref() { + args.push(cargoarg); + } + + args.push(self.command()); + + if let Some(target) = self.target() { + args.extend_from_slice(&["--target", target.triple()]) + } + + if let Some(features) = features.as_ref() { + args.extend_from_slice(&["--features", features]); + } + + if let Some(mode) = mode.map(|m| m.to_flag()).flatten() { + args.push(mode); + } + + args.extend(extra); + + args + } + + /// Turn the ExtraArguments into an interator that contains the separating dashes + /// and the rest of the arguments. + /// + /// NOTE: you _must_ chain this iterator at the _end_ of the extra arguments. + fn extra_args(args: Option<&ExtraArguments>) -> impl Iterator { + #[allow(irrefutable_let_patterns)] + let args = if let Some(ExtraArguments::Other(arguments)) = args { + // Extra arguments must be passed after "--" + ["--"] + .into_iter() + .chain(arguments.iter().map(String::as_str)) + .collect() + } else { + vec![] + }; + args.into_iter() + } + pub fn args(&self) -> Vec<&str> { + fn p(package: &Option) -> impl Iterator { + if let Some(package) = package { + vec!["--package", &package].into_iter() + } else { + vec![].into_iter() + } + } + match self { // For future embedded-ci, for now the same as Qemu CargoCommand::Run { cargoarg, example, - target, features, mode, - } => { - let mut args = vec!["+nightly"]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - - args.extend_from_slice(&[ - self.command(), - "--example", - example, - "--target", - target.triple(), - ]); - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - args - } + // dir is exposed through `chdir` + dir: _, + // Target is added by build_args + target: _, + } => self.build_args( + true, + cargoarg, + features, + Some(mode), + ["--example", example].into_iter(), + ), CargoCommand::Qemu { cargoarg, example, - target, features, mode, - // Dir is exposed through chdir instead + // dir is exposed through `chdir` dir: _, - } => { - let mut args = vec!["+nightly"]; - - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - - args.extend_from_slice(&[ - self.command(), - "--example", - example, - "--target", - target.triple(), - ]); - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - args - } + // Target is added by build_args + target: _, + } => self.build_args( + true, + cargoarg, + features, + Some(mode), + ["--example", example].into_iter(), + ), CargoCommand::Build { cargoarg, package, - target, features, mode, - } => { - let mut args = vec!["+nightly"]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - - args.extend_from_slice(&[self.command(), "--target", target.triple()]); - - if let Some(package) = package { - args.extend_from_slice(&["--package", package]); - } - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - args - } + // Dir is exposed through `chdir` + dir: _, + // Target is added by build_args + target: _, + } => self.build_args(true, cargoarg, features, Some(mode), p(package)), CargoCommand::Check { cargoarg, package, - target: _, features, mode, - } => { - let mut args = vec!["+nightly"]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - args.extend_from_slice(&[self.command()]); - - if let Some(package) = package { - args.extend_from_slice(&["--package", package]); - } - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - args - } + // Dir is exposed through `chdir` + dir: _, + // Target is added by build_args + target: _, + } => self.build_args(true, cargoarg, features, Some(mode), p(package)), CargoCommand::Clippy { cargoarg, package, - target: _, features, - } => { - let mut args = vec!["+nightly"]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - - args.extend_from_slice(&[self.command()]); - - if let Some(package) = package { - args.extend_from_slice(&["--package", package]); - } - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - args - } + // Target is added by build_args + target: _, + } => self.build_args(true, cargoarg, features, None, p(package)), CargoCommand::Doc { cargoarg, features, arguments, } => { - let mut args = vec!["+nightly"]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - - args.extend_from_slice(&[self.command()]); - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - if let Some(ExtraArguments::Other(arguments)) = arguments { - for arg in arguments { - args.extend_from_slice(&[arg.as_str()]); - } - } - args + let extra = Self::extra_args(arguments.as_ref()); + self.build_args(true, cargoarg, features, None, extra) } CargoCommand::Test { package, features, test, } => { - let mut args = vec!["+nightly"]; - args.extend_from_slice(&[self.command()]); - - if let Some(package) = package { - args.extend_from_slice(&["--package", package]); - } - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - if let Some(test) = test { - args.extend_from_slice(&["--test", test]); - } - args + let extra = if let Some(test) = test { + vec!["--test", test] + } else { + vec![] + }; + let package = p(package); + let extra = extra.into_iter().chain(package); + self.build_args(true, &None, features, None, extra) } CargoCommand::Book { arguments } => { let mut args = vec![]; @@ -588,145 +553,89 @@ impl<'a> CargoCommand<'a> { package, check_only, } => { - let mut args = vec!["+nightly", self.command()]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - - if let Some(package) = package { - args.extend_from_slice(&["--package", package]); - } - if *check_only { - args.extend_from_slice(&["--check"]); - } - - args + let extra = if *check_only { Some("--check") } else { None }; + let package = p(package); + self.build_args( + true, + cargoarg, + &None, + None, + extra.into_iter().chain(package), + ) } CargoCommand::ExampleBuild { cargoarg, example, - target, features, mode, - // Dir is exposed through chdir instead + // dir is exposed through `chdir` dir: _, - } => { - let mut args = vec!["+nightly"]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - - args.extend_from_slice(&[ - self.command(), - "--example", - example, - "--target", - target.triple(), - ]); - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - args - } + // Target is added by build_args + target: _, + } => self.build_args( + true, + cargoarg, + features, + Some(mode), + ["--example", example].into_iter(), + ), CargoCommand::ExampleCheck { cargoarg, example, - target, features, mode, - } => { - let mut args = vec!["+nightly"]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } - args.extend_from_slice(&[ - self.command(), - "--example", - example, - "--target", - target.triple(), - ]); - - if let Some(feature) = features { - args.extend_from_slice(&["--features", feature]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - args - } + // Target is added by build_args + target: _, + } => self.build_args( + true, + cargoarg, + features, + Some(mode), + ["--example", example].into_iter(), + ), CargoCommand::ExampleSize { cargoarg, example, - target, features, mode, arguments, - // Dir is exposed through chdir instead + // Target is added by build_args + target: _, + // dir is exposed through `chdir` dir: _, } => { - let mut args = vec!["+nightly"]; - if let Some(cargoarg) = cargoarg { - args.extend_from_slice(&[cargoarg]); - } + let extra = ["--example", example] + .into_iter() + .chain(Self::extra_args(arguments.as_ref())); - args.extend_from_slice(&[ - self.command(), - "--example", - example, - "--target", - target.triple(), - ]); - - if let Some(feature_name) = features { - args.extend_from_slice(&["--features", feature_name]); - } - if let Some(flag) = mode.to_flag() { - args.push(flag); - } - if let Some(ExtraArguments::Other(arguments)) = arguments { - // Arguments to cargo size must be passed after "--" - args.extend_from_slice(&["--"]); - for arg in arguments { - args.extend_from_slice(&[arg.as_str()]); - } - } - args - } - CargoCommand::CheckInDir { mode, dir: _ } => { - let mut args = vec!["+nightly"]; - args.push(self.command()); - - if let Some(mode) = mode.to_flag() { - args.push(mode); - } - - args - } - CargoCommand::BuildInDir { mode, dir: _ } => { - let mut args = vec!["+nightly", self.command()]; - - if let Some(mode) = mode.to_flag() { - args.push(mode); - } - - args + self.build_args(true, cargoarg, features, Some(mode), extra) } } } + /// TODO: integrate this into `args` once `-C` becomes stable. fn chdir(&self) -> Option<&PathBuf> { match self { - CargoCommand::CheckInDir { dir, .. } | CargoCommand::BuildInDir { dir, .. } => { - Some(dir) - } CargoCommand::Qemu { dir, .. } | CargoCommand::ExampleBuild { dir, .. } - | CargoCommand::ExampleSize { dir, .. } => dir.as_ref(), + | CargoCommand::ExampleSize { dir, .. } + | CargoCommand::Build { dir, .. } + | CargoCommand::Run { dir, .. } + | CargoCommand::Check { dir, .. } => dir.as_ref(), + _ => None, + } + } + + fn target(&self) -> Option<&Target> { + match self { + CargoCommand::Run { target, .. } + | CargoCommand::Qemu { target, .. } + | CargoCommand::ExampleBuild { target, .. } + | CargoCommand::ExampleCheck { target, .. } + | CargoCommand::Build { target, .. } + | CargoCommand::Check { target, .. } + | CargoCommand::Clippy { target, .. } + | CargoCommand::ExampleSize { target, .. } => target.as_ref(), _ => None, } } @@ -863,29 +772,17 @@ pub fn handle_results(globals: &Globals, results: Vec) -> Result }; successes.for_each(|(cmd, stdout, stderr)| { - let path = if let Some(dir) = cmd.chdir() { - let path = dir.to_str().unwrap_or("Not displayable"); - format!(" (in {path}") - } else { - format!("") - }; - if globals.verbose > 0 { - info!("✅ Success: {cmd}{path}\n {}", cmd.as_cmd_string()); + info!("✅ Success: {cmd}\n {}", cmd.as_cmd_string()); } else { - info!("✅ Success: {cmd}{path}"); + info!("✅ Success: {cmd}"); } log_stdout_stderr(Level::Debug)((cmd, stdout, stderr)); }); errors.clone().for_each(|(cmd, stdout, stderr)| { - if let Some(dir) = cmd.chdir() { - let path = dir.to_str().unwrap_or("Not displayable"); - error!("❌ Failed: {cmd} (in {path}) \n {}", cmd.as_cmd_string()); - } else { - error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); - } + error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); log_stdout_stderr(Level::Error)((cmd, stdout, stderr)); }); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 0043474ab2..2f350795e3 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -356,9 +356,7 @@ fn command_parser( | CargoCommand::Doc { .. } | CargoCommand::Test { .. } | CargoCommand::Book { .. } - | CargoCommand::ExampleSize { .. } - | CargoCommand::BuildInDir { .. } - | CargoCommand::CheckInDir { .. } => { + | CargoCommand::ExampleSize { .. } => { let cargo_result = run_command(command, output_mode)?; Ok(cargo_result) } From 66a3d02b4585a76615d750c33a37edd5e8fd30e6 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 11:02:49 +0200 Subject: [PATCH 17/31] Rename cargo_commands -> run Rename command -> cargo_command --- xtask/src/argument_parsing.rs | 2 +- xtask/src/{command.rs => cargo_command.rs} | 2 +- xtask/src/main.rs | 10 +++++----- xtask/src/{cargo_commands.rs => run.rs} | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename xtask/src/{command.rs => cargo_command.rs} (99%) rename xtask/src/{cargo_commands.rs => run.rs} (99%) diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 738168e16a..8c8f7d2a2d 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -1,4 +1,4 @@ -use crate::{command::CargoCommand, Target, ARMV6M, ARMV7M, ARMV8MBASE, ARMV8MMAIN}; +use crate::{cargo_command::CargoCommand, Target, ARMV6M, ARMV7M, ARMV8MBASE, ARMV8MMAIN}; use clap::{Args, Parser, Subcommand}; use core::fmt; diff --git a/xtask/src/command.rs b/xtask/src/cargo_command.rs similarity index 99% rename from xtask/src/command.rs rename to xtask/src/cargo_command.rs index 33d0703031..cd38566e45 100644 --- a/xtask/src/command.rs +++ b/xtask/src/cargo_command.rs @@ -1,7 +1,7 @@ use log::{error, info, Level}; use crate::{ - argument_parsing::Globals, cargo_commands::FinalRunResult, ExtraArguments, RunResult, Target, + argument_parsing::Globals, xtasks::FinalRunResult, ExtraArguments, RunResult, Target, TestRunError, }; use core::fmt; diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 2f350795e3..09bf8c7209 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,11 +1,11 @@ mod argument_parsing; mod build; -mod cargo_commands; -mod command; +mod xtasks; +mod cargo_command; use argument_parsing::{ExtraArguments, Globals}; use clap::Parser; -use command::OutputMode; +use cargo_command::OutputMode; use core::fmt; use diffy::{create_patch, PatchFormatter}; use std::{ @@ -23,8 +23,8 @@ use log::{error, info, log_enabled, trace, Level}; use crate::{ argument_parsing::{Backends, BuildOrCheck, Cli, Commands}, build::init_build_dir, - cargo_commands::*, - command::{handle_results, run_command, run_successful, CargoCommand}, + xtasks::*, + cargo_command::{handle_results, run_command, run_successful, CargoCommand}, }; #[derive(Debug, Clone, Copy)] diff --git a/xtask/src/cargo_commands.rs b/xtask/src/run.rs similarity index 99% rename from xtask/src/cargo_commands.rs rename to xtask/src/run.rs index e2982e4f75..32fafc8441 100644 --- a/xtask/src/cargo_commands.rs +++ b/xtask/src/run.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use crate::{ argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, TestMetadata}, - command::{BuildMode, CargoCommand}, + cargo_command::{BuildMode, CargoCommand}, command_parser, RunResult, }; use log::error; From c6b43800d2a368d7948639899b8dca50cc97712f Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 11:05:41 +0200 Subject: [PATCH 18/31] Move all run-related stuff into `run` --- xtask/src/cargo_command.rs | 162 +------------------------------------ xtask/src/main.rs | 7 +- xtask/src/run.rs | 157 ++++++++++++++++++++++++++++++++++- 3 files changed, 160 insertions(+), 166 deletions(-) diff --git a/xtask/src/cargo_command.rs b/xtask/src/cargo_command.rs index cd38566e45..f399b8702d 100644 --- a/xtask/src/cargo_command.rs +++ b/xtask/src/cargo_command.rs @@ -1,16 +1,6 @@ -use log::{error, info, Level}; - -use crate::{ - argument_parsing::Globals, xtasks::FinalRunResult, ExtraArguments, RunResult, Target, - TestRunError, -}; +use crate::{ExtraArguments, Target}; use core::fmt; -use std::{ - fs::File, - io::Read, - path::PathBuf, - process::{Command, Stdio}, -}; +use std::path::PathBuf; #[allow(dead_code)] #[derive(Debug, Clone, Copy, PartialEq)] @@ -19,21 +9,6 @@ pub enum BuildMode { Debug, } -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum OutputMode { - PipedAndCollected, - Inherited, -} - -impl From for Stdio { - fn from(value: OutputMode) -> Self { - match value { - OutputMode::PipedAndCollected => Stdio::piped(), - OutputMode::Inherited => Stdio::inherit(), - } - } -} - #[derive(Debug)] pub enum CargoCommand<'a> { // For future embedded-ci @@ -614,7 +589,7 @@ impl<'a> CargoCommand<'a> { } /// TODO: integrate this into `args` once `-C` becomes stable. - fn chdir(&self) -> Option<&PathBuf> { + pub fn chdir(&self) -> Option<&PathBuf> { match self { CargoCommand::Qemu { dir, .. } | CargoCommand::ExampleBuild { dir, .. } @@ -668,134 +643,3 @@ impl fmt::Display for BuildMode { write!(f, "{cmd}") } } - -pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result { - log::info!("👟 {command}"); - - let mut process = Command::new(command.executable()); - - process - .args(command.args()) - .stdout(Stdio::piped()) - .stderr(stderr_mode); - - if let Some(dir) = command.chdir() { - process.current_dir(dir.canonicalize()?); - } - - let result = process.output()?; - - let exit_status = result.status; - let stderr = String::from_utf8(result.stderr).unwrap_or("Not displayable".into()); - let stdout = String::from_utf8(result.stdout).unwrap_or("Not displayable".into()); - - if command.print_stdout_intermediate() && exit_status.success() { - log::info!("\n{}", stdout); - } - - if exit_status.success() { - log::info!("✅ Success.") - } else { - log::error!("❌ Command failed. Run to completion for the summary."); - } - - Ok(RunResult { - exit_status, - stdout, - stderr, - }) -} - -/// Check if `run` was successful. -/// returns Ok in case the run went as expected, -/// Err otherwise -pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), TestRunError> { - let mut file_handle = - File::open(expected_output_file).map_err(|_| TestRunError::FileError { - file: expected_output_file.to_owned(), - })?; - let mut expected_output = String::new(); - file_handle - .read_to_string(&mut expected_output) - .map_err(|_| TestRunError::FileError { - file: expected_output_file.to_owned(), - })?; - - if expected_output != run.stdout { - Err(TestRunError::FileCmpError { - expected: expected_output.clone(), - got: run.stdout.clone(), - }) - } else if !run.exit_status.success() { - Err(TestRunError::CommandError(run.clone())) - } else { - Ok(()) - } -} - -pub fn handle_results(globals: &Globals, results: Vec) -> Result<(), ()> { - let errors = results.iter().filter_map(|r| { - if let FinalRunResult::Failed(c, r) = r { - Some((c, &r.stdout, &r.stderr)) - } else { - None - } - }); - - let successes = results.iter().filter_map(|r| { - if let FinalRunResult::Success(c, r) = r { - Some((c, &r.stdout, &r.stderr)) - } else { - None - } - }); - - let command_errors = results.iter().filter_map(|r| { - if let FinalRunResult::CommandError(c, e) = r { - Some((c, e)) - } else { - None - } - }); - - let log_stdout_stderr = |level: Level| { - move |(cmd, stdout, stderr): (&CargoCommand, &String, &String)| { - let cmd = cmd.as_cmd_string(); - if !stdout.is_empty() && !stderr.is_empty() { - log::log!(level, "\n{cmd}\nStdout:\n{stdout}\nStderr:\n{stderr}"); - } else if !stdout.is_empty() { - log::log!(level, "\n{cmd}\nStdout:\n{}", stdout.trim_end()); - } else if !stderr.is_empty() { - log::log!(level, "\n{cmd}\nStderr:\n{}", stderr.trim_end()); - } - } - }; - - successes.for_each(|(cmd, stdout, stderr)| { - if globals.verbose > 0 { - info!("✅ Success: {cmd}\n {}", cmd.as_cmd_string()); - } else { - info!("✅ Success: {cmd}"); - } - - log_stdout_stderr(Level::Debug)((cmd, stdout, stderr)); - }); - - errors.clone().for_each(|(cmd, stdout, stderr)| { - error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); - log_stdout_stderr(Level::Error)((cmd, stdout, stderr)); - }); - - command_errors - .clone() - .for_each(|(cmd, error)| error!("❌ Failed: {cmd}\n {}\n{error}", cmd.as_cmd_string())); - - let ecount = errors.count() + command_errors.count(); - if ecount != 0 { - log::error!("{ecount} commands failed."); - Err(()) - } else { - info!("🚀🚀🚀 All tasks succeeded 🚀🚀🚀"); - Ok(()) - } -} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 09bf8c7209..1712d712a2 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,11 +1,10 @@ mod argument_parsing; mod build; -mod xtasks; mod cargo_command; +mod run; use argument_parsing::{ExtraArguments, Globals}; use clap::Parser; -use cargo_command::OutputMode; use core::fmt; use diffy::{create_patch, PatchFormatter}; use std::{ @@ -23,8 +22,8 @@ use log::{error, info, log_enabled, trace, Level}; use crate::{ argument_parsing::{Backends, BuildOrCheck, Cli, Commands}, build::init_build_dir, - xtasks::*, - cargo_command::{handle_results, run_command, run_successful, CargoCommand}, + cargo_command::CargoCommand, + run::*, }; #[derive(Debug, Clone, Copy)] diff --git a/xtask/src/run.rs b/xtask/src/run.rs index 32fafc8441..49437d7c0b 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -1,17 +1,37 @@ -use std::path::PathBuf; +use std::{ + fs::File, + io::Read, + path::PathBuf, + process::{Command, Stdio}, +}; use crate::{ argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, TestMetadata}, cargo_command::{BuildMode, CargoCommand}, - command_parser, RunResult, + command_parser, RunResult, TestRunError, }; -use log::error; +use log::{error, info, Level}; #[cfg(feature = "rayon")] use rayon::prelude::*; use iters::*; +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum OutputMode { + PipedAndCollected, + Inherited, +} + +impl From for Stdio { + fn from(value: OutputMode) -> Self { + match value { + OutputMode::PipedAndCollected => Stdio::piped(), + OutputMode::Inherited => Stdio::inherit(), + } + } +} + #[derive(Debug)] pub enum FinalRunResult<'c> { Success(CargoCommand<'c>, RunResult), @@ -400,3 +420,134 @@ pub fn build_and_check_size<'c>( runner.run_and_coalesce() } + +pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result { + log::info!("👟 {command}"); + + let mut process = Command::new(command.executable()); + + process + .args(command.args()) + .stdout(Stdio::piped()) + .stderr(stderr_mode); + + if let Some(dir) = command.chdir() { + process.current_dir(dir.canonicalize()?); + } + + let result = process.output()?; + + let exit_status = result.status; + let stderr = String::from_utf8(result.stderr).unwrap_or("Not displayable".into()); + let stdout = String::from_utf8(result.stdout).unwrap_or("Not displayable".into()); + + if command.print_stdout_intermediate() && exit_status.success() { + log::info!("\n{}", stdout); + } + + if exit_status.success() { + log::info!("✅ Success.") + } else { + log::error!("❌ Command failed. Run to completion for the summary."); + } + + Ok(RunResult { + exit_status, + stdout, + stderr, + }) +} + +/// Check if `run` was successful. +/// returns Ok in case the run went as expected, +/// Err otherwise +pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), TestRunError> { + let mut file_handle = + File::open(expected_output_file).map_err(|_| TestRunError::FileError { + file: expected_output_file.to_owned(), + })?; + let mut expected_output = String::new(); + file_handle + .read_to_string(&mut expected_output) + .map_err(|_| TestRunError::FileError { + file: expected_output_file.to_owned(), + })?; + + if expected_output != run.stdout { + Err(TestRunError::FileCmpError { + expected: expected_output.clone(), + got: run.stdout.clone(), + }) + } else if !run.exit_status.success() { + Err(TestRunError::CommandError(run.clone())) + } else { + Ok(()) + } +} + +pub fn handle_results(globals: &Globals, results: Vec) -> Result<(), ()> { + let errors = results.iter().filter_map(|r| { + if let FinalRunResult::Failed(c, r) = r { + Some((c, &r.stdout, &r.stderr)) + } else { + None + } + }); + + let successes = results.iter().filter_map(|r| { + if let FinalRunResult::Success(c, r) = r { + Some((c, &r.stdout, &r.stderr)) + } else { + None + } + }); + + let command_errors = results.iter().filter_map(|r| { + if let FinalRunResult::CommandError(c, e) = r { + Some((c, e)) + } else { + None + } + }); + + let log_stdout_stderr = |level: Level| { + move |(cmd, stdout, stderr): (&CargoCommand, &String, &String)| { + let cmd = cmd.as_cmd_string(); + if !stdout.is_empty() && !stderr.is_empty() { + log::log!(level, "\n{cmd}\nStdout:\n{stdout}\nStderr:\n{stderr}"); + } else if !stdout.is_empty() { + log::log!(level, "\n{cmd}\nStdout:\n{}", stdout.trim_end()); + } else if !stderr.is_empty() { + log::log!(level, "\n{cmd}\nStderr:\n{}", stderr.trim_end()); + } + } + }; + + successes.for_each(|(cmd, stdout, stderr)| { + if globals.verbose > 0 { + info!("✅ Success: {cmd}\n {}", cmd.as_cmd_string()); + } else { + info!("✅ Success: {cmd}"); + } + + log_stdout_stderr(Level::Debug)((cmd, stdout, stderr)); + }); + + errors.clone().for_each(|(cmd, stdout, stderr)| { + error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); + log_stdout_stderr(Level::Error)((cmd, stdout, stderr)); + }); + + command_errors + .clone() + .for_each(|(cmd, error)| error!("❌ Failed: {cmd}\n {}\n{error}", cmd.as_cmd_string())); + + let ecount = errors.count() + command_errors.count(); + if ecount != 0 { + log::error!("{ecount} commands failed."); + Err(()) + } else { + info!("🚀🚀🚀 All tasks succeeded 🚀🚀🚀"); + Ok(()) + } +} From b87d55f960178971652df95257ddd1ea4f39c6c0 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 11:12:44 +0200 Subject: [PATCH 19/31] Move run into a subdirectory and split `iter` stuff into a module --- xtask/src/run/iter.rs | 48 +++++++++++++++++ xtask/src/{run.rs => run/mod.rs} | 88 ++++---------------------------- 2 files changed, 59 insertions(+), 77 deletions(-) create mode 100644 xtask/src/run/iter.rs rename xtask/src/{run.rs => run/mod.rs} (86%) diff --git a/xtask/src/run/iter.rs b/xtask/src/run/iter.rs new file mode 100644 index 0000000000..d18ad49892 --- /dev/null +++ b/xtask/src/run/iter.rs @@ -0,0 +1,48 @@ +use super::FinalRunResult; + +pub use iter::*; + +pub trait CoalescingRunner<'c> { + /// Run all the commands in this iterator, and coalesce the results into + /// one error (if any individual commands failed) + fn run_and_coalesce(self) -> Vec>; +} + +#[cfg(not(feature = "rayon"))] +mod iter { + use super::*; + use crate::{argument_parsing::Globals, cargo_command::*, run::run_and_convert}; + + pub fn into_iter(var: T) -> impl Iterator { + var.into_iter() + } + + impl<'g, 'c, I> CoalescingRunner<'c> for I + where + I: Iterator, bool)>, + { + fn run_and_coalesce(self) -> Vec> { + self.map(run_and_convert).collect() + } + } +} + +#[cfg(feature = "rayon")] +mod iter { + use super::*; + use crate::{argument_parsing::Globals, cargo_command::*, run::run_and_convert}; + use rayon::prelude::*; + + pub fn into_iter(var: T) -> impl ParallelIterator { + var.into_par_iter() + } + + impl<'g, 'c, I> CoalescingRunner<'c> for I + where + I: ParallelIterator, bool)>, + { + fn run_and_coalesce(self) -> Vec> { + self.map(run_and_convert).collect() + } + } +} diff --git a/xtask/src/run.rs b/xtask/src/run/mod.rs similarity index 86% rename from xtask/src/run.rs rename to xtask/src/run/mod.rs index 49437d7c0b..daa6256361 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run/mod.rs @@ -5,18 +5,20 @@ use std::{ process::{Command, Stdio}, }; +mod iter; +use iter::{into_iter, CoalescingRunner}; + use crate::{ argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, TestMetadata}, cargo_command::{BuildMode, CargoCommand}, command_parser, RunResult, TestRunError, }; + use log::{error, info, Level}; #[cfg(feature = "rayon")] use rayon::prelude::*; -use iters::*; - #[derive(Debug, Clone, Copy, PartialEq)] pub enum OutputMode { PipedAndCollected, @@ -64,48 +66,6 @@ fn run_and_convert<'a>( output } -pub trait CoalescingRunner<'c> { - /// Run all the commands in this iterator, and coalesce the results into - /// one error (if any individual commands failed) - fn run_and_coalesce(self) -> Vec>; -} - -#[cfg(not(feature = "rayon"))] -mod iters { - use super::*; - - pub fn examples_iter(examples: &[String]) -> impl Iterator { - examples.into_iter() - } - - impl<'g, 'c, I> CoalescingRunner<'c> for I - where - I: Iterator, bool)>, - { - fn run_and_coalesce(self) -> Vec> { - self.map(run_and_convert).collect() - } - } -} - -#[cfg(feature = "rayon")] -mod iters { - use super::*; - - pub fn examples_iter(examples: &[String]) -> impl ParallelIterator { - examples.into_par_iter() - } - - impl<'g, 'c, I> CoalescingRunner<'c> for I - where - I: ParallelIterator, bool)>, - { - fn run_and_coalesce(self) -> Vec> { - self.map(run_and_convert).collect() - } - } -} - /// Cargo command to either build or check pub fn cargo<'c>( globals: &Globals, @@ -119,16 +79,7 @@ pub fn cargo<'c>( .flat_map(|package| { let target = backend.to_target(); let features = package.features(target, backend, globals.partial); - - #[cfg(feature = "rayon")] - { - features.into_par_iter().map(move |f| (package, target, f)) - } - - #[cfg(not(feature = "rayon"))] - { - features.into_iter().map(move |f| (package, target, f)) - } + into_iter(features).map(move |f| (package, target, f)) }) .map(move |(package, target, features)| { let target = target.into(); @@ -165,7 +116,7 @@ pub fn cargo_usage_example( operation: BuildOrCheck, usage_examples: Vec, ) -> Vec> { - examples_iter(&usage_examples) + into_iter(&usage_examples) .map(|example| { let path = format!("examples/{example}"); @@ -202,7 +153,7 @@ pub fn cargo_example<'c>( backend: Backends, examples: &'c [String], ) -> Vec> { - let runner = examples_iter(examples).map(|example| { + let runner = into_iter(examples).map(|example| { let features = Some(backend.to_target().and_features(backend.to_rtic_feature())); let command = match operation { @@ -239,16 +190,7 @@ pub fn cargo_clippy<'c>( .flat_map(|package| { let target = backend.to_target(); let features = package.features(target, backend, globals.partial); - - #[cfg(feature = "rayon")] - { - features.into_par_iter().map(move |f| (package, target, f)) - } - - #[cfg(not(feature = "rayon"))] - { - features.into_iter().map(move |f| (package, target, f)) - } + into_iter(features).map(move |f| (package, target, f)) }) .map(move |(package, target, features)| { let command = CargoCommand::Clippy { @@ -344,7 +286,7 @@ pub fn qemu_run_examples<'c>( let target = backend.to_target(); let features = Some(target.and_features(backend.to_rtic_feature())); - examples_iter(examples) + into_iter(examples) .flat_map(|example| { let target = target.into(); let cmd_build = CargoCommand::ExampleBuild { @@ -365,15 +307,7 @@ pub fn qemu_run_examples<'c>( dir: Some(PathBuf::from("./rtic")), }; - #[cfg(not(feature = "rayon"))] - { - [cmd_build, cmd_qemu].into_iter() - } - - #[cfg(feature = "rayon")] - { - [cmd_build, cmd_qemu].into_par_iter() - } + into_iter([cmd_build, cmd_qemu]) }) .map(|cmd| (globals, cmd, overwrite)) .run_and_coalesce() @@ -390,7 +324,7 @@ pub fn build_and_check_size<'c>( let target = backend.to_target(); let features = Some(target.and_features(backend.to_rtic_feature())); - let runner = examples_iter(examples).map(|example| { + let runner = into_iter(examples).map(|example| { let target = target.into(); // Make sure the requested example(s) are built From 65f1f4c1b7f8de50c6f9462a39c98dcd3a73b4cc Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 11:26:23 +0200 Subject: [PATCH 20/31] Also separate all results and data --- xtask/src/main.rs | 126 +------------------------- xtask/src/run/data.rs | 87 ++++++++++++++++++ xtask/src/run/mod.rs | 191 +++++++++++++++------------------------ xtask/src/run/results.rs | 122 +++++++++++++++++++++++++ 4 files changed, 283 insertions(+), 243 deletions(-) create mode 100644 xtask/src/run/data.rs create mode 100644 xtask/src/run/results.rs diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 1712d712a2..30c3da0503 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -3,26 +3,16 @@ mod build; mod cargo_command; mod run; -use argument_parsing::{ExtraArguments, Globals}; +use argument_parsing::ExtraArguments; use clap::Parser; use core::fmt; -use diffy::{create_patch, PatchFormatter}; -use std::{ - error::Error, - ffi::OsString, - fs::File, - io::prelude::*, - path::{Path, PathBuf}, - process::ExitStatus, - str, -}; +use std::{path::Path, str}; use log::{error, info, log_enabled, trace, Level}; use crate::{ argument_parsing::{Backends, BuildOrCheck, Cli, Commands}, build::init_build_dir, - cargo_command::CargoCommand, run::*, }; @@ -65,56 +55,6 @@ const ARMV7M: Target = Target::new("thumbv7m-none-eabi", false); const ARMV8MBASE: Target = Target::new("thumbv8m.base-none-eabi", false); const ARMV8MMAIN: Target = Target::new("thumbv8m.main-none-eabi", false); -#[derive(Debug, Clone)] -pub struct RunResult { - exit_status: ExitStatus, - stdout: String, - stderr: String, -} - -#[derive(Debug)] -pub enum TestRunError { - FileCmpError { expected: String, got: String }, - FileError { file: String }, - PathConversionError(OsString), - CommandError(RunResult), - IncompatibleCommand, -} -impl fmt::Display for TestRunError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - TestRunError::FileCmpError { expected, got } => { - let patch = create_patch(expected, got); - writeln!(f, "Differing output in files.\n")?; - let pf = PatchFormatter::new().with_color(); - writeln!(f, "{}", pf.fmt_patch(&patch))?; - write!( - f, - "See flag --overwrite-expected to create/update expected output." - ) - } - TestRunError::FileError { file } => { - write!(f, "File error on: {file}\nSee flag --overwrite-expected to create/update expected output.") - } - TestRunError::CommandError(e) => { - write!( - f, - "Command failed with exit status {}: {} {}", - e.exit_status, e.stdout, e.stderr - ) - } - TestRunError::PathConversionError(p) => { - write!(f, "Can't convert path from `OsString` to `String`: {p:?}") - } - TestRunError::IncompatibleCommand => { - write!(f, "Can't run that command in this context") - } - } - } -} - -impl Error for TestRunError {} - fn main() -> anyhow::Result<()> { // if there's an `xtask` folder, we're *probably* at the root of this repo (we can't just // check the name of `env::current_dir()` because people might clone it into a different name) @@ -299,65 +239,3 @@ fn main() -> anyhow::Result<()> { handle_results(globals, final_run_results).map_err(|_| anyhow::anyhow!("Commands failed")) } - -// run example binary `example` -fn command_parser( - glob: &Globals, - command: &CargoCommand, - overwrite: bool, -) -> anyhow::Result { - let output_mode = if glob.stderr_inherited { - OutputMode::Inherited - } else { - OutputMode::PipedAndCollected - }; - - match *command { - CargoCommand::Qemu { example, .. } | CargoCommand::Run { example, .. } => { - let run_file = format!("{example}.run"); - let expected_output_file = ["rtic", "ci", "expected", &run_file] - .iter() - .collect::() - .into_os_string() - .into_string() - .map_err(TestRunError::PathConversionError)?; - - // cargo run <..> - let cargo_run_result = run_command(command, output_mode)?; - - // Create a file for the expected output if it does not exist or mismatches - if overwrite { - let result = run_successful(&cargo_run_result, &expected_output_file); - if let Err(e) = result { - // FileError means the file did not exist or was unreadable - error!("Error: {e}"); - let mut file_handle = File::create(&expected_output_file).map_err(|_| { - TestRunError::FileError { - file: expected_output_file.clone(), - } - })?; - info!("Flag --overwrite-expected enabled"); - info!("Creating/updating file: {expected_output_file}"); - file_handle.write_all(cargo_run_result.stdout.as_bytes())?; - }; - } else { - run_successful(&cargo_run_result, &expected_output_file)?; - }; - - Ok(cargo_run_result) - } - CargoCommand::Format { .. } - | CargoCommand::ExampleCheck { .. } - | CargoCommand::ExampleBuild { .. } - | CargoCommand::Check { .. } - | CargoCommand::Build { .. } - | CargoCommand::Clippy { .. } - | CargoCommand::Doc { .. } - | CargoCommand::Test { .. } - | CargoCommand::Book { .. } - | CargoCommand::ExampleSize { .. } => { - let cargo_result = run_command(command, output_mode)?; - Ok(cargo_result) - } - } -} diff --git a/xtask/src/run/data.rs b/xtask/src/run/data.rs new file mode 100644 index 0000000000..eacd72cbad --- /dev/null +++ b/xtask/src/run/data.rs @@ -0,0 +1,87 @@ +use std::{ + ffi::OsString, + process::{ExitStatus, Stdio}, +}; + +use diffy::{create_patch, PatchFormatter}; + +use crate::cargo_command::CargoCommand; + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum OutputMode { + PipedAndCollected, + Inherited, +} + +impl From for Stdio { + fn from(value: OutputMode) -> Self { + match value { + OutputMode::PipedAndCollected => Stdio::piped(), + OutputMode::Inherited => Stdio::inherit(), + } + } +} + +#[derive(Debug, Clone)] +pub struct RunResult { + pub exit_status: ExitStatus, + pub stdout: String, + pub stderr: String, +} + +#[derive(Debug)] +pub enum FinalRunResult<'c> { + Success(CargoCommand<'c>, RunResult), + Failed(CargoCommand<'c>, RunResult), + CommandError(CargoCommand<'c>, anyhow::Error), +} + +#[derive(Debug)] +pub enum TestRunError { + FileCmpError { + expected: String, + got: String, + }, + FileError { + file: String, + }, + PathConversionError(OsString), + CommandError(RunResult), + #[allow(dead_code)] + IncompatibleCommand, +} + +impl core::fmt::Display for TestRunError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TestRunError::FileCmpError { expected, got } => { + let patch = create_patch(expected, got); + writeln!(f, "Differing output in files.\n")?; + let pf = PatchFormatter::new().with_color(); + writeln!(f, "{}", pf.fmt_patch(&patch))?; + write!( + f, + "See flag --overwrite-expected to create/update expected output." + ) + } + TestRunError::FileError { file } => { + write!(f, "File error on: {file}\nSee flag --overwrite-expected to create/update expected output.") + } + TestRunError::CommandError(e) => { + write!( + f, + "Command failed with exit status {}: {} {}", + e.exit_status, e.stdout, e.stderr + ) + } + TestRunError::PathConversionError(p) => { + write!(f, "Can't convert path from `OsString` to `String`: {p:?}") + } + TestRunError::IncompatibleCommand => { + write!(f, "Can't run that command in this context") + } + } + } +} + +impl std::error::Error for TestRunError {} diff --git a/xtask/src/run/mod.rs b/xtask/src/run/mod.rs index daa6256361..501849d734 100644 --- a/xtask/src/run/mod.rs +++ b/xtask/src/run/mod.rs @@ -1,45 +1,30 @@ use std::{ fs::File, - io::Read, + io::Write, path::PathBuf, process::{Command, Stdio}, }; +mod results; +pub use results::handle_results; + +mod data; +use data::*; + mod iter; use iter::{into_iter, CoalescingRunner}; use crate::{ argument_parsing::{Backends, BuildOrCheck, ExtraArguments, Globals, PackageOpt, TestMetadata}, cargo_command::{BuildMode, CargoCommand}, - command_parser, RunResult, TestRunError, }; -use log::{error, info, Level}; +use log::{error, info}; #[cfg(feature = "rayon")] use rayon::prelude::*; -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum OutputMode { - PipedAndCollected, - Inherited, -} - -impl From for Stdio { - fn from(value: OutputMode) -> Self { - match value { - OutputMode::PipedAndCollected => Stdio::piped(), - OutputMode::Inherited => Stdio::inherit(), - } - } -} - -#[derive(Debug)] -pub enum FinalRunResult<'c> { - Success(CargoCommand<'c>, RunResult), - Failed(CargoCommand<'c>, RunResult), - CommandError(CargoCommand<'c>, anyhow::Error), -} +use self::results::run_successful; fn run_and_convert<'a>( (global, command, overwrite): (&Globals, CargoCommand<'a>, bool), @@ -66,6 +51,68 @@ fn run_and_convert<'a>( output } +// run example binary `example` +fn command_parser( + glob: &Globals, + command: &CargoCommand, + overwrite: bool, +) -> anyhow::Result { + let output_mode = if glob.stderr_inherited { + OutputMode::Inherited + } else { + OutputMode::PipedAndCollected + }; + + match *command { + CargoCommand::Qemu { example, .. } | CargoCommand::Run { example, .. } => { + let run_file = format!("{example}.run"); + let expected_output_file = ["rtic", "ci", "expected", &run_file] + .iter() + .collect::() + .into_os_string() + .into_string() + .map_err(TestRunError::PathConversionError)?; + + // cargo run <..> + let cargo_run_result = run_command(command, output_mode)?; + + // Create a file for the expected output if it does not exist or mismatches + if overwrite { + let result = run_successful(&cargo_run_result, &expected_output_file); + if let Err(e) = result { + // FileError means the file did not exist or was unreadable + error!("Error: {e}"); + let mut file_handle = File::create(&expected_output_file).map_err(|_| { + TestRunError::FileError { + file: expected_output_file.clone(), + } + })?; + info!("Flag --overwrite-expected enabled"); + info!("Creating/updating file: {expected_output_file}"); + file_handle.write_all(cargo_run_result.stdout.as_bytes())?; + }; + } else { + run_successful(&cargo_run_result, &expected_output_file)?; + }; + + Ok(cargo_run_result) + } + CargoCommand::Format { .. } + | CargoCommand::ExampleCheck { .. } + | CargoCommand::ExampleBuild { .. } + | CargoCommand::Check { .. } + | CargoCommand::Build { .. } + | CargoCommand::Clippy { .. } + | CargoCommand::Doc { .. } + | CargoCommand::Test { .. } + | CargoCommand::Book { .. } + | CargoCommand::ExampleSize { .. } => { + let cargo_result = run_command(command, output_mode)?; + Ok(cargo_result) + } + } +} + /// Cargo command to either build or check pub fn cargo<'c>( globals: &Globals, @@ -355,7 +402,7 @@ pub fn build_and_check_size<'c>( runner.run_and_coalesce() } -pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result { +fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result { log::info!("👟 {command}"); let mut process = Command::new(command.executable()); @@ -391,97 +438,3 @@ pub fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::R stderr, }) } - -/// Check if `run` was successful. -/// returns Ok in case the run went as expected, -/// Err otherwise -pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), TestRunError> { - let mut file_handle = - File::open(expected_output_file).map_err(|_| TestRunError::FileError { - file: expected_output_file.to_owned(), - })?; - let mut expected_output = String::new(); - file_handle - .read_to_string(&mut expected_output) - .map_err(|_| TestRunError::FileError { - file: expected_output_file.to_owned(), - })?; - - if expected_output != run.stdout { - Err(TestRunError::FileCmpError { - expected: expected_output.clone(), - got: run.stdout.clone(), - }) - } else if !run.exit_status.success() { - Err(TestRunError::CommandError(run.clone())) - } else { - Ok(()) - } -} - -pub fn handle_results(globals: &Globals, results: Vec) -> Result<(), ()> { - let errors = results.iter().filter_map(|r| { - if let FinalRunResult::Failed(c, r) = r { - Some((c, &r.stdout, &r.stderr)) - } else { - None - } - }); - - let successes = results.iter().filter_map(|r| { - if let FinalRunResult::Success(c, r) = r { - Some((c, &r.stdout, &r.stderr)) - } else { - None - } - }); - - let command_errors = results.iter().filter_map(|r| { - if let FinalRunResult::CommandError(c, e) = r { - Some((c, e)) - } else { - None - } - }); - - let log_stdout_stderr = |level: Level| { - move |(cmd, stdout, stderr): (&CargoCommand, &String, &String)| { - let cmd = cmd.as_cmd_string(); - if !stdout.is_empty() && !stderr.is_empty() { - log::log!(level, "\n{cmd}\nStdout:\n{stdout}\nStderr:\n{stderr}"); - } else if !stdout.is_empty() { - log::log!(level, "\n{cmd}\nStdout:\n{}", stdout.trim_end()); - } else if !stderr.is_empty() { - log::log!(level, "\n{cmd}\nStderr:\n{}", stderr.trim_end()); - } - } - }; - - successes.for_each(|(cmd, stdout, stderr)| { - if globals.verbose > 0 { - info!("✅ Success: {cmd}\n {}", cmd.as_cmd_string()); - } else { - info!("✅ Success: {cmd}"); - } - - log_stdout_stderr(Level::Debug)((cmd, stdout, stderr)); - }); - - errors.clone().for_each(|(cmd, stdout, stderr)| { - error!("❌ Failed: {cmd}\n {}", cmd.as_cmd_string()); - log_stdout_stderr(Level::Error)((cmd, stdout, stderr)); - }); - - command_errors - .clone() - .for_each(|(cmd, error)| error!("❌ Failed: {cmd}\n {}\n{error}", cmd.as_cmd_string())); - - let ecount = errors.count() + command_errors.count(); - if ecount != 0 { - log::error!("{ecount} commands failed."); - Err(()) - } else { - info!("🚀🚀🚀 All tasks succeeded 🚀🚀🚀"); - Ok(()) - } -} diff --git a/xtask/src/run/results.rs b/xtask/src/run/results.rs new file mode 100644 index 0000000000..072cbcfd4d --- /dev/null +++ b/xtask/src/run/results.rs @@ -0,0 +1,122 @@ +use log::{error, info, log, Level}; + +use crate::{argument_parsing::Globals, cargo_command::CargoCommand}; + +use super::data::{FinalRunResult, RunResult, TestRunError}; + +const TARGET: &str = "xtask::results"; + +/// Check if `run` was successful. +/// returns Ok in case the run went as expected, +/// Err otherwise +pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), TestRunError> { + let file = expected_output_file.to_string(); + + let expected_output = std::fs::read(expected_output_file) + .map(|d| String::from_utf8(d).map_err(|_| TestRunError::FileError { file: file.clone() })) + .map_err(|_| TestRunError::FileError { file })??; + + if expected_output != run.stdout { + Err(TestRunError::FileCmpError { + expected: expected_output.clone(), + got: run.stdout.clone(), + }) + } else if !run.exit_status.success() { + Err(TestRunError::CommandError(run.clone())) + } else { + Ok(()) + } +} + +pub fn handle_results(globals: &Globals, results: Vec) -> Result<(), ()> { + let errors = results.iter().filter_map(|r| { + if let FinalRunResult::Failed(c, r) = r { + Some((c, &r.stdout, &r.stderr)) + } else { + None + } + }); + + let successes = results.iter().filter_map(|r| { + if let FinalRunResult::Success(c, r) = r { + Some((c, &r.stdout, &r.stderr)) + } else { + None + } + }); + + let command_errors = results.iter().filter_map(|r| { + if let FinalRunResult::CommandError(c, e) = r { + Some((c, e)) + } else { + None + } + }); + + let log_stdout_stderr = |level: Level| { + move |(cmd, stdout, stderr): (&CargoCommand, &String, &String)| { + let cmd = cmd.as_cmd_string(); + if !stdout.is_empty() && !stderr.is_empty() { + log!( + target: TARGET, + level, + "\n{cmd}\nStdout:\n{stdout}\nStderr:\n{stderr}" + ); + } else if !stdout.is_empty() { + log!( + target: TARGET, + level, + "\n{cmd}\nStdout:\n{}", + stdout.trim_end() + ); + } else if !stderr.is_empty() { + log!( + target: TARGET, + level, + "\n{cmd}\nStderr:\n{}", + stderr.trim_end() + ); + } + } + }; + + successes.for_each(|(cmd, stdout, stderr)| { + if globals.verbose > 0 { + info!( + target: TARGET, + "✅ Success: {cmd}\n {}", + cmd.as_cmd_string() + ); + } else { + info!(target: TARGET, "✅ Success: {cmd}"); + } + + log_stdout_stderr(Level::Debug)((cmd, stdout, stderr)); + }); + + errors.clone().for_each(|(cmd, stdout, stderr)| { + error!( + target: TARGET, + "❌ Failed: {cmd}\n {}", + cmd.as_cmd_string() + ); + log_stdout_stderr(Level::Error)((cmd, stdout, stderr)); + }); + + command_errors.clone().for_each(|(cmd, error)| { + error!( + target: TARGET, + "❌ Failed: {cmd}\n {}\n{error}", + cmd.as_cmd_string() + ) + }); + + let ecount = errors.count() + command_errors.count(); + if ecount != 0 { + error!(target: TARGET, "{ecount} commands failed."); + Err(()) + } else { + info!(target: TARGET, "🚀🚀🚀 All tasks succeeded 🚀🚀🚀"); + Ok(()) + } +} From fd011cd5ecb65b076f94376214ff31e7edcff189 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 11:37:36 +0200 Subject: [PATCH 21/31] FIx printing for Run and Qemu --- xtask/src/run/mod.rs | 58 +++++++++++++++++++++++++++++++++------- xtask/src/run/results.rs | 24 +---------------- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/xtask/src/run/mod.rs b/xtask/src/run/mod.rs index 501849d734..035dc7a7dc 100644 --- a/xtask/src/run/mod.rs +++ b/xtask/src/run/mod.rs @@ -24,8 +24,6 @@ use log::{error, info}; #[cfg(feature = "rayon")] use rayon::prelude::*; -use self::results::run_successful; - fn run_and_convert<'a>( (global, command, overwrite): (&Globals, CargoCommand<'a>, bool), ) -> FinalRunResult<'a> { @@ -65,6 +63,42 @@ fn command_parser( match *command { CargoCommand::Qemu { example, .. } | CargoCommand::Run { example, .. } => { + /// Check if `run` was successful. + /// returns Ok in case the run went as expected, + /// Err otherwise + pub fn run_successful( + run: &RunResult, + expected_output_file: &str, + ) -> Result<(), TestRunError> { + let file = expected_output_file.to_string(); + + let expected_output = std::fs::read(expected_output_file) + .map(|d| { + String::from_utf8(d) + .map_err(|_| TestRunError::FileError { file: file.clone() }) + }) + .map_err(|_| TestRunError::FileError { file })??; + + let res = if expected_output != run.stdout { + Err(TestRunError::FileCmpError { + expected: expected_output.clone(), + got: run.stdout.clone(), + }) + } else if !run.exit_status.success() { + Err(TestRunError::CommandError(run.clone())) + } else { + Ok(()) + }; + + if res.is_ok() { + log::info!("✅ Success."); + } else { + log::error!("❌ Command failed. Run to completion for the summary."); + } + + res + } + let run_file = format!("{example}.run"); let expected_output_file = ["rtic", "ci", "expected", &run_file] .iter() @@ -74,7 +108,7 @@ fn command_parser( .map_err(TestRunError::PathConversionError)?; // cargo run <..> - let cargo_run_result = run_command(command, output_mode)?; + let cargo_run_result = run_command(command, output_mode, false)?; // Create a file for the expected output if it does not exist or mismatches if overwrite { @@ -107,7 +141,7 @@ fn command_parser( | CargoCommand::Test { .. } | CargoCommand::Book { .. } | CargoCommand::ExampleSize { .. } => { - let cargo_result = run_command(command, output_mode)?; + let cargo_result = run_command(command, output_mode, true)?; Ok(cargo_result) } } @@ -402,7 +436,11 @@ pub fn build_and_check_size<'c>( runner.run_and_coalesce() } -fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Result { +fn run_command( + command: &CargoCommand, + stderr_mode: OutputMode, + print_command_success: bool, +) -> anyhow::Result { log::info!("👟 {command}"); let mut process = Command::new(command.executable()); @@ -426,10 +464,12 @@ fn run_command(command: &CargoCommand, stderr_mode: OutputMode) -> anyhow::Resul log::info!("\n{}", stdout); } - if exit_status.success() { - log::info!("✅ Success.") - } else { - log::error!("❌ Command failed. Run to completion for the summary."); + if print_command_success { + if exit_status.success() { + log::info!("✅ Success.") + } else { + log::error!("❌ Command failed. Run to completion for the summary."); + } } Ok(RunResult { diff --git a/xtask/src/run/results.rs b/xtask/src/run/results.rs index 072cbcfd4d..b64e7b18fd 100644 --- a/xtask/src/run/results.rs +++ b/xtask/src/run/results.rs @@ -2,32 +2,10 @@ use log::{error, info, log, Level}; use crate::{argument_parsing::Globals, cargo_command::CargoCommand}; -use super::data::{FinalRunResult, RunResult, TestRunError}; +use super::data::FinalRunResult; const TARGET: &str = "xtask::results"; -/// Check if `run` was successful. -/// returns Ok in case the run went as expected, -/// Err otherwise -pub fn run_successful(run: &RunResult, expected_output_file: &str) -> Result<(), TestRunError> { - let file = expected_output_file.to_string(); - - let expected_output = std::fs::read(expected_output_file) - .map(|d| String::from_utf8(d).map_err(|_| TestRunError::FileError { file: file.clone() })) - .map_err(|_| TestRunError::FileError { file })??; - - if expected_output != run.stdout { - Err(TestRunError::FileCmpError { - expected: expected_output.clone(), - got: run.stdout.clone(), - }) - } else if !run.exit_status.success() { - Err(TestRunError::CommandError(run.clone())) - } else { - Ok(()) - } -} - pub fn handle_results(globals: &Globals, results: Vec) -> Result<(), ()> { let errors = results.iter().filter_map(|r| { if let FinalRunResult::Failed(c, r) = r { From 4d3361658b2487154d8140b06b140e72c0227441 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 11:51:28 +0200 Subject: [PATCH 22/31] Unconditionally deny warnings for clippy --- xtask/src/cargo_command.rs | 21 +++++++++++++++++++-- xtask/src/run/mod.rs | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/xtask/src/cargo_command.rs b/xtask/src/cargo_command.rs index f399b8702d..9cf4f6505b 100644 --- a/xtask/src/cargo_command.rs +++ b/xtask/src/cargo_command.rs @@ -65,6 +65,7 @@ pub enum CargoCommand<'a> { package: Option, target: Option>, features: Option, + deny_warnings: bool, }, Format { cargoarg: &'a Option<&'a str>, @@ -244,10 +245,16 @@ impl core::fmt::Display for CargoCommand<'_> { package, target, features, + deny_warnings, } => { let details = details(target, None, features, cargoarg, None); let package = p(package); - write!(f, "Clippy {package} {details}") + let deny_warns = if *deny_warnings { + format!(" (deny warnings)") + } else { + format!("") + }; + write!(f, "Clippy{deny_warns} {package} {details}") } CargoCommand::Format { cargoarg, @@ -483,9 +490,19 @@ impl<'a> CargoCommand<'a> { cargoarg, package, features, + deny_warnings, // Target is added by build_args target: _, - } => self.build_args(true, cargoarg, features, None, p(package)), + } => { + let package = p(package); + let extra = if *deny_warnings { + vec!["--", "-D", "warnings"].into_iter() + } else { + vec![].into_iter() + }; + + self.build_args(true, cargoarg, features, None, package.chain(extra)) + } CargoCommand::Doc { cargoarg, features, diff --git a/xtask/src/run/mod.rs b/xtask/src/run/mod.rs index 035dc7a7dc..ac35f5ce81 100644 --- a/xtask/src/run/mod.rs +++ b/xtask/src/run/mod.rs @@ -279,6 +279,7 @@ pub fn cargo_clippy<'c>( package: Some(package.name()), target: target.into(), features, + deny_warnings: true, }; (globals, command, false) From 2db26c1015f0a32fe43e71d60f5fd75dbb25f40c Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 12:51:11 +0200 Subject: [PATCH 23/31] Deny on warnings in xtasks --- .github/workflows/build.yml | 24 ++----- rtic-common/src/lib.rs | 1 - rtic-macros/src/lib.rs | 1 - rtic-monotonics/src/lib.rs | 1 - rtic-sync/src/lib.rs | 1 - rtic-time/src/lib.rs | 1 - rtic/src/lib.rs | 1 - xtask/src/argument_parsing.rs | 16 ++++- xtask/src/cargo_command.rs | 116 +++++++++++++++++++++++++--------- xtask/src/run/mod.rs | 19 +++++- 10 files changed, 123 insertions(+), 58 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4fa2b8079d..ad0f5eda40 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,9 +25,6 @@ jobs: - name: Checkout uses: actions/checkout@v3 - - name: Fail on warnings - run: find . -type f -name lib.rs -execdir sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' {} + - - name: Cache Dependencies uses: Swatinem/rust-cache@v2 @@ -62,13 +59,10 @@ jobs: rustup target add thumbv8m.base-none-eabi rustup target add thumbv8m.main-none-eabi - - name: Fail on warnings - run: find . -type f -name lib.rs -execdir sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' {} + - - name: Cache Dependencies uses: Swatinem/rust-cache@v2 - - run: cargo xtask --backend ${{ matrix.backend }} check + - run: cargo xtask --deny-warnings --backend ${{ matrix.backend }} check # Clippy clippy: @@ -101,13 +95,10 @@ jobs: - name: Add Rust component clippy run: rustup component add clippy - - name: Fail on warnings - run: find . -type f -name lib.rs -execdir sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' {} + - - name: Cache Dependencies uses: Swatinem/rust-cache@v2 - - run: cargo xtask --backend ${{ matrix.backend }} clippy + - run: cargo xtask --deny-warnings --backend ${{ matrix.backend }} clippy # Verify all examples, checks checkexamples: @@ -219,12 +210,8 @@ jobs: sudo apt update sudo apt install -y qemu-system-arm - - name: Fail on warnings - working-directory: ./rtic - run: sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' src/lib.rs - - name: Run-pass tests - run: cargo xtask --backend ${{ matrix.backend }} qemu + run: cargo xtask --deny-warnings --backend ${{ matrix.backend }} qemu # Run test suite tests: @@ -260,11 +247,8 @@ jobs: rustup target add thumbv8m.base-none-eabi rustup target add thumbv8m.main-none-eabi - - name: Fail on warnings - run: find . -type f -name lib.rs -execdir sed -i 's,//deny_warnings_placeholder_for_ci,#![deny(warnings)],' {} + - - name: Run cargo test - run: cargo xtask --backend ${{ matrix.backend }} test ${{ matrix.package }} + run: cargo xtask --deny-warnings --backend ${{ matrix.backend }} test ${{ matrix.package }} # Build documentation, check links docs: diff --git a/rtic-common/src/lib.rs b/rtic-common/src/lib.rs index 03d0306373..e8f5af7e71 100644 --- a/rtic-common/src/lib.rs +++ b/rtic-common/src/lib.rs @@ -2,7 +2,6 @@ #![no_std] #![deny(missing_docs)] -//deny_warnings_placeholder_for_ci #[cfg(test)] #[macro_use] diff --git a/rtic-macros/src/lib.rs b/rtic-macros/src/lib.rs index cd2a9245db..e0043d916e 100644 --- a/rtic-macros/src/lib.rs +++ b/rtic-macros/src/lib.rs @@ -2,7 +2,6 @@ html_logo_url = "https://raw.githubusercontent.com/rtic-rs/rtic/master/book/en/src/RTIC.svg", html_favicon_url = "https://raw.githubusercontent.com/rtic-rs/rtic/master/book/en/src/RTIC.svg" )] -//deny_warnings_placeholder_for_ci use proc_macro::TokenStream; use std::{env, fs, path::Path}; diff --git a/rtic-monotonics/src/lib.rs b/rtic-monotonics/src/lib.rs index 04ce4e2451..714200a693 100644 --- a/rtic-monotonics/src/lib.rs +++ b/rtic-monotonics/src/lib.rs @@ -2,7 +2,6 @@ #![no_std] #![deny(missing_docs)] -//deny_warnings_placeholder_for_ci #![allow(incomplete_features)] #![feature(async_fn_in_trait)] diff --git a/rtic-sync/src/lib.rs b/rtic-sync/src/lib.rs index ac062205a8..fd8b6c3ad0 100644 --- a/rtic-sync/src/lib.rs +++ b/rtic-sync/src/lib.rs @@ -2,7 +2,6 @@ #![no_std] #![deny(missing_docs)] -//deny_warnings_placeholder_for_ci pub mod arbiter; pub mod channel; diff --git a/rtic-time/src/lib.rs b/rtic-time/src/lib.rs index 1ed1e9d6ce..7c0c7645a2 100644 --- a/rtic-time/src/lib.rs +++ b/rtic-time/src/lib.rs @@ -2,7 +2,6 @@ #![no_std] #![deny(missing_docs)] -//deny_warnings_placeholder_for_ci #![allow(incomplete_features)] #![feature(async_fn_in_trait)] diff --git a/rtic/src/lib.rs b/rtic/src/lib.rs index ac05d93d6c..53fe287575 100644 --- a/rtic/src/lib.rs +++ b/rtic/src/lib.rs @@ -30,7 +30,6 @@ html_logo_url = "https://raw.githubusercontent.com/rtic-rs/rtic/master/book/en/src/RTIC.svg", html_favicon_url = "https://raw.githubusercontent.com/rtic-rs/rtic/master/book/en/src/RTIC.svg" )] -//deny_warnings_placeholder_for_ci #![allow(clippy::inline_always)] pub use rtic_core::{prelude as mutex_prelude, Exclusive, Mutex}; diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index 8c8f7d2a2d..d7c0262fb7 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -94,7 +94,11 @@ impl Package { pub struct TestMetadata {} impl TestMetadata { - pub fn match_package(package: Package, backend: Backends) -> CargoCommand<'static> { + pub fn match_package( + deny_warnings: bool, + package: Package, + backend: Backends, + ) -> CargoCommand<'static> { match package { Package::Rtic => { let features = format!( @@ -107,32 +111,38 @@ impl TestMetadata { package: Some(package.name()), features, test: Some("ui".to_owned()), + deny_warnings, } } Package::RticMacros => CargoCommand::Test { package: Some(package.name()), features: Some(backend.to_rtic_macros_feature().to_owned()), test: None, + deny_warnings, }, Package::RticSync => CargoCommand::Test { package: Some(package.name()), features: Some("testing".to_owned()), test: None, + deny_warnings, }, Package::RticCommon => CargoCommand::Test { package: Some(package.name()), features: Some("testing".to_owned()), test: None, + deny_warnings, }, Package::RticMonotonics => CargoCommand::Test { package: Some(package.name()), features: None, test: None, + deny_warnings, }, Package::RticTime => CargoCommand::Test { package: Some(package.name()), features: Some("critical-section/std".into()), test: None, + deny_warnings, }, } } @@ -192,6 +202,10 @@ pub enum BuildOrCheck { #[derive(Parser, Clone)] pub struct Globals { + /// Error out on warnings + #[arg(short = 'D', long)] + pub deny_warnings: bool, + /// For which backend to build. #[arg(value_enum, short, default_value = "thumbv7", long, global = true)] pub backend: Option, diff --git a/xtask/src/cargo_command.rs b/xtask/src/cargo_command.rs index 9cf4f6505b..09487cb61b 100644 --- a/xtask/src/cargo_command.rs +++ b/xtask/src/cargo_command.rs @@ -28,6 +28,7 @@ pub enum CargoCommand<'a> { features: Option, mode: BuildMode, dir: Option, + deny_warnings: bool, }, ExampleBuild { cargoarg: &'a Option<&'a str>, @@ -36,6 +37,7 @@ pub enum CargoCommand<'a> { features: Option, mode: BuildMode, dir: Option, + deny_warnings: bool, }, ExampleCheck { cargoarg: &'a Option<&'a str>, @@ -43,6 +45,7 @@ pub enum CargoCommand<'a> { target: Option>, features: Option, mode: BuildMode, + deny_warnings: bool, }, Build { cargoarg: &'a Option<&'a str>, @@ -51,6 +54,7 @@ pub enum CargoCommand<'a> { features: Option, mode: BuildMode, dir: Option, + deny_warnings: bool, }, Check { cargoarg: &'a Option<&'a str>, @@ -59,6 +63,7 @@ pub enum CargoCommand<'a> { features: Option, mode: BuildMode, dir: Option, + deny_warnings: bool, }, Clippy { cargoarg: &'a Option<&'a str>, @@ -81,6 +86,7 @@ pub enum CargoCommand<'a> { package: Option, features: Option, test: Option, + deny_warnings: bool, }, Book { arguments: Option, @@ -123,6 +129,7 @@ impl core::fmt::Display for CargoCommand<'_> { } fn details( + deny_warnings: bool, target: &Option, mode: Option<&BuildMode>, features: &Option, @@ -150,14 +157,20 @@ impl core::fmt::Display for CargoCommand<'_> { format!("debug") }; - if cargoarg.is_some() && path.is_some() { - format!("({target}, {mode}, {feat}, {carg}, {in_dir})") - } else if cargoarg.is_some() { - format!("({target}, {mode}, {feat}, {carg})") - } else if path.is_some() { - format!("({target}, {mode}, {feat}, {in_dir})") + let deny_warnings = if deny_warnings { + format!("deny warnings, ") } else { - format!("({target}, {mode}, {feat})") + format!("") + }; + + if cargoarg.is_some() && path.is_some() { + format!("({deny_warnings}{target}, {mode}, {feat}, {carg}, {in_dir})") + } else if cargoarg.is_some() { + format!("({deny_warnings}{target}, {mode}, {feat}, {carg})") + } else if path.is_some() { + format!("({deny_warnings}{target}, {mode}, {feat}, {in_dir})") + } else { + format!("({deny_warnings}{target}, {mode}, {feat})") } } @@ -173,7 +186,7 @@ impl core::fmt::Display for CargoCommand<'_> { write!( f, "Run example {example} {}", - details(target, Some(mode), features, cargoarg, dir.as_ref()) + details(false, target, Some(mode), features, cargoarg, dir.as_ref()) ) } CargoCommand::Qemu { @@ -183,8 +196,10 @@ impl core::fmt::Display for CargoCommand<'_> { features, mode, dir, + deny_warnings, } => { - let details = details(target, Some(mode), features, cargoarg, dir.as_ref()); + let warns = *deny_warnings; + let details = details(warns, target, Some(mode), features, cargoarg, dir.as_ref()); write!(f, "Run example {example} in QEMU {details}",) } CargoCommand::ExampleBuild { @@ -194,8 +209,10 @@ impl core::fmt::Display for CargoCommand<'_> { features, mode, dir, + deny_warnings, } => { - let details = details(target, Some(mode), features, cargoarg, dir.as_ref()); + let warns = *deny_warnings; + let details = details(warns, target, Some(mode), features, cargoarg, dir.as_ref()); write!(f, "Build example {example} {details}",) } CargoCommand::ExampleCheck { @@ -204,10 +221,11 @@ impl core::fmt::Display for CargoCommand<'_> { target, features, mode, + deny_warnings, } => write!( f, "Check example {example} {}", - details(target, Some(mode), features, cargoarg, None) + details(*deny_warnings, target, Some(mode), features, cargoarg, None) ), CargoCommand::Build { cargoarg, @@ -216,12 +234,14 @@ impl core::fmt::Display for CargoCommand<'_> { features, mode, dir, + deny_warnings, } => { let package = p(package); + let warns = *deny_warnings; write!( f, "Build {package} {}", - details(target, Some(mode), features, cargoarg, dir.as_ref()) + details(warns, target, Some(mode), features, cargoarg, dir.as_ref()) ) } @@ -232,12 +252,14 @@ impl core::fmt::Display for CargoCommand<'_> { features, mode, dir, + deny_warnings, } => { let package = p(package); + let warns = *deny_warnings; write!( f, "Check {package} {}", - details(target, Some(mode), features, cargoarg, dir.as_ref()) + details(warns, target, Some(mode), features, cargoarg, dir.as_ref()) ) } CargoCommand::Clippy { @@ -247,14 +269,9 @@ impl core::fmt::Display for CargoCommand<'_> { features, deny_warnings, } => { - let details = details(target, None, features, cargoarg, None); + let details = details(*deny_warnings, target, None, features, cargoarg, None); let package = p(package); - let deny_warns = if *deny_warnings { - format!(" (deny warnings)") - } else { - format!("") - }; - write!(f, "Clippy{deny_warns} {package} {details}") + write!(f, "Clippy {package} {details}") } CargoCommand::Format { cargoarg, @@ -297,14 +314,20 @@ impl core::fmt::Display for CargoCommand<'_> { package, features, test, + deny_warnings, } => { let p = p(package); let test = test .clone() .map(|t| format!("test {t}")) .unwrap_or("all tests".into()); + let deny_warnings = if *deny_warnings { + format!("deny warnings, ") + } else { + format!("") + }; let feat = feat(features); - write!(f, "Run {test} in {p} (features: {feat})") + write!(f, "Run {test} in {p} ({deny_warnings}features: {feat})") } CargoCommand::Book { arguments: _ } => write!(f, "Build the book"), CargoCommand::ExampleSize { @@ -316,7 +339,7 @@ impl core::fmt::Display for CargoCommand<'_> { arguments: _, dir, } => { - let details = details(target, Some(mode), features, cargoarg, dir.as_ref()); + let details = details(false, target, Some(mode), features, cargoarg, dir.as_ref()); write!(f, "Compute size of example {example} {details}") } } @@ -459,6 +482,8 @@ impl<'a> CargoCommand<'a> { dir: _, // Target is added by build_args target: _, + // deny_warnings is exposed through `rustflags` + deny_warnings: _, } => self.build_args( true, cargoarg, @@ -471,10 +496,12 @@ impl<'a> CargoCommand<'a> { package, features, mode, - // Dir is exposed through `chdir` - dir: _, // Target is added by build_args target: _, + // Dir is exposed through `chdir` + dir: _, + // deny_warnings is exposed through `rustflags` + deny_warnings: _, } => self.build_args(true, cargoarg, features, Some(mode), p(package)), CargoCommand::Check { cargoarg, @@ -485,23 +512,25 @@ impl<'a> CargoCommand<'a> { dir: _, // Target is added by build_args target: _, + // deny_warnings is exposed through `rustflags` + deny_warnings: _, } => self.build_args(true, cargoarg, features, Some(mode), p(package)), CargoCommand::Clippy { cargoarg, package, features, - deny_warnings, // Target is added by build_args target: _, + deny_warnings, } => { - let package = p(package); - let extra = if *deny_warnings { - vec!["--", "-D", "warnings"].into_iter() + let deny_warnings = if *deny_warnings { + vec!["--", "-D", "warnings"] } else { - vec![].into_iter() + vec![] }; - self.build_args(true, cargoarg, features, None, package.chain(extra)) + let extra = p(package).chain(deny_warnings); + self.build_args(true, cargoarg, features, None, extra) } CargoCommand::Doc { cargoarg, @@ -515,6 +544,8 @@ impl<'a> CargoCommand<'a> { package, features, test, + // deny_warnings is exposed through `rustflags` + deny_warnings: _, } => { let extra = if let Some(test) = test { vec!["--test", test] @@ -564,6 +595,8 @@ impl<'a> CargoCommand<'a> { dir: _, // Target is added by build_args target: _, + // deny_warnings is exposed through `rustflags` + deny_warnings: _, } => self.build_args( true, cargoarg, @@ -578,6 +611,8 @@ impl<'a> CargoCommand<'a> { mode, // Target is added by build_args target: _, + // deny_warnings is exposed through `rustflags` + deny_warnings: _, } => self.build_args( true, cargoarg, @@ -632,6 +667,27 @@ impl<'a> CargoCommand<'a> { } } + pub fn rustflags(&self) -> Option<&str> { + match self { + // Clippy is a special case: it sets deny warnings + // through an argument to rustc. + CargoCommand::Clippy { .. } => None, + CargoCommand::Check { deny_warnings, .. } + | CargoCommand::ExampleCheck { deny_warnings, .. } + | CargoCommand::Build { deny_warnings, .. } + | CargoCommand::ExampleBuild { deny_warnings, .. } + | CargoCommand::Test { deny_warnings, .. } + | CargoCommand::Qemu { deny_warnings, .. } => { + if *deny_warnings { + Some("-D warnings") + } else { + None + } + } + _ => None, + } + } + pub fn print_stdout_intermediate(&self) -> bool { match self { Self::ExampleSize { .. } => true, diff --git a/xtask/src/run/mod.rs b/xtask/src/run/mod.rs index ac35f5ce81..4032ea8fed 100644 --- a/xtask/src/run/mod.rs +++ b/xtask/src/run/mod.rs @@ -172,6 +172,7 @@ pub fn cargo<'c>( features, mode: BuildMode::Release, dir: None, + deny_warnings: globals.deny_warnings, }, BuildOrCheck::Build => CargoCommand::Build { cargoarg, @@ -180,6 +181,7 @@ pub fn cargo<'c>( features, mode: BuildMode::Release, dir: None, + deny_warnings: globals.deny_warnings, }, }; @@ -209,6 +211,7 @@ pub fn cargo_usage_example( package: None, target: None, features: None, + deny_warnings: globals.deny_warnings, }, BuildOrCheck::Build => CargoCommand::Build { cargoarg: &None, @@ -217,6 +220,7 @@ pub fn cargo_usage_example( features: None, mode: BuildMode::Release, dir: Some(path.into()), + deny_warnings: globals.deny_warnings, }, }; (globals, command, false) @@ -244,6 +248,7 @@ pub fn cargo_example<'c>( target: Some(backend.to_target()), features, mode: BuildMode::Release, + deny_warnings: globals.deny_warnings, }, BuildOrCheck::Build => CargoCommand::ExampleBuild { cargoarg, @@ -252,6 +257,7 @@ pub fn cargo_example<'c>( features, mode: BuildMode::Release, dir: Some(PathBuf::from("./rtic")), + deny_warnings: globals.deny_warnings, }, }; (globals, command, false) @@ -337,7 +343,10 @@ pub fn cargo_test<'c>( ) -> Vec> { package .packages() - .map(|p| (globals, TestMetadata::match_package(p, backend), false)) + .map(|p| { + let meta = TestMetadata::match_package(globals.deny_warnings, p, backend); + (globals, meta, false) + }) .run_and_coalesce() } @@ -378,6 +387,7 @@ pub fn qemu_run_examples<'c>( features: features.clone(), mode: BuildMode::Release, dir: Some(PathBuf::from("./rtic")), + deny_warnings: globals.deny_warnings, }; let cmd_qemu = CargoCommand::Qemu { @@ -387,6 +397,7 @@ pub fn qemu_run_examples<'c>( features: features.clone(), mode: BuildMode::Release, dir: Some(PathBuf::from("./rtic")), + deny_warnings: globals.deny_warnings, }; into_iter([cmd_build, cmd_qemu]) @@ -417,7 +428,9 @@ pub fn build_and_check_size<'c>( features: features.clone(), mode: BuildMode::Release, dir: Some(PathBuf::from("./rtic")), + deny_warnings: globals.deny_warnings, }; + if let Err(err) = command_parser(globals, &cmd, false) { error!("{err}"); } @@ -455,6 +468,10 @@ fn run_command( process.current_dir(dir.canonicalize()?); } + if let Some(rustflags) = command.rustflags() { + process.env("RUSTFLAGS", rustflags); + } + let result = process.output()?; let exit_status = result.status; From 799e5bf35786de703bf835912f74b92d358dbde0 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 13:04:20 +0200 Subject: [PATCH 24/31] Placate clippy --- rtic/src/export/cortex_basepri.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rtic/src/export/cortex_basepri.rs b/rtic/src/export/cortex_basepri.rs index d3ceba35ba..695236be3a 100644 --- a/rtic/src/export/cortex_basepri.rs +++ b/rtic/src/export/cortex_basepri.rs @@ -66,8 +66,7 @@ pub unsafe fn lock( f: impl FnOnce(&mut T) -> R, ) -> R { if ceiling == (1 << nvic_prio_bits) { - let r = critical_section::with(|_| f(&mut *ptr)); - r + critical_section::with(|_| f(&mut *ptr)) } else { let current = basepri::read(); basepri::write(cortex_logical2hw(ceiling, nvic_prio_bits)); From 85e2cd6d4b1ac801dbbce2295a6617a56f9ea5a0 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 13:16:28 +0200 Subject: [PATCH 25/31] Also always deny warnings for doc --- xtask/src/cargo_command.rs | 32 +++++++++++++++++++++----------- xtask/src/run/mod.rs | 5 +++-- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/xtask/src/cargo_command.rs b/xtask/src/cargo_command.rs index 09487cb61b..ef14a38a5e 100644 --- a/xtask/src/cargo_command.rs +++ b/xtask/src/cargo_command.rs @@ -81,6 +81,7 @@ pub enum CargoCommand<'a> { cargoarg: &'a Option<&'a str>, features: Option, arguments: Option, + deny_warnings: bool, }, Test { package: Option, @@ -297,6 +298,7 @@ impl core::fmt::Display for CargoCommand<'_> { cargoarg, features, arguments, + deny_warnings, } => { let feat = feat(features); let carg = carg(cargoarg); @@ -304,10 +306,15 @@ impl core::fmt::Display for CargoCommand<'_> { .clone() .map(|a| format!("{a}")) .unwrap_or_else(|| "no extra arguments".into()); - if cargoarg.is_some() { - write!(f, "Document ({feat}, {carg}, {arguments})") + let deny_warnings = if *deny_warnings { + format!("deny warnings, ") } else { - write!(f, "Document ({feat}, {arguments})") + format!("") + }; + if cargoarg.is_some() { + write!(f, "Document ({deny_warnings}{feat}, {carg}, {arguments})") + } else { + write!(f, "Document ({deny_warnings}{feat}, {arguments})") } } CargoCommand::Test { @@ -482,7 +489,7 @@ impl<'a> CargoCommand<'a> { dir: _, // Target is added by build_args target: _, - // deny_warnings is exposed through `rustflags` + // deny_warnings is exposed through `extra_env` deny_warnings: _, } => self.build_args( true, @@ -500,7 +507,7 @@ impl<'a> CargoCommand<'a> { target: _, // Dir is exposed through `chdir` dir: _, - // deny_warnings is exposed through `rustflags` + // deny_warnings is exposed through `extra_env` deny_warnings: _, } => self.build_args(true, cargoarg, features, Some(mode), p(package)), CargoCommand::Check { @@ -512,7 +519,7 @@ impl<'a> CargoCommand<'a> { dir: _, // Target is added by build_args target: _, - // deny_warnings is exposed through `rustflags` + // deny_warnings is exposed through `extra_env` deny_warnings: _, } => self.build_args(true, cargoarg, features, Some(mode), p(package)), CargoCommand::Clippy { @@ -536,6 +543,8 @@ impl<'a> CargoCommand<'a> { cargoarg, features, arguments, + // deny_warnings is exposed through `extra_env` + deny_warnings: _, } => { let extra = Self::extra_args(arguments.as_ref()); self.build_args(true, cargoarg, features, None, extra) @@ -544,7 +553,7 @@ impl<'a> CargoCommand<'a> { package, features, test, - // deny_warnings is exposed through `rustflags` + // deny_warnings is exposed through `extra_env` deny_warnings: _, } => { let extra = if let Some(test) = test { @@ -595,7 +604,7 @@ impl<'a> CargoCommand<'a> { dir: _, // Target is added by build_args target: _, - // deny_warnings is exposed through `rustflags` + // deny_warnings is exposed through `extra_env` deny_warnings: _, } => self.build_args( true, @@ -611,7 +620,7 @@ impl<'a> CargoCommand<'a> { mode, // Target is added by build_args target: _, - // deny_warnings is exposed through `rustflags` + // deny_warnings is exposed through `extra_env` deny_warnings: _, } => self.build_args( true, @@ -667,11 +676,12 @@ impl<'a> CargoCommand<'a> { } } - pub fn rustflags(&self) -> Option<&str> { + pub fn extra_env(&self) -> Option<(&str, &str)> { match self { // Clippy is a special case: it sets deny warnings // through an argument to rustc. CargoCommand::Clippy { .. } => None, + CargoCommand::Doc { .. } => Some(("RUSTDOCFLAGS", "-D warnings")), CargoCommand::Check { deny_warnings, .. } | CargoCommand::ExampleCheck { deny_warnings, .. } | CargoCommand::Build { deny_warnings, .. } @@ -679,7 +689,7 @@ impl<'a> CargoCommand<'a> { | CargoCommand::Test { deny_warnings, .. } | CargoCommand::Qemu { deny_warnings, .. } => { if *deny_warnings { - Some("-D warnings") + Some(("RUSTFLAGS", "-D warnings")) } else { None } diff --git a/xtask/src/run/mod.rs b/xtask/src/run/mod.rs index 4032ea8fed..74179c56fd 100644 --- a/xtask/src/run/mod.rs +++ b/xtask/src/run/mod.rs @@ -328,6 +328,7 @@ pub fn cargo_doc<'c>( cargoarg, features, arguments: arguments.clone(), + deny_warnings: true, }; vec![run_and_convert((globals, command, false))] @@ -468,8 +469,8 @@ fn run_command( process.current_dir(dir.canonicalize()?); } - if let Some(rustflags) = command.rustflags() { - process.env("RUSTFLAGS", rustflags); + if let Some((k, v)) = command.extra_env() { + process.env(k, v); } let result = process.output()?; From bc92e43b113dae2a34db6b10812d84227ac5a6d6 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 13:22:10 +0200 Subject: [PATCH 26/31] Rename + better printout --- xtask/src/cargo_command.rs | 2 +- xtask/src/{run/mod.rs => run.rs} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename xtask/src/{run/mod.rs => run.rs} (100%) diff --git a/xtask/src/cargo_command.rs b/xtask/src/cargo_command.rs index ef14a38a5e..b0102ce3c1 100644 --- a/xtask/src/cargo_command.rs +++ b/xtask/src/cargo_command.rs @@ -149,7 +149,7 @@ impl core::fmt::Display for CargoCommand<'_> { let target = if let Some(target) = target { format!("{target}") } else { - format!("") + format!("") }; let mode = if let Some(mode) = mode { diff --git a/xtask/src/run/mod.rs b/xtask/src/run.rs similarity index 100% rename from xtask/src/run/mod.rs rename to xtask/src/run.rs From 319c2263f3cebd5d990ba5fee277ec9cf1b1d2f9 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 13:27:46 +0200 Subject: [PATCH 27/31] Also print extra env variables as cmd_str --- xtask/src/cargo_command.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/xtask/src/cargo_command.rs b/xtask/src/cargo_command.rs index b0102ce3c1..401bab4c41 100644 --- a/xtask/src/cargo_command.rs +++ b/xtask/src/cargo_command.rs @@ -355,6 +355,12 @@ impl core::fmt::Display for CargoCommand<'_> { impl<'a> CargoCommand<'a> { pub fn as_cmd_string(&self) -> String { + let env = if let Some((key, value)) = self.extra_env() { + format!("{key}=\"{value}\" ") + } else { + format!("") + }; + let cd = if let Some(Some(chdir)) = self.chdir().map(|p| p.to_str()) { format!("cd {chdir} && ") } else { @@ -363,7 +369,7 @@ impl<'a> CargoCommand<'a> { let executable = self.executable(); let args = self.args().join(" "); - format!("{cd}{executable} {args}") + format!("{env}{cd}{executable} {args}") } fn command(&self) -> &'static str { From 0ee2d2c2dbd794dd5f77281de3368c22ea4e7e33 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 13:27:54 +0200 Subject: [PATCH 28/31] Actually chain these --- xtask/src/run.rs | 51 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/xtask/src/run.rs b/xtask/src/run.rs index 74179c56fd..13d2e22ee5 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -418,35 +418,34 @@ pub fn build_and_check_size<'c>( let target = backend.to_target(); let features = Some(target.and_features(backend.to_rtic_feature())); - let runner = into_iter(examples).map(|example| { - let target = target.into(); + let runner = into_iter(examples) + .flat_map(|example| { + let target = target.into(); - // Make sure the requested example(s) are built - let cmd = CargoCommand::ExampleBuild { - cargoarg: &Some("--quiet"), - example, - target, - features: features.clone(), - mode: BuildMode::Release, - dir: Some(PathBuf::from("./rtic")), - deny_warnings: globals.deny_warnings, - }; + // Make sure the requested example(s) are built + let cmd_build = CargoCommand::ExampleBuild { + cargoarg: &Some("--quiet"), + example, + target, + features: features.clone(), + mode: BuildMode::Release, + dir: Some(PathBuf::from("./rtic")), + deny_warnings: globals.deny_warnings, + }; - if let Err(err) = command_parser(globals, &cmd, false) { - error!("{err}"); - } + let cmd_size = CargoCommand::ExampleSize { + cargoarg, + example, + target, + features: features.clone(), + mode: BuildMode::Release, + arguments: arguments.clone(), + dir: Some(PathBuf::from("./rtic")), + }; - let cmd = CargoCommand::ExampleSize { - cargoarg, - example, - target, - features: features.clone(), - mode: BuildMode::Release, - arguments: arguments.clone(), - dir: Some(PathBuf::from("./rtic")), - }; - (globals, cmd, false) - }); + [cmd_build, cmd_size] + }) + .map(|cmd| (globals, cmd, false)); runner.run_and_coalesce() } From e4b673646a9e846fabf24d6776e2a915a5c7366d Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 13:30:23 +0200 Subject: [PATCH 29/31] Tests should always deny warnings --- xtask/src/argument_parsing.rs | 18 +++++++----------- xtask/src/run.rs | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index d7c0262fb7..05d0ae45ca 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -94,11 +94,7 @@ impl Package { pub struct TestMetadata {} impl TestMetadata { - pub fn match_package( - deny_warnings: bool, - package: Package, - backend: Backends, - ) -> CargoCommand<'static> { + pub fn match_package(package: Package, backend: Backends) -> CargoCommand<'static> { match package { Package::Rtic => { let features = format!( @@ -111,38 +107,38 @@ impl TestMetadata { package: Some(package.name()), features, test: Some("ui".to_owned()), - deny_warnings, + deny_warnings: true, } } Package::RticMacros => CargoCommand::Test { package: Some(package.name()), features: Some(backend.to_rtic_macros_feature().to_owned()), test: None, - deny_warnings, + deny_warnings: true, }, Package::RticSync => CargoCommand::Test { package: Some(package.name()), features: Some("testing".to_owned()), test: None, - deny_warnings, + deny_warnings: true, }, Package::RticCommon => CargoCommand::Test { package: Some(package.name()), features: Some("testing".to_owned()), test: None, - deny_warnings, + deny_warnings: true, }, Package::RticMonotonics => CargoCommand::Test { package: Some(package.name()), features: None, test: None, - deny_warnings, + deny_warnings: true, }, Package::RticTime => CargoCommand::Test { package: Some(package.name()), features: Some("critical-section/std".into()), test: None, - deny_warnings, + deny_warnings: true, }, } } diff --git a/xtask/src/run.rs b/xtask/src/run.rs index 13d2e22ee5..bf8d3b7b6e 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -345,7 +345,7 @@ pub fn cargo_test<'c>( package .packages() .map(|p| { - let meta = TestMetadata::match_package(globals.deny_warnings, p, backend); + let meta = TestMetadata::match_package(p, backend); (globals, meta, false) }) .run_and_coalesce() From 2b9e8cbf1fa53a201759f5c38c5c9f5a330d2f99 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 13:35:06 +0200 Subject: [PATCH 30/31] Fix UI test --- rtic/ui/task-priority-too-high.rs | 2 +- rtic/ui/task-priority-too-high.stderr | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/rtic/ui/task-priority-too-high.rs b/rtic/ui/task-priority-too-high.rs index 44e4a25dbd..56c77d2636 100644 --- a/rtic/ui/task-priority-too-high.rs +++ b/rtic/ui/task-priority-too-high.rs @@ -9,7 +9,7 @@ mod app { struct Local {} #[init] - fn init(cx: init::Context) -> (Shared, Local) { + fn init(_cx: init::Context) -> (Shared, Local) { (Shared {}, Local {}) } diff --git a/rtic/ui/task-priority-too-high.stderr b/rtic/ui/task-priority-too-high.stderr index 125637773f..026124c8fa 100644 --- a/rtic/ui/task-priority-too-high.stderr +++ b/rtic/ui/task-priority-too-high.stderr @@ -1,11 +1,3 @@ -warning: unused variable: `cx` - --> ui/task-priority-too-high.rs:12:13 - | -12 | fn init(cx: init::Context) -> (Shared, Local) { - | ^^ help: if this is intentional, prefix it with an underscore: `_cx` - | - = note: `#[warn(unused_variables)]` on by default - error[E0080]: evaluation of constant value failed --> ui/task-priority-too-high.rs:3:1 | From b7e4498a7136041d89541bdc7725c8c023fa5c9c Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 16 Apr 2023 14:14:49 +0200 Subject: [PATCH 31/31] Also allow denying for QEMU, and fix the link-arg problem caused by overriding RUSTFLAGS --- xtask/src/cargo_command.rs | 24 ++++++++++++++++++++---- xtask/src/run.rs | 7 +++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/xtask/src/cargo_command.rs b/xtask/src/cargo_command.rs index 401bab4c41..1d5f3c5730 100644 --- a/xtask/src/cargo_command.rs +++ b/xtask/src/cargo_command.rs @@ -100,6 +100,7 @@ pub enum CargoCommand<'a> { mode: BuildMode, arguments: Option, dir: Option, + deny_warnings: bool, }, } @@ -345,8 +346,10 @@ impl core::fmt::Display for CargoCommand<'_> { mode, arguments: _, dir, + deny_warnings, } => { - let details = details(false, target, Some(mode), features, cargoarg, dir.as_ref()); + let warns = *deny_warnings; + let details = details(warns, target, Some(mode), features, cargoarg, dir.as_ref()); write!(f, "Compute size of example {example} {details}") } } @@ -645,6 +648,8 @@ impl<'a> CargoCommand<'a> { target: _, // dir is exposed through `chdir` dir: _, + // deny_warnings is exposed through `extra_env` + deny_warnings: _, } => { let extra = ["--example", example] .into_iter() @@ -688,12 +693,23 @@ impl<'a> CargoCommand<'a> { // through an argument to rustc. CargoCommand::Clippy { .. } => None, CargoCommand::Doc { .. } => Some(("RUSTDOCFLAGS", "-D warnings")), + + CargoCommand::Qemu { deny_warnings, .. } + | CargoCommand::ExampleBuild { deny_warnings, .. } + | CargoCommand::ExampleSize { deny_warnings, .. } => { + if *deny_warnings { + // NOTE: this also needs the link-arg because .cargo/config.toml + // is ignored if you set the RUSTFLAGS env variable. + Some(("RUSTFLAGS", "-D warnings -C link-arg=-Tlink.x")) + } else { + None + } + } + CargoCommand::Check { deny_warnings, .. } | CargoCommand::ExampleCheck { deny_warnings, .. } | CargoCommand::Build { deny_warnings, .. } - | CargoCommand::ExampleBuild { deny_warnings, .. } - | CargoCommand::Test { deny_warnings, .. } - | CargoCommand::Qemu { deny_warnings, .. } => { + | CargoCommand::Test { deny_warnings, .. } => { if *deny_warnings { Some(("RUSTFLAGS", "-D warnings")) } else { diff --git a/xtask/src/run.rs b/xtask/src/run.rs index bf8d3b7b6e..605755116d 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -381,13 +381,15 @@ pub fn qemu_run_examples<'c>( into_iter(examples) .flat_map(|example| { let target = target.into(); + let dir = Some(PathBuf::from("./rtic")); + let cmd_build = CargoCommand::ExampleBuild { cargoarg: &None, example, target, features: features.clone(), mode: BuildMode::Release, - dir: Some(PathBuf::from("./rtic")), + dir: dir.clone(), deny_warnings: globals.deny_warnings, }; @@ -397,7 +399,7 @@ pub fn qemu_run_examples<'c>( target, features: features.clone(), mode: BuildMode::Release, - dir: Some(PathBuf::from("./rtic")), + dir, deny_warnings: globals.deny_warnings, }; @@ -441,6 +443,7 @@ pub fn build_and_check_size<'c>( mode: BuildMode::Release, arguments: arguments.clone(), dir: Some(PathBuf::from("./rtic")), + deny_warnings: globals.deny_warnings, }; [cmd_build, cmd_size]