Skip to content

Commit

Permalink
doc: Update changelog, example config, inline help
Browse files Browse the repository at this point in the history
Rewordings and cleanups.
  • Loading branch information
vincentdephily committed Feb 6, 2024
1 parent a1594ab commit a5b1d3a
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 93 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

* Support searching by multiple terms
- eg `emlop s -e gcc clang llvm rust`
* Support configuration file
- Located by default in `~/.config/emlop.toml`, overridable with `$EMLOP_CONFIG` env var
- Example config added to repo, should be installed alongside emlop docs
- Config options, when available, always correspond to a cli arg
- Many flags/args now take an optional `no` value, so the cli can override the conf
* Improve predict:
- Autodetect `tmpdir` using currently running emerge processes
- Support multiple `--tmpdir` arguments
Expand Down
43 changes: 19 additions & 24 deletions emlop.toml
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
########################################
# This is an example emlop config file.
# This is an example `emlop` config file.
#
# To use it, copy to $HOME/.config/emlop.toml (or to whatever you set $EMLOP_CONFIG to) and
# uncomment the desired lines.
#
# All config items have a corresponding command-line arg, see `emlop <subcommand> --help` for
# detailed format and behavior. Not all command-line args have a config item, this file lists all
# the supported items.
########################################

# It is loaded from `$HOME/.config/emlop.toml` by default.
# Use `$EMLOP_CONFIG` to set a different location, empty string to disable config loading.
# Entries have the same name and format as command-line args, see `emlop <command> --help`.
# Some args are only avaible via the command line.

# logfile = "/var/log/emerge.log"
# date = "rfc2822"
# duration = "human"
# utc = true
# header = true
[log]
#show = "mus"
#starttime = true
# show = "mus"
# starttime = true
[predict]
#show = "emt"
#avg = "arith"
#limit = 20
#unknown = 300
#tmpdir = ["/foo", "/bar"]
# show = "emt"
# avg = "arith"
# limit = 20
# unknown = 300
# tmpdir = ["/foo", "/bar"]
[stats]
#show = "pts"
#avg = "arith"
#limit = 20
#group = "y"
# show = "pts"
# avg = "arith"
# limit = 20
# group = "y"
[accuracy]
#show = "mt"
#avg = "arith"
#limit = 20
# show = "mt"
# avg = "arith"
# limit = 20
135 changes: 66 additions & 69 deletions src/config/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,38 +74,39 @@ pub fn build_cli_nocomplete() -> Command {
m: Package merges\n \
t: Totals\n \
a: All of the above");

let from = Arg::new("from").value_name("date")
.short('f')
let h = "Only parse log entries after <date>\n \
2018-03-04|2018-03-04 12:34:56|2018-03-04T12:34: Absolute ISO date\n \
123456789: Absolute unix timestamp\n \
1 year, 2 months|10d: Relative date";
let from = Arg::new("from").short('f')
.long("from")
.display_order(4)
.value_name("date")
.global(true)
.num_args(1)
.display_order(4)
.help_heading("Filter")
.help("Only parse log entries after <date>")
.long_help("Only parse log entries after <date>\n \
2018-03-04|2018-03-04 12:34:56|2018-03-04T12:34: Absolute ISO date\n \
123456789: Absolute unix timestamp\n \
1 year, 2 months|10d: Relative date");
let to = Arg::new("to").value_name("date")
.short('t')
.help(h.split_once('\n').unwrap().0)
.long_help(h);
let h = "Only parse log entries before <date>\n \
2018-03-04|2018-03-04 12:34:56|2018-03-04T12:34: Absolute ISO date\n \
123456789: Absolute unix timestamp\n \
1 year, 2 months|10d: Relative date";
let to = Arg::new("to").short('t')
.long("to")
.display_order(5)
.value_name("date")
.global(true)
.num_args(1)
.display_order(5)
.help_heading("Filter")
.help("Only parse log entries before <date>")
.long_help("Only parse log entries before <date>\n \
2018-03-04|2018-03-04 12:34:56|2018-03-04T12:34: Absolute ISO date\n \
123456789: Absolute unix timestamp\n \
1 year, 2 months|10d: Relative date");
.help(h.split_once('\n').unwrap().0)
.long_help(h);
let first = Arg::new("first").short('N')
.long("first")
.value_name("num")
.display_order(6)
.num_args(..=1)
.default_missing_value("1")
.value_parser(value_parser!(usize))
.display_order(6)
.help_heading("Filter")
.help("Show only the first <num> entries")
.long_help("Show only the first <num> entries\n \
Expand All @@ -114,53 +115,69 @@ pub fn build_cli_nocomplete() -> Command {
let last = Arg::new("last").short('n')
.long("last")
.value_name("num")
.display_order(7)
.num_args(..=1)
.default_missing_value("1")
.value_parser(value_parser!(usize))
.display_order(7)
.help_heading("Filter")
.help("Show only the last <num> entries")
.long_help("Show only the last <num> entries\n \
(empty)|1: last entry\n \
5: last 5 entries\n");
let h = "Use main, backup, any, or no portage resume list\n\
This is ignored if STDIN is a piped `emerge -p` output\n \
(default): Use main resume list, if currently emerging\n \
any|a|(empty): Use main or backup resume list\n \
main|m: Use main resume list\n \
backup|b: Use backup resume list\n \
no|n: Never use resume list";
let resume = Arg::new("resume").long("resume")
.value_name("source")
.value_parser(value_parser!(crate::config::ResumeKind))
.hide_possible_values(true)
.num_args(..=1)
.default_missing_value("any")
.display_order(8)
.help_heading("Filter")
.help(h.split_once('\n').unwrap().0)
.long_help(h);

////////////////////////////////////////////////////////////
// Stats arguments
////////////////////////////////////////////////////////////
let group = Arg::new("group").short('g')
.long("groupby")
.display_order(1)
.value_name("y,m,w,d,n")
.hide_possible_values(true)
.display_order(10)
.help_heading("Stats")
.help("Group by (y)ear, (m)onth, (w)eek, (d)ay, (n)one")
.long_help("Group by (y)ear, (m)onth, (w)eek, (d)ay, or (n)one\n\
The grouping key is displayed in the first column.\n\
Weeks start on monday and are formated as \
'year-weeknumber'.");
let limit = Arg::new("limit").long("limit")
.display_order(2)
.num_args(1)
.value_name("num")
.num_args(1)
.display_order(11)
.help_heading("Stats")
.help("Use the last <num> merge times to predict durations");
let avg =
Arg::new("avg").long("avg")
.value_name("fn")
.display_order(3)
.hide_possible_values(true)
.display_order(12)
.help_heading("Stats")
.help("Select function used to predict durations")
.long_help("Select function used to predict durations\n \
arith|a: simple 'sum/count' average\n \
(defaut)|median|m: middle value, mitigates outliers\n \
weighted-arith|wa: 'sum/count' with more weight for recent values\n \
weighted-median|wm: \"middle\" value shifted toward recent values");

let unknown = Arg::new("unknown").long("unknown")
.display_order(4)
.num_args(1)
.value_name("secs")
.display_order(13)
.help_heading("Stats")
.help("Assume unkown packages take <secs> seconds to merge");

Expand All @@ -169,19 +186,18 @@ pub fn build_cli_nocomplete() -> Command {
////////////////////////////////////////////////////////////
let header = Arg::new("header").short('H')
.long("header")
.value_name("bool")
.global(true)
.display_order(1)
.num_args(..=1)
.default_missing_value("y")
.value_name("bool")
.display_order(20)
.help_heading("Format")
.help("Show table header");
let date =
Arg::new("date").value_name("format")
.long("date")
.display_order(2)
Arg::new("date").long("date")
.value_name("format")
.global(true)
.display_order(52)
.display_order(21)
.help_heading("Format")
.help("Output dates in different formats")
.long_help("Output dates in different formats\n \
Expand All @@ -192,12 +208,11 @@ pub fn build_cli_nocomplete() -> Command {
rfc2822|2822: Mon, 31 Jan 2022 08:59:46 +00:00\n \
compact: 20220131085946\n \
unix: 1643619586");
let duration = Arg::new("duration").value_name("format")
.long("duration")
.display_order(3)
let duration = Arg::new("duration").long("duration")
.value_name("format")
.global(true)
.hide_possible_values(true)
.display_order(51)
.display_order(22)
.help_heading("Format")
.help("Output durations in different formats")
.long_help("Output durations in different formats\n \
Expand All @@ -206,43 +221,41 @@ pub fn build_cli_nocomplete() -> Command {
secs|s: 630\n \
human|h: 10 minutes, 30 seconds");
let utc = Arg::new("utc").long("utc")
.value_name("bool")
.global(true)
.display_order(4)
.num_args(..=1)
.default_missing_value("y")
.value_name("bool")
.display_order(23)
.help_heading("Format")
.help("Parse/display dates in UTC instead of local time");
let starttime = Arg::new("starttime").long("starttime")
.value_name("bool")
.num_args(..=1)
.default_missing_value("y")
.value_name("bool")
.display_order(5)
.display_order(24)
.help_heading("Format")
.help("Display start time instead of end time");
let color = Arg::new("color").long("color")
.alias("colour")
.display_order(6)
.value_name("when")
.global(true)
.value_parser(value_parser!(crate::ColorStyle))
.hide_possible_values(true)
.num_args(..=1)
.default_missing_value("y")
.value_name("when")
.display_order(55)
.display_order(25)
.help_heading("Format")
.help("Enable color (always/never/y/n)")
.long_help("Enable color (always/never/y/n)\n \
(default): colored if on tty\n \
(empty)|always|y: colored\n \
never|n: not colored");
let output = Arg::new("output").long("output")
.short('o')
let output = Arg::new("output").short('o')
.long("output")
.value_name("format")
.global(true)
.value_parser(value_parser!(crate::OutStyle))
.hide_possible_values(true)
.display_order(7)
.display_order(26)
.help_heading("Format")
.help("Ouput format (columns/c/tab/t)")
.long_help("Ouput format (columns/c/tab/t)\n \
Expand All @@ -253,43 +266,27 @@ pub fn build_cli_nocomplete() -> Command {
////////////////////////////////////////////////////////////
// Misc arguments
////////////////////////////////////////////////////////////
let logfile = Arg::new("logfile").value_name("file")
let logfile = Arg::new("logfile").short('F')
.long("logfile")
.short('F')
.value_name("file")
.global(true)
.num_args(1)
.display_order(1)
.display_order(30)
.help("Location of emerge log file");
let tmpdir = Arg::new("tmpdir").value_name("dir")
.long("tmpdir")
let tmpdir = Arg::new("tmpdir").long("tmpdir")
.value_name("dir")
.num_args(1)
.action(Append)
.value_parser(value_parser!(PathBuf))
.display_order(2)
.display_order(31)
.help("Location of portage tmpdir")
.long_help("Location of portage tmpdir\n\
Multiple folders can be provided\n\
Emlop also looks for tmpdir using current emerge processes");
let h = "Use main, backup, any, or no portage resume list\n\
This is ignored if STDIN is a piped `emerge -p` output\n \
(default): Use main resume list, if currently emerging\n \
any|a|(empty): Use main or backup resume list\n \
main|m: Use main resume list\n \
backup|b: Use backup resume list\n \
no|n: Never use resume list";
let resume = Arg::new("resume").long("resume")
.value_name("source")
.value_parser(value_parser!(crate::config::ResumeKind))
.hide_possible_values(true)
.num_args(..=1)
.default_missing_value("any")
.display_order(3)
.help(h.split_once('\n').unwrap().0)
.long_help(h);
let verbose = Arg::new("verbose").short('v')
.global(true)
.action(Count)
.display_order(4)
.display_order(33)
.help("Increase verbosity (can be given multiple times)")
.long_help("Increase verbosity (defaults to errors only)\n \
-v: show warnings\n \
Expand Down

0 comments on commit a5b1d3a

Please sign in to comment.