Merge pull request #1906 from gaelicWizard/command_duration

Revamp command duration helper/plugin
pull/2100/head^2
John D Pell 2022-03-04 13:00:05 -08:00 committed by GitHub
commit 3a778072db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 93 additions and 115 deletions

View File

@ -51,8 +51,6 @@ if [[ -n "${BASH_IT_THEME:-}" ]]; then
source "${BASH_IT}/themes/githelpers.theme.bash" source "${BASH_IT}/themes/githelpers.theme.bash"
BASH_IT_LOG_PREFIX="themes: p4helpers: " BASH_IT_LOG_PREFIX="themes: p4helpers: "
source "${BASH_IT}/themes/p4helpers.theme.bash" source "${BASH_IT}/themes/p4helpers.theme.bash"
BASH_IT_LOG_PREFIX="themes: command_duration: "
source "${BASH_IT}/themes/command_duration.theme.bash"
BASH_IT_LOG_PREFIX="themes: base: " BASH_IT_LOG_PREFIX="themes: base: "
source "${BASH_IT}/themes/base.theme.bash" source "${BASH_IT}/themes/base.theme.bash"

View File

@ -78,6 +78,7 @@ completion/available/wpscan.completion.bash
# libraries # libraries
lib/appearance.bash lib/appearance.bash
lib/colors.bash lib/colors.bash
lib/command_duration.bash
lib/helpers.bash lib/helpers.bash
lib/history.bash lib/history.bash
lib/log.bash lib/log.bash
@ -155,7 +156,6 @@ themes/bobby-python
themes/brainy themes/brainy
themes/brunton themes/brunton
themes/candy themes/candy
themes/command_duration.theme.bash
themes/easy themes/easy
themes/essential themes/essential
themes/githelpers.theme.bash themes/githelpers.theme.bash

View File

@ -0,0 +1,56 @@
# shellcheck shell=bash
#
# Functions for measuring and reporting how long a command takes to run.
: "${COMMAND_DURATION_START_SECONDS:=${EPOCHREALTIME:-$SECONDS}}"
: "${COMMAND_DURATION_ICON:=🕘}"
: "${COMMAND_DURATION_MIN_SECONDS:=1}"
function _command_duration_pre_exec() {
COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}"
}
function _dynamic_clock_icon {
local -i clock_hand=$(((${1:-${SECONDS}} % 12) + 90))
printf -v 'COMMAND_DURATION_ICON' '%b' "\xf0\x9f\x95\x$clock_hand"
}
function _command_duration() {
[[ -n "${BASH_IT_COMMAND_DURATION:-}" ]] || return
local command_duration=0 command_start="${COMMAND_DURATION_START_SECONDS:-0}"
local -i minutes=0 seconds=0 deciseconds=0
local -i command_start_seconds="${command_start%.*}"
local -i command_start_deciseconds=$((10#${command_start##*.}))
local current_time="${EPOCHREALTIME:-$SECONDS}"
local -i current_time_seconds="${current_time%.*}"
local -i current_time_deciseconds="$((10#${current_time##*.}))"
if [[ "${command_start_seconds:-0}" -gt 0 ]]; then
# seconds
command_duration="$((current_time_seconds - command_start_seconds))"
if ((current_time_deciseconds >= command_start_deciseconds)); then
deciseconds="$((current_time_deciseconds - command_start_deciseconds))"
else
((command_duration -= 1))
deciseconds="$((10 - (command_start_deciseconds - current_time_deciseconds)))"
fi
else
command_duration=0
fi
if ((command_duration > 0)); then
minutes=$((command_duration / 60))
seconds=$((command_duration % 60))
fi
_dynamic_clock_icon "${command_duration}"
if ((minutes > 0)); then
printf "%s%s%dm %ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$minutes" "$seconds"
elif ((seconds >= COMMAND_DURATION_MIN_SECONDS)); then
printf "%s%s%d.%01ds" "${COMMAND_DURATION_ICON:-}" "${COMMAND_DURATION_COLOR:-}" "$seconds" "$deciseconds"
fi
}
_bash_it_library_finalize_hook+=("safe_append_preexec '_command_duration_pre_exec'")

View File

@ -2,15 +2,15 @@
cite about-plugin cite about-plugin
about-plugin 'Alert (BEL) when process ends after a threshold of seconds' about-plugin 'Alert (BEL) when process ends after a threshold of seconds'
precmd_return_notification() { function precmd_return_notification() {
export LAST_COMMAND_DURATION=$(($(date +%s) - ${LAST_COMMAND_TIME:=$(date +%s)})) local command_start="${COMMAND_DURATION_START_SECONDS:=0}"
[[ ${LAST_COMMAND_DURATION} -gt ${NOTIFY_IF_COMMAND_RETURNS_AFTER:-5} ]] && echo -e "\a" local current_time="${EPOCHREALTIME:-$SECONDS}"
export LAST_COMMAND_TIME= local -i command_duration="$((${current_time%.*} - ${command_start%.*}))"
if [[ "${command_duration}" -gt "${NOTIFY_IF_COMMAND_RETURNS_AFTER:-5}" ]]; then
printf '\a'
fi
return 0
} }
preexec_return_notification() { safe_append_prompt_command 'precmd_return_notification'
[[ -z "${LAST_COMMAND_TIME}" ]] && LAST_COMMAND_TIME=$(date +%s) safe_append_preexec '_command_duration_pre_exec'
}
precmd_functions+=(precmd_return_notification)
preexec_functions+=(preexec_return_notification)

View File

@ -3,46 +3,39 @@
load "${MAIN_BASH_IT_DIR?}/test/test_helper.bash" load "${MAIN_BASH_IT_DIR?}/test/test_helper.bash"
function local_setup_file() { function local_setup_file() {
setup_libs "preexec" #"command_duration" setup_libs "command_duration"
load "${BASH_IT?}/plugins/available/cmd-returned-notify.plugin.bash" load "${BASH_IT?}/plugins/available/cmd-returned-notify.plugin.bash"
} }
@test "plugins cmd-returned-notify: notify after elapsed time" { @test "plugins cmd-returned-notify: notify after elapsed time" {
export NOTIFY_IF_COMMAND_RETURNS_AFTER=0 export NOTIFY_IF_COMMAND_RETURNS_AFTER=0
export LAST_COMMAND_TIME=$(date +%s) export COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}"
sleep 1 sleep 1
run precmd_return_notification run precmd_return_notification
assert_success assert_success
assert_output $'\a' assert_output $'\a'
} }
@test "plugins cmd-returned-notify: do not notify before elapsed time" { @test "plugins cmd-returned-notify: do not notify before elapsed time" {
export NOTIFY_IF_COMMAND_RETURNS_AFTER=10 export NOTIFY_IF_COMMAND_RETURNS_AFTER=10
export LAST_COMMAND_TIME=$(date +%s) export COMMAND_DURATION_START_SECONDS="${EPOCHREALTIME:-$SECONDS}"
sleep 1 sleep 1
run precmd_return_notification run precmd_return_notification
assert_success assert_success
assert_output $'' assert_output $''
} }
@test "plugins cmd-returned-notify: preexec no output" { @test "lib command_duration: preexec no output" {
export LAST_COMMAND_TIME= export COMMAND_DURATION_START_SECONDS=
run preexec_return_notification run _command_duration_pre_exec
assert_success assert_success
assert_output "" assert_output ""
} }
@test "lib command_duration: preexec set COMMAND_DURATION_START_SECONDS" {
@test "plugins cmd-returned-notify: preexec no output env set" { export COMMAND_DURATION_START_SECONDS=
export LAST_COMMAND_TIME=$(date +%s) assert_equal "${COMMAND_DURATION_START_SECONDS}" ""
run preexec_return_notification NOW="${EPOCHREALTIME:-$SECONDS}"
assert_failure _command_duration_pre_exec
assert_output "" # We need to make sure to account for nanoseconds...
} assert_equal "${COMMAND_DURATION_START_SECONDS%.*}" "${NOW%.*}"
@test "plugins cmd-returned-notify: preexec set LAST_COMMAND_TIME" {
export LAST_COMMAND_TIME=
assert_equal "${LAST_COMMAND_TIME}" ""
NOW=$(date +%s)
preexec_return_notification
assert_equal "${LAST_COMMAND_TIME}" "${NOW}"
} }

View File

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

View File

@ -1,69 +0,0 @@
# shellcheck shell=bash
if [ -z "$BASH_IT_COMMAND_DURATION" ] || [ "$BASH_IT_COMMAND_DURATION" != true ]; then
_command_duration() {
echo -n
}
return
fi
# Define tmp dir and file
COMMAND_DURATION_TMPDIR="${TMPDIR:-/tmp}"
COMMAND_DURATION_FILE="${COMMAND_DURATION_FILE:-$COMMAND_DURATION_TMPDIR/bashit_theme_execution_$BASHPID}"
COMMAND_DURATION_ICON=${COMMAND_DURATION_ICON:-'  '}
COMMAND_DURATION_MIN_SECONDS=${COMMAND_DURATION_MIN_SECONDS:-'1'}
trap _command_duration_delete_temp_file EXIT HUP INT TERM
_command_duration_delete_temp_file() {
if [[ -f "$COMMAND_DURATION_FILE" ]]; then
rm -f "$COMMAND_DURATION_FILE"
fi
}
_command_duration_pre_exec() {
date +%s.%1N > "$COMMAND_DURATION_FILE"
}
_command_duration() {
local command_duration command_start current_time
local minutes seconds deciseconds
local command_start_sseconds current_time_seconds command_start_deciseconds current_time_deciseconds
current_time=$(date +%s.%1N)
if [[ -f "$COMMAND_DURATION_FILE" ]]; then
command_start=$(< "$COMMAND_DURATION_FILE")
command_start_sseconds=${command_start%.*}
current_time_seconds=${current_time%.*}
command_start_deciseconds=$((10#${command_start#*.}))
current_time_deciseconds=$((10#${current_time#*.}))
# seconds
command_duration=$((current_time_seconds - command_start_sseconds))
if ((current_time_deciseconds >= command_start_deciseconds)); then
deciseconds=$(((current_time_deciseconds - command_start_deciseconds)))
else
((command_duration -= 1))
deciseconds=$((10 - ((command_start_deciseconds - current_time_deciseconds))))
fi
command rm "$COMMAND_DURATION_FILE"
else
command_duration=0
fi
if ((command_duration > 0)); then
minutes=$((command_duration / 60))
seconds=$((command_duration % 60))
fi
if ((minutes > 0)); then
printf "%s%s%dm %ds" "$COMMAND_DURATION_ICON" "$COMMAND_DURATION_COLOR" "$minutes" "$seconds"
elif ((seconds >= COMMAND_DURATION_MIN_SECONDS)); then
printf "%s%s%d.%01ds" "$COMMAND_DURATION_ICON" "$COMMAND_DURATION_COLOR" "$seconds" "$deciseconds"
fi
}
preexec_functions+=(_command_duration_pre_exec)