summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Thiel <sebastian.thiel@icloud.com>2020-07-02 08:03:01 +0800
committerSebastian Thiel <sebastian.thiel@icloud.com>2020-07-02 08:03:01 +0800
commit03e9a2ac143c269d2c44a6bd13a0da10ede8bf38 (patch)
treed4332d8d4dc8415a4e4807886ef3459693412b59
parentd787a9c5b8ccadae678c985b05ecc328d62df8f3 (diff)
All tests work with argh (which really needs aliases)
-rw-r--r--Cargo.lock104
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs31
-rw-r--r--src/options.rs179
-rw-r--r--src/options_argh.rs130
5 files changed, 131 insertions, 314 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 03d7d4e..daf0921 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -109,21 +109,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -229,7 +214,6 @@ dependencies = [
"open",
"petgraph",
"pretty_assertions",
- "structopt",
"termion",
"tui",
"tui-react",
@@ -457,32 +441,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -559,36 +517,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -600,17 +528,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -635,15 +552,6 @@ dependencies = [
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -687,18 +595,6 @@ 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"
source = "registry+https://github.com/rust-lang/crates.io-index"
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<Self, String> {
+ 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<ByteFormat> for LibraryByteFormat {
- fn from(input: ByteFormat) -> Self {
+impl From<CliByteFormat> 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<Command>,
- /// 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<usize>,
- /// 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<ByteFormat>,
+ #[argh(option, short = 'f')]
+ pub format: Option<CliByteFormat>,
- /// 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<PathBuf>,
}
-#[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<PathBuf>,
- },
- /// 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<PathBuf>,
- },
+ 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<PathBuf>,
+}
+
+/// Alias for 'interactive'
+#[derive(FromArgs)]
+#[argh(subcommand, name = "i")]
+pub struct InteractiveAlias {
+ #[argh(positional)]
+ pub input: Vec<PathBuf>,
+}
+
+/// 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<PathBuf>,
+}
+
+/// 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<PathBuf>,
}
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<Self, String> {
- 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<CliByteFormat> 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<Command>,
-
- /// 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<usize>,
-
- /// 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<CliByteFormat>,
-
- /// 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<PathBuf>,
-}
-
-#[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<PathBuf>,
-}
-
-/// Alias for 'interactive'
-#[derive(FromArgs)]
-#[argh(subcommand, name = "i")]
-pub struct InteractiveAlias {
- #[argh(positional)]
- input: Vec<PathBuf>,
-}
-
-/// 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<PathBuf>,
-}