diff --git a/Cargo.lock b/Cargo.lock index 9b622e9..ce15847 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,7 +188,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "leanify-many" -version = "0.2.0" +version = "0.3.1" dependencies = [ "cfg-if", "futures", diff --git a/Cargo.toml b/Cargo.toml index c3624b6..216e15a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "leanify-many" -version = "0.3.0" +version = "0.3.1" description = "spawn leanify subprocesses" authors = ["Avril "] edition = "2018" diff --git a/README.md b/README.md new file mode 100644 index 0000000..687275a --- /dev/null +++ b/README.md @@ -0,0 +1,80 @@ +# leanify-many + +Spawn [leanify] as subprocesses to enable parallel & concurrent compression. +[leanify]: https://github.com/JayXon/Leanify + +## About +[leanify] is a nice tool that losslessly compresses files for you, it works on a large number of file types. +However, it has a couple drawbacks; the main one is it is entirely single threaded, and each file blocks without letting the others also be operated on. + +I'm too stupid to try to fork it and add concurrent processing myself, so I made this hack that just spawns child processes of `leanify` on the file-list instead. This means we can run `leanify` in parallel for a bunch of files easily, with options to set the max (or have no max) number of `leanify` operations allowed to happen at once. + +This can greatly improve speed when using on multiple files. + +## How to use +Usually `leanify-many` can determine where `leanify` is installed by checking your `PATH`. + +``` shell +$ leanify-many *.jpg *.png *.gif +``` + +If not, you can tell it by setting the `LEANIFY` environment variable to the path of the binary + +``` shell +$ LEANIFY=~/bin/leanify leanify-many . +``` + +### Changing number of children + +By default, there is no limit to the number of children spawned. This can cause "too many open files" errors if used with a lot of files, and can also cause slowdowns when trying to spawn many more processes than the CPU has processors. + +You can set the number of children with `--max-children `, and/or you can pass `-m` to limit the max number of children to the number of processors the system currently has. + +### Recursion + +`leanify-many` handles resolving pathnames before sending them to `leanify`, by default there is a max recursion depth of 1 (so, no recursion). Passing a directory instead of the list of files to `leanify-many` does not count towards this limit, so `leanify-many dir/` and `leanify-many dir/*` are the same (except the files she shell excludes from `*`). + +You can specify the max recursion depth with `--recursive `, or set it to unlimited with `-r`. + +### Misc. + +| Option | Description | Notes | +|-----------------|-------------------------------------------------------------|-----------------------------| +| `--no-progress` | Do not display progress bar | Requires `progress` feature | +| `--colour` | Always display colour | Requires `colour` feature | +| `--no-colour` | Never display colour | Requires `colour` feature | +| `-` | Treat all remaining arguments as inputs, stop parsing flags | | + +## Optional features +There are a few compile-time features that can be enabled/disabled for additional functionality. + +| Name | Description | Default | +|------------|----------------------------------------------------|---------| +| `splash` | Show program information when printing help | On | +| `colour` | Enable colouring of certain outputs, like warnings | On | +| `progress` | Enable progress bar | On | +| `threads` | Enable threaded scheduler | Off | + +When building with Rust nightly, some other optimisations and features will be present. + +### Legend + +In `--help` the compiled-with features are listed as so: + - `+feature` means feature enabled + - `-feature` means feature disabled + +When printing with colour: + - Red means enabled by default + - Bright red means enabled specifically + - Blue means disabled by default + - Bright blue means disabled specifically + +# Additional + +I included a Gentoo ebuild for [leanify] in [other] + + [other]: ./extra/Leanify-0.4.3.ebuild + +# License + +GPL'd with <3 diff --git a/other/Leanify-0.4.3.ebuild b/other/Leanify-0.4.3.ebuild new file mode 100644 index 0000000..54ea78d --- /dev/null +++ b/other/Leanify-0.4.3.ebuild @@ -0,0 +1,23 @@ +# Copyright 2020 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 + +DESCRIPTION="lightweight lossless file minifier/optimizer" +HOMEPAGE="https://github.com/JayXon/Leanify" +SRC_URI="https://github.com/JayXon/Leanify/archive/v0.4.3.tar.gz" + +LICENSE="MIT" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="" + +DEPEND="" +RDEPEND="${DEPEND}" +BDEPEND="" + +src_install() { + insinto /usr/bin + newins leanify leanify + fperms 0755 /usr/bin/leanify +} diff --git a/src/arg.rs b/src/arg.rs index 1651ecb..e16bfd3 100644 --- a/src/arg.rs +++ b/src/arg.rs @@ -20,30 +20,74 @@ use lazy_static::lazy_static; &PROG[..] } -fn extra_args() -> &'static str -{ +mod extra { + use lazy_static::lazy_static; + use std::fmt::{self, Write}; + + + #[inline] fn extra_args(#[allow(unused_variables)] output: &mut W) -> fmt::Result + { + #[cfg(feature="progress")] writeln!(output, " --no-progress Do not display progress bar")?; + #[cfg(feature="colour")] writeln!(output, " --no-colour Do not display terminal colours")?; + #[cfg(feature="colour")] writeln!(output, " --colour Always display terminal colour, even if env flags tell us not to")?; + Ok(()) + } + + #[inline] fn extra_mode(#[allow(unused_variables)] output: &mut W) -> fmt::Result + { + //TODO: For extra modes `--install` + Ok(()) + } + + struct ExtraArgs + { + args: &'static str, + modes: &'static str, + } + + fn work(from: F) -> &'static str + where F: FnOnce() -> Result + { + match from() { + Ok(output) => Box::leak(output.into_boxed_str()), + Err(err) => { + eprintln!("Failed to write usage message: {}", err); + "" + }, + } + } + lazy_static! { - static ref EXTRA: &'static str = { - let work = || -> Result { - #[allow(unused_imports)] - use std::fmt::Write as _; - #[allow(unused_mut)] - let mut output = String::new(); - #[cfg(feature="progress")] writeln!(output, " --no-progress Do not display progress bar")?; - #[cfg(feature="colour")] writeln!(output, " --no-colour Do not display terminal colours")?; - #[cfg(feature="colour")] writeln!(output, " --colour Always display terminal colour, even if env flags tell us not to")?; - Ok(output) - }; - match work() { - Ok(output) => Box::leak(output.into_boxed_str()), - Err(err) => { - eprintln!("Failed to write usage message: {}", err); - "" + static ref EXTRA: ExtraArgs = { + + ExtraArgs{ + args: { + work(|| { + let mut output = String::new(); + extra_args(&mut output)?; + Ok(output) + }) + }, + modes: { + work(|| { + let mut output = String::new(); + extra_mode(&mut output)?; + Ok(output) + }) }, } }; } - &EXTRA[..] + + pub fn args() -> &'static str + { + &EXTRA.args[..] + } + + pub fn mode() -> &'static str + { + &EXTRA.modes[..] + } } #[allow(unused_variables)] @@ -52,19 +96,30 @@ mod feature use cfg_if::cfg_if; #[macro_export] macro_rules! check { (on $name:literal, $desc:expr) => { - if cfg!(feature = $name) { - feature::on($name, true, $desc); - } else { - feature::off($name, false, $desc); + cfg_if!{ + if #[cfg(feature = $name)] { + feature::on($name, true, $desc); + } else { + feature::off($name, false, $desc); + } } }; (off $name:literal, $desc:expr) => { - if cfg!(feature = $name) { - feature::on($name, false, $desc); - } else { - feature::off($name, true, $desc); + cfg_if!{ + if #[cfg(feature = $name)] { + feature::on($name, false, $desc); + } else { + feature::off($name, true, $desc); + } } - } + }; + (feature $name:meta, $desc:expr) => { + cfg_if! { + if #[cfg($name)] { + feature::on(stringify!($name), false, $desc); + } else {} + } + } } pub fn on(name: impl AsRef, default: bool, desc: impl AsRef) { @@ -102,6 +157,8 @@ mod feature fn comp_flags() { + check!(feature nightly, "Compiled with Rust nightly optimisations and functionality"); + check!(on "splash", "Show splash-screen"); check!(on "colour", "Enable coloured output"); check!(on "progress", "Enable progress bar"); @@ -115,7 +172,7 @@ pub fn usage() -> ! println!(r"Usage: {prog} [OPTIONS] [-] Usage: {prog} --help - +{modes} OPTIONS: - Stop parsing args here. --max-children Max subprocesses allowed to live at once. Infinite by default. @@ -125,7 +182,7 @@ OPTIONS: {extra} ENVIRONMENT VARS: LEANIFY= Path to leanify executable, defaults to looking in `PATH' if set. -", prog = program_name(), extra = extra_args()); +", prog = program_name(), extra = extra::args(), modes= extra::mode()); println!("Compiled with:"); comp_flags();