Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

static_tests: Add test for Rust code formatting rules #20887

Merged
merged 3 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions dist/tools/cargo-checks/check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

set -eu

FAILURES=""

while IFS= read -r -d '' CARGOTOML
do
if cargo fmt --quiet --check --manifest-path "${CARGOTOML}"; then
continue
else
FAILURES="${FAILURES} ${CARGOTOML%Cargo.toml}"
fi
done < <(find . -name Cargo.toml -print0)

if [ x"" != x"${FAILURES}" ]; then
echo "Some Rust files are following rustfmt, in particular in:"
echo "${FAILURES}"
echo "You can format the code locally using:"
echo
echo "find -name Cargo.toml -exec cargo fmt --manifest-path '{}' ';'"
if [ -n "${GITHUB_RUN_ID:-}" ]; then
echo
echo "The author of this test regrets not knowing how to provide an easy way to just click a button here that provides the right fixup commits."
fi
exit 1
fi
1 change: 1 addition & 0 deletions dist/tools/ci/static_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# directory for more details.
#

. "$(dirname "${0}")"/github_annotate.sh

Check warning on line 13 in dist/tools/ci/static_tests.sh

View workflow job for this annotation

GitHub Actions / static-tests

Not following: ./github_annotate.sh was not specified as input (see shellcheck -x). [SC1091]

declare -A DEPS

Expand Down Expand Up @@ -128,6 +128,7 @@
run ./dist/tools/feature_resolution/check.sh
run ./dist/tools/boards_supported/check.sh
run ./dist/tools/codespell/check.sh
run ./dist/tools/cargo-checks/check.sh
if [ -z "${GITHUB_RUN_ID}" ]; then
run ./dist/tools/uncrustify/uncrustify.sh --check
else
Expand Down
75 changes: 45 additions & 30 deletions drivers/lsm303agr/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#![no_std]

use lsm303agr::{interface, mode, Lsm303agr, AccelOutputDataRate::Hz50, AccelMode};
use lsm303agr::{interface, mode, AccelMode, AccelOutputDataRate::Hz50, Lsm303agr};

use riot_wrappers::{saul, println, i2c, cstr::cstr, mutex::Mutex};
use saul::{Phydat, registration};
use riot_wrappers::{cstr::cstr, i2c, mutex::Mutex, println, saul};
use saul::{registration, Phydat};

// FIXME: Is this the way we want to go? It's mimicking the C way, but we could just as well take
// the board config from some YAML.
Expand All @@ -29,8 +29,10 @@ static DRIVER_MAG: registration::Driver<SaulLSM, MagAspect> = registration::Driv
// device is registered. (In an alternative implementation where all SAUL registries are managed by
// XFA, this would be possible; finding the point in time when they are ready to be used would be
// tricky, though.).
static REG: Mutex<[Option<registration::Registration<SaulLSM>>; NDEVICES]> = Mutex::new([None; NDEVICES]);
static REG_MAG: Mutex<[Option<registration::Registration<SaulLSM, MagAspect>>; NDEVICES]> = Mutex::new([None; NDEVICES]);
static REG: Mutex<[Option<registration::Registration<SaulLSM>>; NDEVICES]> =
Mutex::new([None; NDEVICES]);
static REG_MAG: Mutex<[Option<registration::Registration<SaulLSM, MagAspect>>; NDEVICES]> =
Mutex::new([None; NDEVICES]);
// This can't go into ROM because it contains an inner Mutex (and possibly state data from the
// Lsm303agr instance, didn't bother to check)
static LSM: Mutex<[Option<SaulLSM>; NDEVICES]> = Mutex::new([None; NDEVICES]);
Expand All @@ -45,31 +47,40 @@ pub extern "C" fn auto_init_lsm303agr() {
/// Initialize the configured LSM303AGR device, returning an error string for debug if anything
/// goes wrong
fn init() -> Result<(), &'static str> {
let lsm = LSM
.try_leak()
.expect("LSM303AGR init is only called once");
let lsm = LSM.try_leak().expect("LSM303AGR init is only called once");

let reg = REG
.try_leak()
.expect("LSM303AGR init is only called once");
let reg = REG.try_leak().expect("LSM303AGR init is only called once");
let reg_mag = REG_MAG
.try_leak()
.expect("LSM303AGR init is only called once");

for (&i2cdev, (lsm, (reg, reg_mag))) in I2C_DEVICES.iter().zip(lsm.iter_mut().zip(reg.iter_mut().zip(reg_mag.iter_mut()))) {
for (&i2cdev, (lsm, (reg, reg_mag))) in I2C_DEVICES
.iter()
.zip(lsm.iter_mut().zip(reg.iter_mut().zip(reg_mag.iter_mut())))
{
let mut device = Lsm303agr::new_with_i2c(i2c::I2CDevice::new(i2cdev));

let mut init_clock = riot_wrappers::ztimer::Clock::msec();

device.init()
.map_err(|_| "Device initialization failed")?;
device.set_accel_mode_and_odr(&mut init_clock, AccelMode::Normal, Hz50)
device.init().map_err(|_| "Device initialization failed")?;
device
.set_accel_mode_and_odr(&mut init_clock, AccelMode::Normal, Hz50)
.map_err(|_| "Device configuration failed")?;

let lsm = lsm.insert(SaulLSM { device: Mutex::new(device) });

let reg = reg.insert(registration::Registration::new(&DRIVER, lsm, Some(cstr!("LSM303AGR accelerometer"))));
let reg_mag = reg_mag.insert(registration::Registration::new(&DRIVER_MAG, lsm, Some(cstr!("LSM303AGR magnetometer"))));
let lsm = lsm.insert(SaulLSM {
device: Mutex::new(device),
});

let reg = reg.insert(registration::Registration::new(
&DRIVER,
lsm,
Some(cstr!("LSM303AGR accelerometer")),
));
let reg_mag = reg_mag.insert(registration::Registration::new(
&DRIVER_MAG,
lsm,
Some(cstr!("LSM303AGR magnetometer")),
));

reg.register_static();
reg_mag.register_static();
Expand All @@ -89,13 +100,15 @@ impl registration::Drivable for &SaulLSM {

fn read(self) -> Result<Phydat, registration::Error> {
// SAUL doesn't guarantee exclusive access; different threads may read simultaneously.
let mut device = self.device.try_lock()
.ok_or(registration::Error)?;
let mut device = self.device.try_lock().ok_or(registration::Error)?;

let data = device.acceleration()
.map_err(|_| registration::Error)?;
let data = device.acceleration().map_err(|_| registration::Error)?;
// Data is in the +-2g range by default, which doesn't overflow even the i16 SAUL uses
Ok(Phydat::new(&[data.x_mg() as _, data.y_mg() as _, data.z_mg() as _], Some(saul::Unit::GForce), -3))
Ok(Phydat::new(
&[data.x_mg() as _, data.y_mg() as _, data.z_mg() as _],
Some(saul::Unit::GForce),
-3,
))
}
}

Expand All @@ -114,11 +127,13 @@ impl registration::Drivable for MagAspect {

fn read(self) -> Result<Phydat, registration::Error> {
// SAUL doesn't guarantee exclusive access; different threads may read simultaneously.
let mut device = self.0.device.try_lock()
.ok_or(registration::Error)?;

let data = device.magnetic_field()
.map_err(|_| registration::Error)?;
return Ok(Phydat::fit(&[data.x_nt(), data.y_nt(), data.z_nt()], Some(saul::Unit::T), -9))
let mut device = self.0.device.try_lock().ok_or(registration::Error)?;

let data = device.magnetic_field().map_err(|_| registration::Error)?;
return Ok(Phydat::fit(
&[data.x_nt(), data.y_nt(), data.z_nt()],
Some(saul::Unit::T),
-9,
));
}
}
14 changes: 10 additions & 4 deletions examples/rust-async/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// directory for more details.
#![no_std]

use riot_wrappers::riot_main;
use riot_wrappers::println;
use riot_wrappers::riot_main;
use riot_wrappers::ztimer::{Clock, Ticks};

use static_cell::StaticCell;
Expand All @@ -20,16 +20,22 @@ fn main() {
static EXECUTOR: StaticCell<embassy_executor_riot::Executor> = StaticCell::new();
let executor: &'static mut _ = EXECUTOR.init(embassy_executor_riot::Executor::new());
executor.run(|spawner| {
spawner.spawn(amain(spawner)).expect("Starting task for the first time");
spawner
.spawn(amain(spawner))
.expect("Starting task for the first time");
})
}

#[embassy_executor::task]
async fn amain(spawner: embassy_executor::Spawner) {
println!("Running asynchronously:");

spawner.spawn(fast_messages("A")).expect("Starting task for the first time");
spawner.spawn(fast_messages("B")).expect("Task is configured to allow two instances");
spawner
.spawn(fast_messages("A"))
.expect("Starting task for the first time");
spawner
.spawn(fast_messages("B"))
.expect("Task is configured to allow two instances");

let msec = Clock::msec();

Expand Down
53 changes: 39 additions & 14 deletions examples/rust-gcoap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
// directory for more details.
#![no_std]

use riot_wrappers::{riot_main, println};
use riot_wrappers::{gcoap, ztimer, gnrc};
use riot_wrappers::{gcoap, gnrc, ztimer};
use riot_wrappers::{println, riot_main};

use coap_handler_implementations::{ReportingHandlerBuilder, HandlerBuilder};
use coap_handler_implementations::{HandlerBuilder, ReportingHandlerBuilder};

extern crate rust_riotmodules;

Expand All @@ -21,40 +21,65 @@ fn main() {

unsafe { do_vfs_init() };

static PINGS: riot_coap_handler_demos::ping::PingPool = riot_coap_handler_demos::ping::PingPool::new();
static PING_PASSIVE: riot_coap_handler_demos::ping_passive::PingHistoryMutex<{ riot_coap_handler_demos::ping_passive::DEFAULT_SIZE }> = riot_coap_handler_demos::ping_passive::PingHistoryMutex::new();
static PINGS: riot_coap_handler_demos::ping::PingPool =
riot_coap_handler_demos::ping::PingPool::new();
static PING_PASSIVE: riot_coap_handler_demos::ping_passive::PingHistoryMutex<
{ riot_coap_handler_demos::ping_passive::DEFAULT_SIZE },
> = riot_coap_handler_demos::ping_passive::PingHistoryMutex::new();

let handler = coap_message_demos::full_application_tree(None)
.below(&["ps"], riot_coap_handler_demos::ps::ps_tree())
.below(&["led"], riot_coap_handler_demos::led::all_leds())
.below(&["vfs"], riot_coap_handler_demos::vfs::vfs(""))
.below(&["saul"], riot_coap_handler_demos::saul::SaulHandler::new(&["saul"]))
.below(
&["saul"],
riot_coap_handler_demos::saul::SaulHandler::new(&["saul"]),
)
.below(&["netif"], riot_coap_handler_demos::netif::netif())
.below(&["nib", "neigh"], riot_coap_handler_demos::nib::neighbor_cache())
.below(
&["nib", "neigh"],
riot_coap_handler_demos::nib::neighbor_cache(),
)
.below(&["ping"], riot_coap_handler_demos::ping::ping_tree(&PINGS))
.at(&["pinged"], riot_coap_handler_demos::ping_passive::resource(&PING_PASSIVE))
.with_wkc()
;
.at(
&["pinged"],
riot_coap_handler_demos::ping_passive::resource(&PING_PASSIVE),
)
.with_wkc();
let mut handler = riot_wrappers::coap_handler::v0_2::GcoapHandler(handler);

let mut listener = gcoap::SingleHandlerListener::new_catch_all(&mut handler);

static SLOT: static_cell::StaticCell<gnrc::netreg::callback::Slot<riot_coap_handler_demos::ping::PingCallback>> = static_cell::StaticCell::new();
static SLOT: static_cell::StaticCell<
gnrc::netreg::callback::Slot<riot_coap_handler_demos::ping::PingCallback>,
> = static_cell::StaticCell::new();
PINGS.register(SLOT.init(Default::default()));

static PASSIVE_SLOT: static_cell::StaticCell<gnrc::netreg::callback::Slot<&'static riot_coap_handler_demos::ping_passive::PingHistoryMutex<{ riot_coap_handler_demos::ping_passive::DEFAULT_SIZE }>>> = static_cell::StaticCell::new();
static PASSIVE_SLOT: static_cell::StaticCell<
gnrc::netreg::callback::Slot<
&'static riot_coap_handler_demos::ping_passive::PingHistoryMutex<
{ riot_coap_handler_demos::ping_passive::DEFAULT_SIZE },
>,
>,
> = static_cell::StaticCell::new();
PING_PASSIVE.register(PASSIVE_SLOT.init(Default::default()));

gcoap::scope(|greg| {
greg.register(&mut listener);

println!("CoAP server ready; waiting for interfaces to settle before reporting addresses...");
println!(
"CoAP server ready; waiting for interfaces to settle before reporting addresses..."
);

let sectimer = ztimer::Clock::sec();
sectimer.sleep(ztimer::Ticks(2));

for netif in gnrc::Netif::all() {
println!("Active interface from PID {:?} ({:?})", netif.pid(), netif.pid().get_name().unwrap_or("unnamed"));
println!(
"Active interface from PID {:?} ({:?})",
netif.pid(),
netif.pid().get_name().unwrap_or("unnamed")
);
match netif.ipv6_addrs() {
Ok(addrs) => {
for a in &addrs {
Expand Down
2 changes: 1 addition & 1 deletion examples/rust-hello-world/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// directory for more details.
#![no_std]

use riot_wrappers::riot_main;
use riot_wrappers::println;
use riot_wrappers::riot_main;

extern crate rust_riotmodules;

Expand Down
15 changes: 11 additions & 4 deletions sys/shell/democommands/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#![no_std]

use riot_wrappers::println;
use core::fmt::Write;
use riot_wrappers::println;

riot_wrappers::static_command!(static_hello_world, "hello_world", "Print a greeting", hello_world);
riot_wrappers::static_command!(
static_hello_world,
"hello_world",
"Print a greeting",
hello_world
);

pub fn hello_world<'a>(_w: &mut impl Write, args: impl IntoIterator<Item=&'a str>) {
pub fn hello_world<'a>(_w: &mut impl Write, args: impl IntoIterator<Item = &'a str>) {
let mut args = args.into_iter();
let commandname = args.next().expect("How was this started without an argv[0]?");
let commandname = args
.next()
.expect("How was this started without an argv[0]?");

match args.next() {
Some("--help") => println!("Usage: {commandname}"),
Expand Down
2 changes: 1 addition & 1 deletion tests/rust_minimal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
// directory for more details.
#![no_std]

use riot_wrappers::riot_main;
use riot_wrappers::println;
use riot_wrappers::riot_main;

extern crate rust_riotmodules;

Expand Down
Loading