diff --git a/abi/src/lib.rs b/abi/src/lib.rs index 26a063558..db6873615 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -7,7 +7,8 @@ use zerocopy::{AsBytes, FromBytes, Unaligned}; /// Magic number that appears at the start of an application header (`App`) to /// reassure the kernel that it is not reading uninitialized Flash. -pub const CURRENT_APP_MAGIC: u32 = 0x1DE_fa7a1; +#[allow(clippy::unusual_byte_groupings)] +pub const CURRENT_APP_MAGIC: u32 = 0x1DE_FA7A1; /// Number of region slots in a `TaskDesc` record. Needs to be less or equal to /// than the number of regions in the MPU; may be less to improve context switch diff --git a/drv/lpc55-spi/src/main.rs b/drv/lpc55-spi/src/main.rs index 2224e92dc..77628bb69 100644 --- a/drv/lpc55-spi/src/main.rs +++ b/drv/lpc55-spi/src/main.rs @@ -268,7 +268,7 @@ fn write_byte(spi: &device::spi0::RegisterBlock, tx: &mut Option) { // not easy. For now just send 0 if we're trying to receive but // not actually write spi.fifowr - .write(|w| unsafe { w.len().bits(7).txdata().bits(0x00 as u16) }); + .write(|w| unsafe { w.len().bits(7).txdata().bits(0) }); return; } @@ -305,14 +305,11 @@ fn write_byte(spi: &device::spi0::RegisterBlock, tx: &mut Option) { }); if txs.pos == txs.len { spi.fifointenclr.write(|w| w.txlvl().set_bit()); - core::mem::replace(tx, None).unwrap().task.reply(()); + tx.take().unwrap().task.reply(()); } } else { spi.fifointenclr.write(|w| w.txlvl().set_bit()); - core::mem::replace(tx, None) - .unwrap() - .task - .reply_fail(ResponseCode::BadArg); + tx.take().unwrap().task.reply_fail(ResponseCode::BadArg); } } @@ -328,19 +325,16 @@ fn read_byte(spi: &device::spi0::RegisterBlock, tx: &mut Option) { let borrow = txs.task.borrow(0); - if let Some(_) = borrow.write_at(txs.pos, byte) { + if borrow.write_at(txs.pos, byte).is_some() { txs.pos += 1; if txs.pos == txs.len { spi.fifointenclr.write(|w| w.txlvl().set_bit()); spi.fifointenclr.write(|w| w.rxlvl().set_bit()); - core::mem::replace(tx, None).unwrap().task.reply(()); + tx.take().unwrap().task.reply(()); } } else { spi.fifointenclr.write(|w| w.txlvl().set_bit()); spi.fifointenclr.write(|w| w.rxlvl().set_bit()); - core::mem::replace(tx, None) - .unwrap() - .task - .reply_fail(ResponseCode::BadArg); + tx.take().unwrap().task.reply_fail(ResponseCode::BadArg); } } diff --git a/drv/stm32f4-usart/src/main.rs b/drv/stm32f4-usart/src/main.rs index de9e01ffa..41496cbdf 100644 --- a/drv/stm32f4-usart/src/main.rs +++ b/drv/stm32f4-usart/src/main.rs @@ -220,7 +220,7 @@ fn step_transmit( state: &mut Option, ) -> hl::Caller<()> { usart.cr1.modify(|_, w| w.txeie().disabled()); - core::mem::replace(state, None).unwrap().caller + state.take().unwrap().caller } let txs = if let Some(txs) = tx { txs } else { return }; diff --git a/drv/stm32h7-usart/src/main.rs b/drv/stm32h7-usart/src/main.rs index d57137e62..87217ebde 100644 --- a/drv/stm32h7-usart/src/main.rs +++ b/drv/stm32h7-usart/src/main.rs @@ -213,7 +213,7 @@ fn step_transmit( state: &mut Option, ) -> hl::Caller<()> { usart.cr1.modify(|_, w| w.txeie().disabled()); - core::mem::replace(state, None).unwrap().caller + state.take().unwrap().caller } let txs = if let Some(txs) = tx { txs } else { return }; diff --git a/kern/build.rs b/kern/build.rs index 878f70093..1194a7fe1 100644 --- a/kern/build.rs +++ b/kern/build.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::Write; use std::path::PathBuf; -fn main() -> Result<(), Box> { +fn main() { build_util::expose_m_profile(); let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); @@ -39,5 +39,4 @@ fn main() -> Result<(), Box> { writeln!(const_file, "pub const EXC_RETURN_CONST : u32 = 0xFFFFFFED;") .unwrap(); } - Ok(()) } diff --git a/kern/src/arch/arm_m.rs b/kern/src/arch/arm_m.rs index ecb7580b3..fee734edc 100644 --- a/kern/src/arch/arm_m.rs +++ b/kern/src/arch/arm_m.rs @@ -456,7 +456,7 @@ pub fn apply_memory_protection(task: &task::Task) { }; // RLAR = our upper bound - let rlar = region.base + region.size + let rlar = (region.base + region.size) | (i as u32) << 1 // AttrIndx | (1 << 0); // enable @@ -472,11 +472,11 @@ pub fn apply_memory_protection(task: &task::Task) { // MAIR if rnr < 4 { let mut mair0 = (0xe000_edc0 as *const u32).read_volatile(); - mair0 = mair0 | (mair as u32) << (rnr * 8); + mair0 |= (mair as u32) << (rnr * 8); core::ptr::write_volatile(0xe000_edc0 as *mut u32, mair0); } else { let mut mair1 = (0xe000_edc4 as *const u32).read_volatile(); - mair1 = mair1 | (mair as u32) << ((rnr - 4) * 8); + mair1 |= (mair as u32) << ((rnr - 4) * 8); core::ptr::write_volatile(0xe000_edc4 as *mut u32, mair1); } // RBAR @@ -749,6 +749,7 @@ fn safe_sys_tick_handler(ticks: &mut u64, tasks: &mut [task::Task]) { // accidentally do it again. *ticks += 1; let now = Timestamp::from(*ticks); + #[allow(clippy::drop_ref)] drop(ticks); // Process any timers. diff --git a/kern/src/kipc.rs b/kern/src/kipc.rs index 51d78b354..042467a4e 100644 --- a/kern/src/kipc.rs +++ b/kern/src/kipc.rs @@ -24,9 +24,9 @@ pub fn handle_kernel_message( 2 => restart_task(tasks, caller, maybe_message?), _ => { // Task has sent an unknown message to the kernel. That's bad. - return Err(UserError::Unrecoverable(FaultInfo::SyscallUsage( + Err(UserError::Unrecoverable(FaultInfo::SyscallUsage( UsageError::BadKernelMessage, - ))); + ))) } } } diff --git a/kern/src/startup.rs b/kern/src/startup.rs index 9527aeb66..10ea62f61 100644 --- a/kern/src/startup.rs +++ b/kern/src/startup.rs @@ -94,20 +94,20 @@ pub unsafe fn start_kernel( for ®ion_idx in &task.regions { uassert!(region_idx < app_header.region_count as u8); let region = ®ions[region_idx as usize]; - if task.entry_point.wrapping_sub(region.base) < region.size { - if region.attributes.contains(app::RegionAttributes::EXECUTE) { - entry_pt_found = true; - } + if task.entry_point.wrapping_sub(region.base) < region.size + && region.attributes.contains(app::RegionAttributes::EXECUTE) + { + entry_pt_found = true; } // Note that stack pointer is compared using <=, because it's okay // to have it point just off the end as the stack is initially // empty. - if task.initial_stack.wrapping_sub(region.base) <= region.size { - if region.attributes.contains( + if task.initial_stack.wrapping_sub(region.base) <= region.size + && region.attributes.contains( app::RegionAttributes::READ | app::RegionAttributes::WRITE, - ) { - stack_ptr_found = true; - } + ) + { + stack_ptr_found = true; } } diff --git a/kern/src/syscalls.rs b/kern/src/syscalls.rs index 3336d4b69..22bb629fe 100644 --- a/kern/src/syscalls.rs +++ b/kern/src/syscalls.rs @@ -83,7 +83,7 @@ fn safe_syscall_entry(nr: u32, current: usize, tasks: &mut [Task]) -> NextTask { Ok(Sysnum::BorrowWrite) => borrow_write(tasks, current), Ok(Sysnum::BorrowInfo) => borrow_info(tasks, current), Ok(Sysnum::IrqControl) => irq_control(tasks, current), - Ok(Sysnum::Panic) => explicit_panic(tasks, current), + Ok(Sysnum::Panic) => Ok(explicit_panic(tasks, current)), Ok(Sysnum::GetTimer) => Ok(get_timer(&mut tasks[current], arch::now())), Err(_) => { // Bogus syscall number! That's a fault. @@ -156,7 +156,7 @@ fn send(tasks: &mut [Task], caller: usize) -> Result { tasks[caller].set_healthy_state(SchedState::InSend(callee_id)); // We may not know what task to run next, but we're pretty sure it isn't the // caller. - return Ok(NextTask::Other.combine(next_task)); + Ok(NextTask::Other.combine(next_task)) } /// Implementation of the RECV IPC primitive. @@ -364,7 +364,7 @@ fn reply(tasks: &mut [Task], caller: usize) -> Result { // KEY ASSUMPTION: sends go from less important tasks to more important // tasks. As a result, Reply doesn't have scheduling implications unless // the task using it faults. - return Ok(NextTask::Same); + Ok(NextTask::Same) } /// Implementation of the `SET_TIMER` syscall. @@ -431,12 +431,12 @@ fn borrow_read( tasks[caller] .save_mut() .set_borrow_response_and_length(0, n); - return Ok(NextTask::Same); + Ok(NextTask::Same) } Err(interact) => { let wake_hint = interact.apply_to_src(tasks, lender)?; // Copy failed but not our side, report defecting lender. - return Err(UserError::Recoverable(abi::DEFECT, wake_hint)); + Err(UserError::Recoverable(abi::DEFECT, wake_hint)) } } } @@ -477,12 +477,12 @@ fn borrow_write( tasks[caller] .save_mut() .set_borrow_response_and_length(0, n); - return Ok(NextTask::Same); + Ok(NextTask::Same) } Err(interact) => { let wake_hint = interact.apply_to_dst(tasks, lender)?; // Copy failed but not our side, report defecting lender. - return Err(UserError::Recoverable(abi::DEFECT, wake_hint)); + Err(UserError::Recoverable(abi::DEFECT, wake_hint)) } } } @@ -503,7 +503,7 @@ fn borrow_info( tasks[caller] .save_mut() .set_borrow_info(lease.attributes.bits(), lease.length as usize); - return Ok(NextTask::Same); + Ok(NextTask::Same) } fn borrow_lease( @@ -564,12 +564,10 @@ fn borrow_lease( if offset <= lease.length as usize { lease.base_address += offset as u32; lease.length -= offset as u32; + Ok(lease) } else { - return Err( - FaultInfo::SyscallUsage(UsageError::OffsetOutOfRange).into() - ); + Err(FaultInfo::SyscallUsage(UsageError::OffsetOutOfRange).into()) } - Ok(lease) } else { // Borrower provided an invalid lease number. Borrower was told the // number of leases on successful RECV and should respect that. (Note: @@ -700,10 +698,7 @@ fn irq_control( Ok(NextTask::Same) } -fn explicit_panic( - tasks: &mut [Task], - caller: usize, -) -> Result { +fn explicit_panic(tasks: &mut [Task], caller: usize) -> NextTask { // Make an attempt at printing the message. let args = tasks[caller].save().as_panic_args(); let message = args.message(); @@ -724,5 +719,5 @@ fn explicit_panic( } } - Ok(task::force_fault(tasks, caller, FaultInfo::Panic)) + task::force_fault(tasks, caller, FaultInfo::Panic) } diff --git a/kern/src/task.rs b/kern/src/task.rs index 7652ca990..c406b658a 100644 --- a/kern/src/task.rs +++ b/kern/src/task.rs @@ -683,7 +683,7 @@ pub fn check_task_id_against_table( return Err(UserError::Recoverable(code, NextTask::Same)); } - return Ok(id.index()); + Ok(id.index()) } /// Selects a new task to run after `previous`. Tries to be fair, kind of. diff --git a/task-ping/src/main.rs b/task-ping/src/main.rs index 26d7c1c65..dc7a4c327 100644 --- a/task-ping/src/main.rs +++ b/task-ping/src/main.rs @@ -20,7 +20,7 @@ const UART: Task = Task::usart_driver; fn nullread() { unsafe { // 0 is not in a region we can access; memory fault - (0 as *const u8).read_volatile(); + core::ptr::null::().read_volatile(); } } diff --git a/task-pong/src/main.rs b/task-pong/src/main.rs index 9d06ed81e..91dbcda3a 100644 --- a/task-pong/src/main.rs +++ b/task-pong/src/main.rs @@ -33,7 +33,7 @@ pub fn main() -> ! { loop { match user_leds.led_toggle(current >> 1) { Ok(_) => { - current = current + 1; + current += 1; break; } Err(drv_user_leds_api::LedError::NoSuchLed) => { diff --git a/task-template/src/main.rs b/task-template/src/main.rs index ce9c5bc4a..8d704763d 100644 --- a/task-template/src/main.rs +++ b/task-template/src/main.rs @@ -9,6 +9,7 @@ use userlib::*; #[export_name = "main"] fn main() -> ! { + #[allow(clippy::empty_loop)] loop { // NOTE: you need to put code here before running this! Otherwise LLVM // will turn this into a single undefined instruction. diff --git a/test/test-assist/src/main.rs b/test/test-assist/src/main.rs index 517fba7ce..b6c8fcdb1 100644 --- a/test/test-assist/src/main.rs +++ b/test/test-assist/src/main.rs @@ -67,7 +67,7 @@ fn textoob(_arg: u32) { // fly off the end of our text -- which will either induce // a memory fault (end of MPU-provided region) or a bus error // (reading never-written flash on some MCUs/boards, e.g. LPC55) - let mut val: u32 = core::mem::transmute(main as fn() -> _); + let mut val = main as fn() -> _ as usize; loop { (val as *const u8).read_volatile(); diff --git a/userlib/build.rs b/userlib/build.rs index 5ca65273e..68b3955e4 100644 --- a/userlib/build.rs +++ b/userlib/build.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::Write; use std::path::PathBuf; -fn main() -> Result<(), Box> { +fn main() { // Do an architecture check. if env::var("CARGO_CFG_TARGET_OS").unwrap() != "none" { eprintln!("***********************************************"); @@ -22,10 +22,10 @@ fn main() -> Result<(), Box> { let task_count; if let Ok(task_names) = env::var("HUBRIS_TASKS") { println!("HUBRIS_TASKS = {}", task_names); - for (i, name) in task_names.split(",").enumerate() { + for (i, name) in task_names.split(',').enumerate() { task_enum.push(format!(" {} = {},", name, i)); } - task_count = task_names.split(",").count(); + task_count = task_names.split(',').count(); } else { task_enum.push(" anonymous = 0,".to_string()); task_count = 1; @@ -39,6 +39,4 @@ fn main() -> Result<(), Box> { writeln!(task_file, "}}").unwrap(); writeln!(task_file, "pub const NUM_TASKS: usize = {};", task_count) .unwrap(); - - Ok(()) } diff --git a/userlib/src/hl.rs b/userlib/src/hl.rs index 7cdfefa2f..172f8ee4c 100644 --- a/userlib/src/hl.rs +++ b/userlib/src/hl.rs @@ -89,20 +89,18 @@ pub fn recv<'a, O, E, S>( let sender = rm.sender; if rm.sender == TaskId::KERNEL { notify(state, rm.operation); - } else { - if let Some(op) = O::from_u32(rm.operation) { - let m = Message { - buffer: &buffer[..rm.message_len], - sender: rm.sender, - response_capacity: rm.response_capacity, - lease_count: rm.lease_count, - }; - if let Err(e) = msg(state, op, m) { - sys_reply(sender, e.into(), &[]); - } - } else { - sys_reply(sender, 1, &[]); + } else if let Some(op) = O::from_u32(rm.operation) { + let m = Message { + buffer: &buffer[..rm.message_len], + sender: rm.sender, + response_capacity: rm.response_capacity, + lease_count: rm.lease_count, + }; + if let Err(e) = msg(state, op, m) { + sys_reply(sender, e.into(), &[]); } + } else { + sys_reply(sender, 1, &[]); } } @@ -291,9 +289,7 @@ impl Borrow<'_> { /// client. pub fn read_fully_at(&self, offset: usize, dest: &mut [u8]) -> Option<()> { let (rc, n) = sys_borrow_read(self.id, self.index, offset, dest); - if rc != 0 { - None - } else if n != dest.len() { + if rc != 0 || n != dest.len() { None } else { Some(()) @@ -320,9 +316,7 @@ impl Borrow<'_> { let mut dest = T::default(); let (rc, n) = sys_borrow_read(self.id, self.index, offset, dest.as_bytes_mut()); - if rc != 0 { - None - } else if n != core::mem::size_of::() { + if rc != 0 || n != core::mem::size_of::() { None } else { Some(dest) @@ -346,9 +340,7 @@ impl Borrow<'_> { { let (rc, n) = sys_borrow_write(self.id, self.index, offset, value.as_bytes()); - if rc != 0 { - None - } else if n != core::mem::size_of::() { + if rc != 0 || n != core::mem::size_of::() { None } else { Some(()) diff --git a/userlib/src/kipc.rs b/userlib/src/kipc.rs index 93ef87318..3d0f19665 100644 --- a/userlib/src/kipc.rs +++ b/userlib/src/kipc.rs @@ -24,6 +24,6 @@ pub fn restart_task(task: usize, start: bool) { ssmarshal::serialize(&mut buf, &msg) .map_err(|_| ()) .unwrap(); - let (rc, _len) = sys_send(TaskId::KERNEL, 2, &mut buf, &mut [], &[]); + let (rc, _len) = sys_send(TaskId::KERNEL, 2, &buf, &mut [], &[]); assert_eq!(rc, 0); } diff --git a/xtask/src/check.rs b/xtask/src/check.rs index c70313256..15e8424e8 100644 --- a/xtask/src/check.rs +++ b/xtask/src/check.rs @@ -25,9 +25,9 @@ pub fn run(package: Option, target: Option) -> Result<()> { cmd.arg("-p"); cmd.arg(&package); - if target.is_some() { + if let Some(target) = target { cmd.arg("--target"); - cmd.arg(target.unwrap()); + cmd.arg(target); } // this is only actually used for demo-stm32h7 but is harmless to include, so let's do diff --git a/xtask/src/clippy.rs b/xtask/src/clippy.rs new file mode 100644 index 000000000..b61c7bdab --- /dev/null +++ b/xtask/src/clippy.rs @@ -0,0 +1,63 @@ +use std::env; +use std::process::Command; + +use anyhow::{bail, Result}; + +pub fn run(package: Option, target: Option) -> Result<()> { + let package = package.unwrap_or_else(|| { + let path = env::current_dir().unwrap(); + let manifest_path = path.join("Cargo.toml"); + let contents = std::fs::read(manifest_path).unwrap(); + let toml: toml::Value = toml::from_slice(&contents).unwrap(); + + // someday, try blocks will be stable... + toml.get("package") + .and_then(|v| v.get("name")) + .and_then(|v| v.as_str()) + .expect("Couldn't find [package.name]; pass -p to run clippy on a specific package or --all to check all packages") + .to_string() + }); + + println!("Running clippy on: {}", package); + + let mut cmd = Command::new("cargo"); + cmd.arg("clippy"); + // TODO: Remove this argument once resolved on stable: + // + // https://github.com/rust-lang/rust-clippy/issues/4612 + // + // TL;DR: Switching back and forth between "clippy" and "check" + // caches the results from one execution. This means a succeeding + // "check" execution may hide a failing "clippy" execution. + cmd.arg("-Zunstable-options"); + cmd.arg("-p"); + cmd.arg(&package); + + if let Some(target) = target { + cmd.arg("--target"); + cmd.arg(target); + } + + // Clippy arguments + cmd.arg("--"); + cmd.arg("-D"); + cmd.arg("clippy::all"); + cmd.arg("-A"); + cmd.arg("clippy::missing_safety_doc"); + cmd.arg("-A"); + cmd.arg("clippy::identity_op"); + cmd.arg("-A"); + cmd.arg("clippy::too_many_arguments"); + + // this is only actually used for demo-stm32h7 but is harmless to include, so let's do + // it unconditionally + cmd.env("HUBRIS_BOARD", "nucleo-h743zi2"); + + let status = cmd.status()?; + + if !status.success() { + bail!("Could not build {}", package); + } + + Ok(()) +} diff --git a/xtask/src/dist.rs b/xtask/src/dist.rs index 08926faf7..8fc57d8f6 100644 --- a/xtask/src/dist.rs +++ b/xtask/src/dist.rs @@ -722,7 +722,7 @@ fn make_descriptors( let mut words = vec![]; // App header - words.push(0x1DE_fa7a1); + words.push(abi::CURRENT_APP_MAGIC); words.push(task_descs.len() as u32); words.push(regions.len() as u32); words.push(irqs.len() as u32); diff --git a/xtask/src/gdb.rs b/xtask/src/gdb.rs index 509ade867..07cb115ac 100644 --- a/xtask/src/gdb.rs +++ b/xtask/src/gdb.rs @@ -26,8 +26,9 @@ pub fn run(cfg: &Path, gdb_cfg: &Path) -> anyhow::Result<()> { } } - let mut cmd = - cmd.ok_or(anyhow::anyhow!("GDB not found. Tried: {:?}", GDB_NAMES))?; + let mut cmd = cmd.ok_or_else(|| { + anyhow::anyhow!("GDB not found. Tried: {:?}", GDB_NAMES) + })?; cmd.arg("-q") .arg("-x") diff --git a/xtask/src/humility.rs b/xtask/src/humility.rs index f84ba593b..30c426d1b 100644 --- a/xtask/src/humility.rs +++ b/xtask/src/humility.rs @@ -5,7 +5,7 @@ use anyhow::Context; use crate::Config; -pub fn run(cfg: &Path, options: &Vec) -> anyhow::Result<()> { +pub fn run(cfg: &Path, options: &[String]) -> anyhow::Result<()> { let cfg_contents = std::fs::read(&cfg)?; let toml: Config = toml::from_slice(&cfg_contents)?; diff --git a/xtask/src/main.rs b/xtask/src/main.rs index bcb5cb35b..6e9d8fa45 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -8,6 +8,7 @@ use serde::Deserialize; use indexmap::IndexMap; mod check; +mod clippy; mod dist; mod flash; mod gdb; @@ -85,6 +86,21 @@ enum Xtask { #[structopt(long)] all: bool, }, + + /// Runs `cargo clippy` on a specified task + Clippy { + /// the target to build for, uses [package.metadata.build.target] if not passed + #[structopt(long)] + target: Option, + + /// the package you're trying to build, uses current directory if not passed + #[structopt(short)] + package: Option, + + /// check all packages, not only one + #[structopt(long)] + all: bool, + }, } #[derive(Clone, Debug, Deserialize)] @@ -174,6 +190,76 @@ struct LoadSegment { data: Vec, } +// For commands which may execute on specific packages, this enum +// identifies the set of packages that should be operated upon. +enum RequestedPackages { + // Specifies a single specific (Package, Target) pair. + Specific(Option, Option), + // Specifies the command should operate on all packages. + All, +} + +impl RequestedPackages { + fn new(package: Option, target: Option, all: bool) -> Self { + if all { + RequestedPackages::All + } else { + RequestedPackages::Specific(package, target) + } + } +} + +// Runs a function on the a requested set of packages. +// +// # Arguments +// +// * `requested` - The requested packages to operate upon. +// * `func` - The function to execute for requested packages, +// acting on a (Package, Target) pair. +fn run_for_packages(requested: RequestedPackages, func: F) -> Result<()> +where + F: Fn(Option, Option) -> Result<()>, +{ + match requested { + RequestedPackages::Specific(package, target) => func(package, target)?, + RequestedPackages::All => { + use cargo_metadata::MetadataCommand; + + let metadata = MetadataCommand::new() + .manifest_path("./Cargo.toml") + .exec() + .unwrap(); + + #[derive(Debug, Deserialize)] + struct CustomMetadata { + build: Option, + } + + #[derive(Debug, Deserialize)] + struct BuildMetadata { + target: Option, + } + + for id in &metadata.workspace_members { + let package = metadata + .packages + .iter() + .find(|p| &p.id == id) + .unwrap() + .clone(); + + let m: Option = + serde_json::from_value(package.metadata)?; + + let target = (|| m?.build?.target)(); + + func(Some(package.name), target)?; + } + } + } + Ok(()) +} + fn main() -> Result<()> { let xtask = Xtask::from_args(); @@ -209,42 +295,16 @@ fn main() -> Result<()> { target, all, } => { - if !all { - check::run(package, target)?; - } else { - use cargo_metadata::MetadataCommand; - - let metadata = MetadataCommand::new() - .manifest_path("./Cargo.toml") - .exec() - .unwrap(); - - #[derive(Debug, Deserialize)] - struct CustomMetadata { - build: Option, - } - - #[derive(Debug, Deserialize)] - struct BuildMetadata { - target: Option, - } - - for id in &metadata.workspace_members { - let package = metadata - .packages - .iter() - .find(|p| &p.id == id) - .unwrap() - .clone(); - - let m: Option = - serde_json::from_value(package.metadata)?; - - let target = (|| m?.build?.target)(); - - check::run(Some(package.name), target)?; - } - } + let requested = RequestedPackages::new(package, target, all); + run_for_packages(requested, check::run)?; + } + Xtask::Clippy { + package, + target, + all, + } => { + let requested = RequestedPackages::new(package, target, all); + run_for_packages(requested, clippy::run)?; } }