diff --git a/Cargo.lock b/Cargo.lock index 62ae977..9c7e3d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,11 +1,66 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" + +[[package]] +name = "aho-corasick" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86" +dependencies = [ + "memchr", +] + [[package]] name = "arc-swap" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backtrace" +version = "0.3.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec1931848a574faa8f7c71a12ea00453ff5effbb5f51afe7f77d7a48cace6ac1" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bitflags" version = "1.2.1" @@ -24,6 +79,42 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "color-eyre" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2a5123db5af8349c41c43ed0e5dca1cd56c911ea0c4ce6e6ff30f159fa5d27e" +dependencies = [ + "backtrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "eyre" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c5cb4dc433c59f09df4b4450f649cbfed61e8a3505abe32e4154066439157e" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fnv" version = "1.0.7" @@ -46,11 +137,106 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "futures" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8e3078b7b2a8a671cb7a3d17b4760e4181ea243227776ba83fd043b4ca034e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a4d35f7401e948629c9c3d6638fb9bf94e0b2121e96c3b428cc4e631f3eb74" +dependencies = [ + "futures-core", + "futures-sink", +] + [[package]] name = "futures-core" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" +checksum = "d674eaa0056896d5ada519900dbf97ead2e46a7b6621e8160d79e2f2e1e2784b" + +[[package]] +name = "futures-executor" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc709ca1da6f66143b8c9bec8e6260181869893714e9b5a490b169b0414144ab" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc94b64bb39543b4e432f1790b6bf18e3ee3b74653c5449f63310e9a74b123c" + +[[package]] +name = "futures-macro" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f57ed14da4603b2554682e9f2ff3c65d7567b53188db96cb71538217fc64581b" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8764258ed64ebc5d9ed185cf86a95db5cac810269c5d20ececb32e0088abbd" + +[[package]] +name = "futures-task" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd26820a9f3637f1302da8bceba3ff33adbe53464b54ca24d4e2d4f1db30f94" +dependencies = [ + "once_cell", +] + +[[package]] +name = "futures-util" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a894a0acddba51a2d49a6f4263b1e64b8c579ece8af50fa86503d52cd1eea34" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "gimli" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724" [[package]] name = "hermit-abi" @@ -61,6 +247,21 @@ dependencies = [ "libc", ] +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + +[[package]] +name = "indenter" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0bd112d44d9d870a6819eb505d04dd92b5e4d94bb8c304924a0872ae7016fb5" + [[package]] name = "iovec" version = "0.1.4" @@ -107,6 +308,16 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +[[package]] +name = "miniz_oxide" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9" +dependencies = [ + "adler", + "autocfg", +] + [[package]] name = "mio" version = "0.6.22" @@ -192,12 +403,78 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" + +[[package]] +name = "once_cell" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad" + +[[package]] +name = "owo-colors" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a1250cdd103eef6bd542b5ae82989f931fc00a41a27f60377338241594410f3" + +[[package]] +name = "pin-project" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13fbdfd6bdee3dc9be46452f86af4a4072975899cf8592466668620bebfbcc17" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c82fb1329f632c3552cf352d14427d57a511b1cf41db93b3a7d77906a82dcc8e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e555d9e657502182ac97b539fb3dae8b79cda19e3e4f8ffb5e8de4f18df93c95" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598" + +[[package]] +name = "proc-macro-nested" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" + [[package]] name = "proc-macro2" version = "1.0.24" @@ -207,6 +484,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.7" @@ -222,11 +505,64 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "regex" +version = "1.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8" + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" + +[[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 = "sever" version = "0.1.0" dependencies = [ "cfg-if", + "color-eyre", + "futures", + "log", + "pretty_env_logger", + "rustc_version", "tokio", ] @@ -269,6 +605,24 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + [[package]] name = "tokio" version = "0.2.22" @@ -338,6 +692,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 4672000..12c178f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,9 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -parallel = ["tokio"] +default = ["parallel"] + +parallel = ["tokio", "futures"] threads = ["parallel", "tokio/rt-threaded"] # use PRETTY_ENV_LOGGER I guess @@ -18,3 +20,10 @@ threads = ["parallel", "tokio/rt-threaded"] [dependencies] cfg-if = "0.1.10" tokio = {version = "0.2", features = ["full"], optional = true} +log = "0.4.11" +pretty_env_logger = "0.4.0" +color-eyre = {version = "0.5.6", default-features=false} +futures = {version = "0.3.5", optional = true} + +[build-dependencies] +rustc_version = "0.2" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..6399463 --- /dev/null +++ b/build.rs @@ -0,0 +1,24 @@ + +extern crate rustc_version; +use rustc_version::{version, version_meta, Channel}; + +fn main() { + // Assert we haven't travelled back in time + assert!(version().unwrap().major >= 1); + + // Set cfg flags depending on release channel + match version_meta().unwrap().channel { + Channel::Stable => { + println!("cargo:rustc-cfg=stable"); + } + Channel::Beta => { + println!("cargo:rustc-cfg=beta"); + } + Channel::Nightly => { + println!("cargo:rustc-cfg=nightly"); + } + Channel::Dev => { + println!("cargo:rustc-cfg=dev"); + } + } +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..d5d1045 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,94 @@ +use super::*; +use std::{ + error, fmt, + io, + path::{PathBuf, Path,} +}; + +#[derive(Debug)] +#[non_exhaustive] +pub enum ErrorKind +{ + Stat(io::Error), + Open(io::Error), + Copy(io::Error), +} + +impl ErrorKind +{ + pub fn is_skippable(&self) -> bool + { + match self { + Self::Stat(_) => true, + _ => false, + } + } + + pub fn suggestion(&self) -> &'static str + { + //TODO: Maybe? + match self { + _ => "Are you sure file exists, and you have write privilages here?" + } + } +} + +#[derive(Debug)] +pub struct Error { + kind: ErrorKind, + path: PathBuf, +} + +impl> From<(ErrorKind, P)> for Error +{ + fn from((kind, p): (ErrorKind, P)) -> Self + { + Self::new(kind, p.as_ref()) + } +} + + +impl Error +{ + pub fn new(kind: ErrorKind, path: impl Into) -> Self + { + Self { + kind, + path: path.into() + } + } + pub fn path(&self) -> &Path + { + self.path.as_ref() + } + pub fn kind(&self) -> &ErrorKind + { + &self.kind + } +} + +impl std::error::Error for Error +{ + fn source(&self) -> Option<&(dyn error::Error + 'static)> + { + Some(match &self.kind { + ErrorKind::Stat(io) => io, + ErrorKind::Open(io) => io, + ErrorKind::Copy(io) => io, + // _ => return None, + }) + } +} +impl std::fmt::Display for Error +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + match &self.kind { + ErrorKind::Stat(_) => write!(f, "Failed to stat file {:?}", self.path), + ErrorKind::Open(_) => write!(f, "Failed to open file {:?}", self.path), + ErrorKind::Copy(_) => write!(f, "Failed to create copy of file {:?}", self.path), + } + } +} + + diff --git a/src/macros.rs b/src/macros.rs new file mode 100644 index 0000000..1357eab --- /dev/null +++ b/src/macros.rs @@ -0,0 +1,60 @@ +#![allow(unused_macros)] + +/// Run something as async or or depending on feature flag `parallel` +macro_rules! sync +{ + (if {$($if:tt)*} else {$($else:tt)*}) => { + cfg_if::cfg_if! { + if #[cfg(feature="parallel")] { + $($if)* + } else { + $($else)* + } + } + }; + + (if {$($if:tt)*}) => { + cfg_if::cfg_if! { + if #[cfg(feature="parallel")] { + $($if)* + } + } + }; + + (else {$($if:tt)*}) => { + cfg_if::cfg_if! { + if #[cfg(not(eature="parallel"))] { + $($if)* + } + } + }; +} + +#[macro_export] macro_rules! reyre { + (m {$($body:tt)*} $lit:literal $($tt:tt)*) => { + { + let cls = move || { + $($body)* + }; + $crate::reyre!{ + cls(), $lit $($tt)* + } + } + }; + ({$($body:tt)*} $lit:literal $($tt:tt)*) => { + { + let cls = || { + $($body)* + }; + $crate::reyre!{ + cls(), $lit $($tt)* + } + } + }; + ($expr:expr, $lit:literal $($tt:tt)*) => { + { + use ::color_eyre::eyre::WrapErr; + $expr.wrap_err_with(|| ::color_eyre::eyre::eyre!($lit $($tt)*)) + } + } +} diff --git a/src/main.rs b/src/main.rs index f110deb..23856f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,42 +1,39 @@ +#![allow(dead_code)] -/// Run something as async or or depending on feature flag `parallel` -macro_rules! sync +#[macro_use] extern crate log; +#[macro_use] mod macros; + +use color_eyre::{ + eyre::{self, eyre, WrapErr}, + Help, SectionExt, +}; + +fn init() -> eyre::Result<()> { - (if {$($if:tt)*} else {$($else:tt)*}) => { - cfg_if::cfg_if! { - if #[cfg(feature="parallel")] { - $($if)* - } else { - $($else)* - } - } - }; - - (if {$($if:tt)*}) => { - cfg_if::cfg_if! { - if #[cfg(feature="parallel")] { - $($if)* - } - } - }; - - (else {$($if:tt)*}) => { - cfg_if::cfg_if! { - if #[cfg(not(eature="parallel"))] { - $($if)* - } - } - }; + color_eyre::install()?; + pretty_env_logger::init(); //TODO: Change to builder + trace!("Initialised"); + Ok(()) } +mod error; + +#[cfg(feature="parallel")] +mod parallel; + #[cfg(feature="parallel")] #[cfg_attr(feature="parallel", tokio::main)] -async fn main() { - println!("Hello world!") +async fn main() -> eyre::Result<()> { + reyre!(init(), "Failed to initialise")?; + + reyre!(parallel::main(std::env::args().skip(1)).await, "Jobs failed") } +#[cfg(not(feature="parallel"))] +mod serial; #[cfg(not(feature="parallel"))] -fn main() { - println!("Hello world! sync") +fn main() -> eyre::Result<()> { + reyre!(init(), "Failed to initialise")?; + todo!("Sync unimplemented") } diff --git a/src/parallel.rs b/src/parallel.rs new file mode 100644 index 0000000..f4a50e3 --- /dev/null +++ b/src/parallel.rs @@ -0,0 +1,132 @@ +//! Async operations +use super::*; +use std::{ + num::NonZeroUsize, + convert::{TryFrom, TryInto,}, + path::Path, + sync::Arc, +}; +use futures::{ + future::{ + OptionFuture, + FutureExt, + join_all, + }, +}; +use tokio::{ + sync::{ + Semaphore, + }, + fs::{ + OpenOptions, + File, + self, + }, +}; +use error::{Error, ErrorKind}; + +const MAX_WORKERS: Option = Some(unsafe {NonZeroUsize::new_unchecked(4096)}); + +fn gensem() -> Option> +{ + trace!("Limiting concurrency to {:?}", MAX_WORKERS); + match MAX_WORKERS { + Some(nz) => Some(Arc::new(Semaphore::new(nz.into()))), + None => None, + } +} + +fn tpath() -> String +{ + todo!(); + ".test.tmp".to_owned() +} + +async fn unlink(path: &Path) -> Result<(), Error> +{ + let tmp = path.parent().unwrap().join(tpath()); + fs::copy(path, tmp).await.map_err(|e| Error::new(ErrorKind::Copy(e), path.to_owned()))?; + todo!(); + Ok(()) +} + +async fn work>(apath: P, sem: Option>) -> Result<(P, bool), Error> +{ + let path = apath.as_ref(); + let _lock = OptionFuture::from(sem.map(Semaphore::acquire_owned)).await; + let file = OpenOptions::new() + .read(true) + .open(path).await + .map_err(|e| (ErrorKind::Open(e), path))?; + + let meta = match file.metadata().await { + Ok(meta) => meta, + Err(err) => { + debug!("Failed to stat file: {}", err); + warn!("Failed to stat {:?}, skipping", path); + return Err((ErrorKind::Stat(err), path).into()); + }, + }; + + use std::os::unix::fs::MetadataExt; + + let nlink = meta.nlink(); + trace!("<{:?}> Links: {}", path, nlink); + if nlink > 1 { + //todo work i guess fuck it + unlink(path).await?; + Ok((apath, true)) + } else { + Ok((apath, false)) + } +} + +pub async fn main>(list: I) -> eyre::Result<()> +{ + let sem = gensem(); + let mut failures = 0usize; + for (i, res) in (0usize..).zip(join_all(list.into_iter().map(|file| tokio::spawn(work(file, sem.clone())))) + .map(|x| {trace!("--- {} Finished ---", x.len()); x}).await) + { + //trace!("Done on {:?}", res); + match res { + Ok(Ok((path, true))) => info!("<{:?}> OK (processed)", path), + Ok(Ok((path, false))) => info!("<{:?}> OK (skipped)", path), + Err(e) => { + trace!("child {} cancelled by {}", i, if e.is_panic(){"panic"} else {"cancel"}); + if e.is_panic() { + return Err(eyre!("Child {} panic", i)) + .with_error(move || e) + .with_warning(|| "This suggests a bug in the program"); + } else { + warn!("Child {} cancelled", i); + failures += 1; + } + }, + Ok(Err(kind)) if !kind.kind().is_skippable() => { // + let fuck = format!("{:?}", kind.path()); + let sug = kind.kind().suggestion(); + let err = Err::(kind) + .wrap_err_with(|| eyre!("<{}> Failed", fuck)) + .with_section(move || fuck.header("Path was")) + .with_suggestion(|| sug) + .unwrap_err(); + error!("{}", err); + debug!("Error: {:?}", err); + failures += 1; + }, + Ok(Err(k)) => { + trace!("<{:?}> Failed (skipped)", k.path()); + failures+=1; + }, + } + } + + if failures > 0 { + return Err(eyre!("Some tasks failed to complete successfullly")) + .with_section(|| failures.to_string().header("Number of failed tasks")) + .with_suggestion(|| "Run with `RUST_LOG=debug` or `RUST_LOG=trace` for verbose error reporting"); + } + + Ok(()) +} diff --git a/src/serial.rs b/src/serial.rs new file mode 100644 index 0000000..ec6e2a0 --- /dev/null +++ b/src/serial.rs @@ -0,0 +1,3 @@ +//! Sync operations +use super::*; +