You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
3.0 KiB
109 lines
3.0 KiB
#![cfg_attr(nightly, feature(linked_list_remove))]
|
|
#![cfg_attr(nightly, feature(never_type))]
|
|
|
|
|
|
#![allow(dead_code)]
|
|
|
|
use cfg_if::cfg_if;
|
|
|
|
mod defer;
|
|
mod ext;
|
|
pub use ext::JoinStrsExt as _;
|
|
|
|
#[cfg(feature="splash")]
|
|
mod splash;
|
|
mod flags;
|
|
mod arg;
|
|
mod error;
|
|
pub use error::{ErrorExt as _, ResultExt as _};
|
|
|
|
mod stage;
|
|
mod leanify;
|
|
|
|
mod colour;
|
|
mod dir;
|
|
mod fixed_stack;
|
|
mod process;
|
|
mod work;
|
|
|
|
//mod timeout;
|
|
mod maybe_single;
|
|
#[cfg(feature="progress")] mod task_list;
|
|
#[cfg(feature="progress")] mod progress;
|
|
|
|
async fn work() -> Result<(), Box<dyn std::error::Error>>
|
|
{
|
|
|
|
//println!("umm {}", colour::style(colour!(Color::Blue), "hiii"));
|
|
let args = arg::parse_args().await.with_prefix("failed to parse args")?;
|
|
let leanify = leanify::find_binary().with_prefix("Couldn't find leanify binary")?;
|
|
|
|
#[cfg(feature="colour")] {
|
|
match args.flags.coloured {
|
|
Some(x) => recolored::control::set_override(x),
|
|
_ => {},
|
|
}
|
|
}
|
|
|
|
use futures::future::FutureExt;
|
|
|
|
/// Gets the graceful shutdown future if there is one both allowed by the feature flags (see `shutdown` feature) and not disabled by user-provided argument(s).
|
|
///
|
|
/// __NOTE__: This is extracted from the cancel future expression in the call to `work::work()` due to the requirement of the use of `cfg_if!` in a non-expression context only.
|
|
#[inline(always)]
|
|
fn get_shutdown_future(_flags: &arg::Flags) -> impl futures::future::Future + Send + Unpin + 'static
|
|
{
|
|
cfg_if! {
|
|
if #[cfg(feature="shutdown")] {
|
|
use futures::future::{
|
|
self,
|
|
// OptionFuture, // NOTE: Not used here as `OptionFuture` returns *immediately* on `None`, instead of never on `None`, which is what we want.
|
|
Either,
|
|
};
|
|
|
|
return _flags.graceful_shutdown
|
|
.then(|| Either::Left(tokio::signal::ctrl_c().boxed())) //TODO: Inside `ctrl_c()` handler, make a 2nd interrupt send `SIGINT` to the children maybe?
|
|
.unwrap_or(Either::Right(future::pending()));
|
|
} else if #[cfg(nightly)] {
|
|
return futures::future::pending::<!>();
|
|
} else {
|
|
return futures::future::pending::<std::convert::Infallible>();
|
|
}
|
|
}
|
|
}
|
|
|
|
work::work(&args.flags, leanify, args.files, match args.flags.hard_limit {
|
|
Some(hard_limit) => {
|
|
// We have hard limit
|
|
match args.max_children {
|
|
// We also have max children, and it's higher than hard limit,
|
|
Some(max_children) if max_children > hard_limit => Some(hard_limit),
|
|
// We have no max children
|
|
None => Some(hard_limit),
|
|
//Max children is lower than hard limit
|
|
_ => args.max_children,
|
|
}
|
|
},
|
|
_ => args.max_children,
|
|
}, get_shutdown_future(&args.flags).fuse()).await
|
|
}
|
|
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
prettify_expect(work().await.map_err(|e| e.to_string()), "exited with error");
|
|
}
|
|
|
|
#[inline] fn prettify_expect<T,E,S>(res: Result<T,E>, msg: S) -> T
|
|
where S: AsRef<str>,
|
|
E: std::fmt::Display
|
|
{
|
|
match res {
|
|
Ok(v) => v,
|
|
Err(e) => {
|
|
eprintln!("\n{}: {}", msg.as_ref(), e);
|
|
std::process::exit(1)
|
|
},
|
|
}
|
|
}
|