From 03e9a2ac143c269d2c44a6bd13a0da10ede8bf38 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 2 Jul 2020 08:03:01 +0800 Subject: All tests work with argh (which really needs aliases) --- Cargo.lock | 104 ------------------------------ Cargo.toml | 1 - src/main.rs | 31 ++++----- src/options.rs | 179 +++++++++++++++++++++++++++++++++------------------- src/options_argh.rs | 130 -------------------------------------- 5 files changed, 131 insertions(+), 314 deletions(-) delete mode 100644 src/options_argh.rs diff --git a/Cargo.lock b/Cargo.lock index 03d7d4e..daf0921 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,21 +108,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" -[[package]] -name = "clap" -version = "2.33.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - [[package]] name = "crossbeam" version = "0.7.3" @@ -229,7 +214,6 @@ dependencies = [ "open", "petgraph", "pretty_assertions", - "structopt", "termion", "tui", "tui-react", @@ -456,32 +440,6 @@ dependencies = [ "output_vt100", ] -[[package]] -name = "proc-macro-error" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "syn-mid", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.18" @@ -558,36 +516,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "syn" version = "1.0.33" @@ -599,17 +527,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "syn-mid" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "synstructure" version = "0.12.4" @@ -634,15 +551,6 @@ dependencies = [ "redox_termios", ] -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - [[package]] name = "tui" version = "0.9.5" @@ -686,18 +594,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" - [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 0e1c6a6..2e7a9f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ include = ["src/**/*", "Cargo.*", "LICENSE", "README.md", "CHANGELOG.md", "!**/* [dependencies] failure = "0.1.1" failure-tools = "4.0.2" -structopt = "0.3" argh = "0.1.3" jwalk = "0.5.0" byte-unit = "4" diff --git a/src/main.rs b/src/main.rs index 0eb80a6..3630be3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,27 +1,21 @@ #![forbid(unsafe_code)] #![allow(clippy::match_bool)] -extern crate failure; -extern crate failure_tools; -extern crate structopt; - use crate::interactive::{Interaction, TerminalApp}; use dua::{ByteFormat, Color, TraversalSorting}; use failure::{Error, ResultExt}; use failure_tools::ok_or_exit; use std::{fs, io, io::Write, path::PathBuf, process}; -use structopt::StructOpt; use termion::{raw::IntoRawMode, screen::AlternateScreen}; use tui::backend::TermionBackend; use tui_react::Terminal; mod interactive; mod options; -mod options_argh; fn run() -> Result<(), Error> { - use options::Command::*; + use options::*; - let opt: options::Args = options::Args::from_args(); + let opt: options::Args = argh::from_env(); let walk_options = dua::WalkOptions { threads: opt.threads.unwrap_or(0), byte_format: opt.format.map(Into::into).unwrap_or(ByteFormat::Metric), @@ -36,7 +30,8 @@ fn run() -> Result<(), Error> { cross_filesystems: !opt.stay_on_filesystem, }; let res = match opt.command { - Some(Interactive { input }) => { + Some(Command::Interactive(Interactive { input })) + | Some(Command::InteractiveAlias(InteractiveAlias { input })) => { let mut terminal = { let stdout = io::stdout() .into_raw_mode() @@ -65,23 +60,29 @@ fn run() -> Result<(), Error> { // Exit 'quickly' to avoid having to not have to deal with slightly different types in the other match branches std::process::exit(res.transpose()?.map(|e| e.to_exit_code()).unwrap_or(0)); } - Some(Aggregate { + Some(Command::Aggregate(Aggregate { + input, + no_total, + no_sort, + stats, + })) + | Some(Command::AggregateAlias(AggregateAlias { input, no_total, no_sort, - statistics, - }) => { + stats, + })) => { let stdout = io::stdout(); let stdout_locked = stdout.lock(); - let (res, stats) = dua::aggregate( + let (res, statistics) = dua::aggregate( stdout_locked, walk_options, !no_total, !no_sort, paths_from(input)?, )?; - if statistics { - writeln!(io::stderr(), "{:?}", stats).ok(); + if stats { + writeln!(io::stderr(), "{:?}", statistics).ok(); } res } diff --git a/src/options.rs b/src/options.rs index 5b9d604..219afe0 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,47 +1,63 @@ -use dua::ByteFormat as LibraryByteFormat; use std::path::PathBuf; -use structopt::{clap::arg_enum, StructOpt}; - -arg_enum! { - #[derive(PartialEq, Debug)] - pub enum ByteFormat { - Metric, - Binary, - Bytes, - GB, - GiB, - MB, - MiB + +use argh::{FromArgValue, FromArgs}; +use dua::ByteFormat; + +pub enum CliByteFormat { + Metric, + Binary, + Bytes, + GB, + GiB, + MB, + MiB, +} + +impl FromArgValue for CliByteFormat { + fn from_arg_value(value: &str) -> Result { + use CliByteFormat::*; + let value_lc = value.to_ascii_lowercase(); + Ok(match value_lc.as_str() { + "metric" => Metric, + "binary" => Binary, + "bytes" => Bytes, + "gb" => GB, + "gib" => GiB, + "mb" => MB, + "mib" => MiB, + _ => return Err(format!("Invalid byte format: {}", value)), + }) } } -impl From for LibraryByteFormat { - fn from(input: ByteFormat) -> Self { +impl From for ByteFormat { + fn from(input: CliByteFormat) -> Self { + use CliByteFormat::*; match input { - ByteFormat::Metric => LibraryByteFormat::Metric, - ByteFormat::Binary => LibraryByteFormat::Binary, - ByteFormat::Bytes => LibraryByteFormat::Bytes, - ByteFormat::GB => LibraryByteFormat::GB, - ByteFormat::GiB => LibraryByteFormat::GiB, - ByteFormat::MB => LibraryByteFormat::MB, - ByteFormat::MiB => LibraryByteFormat::MiB, + Metric => ByteFormat::Metric, + Binary => ByteFormat::Binary, + Bytes => ByteFormat::Bytes, + GB => ByteFormat::GB, + GiB => ByteFormat::GiB, + MB => ByteFormat::MB, + MiB => ByteFormat::MiB, } } } -#[derive(Debug, StructOpt)] -#[structopt(name = "dua", about = "A tool to learn about disk usage, fast!")] -#[structopt(setting = structopt::clap::AppSettings::ColoredHelp)] +/// a tool to learn about disk usage, fast! +#[derive(FromArgs)] +#[argh(name = "dua")] pub struct Args { - #[structopt(subcommand)] + #[argh(subcommand)] pub command: Option, - /// The amount of threads to use. Defaults to the amount of logical processors. + /// the amount of threads to use. Defaults to the amount of logical processors. /// Set to 1 to use only a single thread. - #[structopt(short = "t", long = "threads")] + #[argh(option, short = 't')] pub threads: Option, - /// The format with which to print byte counts. + /// the format with which to print byte counts. /// Metric - uses 1000 as base (default) /// Binary - uses 1024 as base /// Bytes - plain bytes without any formatting @@ -49,50 +65,85 @@ pub struct Args { /// GiB - only gibibytes /// MB - only megabytes /// MiB - only mebibytes - #[structopt(short = "f", long)] - pub format: Option, + #[argh(option, short = 'f')] + pub format: Option, - /// Display apparent size instead of disk usage. - #[structopt(short = "A", long)] + /// display apparent size instead of disk usage. + #[argh(switch, short = 'A')] pub apparent_size: bool, - /// Count hard-linked files each time they are seen - #[structopt(short = "l", long)] + /// count hard-linked files each time they are seen + #[argh(switch, short = 'l')] pub count_hard_links: bool, - /// If set, we will not cross filesystems or traverse mount points - #[structopt(short = "x", long)] + /// if set, we will not cross filesystems or traverse mount points + #[argh(switch, short = 'x')] pub stay_on_filesystem: bool, - /// One or more input files or directories. If unset, we will use all entries in the current working directory. - #[structopt(parse(from_os_str))] + /// one or more input files or directories. If unset, we will use all entries in the current working directory. + #[argh(positional)] pub input: Vec, } -#[derive(Debug, StructOpt)] +#[derive(FromArgs)] +#[argh(subcommand)] pub enum Command { - /// Launch the terminal user interface - #[structopt(name = "interactive", alias = "i")] - Interactive { - /// One or more input files or directories. If unset, we will use all entries in the current working directory. - #[structopt(parse(from_os_str))] - input: Vec, - }, - /// Aggregrate the consumed space of one or more directories or files - #[structopt(name = "aggregate", alias = "a")] - Aggregate { - /// If set, print additional statistics about the file traversal to stderr - #[structopt(long = "stats")] - statistics: bool, - /// If set, paths will be printed in their order of occurrence on the command-line. - /// Otherwise they are sorted by their size in bytes, ascending. - #[structopt(long)] - no_sort: bool, - /// If set, no total column will be computed for multiple inputs - #[structopt(long)] - no_total: bool, - /// One or more input files or directories. If unset, we will use all entries in the current working directory. - #[structopt(parse(from_os_str))] - input: Vec, - }, + Interactive(Interactive), + InteractiveAlias(InteractiveAlias), + Aggregate(Aggregate), + AggregateAlias(AggregateAlias), +} + +/// Launch the terminal user interface +#[derive(FromArgs)] +#[argh(subcommand, name = "interactive")] +pub struct Interactive { + /// one or more input files or directories. If unset, we will use all entries in the current working directory. + #[argh(positional)] + pub input: Vec, +} + +/// Alias for 'interactive' +#[derive(FromArgs)] +#[argh(subcommand, name = "i")] +pub struct InteractiveAlias { + #[argh(positional)] + pub input: Vec, +} + +/// Aggregate the consumed space of one or more directories or files +#[derive(FromArgs)] +#[argh(subcommand, name = "aggregate")] +pub struct Aggregate { + /// if set, print additional statistics about the file traversal to stderr + #[argh(switch)] + pub stats: bool, + /// if set, paths will be printed in their order of occurrence on the command-line. + /// Otherwise they are sorted by their size in bytes, ascending. + #[argh(switch)] + pub no_sort: bool, + /// if set, no total column will be computed for multiple inputs + #[argh(switch)] + pub no_total: bool, + /// one or more input files or directories. If unset, we will use all entries in the current working directory. + #[argh(positional)] + pub input: Vec, +} + +/// An alias for "aggregate" +#[derive(FromArgs)] +#[argh(subcommand, name = "a")] +pub struct AggregateAlias { + /// see `dua aggregate --help` + #[argh(switch)] + pub stats: bool, + /// see `dua aggregate --help` + #[argh(switch)] + pub no_sort: bool, + /// see `dua aggregate --help` + #[argh(switch)] + pub no_total: bool, + /// see `dua aggregate --help` + #[argh(positional)] + pub input: Vec, } diff --git a/src/options_argh.rs b/src/options_argh.rs deleted file mode 100644 index 688931b..0000000 --- a/src/options_argh.rs +++ /dev/null @@ -1,130 +0,0 @@ -use std::path::PathBuf; - -use argh::{FromArgValue, FromArgs}; -use dua::ByteFormat; - -pub enum CliByteFormat { - Metric, - Binary, - Bytes, - GB, - GiB, - MB, - MiB, -} - -impl FromArgValue for CliByteFormat { - fn from_arg_value(value: &str) -> Result { - use CliByteFormat::*; - let value_lc = value.to_ascii_lowercase(); - Ok(match value_lc.as_str() { - "metric" => Metric, - "binary" => Binary, - "bytes" => Bytes, - "gb" => GB, - "gib" => GiB, - "mb" => MB, - "mib" => MiB, - _ => return Err(format!("Invalid byte format: {}", value)), - }) - } -} - -impl From for ByteFormat { - fn from(input: CliByteFormat) -> Self { - use CliByteFormat::*; - match input { - Metric => ByteFormat::Metric, - Binary => ByteFormat::Binary, - Bytes => ByteFormat::Bytes, - GB => ByteFormat::GB, - GiB => ByteFormat::GiB, - MB => ByteFormat::MB, - MiB => ByteFormat::MiB, - } - } -} - -/// a tool to learn about disk usage, fast! -#[derive(FromArgs)] -#[argh(name = "dua")] -pub struct Args { - #[argh(subcommand)] - pub command: Option, - - /// the amount of threads to use. Defaults to the amount of logical processors. - /// Set to 1 to use only a single thread. - #[argh(option, short = 't')] - pub threads: Option, - - /// the format with which to print byte counts. - /// Metric - uses 1000 as base (default) - /// Binary - uses 1024 as base - /// Bytes - plain bytes without any formatting - /// GB - only gigabytes - /// GiB - only gibibytes - /// MB - only megabytes - /// MiB - only mebibytes - #[argh(option, short = 'f')] - pub format: Option, - - /// display apparent size instead of disk usage. - #[argh(switch, short = 'A')] - pub apparent_size: bool, - - /// count hard-linked files each time they are seen - #[argh(switch, short = 'l')] - pub count_hard_links: bool, - - /// if set, we will not cross filesystems or traverse mount points - #[argh(switch, short = 'x')] - pub stay_on_filesystem: bool, - - /// one or more input files or directories. If unset, we will use all entries in the current working directory. - #[argh(positional)] - pub input: Vec, -} - -#[derive(FromArgs)] -#[argh(subcommand)] -pub enum Command { - Interactive(Interactive), - InteractiveAlias(InteractiveAlias), - Aggregate(Aggregate), -} - -/// Launch the terminal user interface -#[derive(FromArgs)] -#[argh(subcommand, name = "interactive")] -pub struct Interactive { - /// one or more input files or directories. If unset, we will use all entries in the current working directory. - #[argh(positional)] - input: Vec, -} - -/// Alias for 'interactive' -#[derive(FromArgs)] -#[argh(subcommand, name = "i")] -pub struct InteractiveAlias { - #[argh(positional)] - input: Vec, -} - -/// Aggregate the consumed space of one or more directories or files -#[derive(FromArgs)] -#[argh(subcommand, name = "aggregate")] -pub struct Aggregate { - /// if set, print additional statistics about the file traversal to stderr - #[argh(switch)] - stats: bool, - /// if set, paths will be printed in their order of occurrence on the command-line. - /// Otherwise they are sorted by their size in bytes, ascending. - #[argh(switch)] - no_sort: bool, - /// if set, no total column will be computed for multiple inputs - #[argh(switch)] - no_total: bool, - /// one or more input files or directories. If unset, we will use all entries in the current working directory. - #[argh(positional)] - input: Vec, -} -- cgit v1.2.3