Skip to content

Commit 3a77807

Browse files
authored
Merge pull request #1906 from gaelicWizard/command_duration
Revamp command duration helper/plugin
2 parents ca8101b + 866e5be commit 3a77807

7 files changed

+93
-115
lines changed

bash_it.sh

-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ if [[ -n "${BASH_IT_THEME:-}" ]]; then
5151
source "${BASH_IT}/themes/githelpers.theme.bash"
5252
BASH_IT_LOG_PREFIX="themes: p4helpers: "
5353
source "${BASH_IT}/themes/p4helpers.theme.bash"
54-
BASH_IT_LOG_PREFIX="themes: command_duration: "
55-
source "${BASH_IT}/themes/command_duration.theme.bash"
5654
BASH_IT_LOG_PREFIX="themes: base: "
5755
source "${BASH_IT}/themes/base.theme.bash"
5856

clean_files.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ completion/available/wpscan.completion.bash
7878
# libraries
7979
lib/appearance.bash
8080
lib/colors.bash
81+
lib/command_duration.bash
8182
lib/helpers.bash
8283
lib/history.bash
8384
lib/log.bash
@@ -155,7 +156,6 @@ themes/bobby-python
155156
themes/brainy
156157
themes/brunton
157158
themes/candy
158-
themes/command_duration.theme.bash
159159
themes/easy
160160
themes/essential
161161
themes/githelpers.theme.bash

lib/command_duration.bash

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# shellcheck shell=bash
2+
#
3+
# Functions for measuring and reporting how long a command takes to run.
4+
5+
: "${COMMAND_DURATION_START_SECONDS:=${EPOCHREALTIME:-$SECONDS}}"
6+
: "${COMMAND_DURATION_ICON:=🕘}"
7+
: "${COMMAND_DURATION_MIN_SECONDS:=1}"
8+
9+
function _command_duration_pre_exec() {
10+
COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}"
11+
}
12+
13+
function _dynamic_clock_icon {
14+
local -i clock_hand=$(((${1:-${SECONDS}} % 12) + 90))
15+
printf -v 'COMMAND_DURATION_ICON' '%b' "\xf0\x9f\x95\x$clock_hand"
16+
}
17+
18+
function _command_duration() {
19+
[[ -n "${BASH_IT_COMMAND_DURATION:-}" ]] || return
20+
21+
local command_duration=0 command_start="${COMMAND_DURATION_START_SECONDS:-0}"
22+
local -i minutes=0 seconds=0 deciseconds=0
23+
local -i command_start_seconds="${command_start%.*}"
24+
local -i command_start_deciseconds=$((10#${command_start##*.}))
25+
local current_time="${EPOCHREALTIME:-$SECONDS}"
26+
local -i current_time_seconds="${current_time%.*}"
27+
local -i current_time_deciseconds="$((10#${current_time##*.}))"
28+
29+
if [[ "${command_start_seconds:-0}" -gt 0 ]]; then
30+
# seconds
31+
command_duration="$((current_time_seconds - command_start_seconds))"
32+
33+
if ((current_time_deciseconds >= command_start_deciseconds)); then
34+
deciseconds="$((current_time_deciseconds - command_start_deciseconds))"
35+
else
36+
((command_duration -= 1))
37+
deciseconds="$((10 - (command_start_deciseconds - current_time_deciseconds)))"
38+
fi
39+
else
40+
command_duration=0
41+
fi
42+
43+
if ((command_duration > 0)); then
44+
minutes=$((command_duration / 60))
45+
seconds=$((command_duration % 60))
46+
fi
47+
48+
_dynamic_clock_icon "${command_duration}"
49+
if ((minutes > 0)); then
50+
printf "%s%s%dm %ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$minutes" "$seconds"
51+
elif ((seconds >= COMMAND_DURATION_MIN_SECONDS)); then
52+
printf "%s%s%d.%01ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$seconds" "$deciseconds"
53+
fi
54+
}
55+
56+
_bash_it_library_finalize_hook+=("safe_append_preexec '_command_duration_pre_exec'")

plugins/available/cmd-returned-notify.plugin.bash

+10-10
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
cite about-plugin
33
about-plugin 'Alert (BEL) when process ends after a threshold of seconds'
44

5-
precmd_return_notification() {
6-
export LAST_COMMAND_DURATION=$(($(date +%s) - ${LAST_COMMAND_TIME:=$(date +%s)}))
7-
[[ ${LAST_COMMAND_DURATION} -gt ${NOTIFY_IF_COMMAND_RETURNS_AFTER:-5} ]] && echo -e "\a"
8-
export LAST_COMMAND_TIME=
5+
function precmd_return_notification() {
6+
local command_start="${COMMAND_DURATION_START_SECONDS:=0}"
7+
local current_time="${EPOCHREALTIME:-$SECONDS}"
8+
local -i command_duration="$((${current_time%.*} - ${command_start%.*}))"
9+
if [[ "${command_duration}" -gt "${NOTIFY_IF_COMMAND_RETURNS_AFTER:-5}" ]]; then
10+
printf '\a'
11+
fi
12+
return 0
913
}
1014

11-
preexec_return_notification() {
12-
[[ -z "${LAST_COMMAND_TIME}" ]] && LAST_COMMAND_TIME=$(date +%s)
13-
}
14-
15-
precmd_functions+=(precmd_return_notification)
16-
preexec_functions+=(preexec_return_notification)
15+
safe_append_prompt_command 'precmd_return_notification'
16+
safe_append_preexec '_command_duration_pre_exec'

test/plugins/cmd-returned-notify.plugin.bats

+25-32
Original file line numberDiff line numberDiff line change
@@ -3,46 +3,39 @@
33
load "${MAIN_BASH_IT_DIR?}/test/test_helper.bash"
44

55
function local_setup_file() {
6-
setup_libs "preexec" #"command_duration"
6+
setup_libs "command_duration"
77
load "${BASH_IT?}/plugins/available/cmd-returned-notify.plugin.bash"
88
}
99

1010
@test "plugins cmd-returned-notify: notify after elapsed time" {
11-
export NOTIFY_IF_COMMAND_RETURNS_AFTER=0
12-
export LAST_COMMAND_TIME=$(date +%s)
13-
sleep 1
14-
run precmd_return_notification
15-
assert_success
16-
assert_output $'\a'
11+
export NOTIFY_IF_COMMAND_RETURNS_AFTER=0
12+
export COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}"
13+
sleep 1
14+
run precmd_return_notification
15+
assert_success
16+
assert_output $'\a'
1717
}
1818

1919
@test "plugins cmd-returned-notify: do not notify before elapsed time" {
20-
export NOTIFY_IF_COMMAND_RETURNS_AFTER=10
21-
export LAST_COMMAND_TIME=$(date +%s)
22-
sleep 1
23-
run precmd_return_notification
24-
assert_success
25-
assert_output $''
20+
export NOTIFY_IF_COMMAND_RETURNS_AFTER=10
21+
export COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}"
22+
sleep 1
23+
run precmd_return_notification
24+
assert_success
25+
assert_output $''
2626
}
2727

28-
@test "plugins cmd-returned-notify: preexec no output" {
29-
export LAST_COMMAND_TIME=
30-
run preexec_return_notification
31-
assert_success
32-
assert_output ""
28+
@test "lib command_duration: preexec no output" {
29+
export COMMAND_DURATION_START_SECONDS=
30+
run _command_duration_pre_exec
31+
assert_success
32+
assert_output ""
3333
}
34-
35-
@test "plugins cmd-returned-notify: preexec no output env set" {
36-
export LAST_COMMAND_TIME=$(date +%s)
37-
run preexec_return_notification
38-
assert_failure
39-
assert_output ""
40-
}
41-
42-
@test "plugins cmd-returned-notify: preexec set LAST_COMMAND_TIME" {
43-
export LAST_COMMAND_TIME=
44-
assert_equal "${LAST_COMMAND_TIME}" ""
45-
NOW=$(date +%s)
46-
preexec_return_notification
47-
assert_equal "${LAST_COMMAND_TIME}" "${NOW}"
34+
@test "lib command_duration: preexec set COMMAND_DURATION_START_SECONDS" {
35+
export COMMAND_DURATION_START_SECONDS=
36+
assert_equal "${COMMAND_DURATION_START_SECONDS}" ""
37+
NOW="${EPOCHREALTIME:-$SECONDS}"
38+
_command_duration_pre_exec
39+
# We need to make sure to account for nanoseconds...
40+
assert_equal "${COMMAND_DURATION_START_SECONDS%.*}" "${NOW%.*}"
4841
}

test/test_helper.bash

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function common_setup_file() {
5757
function setup_libs() {
5858
local lib
5959
# Use a loop to allow convenient short-circuiting for some test files
60-
for lib in "log" "utilities" "helpers" "search" "preexec" "colors"; do
60+
for lib in "log" "utilities" "helpers" "search" "preexec" "colors" "command_duration"; do
6161
load "${BASH_IT?}/lib/${lib}.bash" || return
6262
# shellcheck disable=SC2015 # short-circuit if we've reached the requested library
6363
[[ "${lib}" == "${1:-}" ]] && return 0 || true

themes/command_duration.theme.bash

-69
This file was deleted.

0 commit comments

Comments
 (0)