Add --timestamp-format
(#2106)
This commit is contained in:
parent
9d2c6b8858
commit
77a6e02964
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@ -32,7 +32,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Completion Scripts
|
- name: Completion Scripts
|
||||||
run: |
|
run: |
|
||||||
./bin/generate-completions
|
./bin/update-completions
|
||||||
git diff --no-ext-diff --quiet --exit-code
|
git diff --no-ext-diff --quiet --exit-code
|
||||||
./tests/completions/just.bash
|
./tests/completions/just.bash
|
||||||
|
|
||||||
|
37
README.md
37
README.md
@ -3372,6 +3372,43 @@ Since `set windows-shell` has higher precedence than `set shell`, you can use
|
|||||||
`set windows-shell` to pick a shell on Windows, and `set shell` to pick a shell
|
`set windows-shell` to pick a shell on Windows, and `set shell` to pick a shell
|
||||||
for all other platforms.
|
for all other platforms.
|
||||||
|
|
||||||
|
### Timestamps
|
||||||
|
|
||||||
|
`just` can print timestamps before each recipe commands:
|
||||||
|
|
||||||
|
```just
|
||||||
|
recipe:
|
||||||
|
echo one
|
||||||
|
sleep 2
|
||||||
|
echo two
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
$ just --timestamp recipe
|
||||||
|
[07:28:46] echo one
|
||||||
|
one
|
||||||
|
[07:28:46] sleep 2
|
||||||
|
[07:28:48] echo two
|
||||||
|
two
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, timestamps are formatted as `HH:MM:SS`. The format can be changed
|
||||||
|
with `--timestamp-format`:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ just --timestamp recipe --timestamp-format '%H:%M:%S%.3f %Z'
|
||||||
|
[07:32:11:.349 UTC] echo one
|
||||||
|
one
|
||||||
|
[07:32:11:.350 UTC] sleep 2
|
||||||
|
[07:32:13:.352 UTC] echo two
|
||||||
|
two
|
||||||
|
```
|
||||||
|
|
||||||
|
The argument to `--timestamp-format` is a `strftime`-style format string, see
|
||||||
|
the
|
||||||
|
[`chrono` library docs](https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
|
||||||
|
for details.
|
||||||
|
|
||||||
Changelog
|
Changelog
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ _just() {
|
|||||||
|
|
||||||
case "${cmd}" in
|
case "${cmd}" in
|
||||||
just)
|
just)
|
||||||
opts="-n -f -q -u -v -d -c -e -l -s -E -g -h -V --check --chooser --color --command-color --yes --dry-run --dump-format --highlight --list-heading --list-prefix --no-aliases --no-deps --no-dotenv --no-highlight --justfile --quiet --set --shell --shell-arg --shell-command --clear-shell-args --unsorted --unstable --verbose --working-directory --changelog --choose --command --completions --dump --edit --evaluate --fmt --init --list --groups --man --show --summary --variables --dotenv-filename --dotenv-path --global-justfile --timestamps --help --version [ARGUMENTS]..."
|
opts="-n -f -q -u -v -d -c -e -l -s -E -g -h -V --check --chooser --color --command-color --yes --dry-run --dump-format --highlight --list-heading --list-prefix --no-aliases --no-deps --no-dotenv --no-highlight --justfile --quiet --set --shell --shell-arg --shell-command --clear-shell-args --unsorted --unstable --verbose --working-directory --changelog --choose --command --completions --dump --edit --evaluate --fmt --init --list --groups --man --show --summary --variables --dotenv-filename --dotenv-path --global-justfile --timestamp --timestamp-format --help --version [ARGUMENTS]..."
|
||||||
if [[ ${cur} == -* ]] ; then
|
if [[ ${cur} == -* ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
return 0
|
return 0
|
||||||
@ -144,6 +144,10 @@ _just() {
|
|||||||
COMPREPLY=($(compgen -f "${cur}"))
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
--timestamp-format)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
;;
|
;;
|
||||||
|
@ -40,6 +40,7 @@ set edit:completion:arg-completer[just] = {|@words|
|
|||||||
cand --dotenv-filename 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
cand --dotenv-filename 'Search for environment file named <DOTENV-FILENAME> instead of `.env`'
|
||||||
cand -E 'Load <DOTENV-PATH> as environment file instead of searching for one'
|
cand -E 'Load <DOTENV-PATH> as environment file instead of searching for one'
|
||||||
cand --dotenv-path 'Load <DOTENV-PATH> as environment file instead of searching for one'
|
cand --dotenv-path 'Load <DOTENV-PATH> as environment file instead of searching for one'
|
||||||
|
cand --timestamp-format 'Timestamp format string'
|
||||||
cand --check 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
cand --check 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
||||||
cand --yes 'Automatically confirm all recipes.'
|
cand --yes 'Automatically confirm all recipes.'
|
||||||
cand -n 'Print what just would do without doing it'
|
cand -n 'Print what just would do without doing it'
|
||||||
@ -72,7 +73,7 @@ set edit:completion:arg-completer[just] = {|@words|
|
|||||||
cand --variables 'List names of variables'
|
cand --variables 'List names of variables'
|
||||||
cand -g 'Use global justfile'
|
cand -g 'Use global justfile'
|
||||||
cand --global-justfile 'Use global justfile'
|
cand --global-justfile 'Use global justfile'
|
||||||
cand --timestamps 'Print recipe command timestamps'
|
cand --timestamp 'Print recipe command timestamps'
|
||||||
cand -h 'Print help'
|
cand -h 'Print help'
|
||||||
cand --help 'Print help'
|
cand --help 'Print help'
|
||||||
cand -V 'Print version'
|
cand -V 'Print version'
|
||||||
|
@ -52,6 +52,7 @@ complete -c just -s l -l list -d 'List available recipes and their arguments' -r
|
|||||||
complete -c just -s s -l show -d 'Show information about <RECIPE>' -r
|
complete -c just -s s -l show -d 'Show information about <RECIPE>' -r
|
||||||
complete -c just -l dotenv-filename -d 'Search for environment file named <DOTENV-FILENAME> instead of `.env`' -r
|
complete -c just -l dotenv-filename -d 'Search for environment file named <DOTENV-FILENAME> instead of `.env`' -r
|
||||||
complete -c just -s E -l dotenv-path -d 'Load <DOTENV-PATH> as environment file instead of searching for one' -r -F
|
complete -c just -s E -l dotenv-path -d 'Load <DOTENV-PATH> as environment file instead of searching for one' -r -F
|
||||||
|
complete -c just -l timestamp-format -d 'Timestamp format string' -r
|
||||||
complete -c just -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
complete -c just -l check -d 'Run `--fmt` in \'check\' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.'
|
||||||
complete -c just -l yes -d 'Automatically confirm all recipes.'
|
complete -c just -l yes -d 'Automatically confirm all recipes.'
|
||||||
complete -c just -s n -l dry-run -d 'Print what just would do without doing it'
|
complete -c just -s n -l dry-run -d 'Print what just would do without doing it'
|
||||||
@ -78,6 +79,6 @@ complete -c just -l man -d 'Print man page'
|
|||||||
complete -c just -l summary -d 'List names of available recipes'
|
complete -c just -l summary -d 'List names of available recipes'
|
||||||
complete -c just -l variables -d 'List names of variables'
|
complete -c just -l variables -d 'List names of variables'
|
||||||
complete -c just -s g -l global-justfile -d 'Use global justfile'
|
complete -c just -s g -l global-justfile -d 'Use global justfile'
|
||||||
complete -c just -l timestamps -d 'Print recipe command timestamps'
|
complete -c just -l timestamp -d 'Print recipe command timestamps'
|
||||||
complete -c just -s h -l help -d 'Print help'
|
complete -c just -s h -l help -d 'Print help'
|
||||||
complete -c just -s V -l version -d 'Print version'
|
complete -c just -s V -l version -d 'Print version'
|
||||||
|
@ -43,6 +43,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
|||||||
[CompletionResult]::new('--dotenv-filename', 'dotenv-filename', [CompletionResultType]::ParameterName, 'Search for environment file named <DOTENV-FILENAME> instead of `.env`')
|
[CompletionResult]::new('--dotenv-filename', 'dotenv-filename', [CompletionResultType]::ParameterName, 'Search for environment file named <DOTENV-FILENAME> instead of `.env`')
|
||||||
[CompletionResult]::new('-E', 'E ', [CompletionResultType]::ParameterName, 'Load <DOTENV-PATH> as environment file instead of searching for one')
|
[CompletionResult]::new('-E', 'E ', [CompletionResultType]::ParameterName, 'Load <DOTENV-PATH> as environment file instead of searching for one')
|
||||||
[CompletionResult]::new('--dotenv-path', 'dotenv-path', [CompletionResultType]::ParameterName, 'Load <DOTENV-PATH> as environment file instead of searching for one')
|
[CompletionResult]::new('--dotenv-path', 'dotenv-path', [CompletionResultType]::ParameterName, 'Load <DOTENV-PATH> as environment file instead of searching for one')
|
||||||
|
[CompletionResult]::new('--timestamp-format', 'timestamp-format', [CompletionResultType]::ParameterName, 'Timestamp format string')
|
||||||
[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.')
|
[CompletionResult]::new('--check', 'check', [CompletionResultType]::ParameterName, 'Run `--fmt` in ''check'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.')
|
||||||
[CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Automatically confirm all recipes.')
|
[CompletionResult]::new('--yes', 'yes', [CompletionResultType]::ParameterName, 'Automatically confirm all recipes.')
|
||||||
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Print what just would do without doing it')
|
||||||
@ -75,7 +76,7 @@ Register-ArgumentCompleter -Native -CommandName 'just' -ScriptBlock {
|
|||||||
[CompletionResult]::new('--variables', 'variables', [CompletionResultType]::ParameterName, 'List names of variables')
|
[CompletionResult]::new('--variables', 'variables', [CompletionResultType]::ParameterName, 'List names of variables')
|
||||||
[CompletionResult]::new('-g', 'g', [CompletionResultType]::ParameterName, 'Use global justfile')
|
[CompletionResult]::new('-g', 'g', [CompletionResultType]::ParameterName, 'Use global justfile')
|
||||||
[CompletionResult]::new('--global-justfile', 'global-justfile', [CompletionResultType]::ParameterName, 'Use global justfile')
|
[CompletionResult]::new('--global-justfile', 'global-justfile', [CompletionResultType]::ParameterName, 'Use global justfile')
|
||||||
[CompletionResult]::new('--timestamps', 'timestamps', [CompletionResultType]::ParameterName, 'Print recipe command timestamps')
|
[CompletionResult]::new('--timestamp', 'timestamp', [CompletionResultType]::ParameterName, 'Print recipe command timestamps')
|
||||||
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
|
[CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help')
|
||||||
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
|
[CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help')
|
||||||
[CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version')
|
[CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version')
|
||||||
|
@ -38,6 +38,7 @@ _just() {
|
|||||||
'(-E --dotenv-path)--dotenv-filename=[Search for environment file named <DOTENV-FILENAME> instead of \`.env\`]: : ' \
|
'(-E --dotenv-path)--dotenv-filename=[Search for environment file named <DOTENV-FILENAME> instead of \`.env\`]: : ' \
|
||||||
'-E+[Load <DOTENV-PATH> as environment file instead of searching for one]: :_files' \
|
'-E+[Load <DOTENV-PATH> as environment file instead of searching for one]: :_files' \
|
||||||
'--dotenv-path=[Load <DOTENV-PATH> as environment file instead of searching for one]: :_files' \
|
'--dotenv-path=[Load <DOTENV-PATH> as environment file instead of searching for one]: :_files' \
|
||||||
|
'--timestamp-format=[Timestamp format string]: : ' \
|
||||||
'--check[Run \`--fmt\` in '\''check'\'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.]' \
|
'--check[Run \`--fmt\` in '\''check'\'' mode. Exits with 0 if justfile is formatted correctly. Exits with 1 and prints a diff if formatting is required.]' \
|
||||||
'--yes[Automatically confirm all recipes.]' \
|
'--yes[Automatically confirm all recipes.]' \
|
||||||
'(-q --quiet)-n[Print what just would do without doing it]' \
|
'(-q --quiet)-n[Print what just would do without doing it]' \
|
||||||
@ -70,7 +71,7 @@ _just() {
|
|||||||
'--variables[List names of variables]' \
|
'--variables[List names of variables]' \
|
||||||
'(-f --justfile -d --working-directory)-g[Use global justfile]' \
|
'(-f --justfile -d --working-directory)-g[Use global justfile]' \
|
||||||
'(-f --justfile -d --working-directory)--global-justfile[Use global justfile]' \
|
'(-f --justfile -d --working-directory)--global-justfile[Use global justfile]' \
|
||||||
'--timestamps[Print recipe command timestamps]' \
|
'--timestamp[Print recipe command timestamps]' \
|
||||||
'-h[Print help]' \
|
'-h[Print help]' \
|
||||||
'--help[Print help]' \
|
'--help[Print help]' \
|
||||||
'-V[Print version]' \
|
'-V[Print version]' \
|
||||||
|
4
justfile
4
justfile
@ -164,8 +164,8 @@ watch-readme:
|
|||||||
just render-readme
|
just render-readme
|
||||||
fswatch -ro README.adoc | xargs -n1 -I{} just render-readme
|
fswatch -ro README.adoc | xargs -n1 -I{} just render-readme
|
||||||
|
|
||||||
generate-completions:
|
update-completions:
|
||||||
./bin/generate-completions
|
./bin/update-completions
|
||||||
|
|
||||||
test-completions:
|
test-completions:
|
||||||
./tests/completions/just.bash
|
./tests/completions/just.bash
|
||||||
|
@ -39,7 +39,8 @@ pub(crate) struct Config {
|
|||||||
pub(crate) shell_args: Option<Vec<String>>,
|
pub(crate) shell_args: Option<Vec<String>>,
|
||||||
pub(crate) shell_command: bool,
|
pub(crate) shell_command: bool,
|
||||||
pub(crate) subcommand: Subcommand,
|
pub(crate) subcommand: Subcommand,
|
||||||
pub(crate) timestamps: bool,
|
pub(crate) timestamp: bool,
|
||||||
|
pub(crate) timestamp_format: String,
|
||||||
pub(crate) unsorted: bool,
|
pub(crate) unsorted: bool,
|
||||||
pub(crate) unstable: bool,
|
pub(crate) unstable: bool,
|
||||||
pub(crate) verbosity: Verbosity,
|
pub(crate) verbosity: Verbosity,
|
||||||
@ -109,7 +110,8 @@ mod arg {
|
|||||||
pub(crate) const SHELL: &str = "SHELL";
|
pub(crate) const SHELL: &str = "SHELL";
|
||||||
pub(crate) const SHELL_ARG: &str = "SHELL-ARG";
|
pub(crate) const SHELL_ARG: &str = "SHELL-ARG";
|
||||||
pub(crate) const SHELL_COMMAND: &str = "SHELL-COMMAND";
|
pub(crate) const SHELL_COMMAND: &str = "SHELL-COMMAND";
|
||||||
pub(crate) const TIMESTAMPS: &str = "TIMESTAMPS";
|
pub(crate) const TIMESTAMP: &str = "TIMESTAMP";
|
||||||
|
pub(crate) const TIMESTAMP_FORMAT: &str = "TIMESTAMP_FORMAT";
|
||||||
pub(crate) const UNSORTED: &str = "UNSORTED";
|
pub(crate) const UNSORTED: &str = "UNSORTED";
|
||||||
pub(crate) const UNSTABLE: &str = "UNSTABLE";
|
pub(crate) const UNSTABLE: &str = "UNSTABLE";
|
||||||
pub(crate) const VERBOSE: &str = "VERBOSE";
|
pub(crate) const VERBOSE: &str = "VERBOSE";
|
||||||
@ -486,12 +488,20 @@ impl Config {
|
|||||||
.help("Use global justfile")
|
.help("Use global justfile")
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(
|
||||||
Arg::new(arg::TIMESTAMPS)
|
Arg::new(arg::TIMESTAMP)
|
||||||
.action(ArgAction::SetTrue)
|
.action(ArgAction::SetTrue)
|
||||||
.long("timestamps")
|
.long("timestamp")
|
||||||
.env("JUST_TIMESTAMPS")
|
.env("JUST_TIMESTAMP")
|
||||||
.help("Print recipe command timestamps")
|
.help("Print recipe command timestamps")
|
||||||
)
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new(arg::TIMESTAMP_FORMAT)
|
||||||
|
.action(ArgAction::Set)
|
||||||
|
.long("timestamp-format")
|
||||||
|
.env("JUST_TIMESTAMP_FORMAT")
|
||||||
|
.default_value("%H:%M:%S")
|
||||||
|
.help("Timestamp format string")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_from_matches(matches: &ArgMatches) -> ConfigResult<Color> {
|
fn color_from_matches(matches: &ArgMatches) -> ConfigResult<Color> {
|
||||||
@ -743,7 +753,11 @@ impl Config {
|
|||||||
shell_args,
|
shell_args,
|
||||||
shell_command: matches.get_flag(arg::SHELL_COMMAND),
|
shell_command: matches.get_flag(arg::SHELL_COMMAND),
|
||||||
subcommand,
|
subcommand,
|
||||||
timestamps: matches.get_flag(arg::TIMESTAMPS),
|
timestamp: matches.get_flag(arg::TIMESTAMP),
|
||||||
|
timestamp_format: matches
|
||||||
|
.get_one::<String>(arg::TIMESTAMP_FORMAT)
|
||||||
|
.unwrap()
|
||||||
|
.into(),
|
||||||
unsorted: matches.get_flag(arg::UNSORTED),
|
unsorted: matches.get_flag(arg::UNSORTED),
|
||||||
unstable,
|
unstable,
|
||||||
verbosity,
|
verbosity,
|
||||||
|
@ -61,7 +61,6 @@ pub(crate) use {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
camino::Utf8Path,
|
camino::Utf8Path,
|
||||||
chrono::Utc,
|
|
||||||
derivative::Derivative,
|
derivative::Derivative,
|
||||||
edit_distance::edit_distance,
|
edit_distance::edit_distance,
|
||||||
lexiclean::Lexiclean,
|
lexiclean::Lexiclean,
|
||||||
|
@ -243,10 +243,14 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
.unwrap_or(config.color)
|
.unwrap_or(config.color)
|
||||||
.stderr();
|
.stderr();
|
||||||
|
|
||||||
if config.timestamps {
|
if config.timestamp {
|
||||||
eprint!(
|
eprint!(
|
||||||
"[{}] ",
|
"[{}] ",
|
||||||
color.paint(&Utc::now().format("%H:%M:%S").to_string())
|
color.paint(
|
||||||
|
&chrono::Local::now()
|
||||||
|
.format(&config.timestamp_format)
|
||||||
|
.to_string()
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,23 @@ fn print_timestamps() {
|
|||||||
echo 'one'
|
echo 'one'
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.arg("--timestamps")
|
.arg("--timestamp")
|
||||||
.stderr_regex(concat!(r"\[\d\d:\d\d:\d\d\] echo 'one'", "\n"))
|
.stderr_regex(concat!(r"\[\d\d:\d\d:\d\d\] echo 'one'", "\n"))
|
||||||
.stdout("one\n")
|
.stdout("one\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn print_timestamps_with_format_string() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
recipe:
|
||||||
|
echo 'one'
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.args(["--timestamp", "--timestamp-format", "%H:%M:%S.%3f"])
|
||||||
|
.stderr_regex(concat!(r"\[\d\d:\d\d:\d\d\.\d\d\d] echo 'one'", "\n"))
|
||||||
|
.stdout("one\n")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user