Skip to content

Commit

Permalink
Unify all configuration under the -s option.
Browse files Browse the repository at this point in the history
Settings are now changed with '-s name=value' options. '-s show' prints the
current values.
  • Loading branch information
ayosec committed Aug 26, 2021
1 parent 96f49f4 commit fb71c64
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 54 deletions.
125 changes: 78 additions & 47 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
//! timehistory bash builtin

use bash_builtins::{builtin_metadata, Args, Builtin, BuiltinOptions, Result as BuiltinResult};
use bash_builtins::{builtin_metadata, Args, Builtin, BuiltinOptions};
use bash_builtins::{Error::Usage, Result as BuiltinResult};
use std::io::{self, BufWriter, Write};

builtin_metadata!(
name = "timehistory",
try_create = TimeHistory::new,
short_doc = "timehistory [-h -f fmt | -v | -j] [<n> | +<n>] | -R | -C | [-L limit] [-F fmt]",
short_doc = "timehistory [-f FMT | -v | -j] [<n> | +<n>] | -s SET | -R",
long_doc = "
Displays information about the resources used by programs executed in
the running shell.
Options:
-h\tDisplay a header with field labels.
-f FMT\tUse FMT as the format string for every history entry,
\tinstead of the default value.
-v\tUse the verbose format, similar to GNU time.
-j\tPrint information as JSON format.
-s SET\tChange the value of a setting. See below.
-R\tRemove all entries in the history.
-C\tShow the current configuration.
-F\tChange the default format string.
-L\tChange the history limit.
Use '-f help' to get information about the formatting syntax.
If <n> is given, it displays information for a specific history entry.
The number for every entry is printed with the %n specifier in the
format string. If the number is prefixed with a plus symbol (+<n>) it
is the offset from the end of the list ('+1' is the last entry).
If <n> is given, it displays all information for a specific history
entry. The number for every entry is printed with the %n specifier in
the format string. If the number is prefixed with a plus symbol (+<n>)
it is the offset from the end of the list ('+1' is the last entry).
Format:
Use '-f help' to get information about the formatting syntax.
Settings:
The following settings are available:
format\tDefault format string.
header\tShow a header with the labels of every resource.
limit\tHistory limit.
To change a setting, use '-s name=value', where 'name' is any of the
previous values. Use one '-s' for every setting to change.
To see the current values use '-c show'.
",
);

Expand All @@ -42,18 +53,18 @@ mod tests;

use std::time::Duration;

const DEFAULT_FORMAT: &str = "%n\t%(time:%X)\t%P\t%e\t%C";
const DEFAULT_FORMAT: &str = "%n\\t%(time:%X)\\t%P\\t%e\\t%C";

struct TimeHistory {
/// Default format to print history entries.
default_format: String,

/// Show header with field labels.
show_header: bool,
}

#[derive(BuiltinOptions)]
enum Opt<'a> {
#[opt = 'h']
Header,

#[opt = 'f']
Format(&'a str),

Expand All @@ -66,14 +77,8 @@ enum Opt<'a> {
#[opt = 'R']
Reset,

#[opt = 'C']
PrintConfig,

#[opt = 'F']
SetDefaultFormat(String),

#[opt = 'L']
SetLimit(usize),
#[opt = 's']
Setting(&'a str),

#[cfg(feature = "option-for-panics")]
#[opt = 'P']
Expand Down Expand Up @@ -106,6 +111,7 @@ impl TimeHistory {

Ok(TimeHistory {
default_format: DEFAULT_FORMAT.into(),
show_header: false,
})
}
}
Expand All @@ -123,15 +129,14 @@ impl Builtin for TimeHistory {
// Extract options from command-line.

let mut exit_after_options = false;
let mut show_header = false;
let mut output_format = None;
let mut action = Action::List;

macro_rules! set_format {
($($t:tt)+) => {{
if output_format.is_some() {
bash_builtins::log::show_usage();
return Err(bash_builtins::Error::Usage);
return Err(Usage);
}

output_format = Some(Output::$($t)+);
Expand All @@ -140,8 +145,6 @@ impl Builtin for TimeHistory {

for opt in args.options() {
match opt? {
Opt::Header => show_header = true,

Opt::Format("help") => {
output.write_all(format::HELP)?;
exit_after_options = true;
Expand All @@ -155,29 +158,41 @@ impl Builtin for TimeHistory {

Opt::Reset => action = Action::Reset,

Opt::PrintConfig => {
writeln!(
&mut output,
"-L {} -F {}",
history.size(),
format::EscapeArgument(self.default_format.as_bytes())
)?;

Opt::Setting("show") => {
self.print_config(&mut output, &history)?;
exit_after_options = true;
}

Opt::SetDefaultFormat(fmt) => {
self.default_format = if fmt.is_empty() {
DEFAULT_FORMAT.into()
} else {
fmt
};

exit_after_options = true;
}
Opt::Setting(setting) => {
let mut parts = setting.splitn(2, '=');
match (parts.next(), parts.next()) {
(Some("limit"), Some(value)) => {
history.set_size(value.parse()?);
}

(Some("header"), Some(value)) => {
self.show_header = value.parse()?;
}

(Some("format"), Some(value)) => {
self.default_format = if value.is_empty() {
DEFAULT_FORMAT.into()
} else {
value.to_owned()
};
}

(Some(name), _) => {
bash_builtins::error!("{}: invalid setting", name);
return Err(Usage);
}

_ => {
bash_builtins::error!("{}: missing value", setting);
return Err(Usage);
}
}

Opt::SetLimit(l) => {
history.set_size(l as usize);
exit_after_options = true;
}

Expand Down Expand Up @@ -213,7 +228,7 @@ impl Builtin for TimeHistory {
Some(Output::Json) => None,
};

if show_header {
if self.show_header {
if let Some(fmt) = &format {
format::labels(fmt, &mut output)?;
output.write_all(b"\n")?;
Expand Down Expand Up @@ -264,3 +279,19 @@ impl Builtin for TimeHistory {
Ok(())
}
}

impl TimeHistory {
fn print_config(&self, mut output: impl Write, history: &history::History) -> io::Result<()> {
writeln!(
&mut output,
"format={}\n\
header={}\n\
limit={}",
self.default_format,
self.show_header,
history.size(),
)?;

Ok(())
}
}
12 changes: 8 additions & 4 deletions src/tests/shell/change-config.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@

load_builtin

timehistory -L 5000 -F '%n\t%P\t%C'
timehistory -s limit=5000 -s format='%n\t%P\t%C'

ASSERT_OUTPUT \
"timehistory -C" \
$'-L 5000 -F \'%n\\\\t%P\\\\t%C\''
"timehistory -s show" \
<<-'ITEMS'
format=%n\t%P\t%C
header=false
limit=5000
ITEMS

timehistory -F '> %C'
timehistory -s format='> %C'

command expr 1 + 2
ASSERT_OUTPUT \
Expand Down
3 changes: 2 additions & 1 deletion src/tests/shell/headers.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

load_builtin

timehistory -s header=true
ASSERT_OUTPUT \
"timehistory -h -f '%n %C'" \
"timehistory -f '%n %C'" \
"NUMBER COMMAND"
2 changes: 1 addition & 1 deletion src/tests/shell/rotate-history.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

load_builtin

timehistory -L 5
timehistory -s limit=5
for N in {1..10}
do
/bin/true $N
Expand Down
1 change: 0 additions & 1 deletion src/tests/shell/track-subshell.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

load_builtin

timehistory -F '%C'
(
/bin/echo 1
/bin/echo 2
Expand Down

0 comments on commit fb71c64

Please sign in to comment.