Optimized git
Some checks failed
git-sync-with-mirror / git-sync (push) Failing after 4s
CI Pipeline / shasums (push) Successful in 16s
CI Pipeline / build (push) Successful in 41s
CI Pipeline / tests (push) Failing after 29s
CI Pipeline / performance (push) Has been skipped

This commit is contained in:
2025-11-03 16:17:09 -05:00
parent 6185230dfd
commit 900cb47aa0
7 changed files with 841 additions and 347 deletions

View File

@@ -1,12 +1,17 @@
name: CI Pipeline name: CI Pipeline
on: [push, pull_request] on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
workflow_dispatch:
jobs: jobs:
shasums: shasums:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Run shasums script - name: Run shasums script
run: | run: |
cp -rv ./hyperterm/ "$HOME/.hyperterm/" cp -rv ./hyperterm/ "$HOME/.hyperterm/"
@@ -79,6 +84,11 @@ jobs:
shellcheck hyperterm/tools/sysinfo.sh shellcheck hyperterm/tools/sysinfo.sh
shellcheck hyperterm/tools/virtualenv.sh shellcheck hyperterm/tools/virtualenv.sh
- name: Run shellcheck on test scripts
run: |
shellcheck tests/test_prompt.sh
shellcheck tests/quick_test.sh
- name: Run shellcheck on install script - name: Run shellcheck on install script
run: shellcheck install.sh run: shellcheck install.sh
@@ -90,3 +100,138 @@ jobs:
- name: Run uninstall script - name: Run uninstall script
run: bash -x uninstall.sh -s run: bash -x uninstall.sh -s
tests:
runs-on: ubuntu-latest
needs: build
env:
CI: true
steps:
- uses: actions/checkout@v4
- name: Set up git configuration for tests
run: |
git config --global user.name "CI Test User"
git config --global user.email "ci-test@example.com"
- name: Install dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y git bash
- name: Run quick prompt test
run: |
echo "INFO: Running quick prompt test"
bash tests/quick_test.sh
- name: Run comprehensive prompt test
run: |
echo "INFO: Running comprehensive prompt test"
# Run in non-interactive mode for CI
bash tests/test_prompt.sh --non-interactive
- name: Test prompt performance
run: |
echo "INFO: Testing prompt performance in git repository"
# Create test changes to verify git status detection
echo "test change" >> README.md
echo "untracked file" > test_file.txt
# Source the hyperterm functions
source hyperterm/core/colors.sh
source hyperterm/core/git.sh
# Test prompt generation
echo "Testing prompt generation..."
__prompt_git
echo ""
echo "SUCCESS: Prompt generation completed"
- name: Validate optimizations
run: |
echo "INFO: Validating optimizations"
# Check that git_optimized.sh doesn't exist (should be integrated into git.sh)
if [[ -f "hyperterm/core/git_optimized.sh" ]]; then
echo "ERROR: git_optimized.sh should not exist (should be integrated)"
exit 1
fi
# Check that git.sh exists and is optimized
if [[ ! -f "hyperterm/core/git.sh" ]]; then
echo "ERROR: git.sh not found"
exit 1
fi
# Verify the optimized functions exist
source hyperterm/core/git.sh
if ! command -v _get_git_status_fast >/dev/null 2>&1; then
echo "ERROR: Optimized function _get_git_status_fast not found"
exit 1
fi
echo "SUCCESS: Optimizations validated"
performance:
runs-on: ubuntu-latest
needs: tests
steps:
- uses: actions/checkout@v4
- name: Set up git configuration
run: |
git config --global user.name "Performance Test"
git config --global user.email "perf-test@example.com"
- name: Performance benchmark
run: |
echo "INFO: Running performance benchmark"
# Create a test repository with various states
mkdir -p /tmp/perf_test
cd /tmp/perf_test
git init
git config user.name "Test User"
git config user.email "test@example.com"
# Create initial commit
echo "# Performance Test" > README.md
git add README.md
git commit -m "Initial commit"
# Create various git states
echo "modified content" >> README.md
echo "untracked file" > untracked.txt
echo "staged file" > staged.txt
git add staged.txt
# Source hyperterm functions
cd "$GITEA_WORKSPACE"
source hyperterm/core/colors.sh
source hyperterm/core/git.sh
# Run performance test
cd /tmp/perf_test
echo "Running 50 iterations of prompt generation..."
start_time=$(date +%s%N)
for i in {1..50}; do
__prompt_git >/dev/null 2>&1
done
end_time=$(date +%s%N)
duration=$(( (end_time - start_time) / 1000000 ))
avg_duration=$(( duration / 50 ))
echo "Performance Results:"
echo " Total time: ${duration}ms"
echo " Average per call: ${avg_duration}ms"
echo " Iterations: 50"
# Performance validation
if [[ $avg_duration -lt 100 ]]; then
echo "SUCCESS: Performance is good (${avg_duration}ms < 100ms)"
else
echo "WARNING: Performance may need optimization (${avg_duration}ms >= 100ms)"
# Don't fail the build, just warn
fi

View File

@@ -10,9 +10,10 @@ function install_package() {
msg "El paquete $pkg no se encontró. Procediendo a instalar..." \ msg "El paquete $pkg no se encontró. Procediendo a instalar..." \
"$pkg not found. Attempting to install..." "$pkg not found. Attempting to install..."
local INSTALLER="" local INSTALLER
local SUDO="" local SUDO
local USER_CMD=$(command -v sudo || command -v doas) local USER_CMD
USER_CMD=$(command -v sudo || command -v doas)=$(command -v sudo || command -v doas)
[[ "$(id -u)" -ne 0 ]] && SUDO="$USER_CMD" [[ "$(id -u)" -ne 0 ]] && SUDO="$USER_CMD"

View File

@@ -1,373 +1,157 @@
#!/bin/bash #!/bin/bash
# Set up symbols # Cache symbols (generate once)
function _symbols() { declare -A GIT_SYMBOLS
_init_git_symbols() {
[[ -n "${GIT_SYMBOLS[clean]:-}" ]] && return # Already initialized
# Import colors
_colors_bash "$@" _colors_bash "$@"
__ps="$(printf '%b%b%b' "${BOLD}${LEMON}" "\x7C" "${RESET}")" # | GIT_SYMBOLS[pipe]="\x7C"
__ss="$(printf '%b%b' "${BOLD}${CYAN}" "\xE2\x9C\x94")" # ✔ GIT_SYMBOLS[clean]="✔"
__dss="$(printf '%b%b' "${BOLD}${RED}" "\x2A")" # GIT_SYMBOLS[dirty]=""
__ahs="$(printf '%b%b' "${BOLD}${CYAN}" "\xE2\x86\x91")" # ↑ GIT_SYMBOLS[ahead]="↑"
__bhs="$(printf '%b%b' "${BOLD}${RED}" "\xE2\x86\x93")" # ↓ GIT_SYMBOLS[behind]="↓"
__duphs="$(printf '%b%b' "${BOLD}${YELLOW}" "\xE2\x96\x82" )" # ▲ GIT_SYMBOLS[diverged]="⇅"
__duplls="$(printf '%b%b' "${BOLD}${RED}" "\xE2\x96\xBC")" # ▼ GIT_SYMBOLS[untracked]="?"
__duus="$(printf '%b%b%b' "${BOLD}${CYAN}" "\x64" "\x75")" # du GIT_SYMBOLS[added]="+"
__upulls="$(printf '%b%b' "${BOLD}${GREEN}" "\xE2\x96\xBD")" # ▽ GIT_SYMBOLS[deleted]="D"
__sts="$(printf '%b%b%b' "${BOLD}${CYAN}" "\xE2\x86\x92" "\x4D")" # →M GIT_SYMBOLS[modified]="M"
__usts="$(printf '%b%b%b' "${BOLD}${RED}" "\xE2\x86\x90" "\x4D")" # ←M GIT_SYMBOLS[renamed]="R"
__stusts="$(printf '%b%b%b%b' "${BOLD}${RED}" "\x3C" "\x4D" "\x3E")" # <M> GIT_SYMBOLS[staged]="●"
__uts="$(printf '%b%b' "${BOLD}${RED}" "\x3F")" # ?
__nfs="$(printf '%b%b' "${BOLD}${CYAN}" "\x2B")" # +
__dfs="$(printf '%b%b' "${BOLD}${RED}" "\x44")" # D
__rns="$(printf '%b%b%b' "${BOLD}${RED}" "\xE2\x8E\x87" "\x20")" # ⎇
} }
function _get_git_branch() { _get_git_branch() {
# On branches, this will return the branch name git symbolic-ref --short HEAD 2>/dev/null || echo "(no branch)"
# On non-branches, (no branch) }
ref="$(git symbolic-ref HEAD 2> /dev/null | sed -e 's/refs\/heads\///')"
if [[ -n $ref ]]; then _get_git_progress() {
printf '%s' "$ref" local git_dir
git_dir="$(git rev-parse --git-dir 2>/dev/null)" || return 0
[[ -f "$git_dir/MERGE_HEAD" ]] && echo " [merge]" && return 0
[[ -d "$git_dir/rebase-apply" ]] && echo " [rebase]" && return 0
[[ -d "$git_dir/rebase-merge" ]] && echo " [rebase]" && return 0
[[ -f "$git_dir/CHERRY_PICK_HEAD" ]] && echo " [cherry-pick]" && return 0
[[ -f "$git_dir/BISECT_LOG" ]] && echo " [bisect]" && return 0
[[ -f "$git_dir/REVERT_HEAD" ]] && echo " [revert]" && return 0
return 0
}
# Single git status call - parse everything at once
_parse_git_status() {
local status_output ahead_behind
# Single git status call
status_output="$(git status --porcelain=v1 2>/dev/null)"
# Get ahead/behind counts in one call
if git rev-parse --abbrev-ref "@{upstream}" >/dev/null 2>&1; then
ahead_behind="$(git rev-list --left-right --count "@{upstream}"...HEAD 2>/dev/null)"
GIT_STATUS[behind]="${ahead_behind% *}"
GIT_STATUS[ahead]="${ahead_behind#* }"
else else
printf "(no branch)" GIT_STATUS[behind]=0
GIT_STATUS[ahead]=0
fi fi
}
function _get_git_progress() { # Parse status output
# Detect in-progress actions (e.g. merge, rebase) GIT_STATUS[dirty]=0
# https://github.com/git/git/blob/v1.9-rc2/wt-status.c#L1199-L1241 GIT_STATUS[staged]=0
git_dir="$(git rev-parse --git-dir)" GIT_STATUS[untracked]=0
GIT_STATUS[modified]=0
GIT_STATUS[added]=0
GIT_STATUS[deleted]=0
GIT_STATUS[renamed]=0
# git merge [[ -z "$status_output" ]] && return
if [[ -f "$git_dir/MERGE_HEAD" ]]; then
printf " [merge]"
elif [[ -d "$git_dir/rebase-apply" ]]; then
# git am
if [[ -f "$git_dir/rebase-apply/applying" ]]; then
printf " [am]"
# git rebase
else
printf " [rebase]"
fi
elif [[ -d "$git_dir/rebase-merge" ]]; then
# git rebase --interactive/--merge
printf " [rebase]"
elif [[ -f "$git_dir/CHERRY_PICK_HEAD" ]]; then
# git cherry-pick
printf " [cherry-pick]"
fi
if [[ -f "$git_dir/BISECT_LOG" ]]; then
# git bisect
printf " [bisect]"
fi
if [[ -f "$git_dir/REVERT_HEAD" ]]; then
# git revert --no-commit
printf " [revert]"
fi
}
_prompt_is_branch1_behind_branch2 () { local line
# $ git log origin/master..master -1 while IFS= read -r line; do
# commit 4a633f715caf26f6e9495198f89bba20f3402a32 [[ -z "$line" ]] && continue
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# Find the first log (if any) that is in branch1 but not branch2 local index_status="${line:0:1}"
first_log="$(git log "$1..$2" -1 2> /dev/null)" local work_status="${line:1:1}"
# Exit with 0 if there is a first log, 1 if there is not # Count changes
[[ -n "$first_log" ]] ((GIT_STATUS[dirty]++))
}
_prompt_branch_exists () { # Index (staged) changes
# List remote branches | # Find our branch and exit with 0 or 1 if found/not found case "$index_status" in
git branch --remote 2> /dev/null | grep --quiet "$1" [MADRC]) ((GIT_STATUS[staged]++)) ;;
}
_prompt_parse_git_ahead () {
# Grab the local and remote branch
branch="$(_get_git_branch)"
remote="$(git config --get "branch.${branch}.remote" || echo -n "origin")"
remote_branch="$remote/$branch"
# $ git log origin/master..master
# commit 4a633f715caf26f6e9495198f89bba20f3402a32
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# If the remote branch is behind the local branch
# or it has not been merged into origin (remote branch doesn't exist)
if (_prompt_is_branch1_behind_branch2 "$remote_branch" "$branch" || ! _prompt_branch_exists "$remote_branch"); then echo -n "0"; else echo -n "1"; fi
}
_prompt_parse_git_behind() {
# Grab the branch
branch="$(_get_git_branch)"
remote="$(git config --get "branch.${branch}.remote" || echo -n "origin")"
remote_branch="$remote/$branch"
# $ git log master..origin/master
# commit 4a633f715caf26f6e9495198f89bba20f3402a32
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# If the local branch is behind the remote branch
if _prompt_is_branch1_behind_branch2 "$branch" "$remote_branch"; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_dirty() {
# If the git status has *any* changes (e.g. dirty), printf our character
if [[ -n "$(git status --porcelain 2> /dev/null)" ]]; then echo -n '0'; else echo -n '1'; fi
}
# start counter on git
function _git_dirty_count() {
local _dirty_status
local _git_status
_dirty_status="$(_prompt_parse_git_dirty)"
_git_status="$(git status --porcelain 2> /dev/null)"
if [[ "$_dirty_status" == 0 ]]; then
local change_count
change_count="$(echo "$_git_status" | wc -l | tr -d '[:space:]')"
case $change_count in
1) printf '%b\u2022%s' "${BOLD}${GREY}" "$change_count";;
2) printf '%b\u2236%s' "${BOLD}${GREY}" "$change_count";;
3) printf '%b\u2026%s' "${BOLD}${GREY}" "$change_count";;
*) printf '%b\u00BB%s' "${BOLD}${GREY}" "$change_count";;
esac
fi
}
function _git_behind_count() {
local __behind_count
if git rev-parse --symbolic-full-name --abbrev-ref "@{upstream}" > /dev/null 2>&1; then
__behind_count="$(git rev-list --left-right --count "@{upstream}"...HEAD | cut -f1 2> /dev/null)"
case $__behind_count in
0) echo -n '';;
*) echo -n "$__behind_count";;
esac
fi
}
function _git_ahead_count() {
local __ahead_count
if git rev-parse --symbolic-full-name --abbrev-ref "@{upstream}" > /dev/null 2>&1; then
__ahead_count="$(git rev-list --left-right --count "@{upstream}"...HEAD | cut -f2 2> /dev/null)"
case $__ahead_count in
0) echo -n '';;
*) echo -n "$__ahead_count";;
esac
fi
}
# ends counter on git
function _prompt_parse_git_untracked() {
local untracked
local evaltask
untracked="$(git status 2>&1 | tee)"
grep -E 'Untracked files:' <<<"$untracked" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_newfile() {
local newfile
local evaltask
newfile="$(git status 2>&1 | tee)"
grep -E 'new file:' <<<"$newfile" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_deleted_file() {
local deleted_file
local evaltask
deleted_file="$(git status 2>&1 | tee)"
grep -E 'deleted:' <<<"$deleted_file" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_renamed() {
local renamed
local evaltask
renamed="$(git status 2>&1 | tee)"
grep -E 'renamed:' <<<"$renamed" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_unstage() {
local unstage
local evaltask
unstage="$(git status 2>&1 | tee)"
grep -E 'not staged' <<<"$unstage" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_stage() {
local stage
local evaltask
stage="$(git status -s 2>&1 | tee)"
grep -E 'M' <<<"$stage" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_is_on_git() {
git rev-parse 2> /dev/null
}
function _prompt_get_git_status() {
_symbols "$@"
# Grab the git dirty and git behind
count_dirty="$(_git_dirty_count)"
count_behind="$(_git_behind_count)"
count_ahead="$(_git_ahead_count)"
dirty_branch="$(_prompt_parse_git_dirty)"
branch_ahead="$(_prompt_parse_git_ahead)"
branch_behind="$(_prompt_parse_git_behind)"
branch_stage="$(_prompt_parse_git_stage)"
branch_unstage="$(_prompt_parse_git_unstage)"
branch_untracked="$(_prompt_parse_git_untracked)"
branch_newfile="$(_prompt_parse_git_newfile)"
branch_deleted_file="$(_prompt_parse_git_deleted_file)"
branch_renamed="$(_prompt_parse_git_renamed)"
# Iterate through all the cases and if it matches, then printf
case ${dirty_branch}${branch_ahead}${branch_behind}${branch_stage}${branch_unstage}${branch_newfile}${branch_untracked}${branch_deleted_file}${branch_renamed} in
111111111) printf '%s' "${__ss}";;
100111111) printf '%s' "${__ps}${__ahs}$count_ahead${__ps}${__bhs}$count_behind";;
110111111) printf '%s%s' "${__upulls}" "$count_behind";;
101111111) printf '%s%s' "${__ahs}" "$count_ahead";;
111001111) printf '%s%s' "${__ps}${__duus}${__stusts}" "$count_dirty";;
011111111) printf '%s%s' "${__dss}" "$count_dirty";;
010111111) printf '%s%s%s' "${__duplls}" "$count_behind" "$count_dirty";;
001111111) printf '%s%s%s' "${__duphs}" "$count_ahead" "$count_dirty";;
000111111) printf '%s%s%s' "${__duus}" "$count_behind-$count_ahead" "$count_dirty";;
000111011) printf '%s%s' "${__ps}${__ahs}$count_ahead${__ps}${__bhs}$count_behind${__ps}${__uts}${__ps}" "$count_dirty" ;;
010111011) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__uts}" "${__ps}$count_dirty";;
010110111) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}" "${__ps}$count_dirty";;
010110011) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__uts}" "${__ps}$count_dirty";;
010100001) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__usts}${__uts}${__dfs}" "${__ps}$count_dirty";;
010000001) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__stusts}${__uts}${__dfs}" "${__ps}$count_dirty";;
010010100) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__dfs}${__rns}" "${__ps}${__sts}${__ps}$count_dirty";;
010010000) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__dfs}${__rns}${__ps}${__uts}" "${__ps}${__sts}${__ps}$count_dirty";;
011001111) printf '%s%s' "${__ps}${__dss}${__stusts}" "$count_dirty";;
011000111) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}" "$count_dirty";;
011001101) printf '%s%s' "${__ps}${__dss}${__stusts}${__dfs}" "$count_dirty";;
011001011) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}" "$count_dirty" ;;
011001001) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__dfs}" "$count_dirty";;
011000101) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__dfs}" "$count_dirty";;
011000001) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
011011111) printf '%s%s' "${__ps}${__dss}${__sts}" "$count_dirty";;
011010111) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}" "$count_dirty";;
011010011) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}" "$count_dirty";;
011010101) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__dfs}" "$count_dirty" ;;
011010001) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
011011011) printf '%s%s' "${__ps}${__dss}${__sts}${__uts}" "$count_dirty";;
011011101) printf '%s%s' "${__ps}${__dss}${__sts}${__dfs}" "$count_dirty";;
011110111) printf '%s%s' "${__ps}${__dss}${__nfs}" "$count_dirty";;
011110011) printf '%s%s' "${__ps}${__dss}${__nfs}${__uts}" "$count_dirty";;
011111011) printf '%s%s' "${__ps}${__dss}${__uts}" "$count_dirty";;
011101001) printf '%s%s' "${__ps}${__dss}${__usts}${__uts}${__dfs}" "$count_dirty";;
011111110) printf '%s%s' "${__ps}${__dss}${__rns}" "$count_dirty";;
011110110) printf '%s%s' "${__ps}${__dss}${__nfs}${__rns}" "$count_dirty";;
011110010) printf '%s%s' "${__ps}${__dss}${__nfs}${__uts}${__rns}" "$count_dirty";;
011011110) printf '%s%s' "${__ps}${__dss}${__sts}${__rns}" "$count_dirty";;
011010100) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__dfs}${__rns}" "$count_dirty" ;;
011010000) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
011001010) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__rns}" "$count_dirty";;
011001000) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__dfs}${__rns}" "$count_dirty";;
011000011) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}" "$count_dirty";;
011000110) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__rns}" "$count_dirty";;
011000010) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__rns}" "$count_dirty";;
011000000) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
011000100) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__dfs}${__rns}" "$count_dirty";;
011010010) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__rns}" "$count_dirty";;
011011010) printf '%s%s' "${__ps}${__dss}${__sts}${__uts}${__rns}" "$count_dirty";;
011111010) printf '%s%s' "${__ps}${__dss}${__uts}${__rns}" "$count_dirty";;
001001111) printf '%s%s' "${__ps}${__duus}${__stusts}" "$count_dirty";;
001000111) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}" "$count_dirty";;
001001101) printf '%s%s' "${__ps}${__duus}${__stusts}${__dfs}" "$count_dirty";;
001001011) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}" "$count_dirty";;
001001001) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__dfs}" "$count_dirty";;
001000101) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__dfs}" "$count_dirty";;
001000001) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
001011111) printf '%s%s' "${__ps}${__duus}${__sts}" "$count_dirty";;
001010111) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}" "$count_dirty" ;;
001010011) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}" "$count_dirty";;
001010101) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__dfs}" "$count_dirty" ;;
001010001) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
001011011) printf '%s%s' "${__ps}${__duus}${__sts}${__uts}" "$count_dirty";;
001011101) printf '%s%s' "${__ps}${__duus}${__sts}${__dfs}" "$count_dirty";;
001110111) printf '%s%s' "${__ps}${__duus}${__nfs}" "$count_dirty";;
001110011) printf '%s%s' "${__ps}${__duus}${__nfs}${__uts}" "$count_dirty";;
001111011) printf '%s%s' "${__ps}${__duus}${__uts}" "$count_dirty";;
001101001) printf '%s%s' "${__ps}${__duus}${__usts}${__uts}${__dfs}" "$count_dirty";;
001101101) printf '%s%s' "${__ps}${__duus}${__usts}${__dfs}" "$count_dirty";;
001111110) printf '%s%s' "${__ps}${__duus}${__rns}" "$count_dirty";;
001110110) printf '%s%s' "${__ps}${__duus}${__nfs}${__rns}" "$count_dirty";;
001110010) printf '%s%s' "${__ps}${__duus}${__nfs}${__uts}${__rns}" "$count_dirty";;
001011110) printf '%s%s' "${__ps}${__duus}${__sts}${__rns}" "$count_dirty";;
001010100) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__dfs}${__rns}" "$count_dirty" ;;
001010000) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
001001010) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__rns}" "$count_dirty";;
001001000) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__dfs}${__rns}" "$count_dirty";;
001000011) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}" "$count_dirty";;
001000110) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__rns}" "$count_dirty";;
001000010) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__rns}" "$count_dirty";;
001000000) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
001000100) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__dfs}${__rns}" "$count_dirty";;
001010010) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__rns}" "$count_dirty";;
001011010) printf '%s%s' "${__ps}${__duus}${__sts}${__uts}${__rns}" "$count_dirty";;
001111010) printf '%s%s' "${__ps}${__duus}${__uts}${__rns}" "$count_dirty";;
*) echo -n "${__uts}" ;;
esac esac
# # Working tree changes
# dirty + unpushed = du stage + unstage = <M> case "$work_status" in
# ↑ ↓ →M ←M + ? D ⎇ M) ((GIT_STATUS[modified]++)) ;;
# echo "${dirty_branch}${branch_ahead}${branch_behind}${branch_stage}${branch_unstage}${branch_newfile}${branch_untracked}${branch_deleted_file}${branch_renamed}" D) ((GIT_STATUS[deleted]++)) ;;
# 0 1 0 1 1 1 0 1 1 esac
# Special cases
case "$line" in
"??*") ((GIT_STATUS[untracked]++)) ;;
"A "*) ((GIT_STATUS[added]++)) ;;
"R "*) ((GIT_STATUS[renamed]++)) ;;
esac
done <<< "$status_output"
} }
_prompt_get_git_info() { # Fast git status generation
# Import colors _get_git_status_fast() {
_init_git_symbols "$@"
declare -A GIT_STATUS
_parse_git_status
local output=""
# Clean repo
if [[ ${GIT_STATUS[dirty]} -eq 0 ]]; then
echo -n "${BOLD}${CYAN}${GIT_SYMBOLS[clean]}${RESET}"
return
fi
# Dirty count
output="${BOLD}${RED}${GIT_SYMBOLS[dirty]}${GIT_STATUS[dirty]}${RESET}"
# Ahead/behind
if [[ ${GIT_STATUS[ahead]} -gt 0 && ${GIT_STATUS[behind]} -gt 0 ]]; then
output+="${BOLD}${YELLOW}${GIT_SYMBOLS[diverged]}${GIT_STATUS[ahead]}/${GIT_STATUS[behind]}${RESET}"
elif [[ ${GIT_STATUS[ahead]} -gt 0 ]]; then
output+="${BOLD}${GREEN}${GIT_SYMBOLS[ahead]}${GIT_STATUS[ahead]}${RESET}"
elif [[ ${GIT_STATUS[behind]} -gt 0 ]]; then
output+="${BOLD}${RED}${GIT_SYMBOLS[behind]}${GIT_STATUS[behind]}${RESET}"
fi
# File status indicators
[[ ${GIT_STATUS[staged]} -gt 0 ]] && output+="${BOLD}${GREEN}${GIT_SYMBOLS[staged]}${RESET}"
[[ ${GIT_STATUS[untracked]} -gt 0 ]] && output+="${BOLD}${RED}${GIT_SYMBOLS[untracked]}${RESET}"
[[ ${GIT_STATUS[added]} -gt 0 ]] && output+="${BOLD}${GREEN}${GIT_SYMBOLS[added]}${RESET}"
[[ ${GIT_STATUS[deleted]} -gt 0 ]] && output+="${BOLD}${RED}${GIT_SYMBOLS[deleted]}${RESET}"
[[ ${GIT_STATUS[renamed]} -gt 0 ]] && output+="${BOLD}${BLUE}${GIT_SYMBOLS[renamed]}${RESET}"
echo -n "$output"
}
_prompt_get_git_info_fast() {
_colors_bash "$@" _colors_bash "$@"
# Grab branch local branch
branch=$(_get_git_branch) branch="$(_get_git_branch)"
# If there are any branches if [[ -n "$branch" ]]; then
if [[ -n $branch ]]; then local status
# Add on the git status status="$(_get_git_status_fast "$@")"
output=$(_prompt_get_git_status "$@") printf '%b%s%s%b' "${BOLD}${YELLOW}" "git:($branch" "$status" "${BOLD}${YELLOW})"
# Printf our output
printf '%b%s%b' "${BOLD}${LEMON}" "git:($branch$output" "${BOLD}${LEMON})"
fi fi
} }
__prompt_git() { __prompt_git() {
if _prompt_is_on_git &> /dev/null; then if git rev-parse --git-dir >/dev/null 2>&1; then
echo -n "${BOLD}${WHITE} on $RESET" && \ echo -n "${BOLD}${WHITE} on ${RESET}"
echo -n "$(_prompt_get_git_info "$@")" && \ _prompt_get_git_info_fast "$@"
echo -n "${BOLD}${RED}$(_get_git_progress)" && \ echo -n "${BOLD}${RED}$(_get_git_progress)${RESET}"
echo -n "$RESET"
fi fi
} }

View File

@@ -2,9 +2,9 @@ cdfe049ec07f02a1893cda29c13085d06709e09a30b0c2e1111585278315f03139d61080c883cb3f
f363606f41a2c2c8f1cc44110c64fe23b1c8feb4c788ee006222db0f5c7a3adeac2b0948626b313adc985e9b8d303a0b9ce1c5ba42746810accb54efddcd4b84 ./hyperterm.sh f363606f41a2c2c8f1cc44110c64fe23b1c8feb4c788ee006222db0f5c7a3adeac2b0948626b313adc985e9b8d303a0b9ce1c5ba42746810accb54efddcd4b84 ./hyperterm.sh
b760a908a3f6222b974abc1f7464bde0f5427f120f1e7ef1c6d97ae61769e552ef3b5cb88e193e955da72a592f07eadb812413dd50a691cd3dbb33e3da581ea6 ./core/update.sh b760a908a3f6222b974abc1f7464bde0f5427f120f1e7ef1c6d97ae61769e552ef3b5cb88e193e955da72a592f07eadb812413dd50a691cd3dbb33e3da581ea6 ./core/update.sh
1cfba599047d84a17ff92b695ebf527a505a30acc9ec21a2b9f410a7ea6dde4b23b5cf62e557d82f2fe9a8980649942424b879ca53baae4d4cb3057681baa7b6 ./core/colors.sh 1cfba599047d84a17ff92b695ebf527a505a30acc9ec21a2b9f410a7ea6dde4b23b5cf62e557d82f2fe9a8980649942424b879ca53baae4d4cb3057681baa7b6 ./core/colors.sh
2036a79215a5434e31f3406bea3f2ffa7e94ffef86c2d1ceb8865db29f19fe7f342f9cab93288f57c75daed36ef146f85d15f8d633931a27d55c3983f55ef15b ./core/git.sh e3bacd715a327802c18de9b3c9f958f704eec4055295433403df284130e23f956f330bdf737c524bec3a89ef67a44ff0ab5dec40ffad5363aced3396bff54283 ./core/git.sh
f3e00b2aa8ab9f3ab44570adaa2520408ed66fd00f551654d60b64a4be3546ec781b7efa39bcd774937e654b6ffb4c7af3f21eeb36caf9c01f82f85cf28e2b4d ./core/languages.sh f3e00b2aa8ab9f3ab44570adaa2520408ed66fd00f551654d60b64a4be3546ec781b7efa39bcd774937e654b6ffb4c7af3f21eeb36caf9c01f82f85cf28e2b4d ./core/languages.sh
fdc570118a65a2b00571fd374be1aa983d41e9722bee6e604e2b00fcd2e1931df4dfd8951f15a2402dfcb3cbc76a5fe8d9d564a83fec73595dcaae2e38ac338a ./core/autodep.sh b205de01644af11ef1dc96230e4bf12087482e26b7c0472fb6a153bf94662e4dfc01b2da0c3ca0da4af93bce05faf0e33be5422fbee85e6b69ca1cccbe194cff ./core/autodep.sh
7447d3e167ab207d3ef4218e201a06bf5a3fc23281639f16f7f405f1d66b73923845d450fdb0a94672757866a9da0324f728564a1b61b2ed1678fe576eb565cf ./core/autocomplete.sh 7447d3e167ab207d3ef4218e201a06bf5a3fc23281639f16f7f405f1d66b73923845d450fdb0a94672757866a9da0324f728564a1b61b2ed1678fe576eb565cf ./core/autocomplete.sh
99f9e937e39495f60495bc89f055f29e1bee25911c9bea5c8b2a7c6a5bdc417502f17da8cb9e63ea957eea9337c6fe1c63c208a3ff3ed33ef2ca8c1dbe328599 ./core/status.sh 99f9e937e39495f60495bc89f055f29e1bee25911c9bea5c8b2a7c6a5bdc417502f17da8cb9e63ea957eea9337c6fe1c63c208a3ff3ed33ef2ca8c1dbe328599 ./core/status.sh
65f850342f43bdfe68b2b0339a051a795c6640b4bd4f7c6b6b979ca214607f9a87d9cfdc6955785c5ca087d09294781ee8cb3a62dc0160cd8a105ff65cc82465 ./themes/minterm.sh 65f850342f43bdfe68b2b0339a051a795c6640b4bd4f7c6b6b979ca214607f9a87d9cfdc6955785c5ca087d09294781ee8cb3a62dc0160cd8a105ff65cc82465 ./themes/minterm.sh

84
tests/README.md Normal file
View File

@@ -0,0 +1,84 @@
# HyperTerm Tests
Test suite for HyperTerm prompt functionality and performance.
## Test Files
### test_prompt.sh
Comprehensive test suite with full functionality testing.
**Features:**
- Individual function testing
- Performance benchmarking
- Git state testing
- Interactive test mode (skipped in CI)
- Non-interactive mode for CI/automation
**Usage:**
```bash
cd tests
bash test_prompt.sh # Interactive mode
bash test_prompt.sh --non-interactive # Non-interactive mode (for CI)
```
### quick_test.sh
Fast validation test for immediate feedback.
**Features:**
- Quick function validation
- Basic performance check
- Works in current directory or creates temp repo
**Usage:**
```bash
cd tests
bash quick_test.sh
```
## Test Environment
Tests create isolated environments to avoid affecting your working directory:
- Temporary git repositories in `/tmp/`
- Various git states (clean, dirty, staged, untracked)
- Automatic cleanup on exit
## Performance Testing
Both test scripts include performance measurements:
- Multiple iterations for accurate timing
- Average execution time per prompt call
- Performance classification (Excellent < 10ms, Good < 50ms)
## Git States Tested
- Clean repository
- Modified files
- Untracked files
- Staged files
- Mixed states
- Ahead/behind tracking
## Requirements
- Git installed and available in PATH
- Bash 4.0 or later
- HyperTerm core files in `../hyperterm/core/`
## Logging
All tests use structured logging:
- `[INFO]` - General information
- `[SUCCESS]` - Successful operations
- `[WARN]` - Warnings
- `[ERROR]` - Errors
## Interactive Mode
The full test suite includes an interactive mode with commands:
- `status` - Show git status
- `prompt` - Show full prompt
- `perf` - Run performance test
- `states` - Test different git states
- `modify` - Create test modifications
- `clean` - Clean working directory
- `exit` - Exit interactive mode

176
tests/quick_test.sh Normal file
View File

@@ -0,0 +1,176 @@
#!/bin/bash
# Quick Prompt Test - Fast validation
# Simple test for immediate feedback
# shellcheck disable=SC1090,SC2034,SC2155
set -e
# Logging
log_info() { echo "[INFO] $*"; }
log_error() { echo "[ERROR] $*"; }
log_success() { echo "[SUCCESS] $*"; }
# Configuration
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Basic colors fallback
setup_colors() {
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
CYAN='\033[36m'
WHITE='\033[37m'
GREY='\033[90m'
}
# Load functions
load_functions() {
log_info "Loading HyperTerm functions"
# Load colors if available
local colors_file="$PROJECT_ROOT/hyperterm/core/colors.sh"
if [[ -f "$colors_file" ]]; then
source "$colors_file"
else
setup_colors
fi
# Load git functions
local git_file="$PROJECT_ROOT/hyperterm/core/git.sh"
if [[ -f "$git_file" ]]; then
source "$git_file"
log_success "Git functions loaded"
return 0
else
log_error "Git functions not found"
return 1
fi
}
# Test in current directory
test_current_directory() {
if git rev-parse --git-dir >/dev/null 2>&1; then
log_success "Current directory is a git repository"
echo "Current git state:"
echo -n " Branch: "
_get_git_branch
echo ""
echo -n " Status: "
if command -v _get_git_status_fast >/dev/null 2>&1; then
_get_git_status_fast
else
_prompt_get_git_status
fi
echo ""
echo -n " Full prompt: "
__prompt_git
echo ""
return 0
else
log_info "Current directory is not a git repository"
return 1
fi
}
# Create temporary test
test_with_temp_repo() {
log_info "Creating temporary git repository for testing"
local temp_dir="/tmp/quick_test_$$"
mkdir -p "$temp_dir"
(
cd "$temp_dir"
git init --quiet
git config user.name "Test User"
git config user.email "test@example.com"
echo "# Quick Test" > README.md
echo "test content" > file.txt
git add README.md
git commit -m "Initial commit" --quiet
# Create changes
echo "modified" >> file.txt
echo "untracked" > new.txt
log_success "Temporary repository created with changes"
echo "Test results:"
echo -n " Branch: "
_get_git_branch
echo ""
echo -n " Status: "
if command -v _get_git_status_fast >/dev/null 2>&1; then
_get_git_status_fast
else
_prompt_get_git_status
fi
echo ""
echo -n " Full prompt: "
__prompt_git
echo ""
)
rm -rf "$temp_dir"
log_info "Temporary repository cleaned up"
}
# Performance check
quick_performance_check() {
log_info "Running quick performance check"
local iterations=10
local start_time end_time duration
start_time=$(date +%s%N)
for ((i=1; i<=iterations; i++)); do
__prompt_git >/dev/null 2>&1
done
end_time=$(date +%s%N)
duration=$(( (end_time - start_time) / 1000000 ))
local avg_duration=$(( duration / iterations ))
echo "Performance: ${avg_duration}ms average (${iterations} iterations)"
if [[ $avg_duration -lt 50 ]]; then
log_success "Performance is good"
elif [[ $avg_duration -lt 100 ]]; then
log_info "Performance is acceptable"
else
log_error "Performance may need optimization"
fi
}
# Main execution
main() {
log_info "HyperTerm Quick Test"
if ! load_functions; then
exit 1
fi
if ! test_current_directory; then
test_with_temp_repo
fi
quick_performance_check
log_success "Quick test completed"
}
# Execute if run directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi

304
tests/test_prompt.sh Normal file
View File

@@ -0,0 +1,304 @@
#!/bin/bash
# HyperTerm Prompt Test Suite
# Organized testing environment for prompt functionality
# shellcheck disable=SC1090,SC2034,SC2155
set -e
# Logging functions
log_info() { echo "[INFO] $*"; }
log_warn() { echo "[WARN] $*"; }
log_error() { echo "[ERROR] $*"; }
log_success() { echo "[SUCCESS] $*"; }
# Configuration
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
readonly TEST_DIR="/tmp/hyperterm_test_$(date +%s)"
# Cleanup function
cleanup() {
if [[ -n "${TEST_DIR:-}" && -d "$TEST_DIR" ]]; then
rm -rf "$TEST_DIR"
log_info "Test directory cleaned: $TEST_DIR"
fi
}
# Setup test environment
setup_test_env() {
log_info "Setting up test environment"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
# Create test git repository
git init --quiet
git config user.name "Test User"
git config user.email "test@example.com"
echo "# Test Repository" > README.md
echo "test content" > test.txt
git add README.md
git commit -m "Initial commit" --quiet
# Create various git states for testing
echo "modified content" >> test.txt
echo "untracked file" > untracked.txt
echo "staged content" > staged.txt
git add staged.txt
log_success "Test environment created at: $TEST_DIR"
log_info "Git states created: modified, untracked, staged files"
}
# Load hyperterm functions
load_hyperterm_functions() {
log_info "Loading HyperTerm functions"
# Load colors
local colors_file="$PROJECT_ROOT/hyperterm/core/colors.sh"
if [[ -f "$colors_file" ]]; then
source "$colors_file"
log_success "Colors loaded from: $colors_file"
else
log_warn "Colors file not found, using fallback"
# Fallback colors
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
CYAN='\033[36m'
WHITE='\033[37m'
GREY='\033[90m'
fi
# Load git functions
local git_file="$PROJECT_ROOT/hyperterm/core/git.sh"
if [[ -f "$git_file" ]]; then
source "$git_file"
log_success "Git functions loaded"
return 0
else
log_error "Git functions not found"
return 1
fi
}
# Test individual functions
test_individual_functions() {
log_info "Testing individual functions"
echo "Branch detection:"
if command -v _get_git_branch >/dev/null 2>&1; then
local branch
branch="$(_get_git_branch)"
echo " Result: $branch"
log_success "Branch detection working"
else
log_error "Branch detection function not found"
fi
echo "Git progress detection:"
if command -v _get_git_progress >/dev/null 2>&1; then
local progress
progress="$(_get_git_progress)"
echo " Result: ${progress:-"(none)"}"
log_success "Progress detection working"
else
log_error "Progress detection function not found"
fi
echo "Git status:"
if command -v _get_git_status_fast >/dev/null 2>&1; then
local status
status="$(_get_git_status_fast)"
echo " Result: $status"
log_success "Fast git status working"
elif command -v _prompt_get_git_status >/dev/null 2>&1; then
local status
status="$(_prompt_get_git_status)"
echo " Result: $status"
log_success "Original git status working"
else
log_error "No git status function found"
fi
}
# Performance benchmark
run_performance_test() {
log_info "Running performance benchmark"
if ! command -v __prompt_git >/dev/null 2>&1; then
log_error "Prompt function not available"
return 1
fi
local iterations=50
local start_time end_time duration
log_info "Running $iterations iterations"
start_time=$(date +%s%N)
for ((i=1; i<=iterations; i++)); do
__prompt_git >/dev/null 2>&1
done
end_time=$(date +%s%N)
duration=$(( (end_time - start_time) / 1000000 ))
local avg_duration=$(( duration / iterations ))
echo "Performance Results:"
echo " Total time: ${duration}ms"
echo " Average per call: ${avg_duration}ms"
echo " Iterations: $iterations"
if [[ $avg_duration -lt 10 ]]; then
log_success "Performance: Excellent (< 10ms per call)"
elif [[ $avg_duration -lt 50 ]]; then
log_success "Performance: Good (< 50ms per call)"
else
log_warn "Performance: Slow (>= 50ms per call)"
fi
}
# Test different git states
test_git_states() {
log_info "Testing different git states"
# Clean state
git checkout -- . >/dev/null 2>&1
git clean -fd >/dev/null 2>&1
echo "Clean repository:"
__prompt_git
echo ""
# Modified files
echo "modified" >> test.txt
echo "Modified files:"
__prompt_git
echo ""
# Untracked files
echo "untracked" > new_file.txt
echo "With untracked files:"
__prompt_git
echo ""
# Staged files
git add new_file.txt
echo "With staged files:"
__prompt_git
echo ""
log_success "Git states testing completed"
}
# Interactive test mode
interactive_mode() {
log_info "Entering interactive test mode"
echo "Available commands:"
echo " status - Show current git status"
echo " prompt - Show full prompt"
echo " perf - Run performance test"
echo " states - Test different git states"
echo " modify - Modify files for testing"
echo " clean - Clean working directory"
echo " help - Show this help"
echo " exit - Exit interactive mode"
echo ""
while true; do
echo -n "test> "
read -r command
case "$command" in
"status")
if command -v _get_git_status_fast >/dev/null 2>&1; then
_get_git_status_fast
else
_prompt_get_git_status
fi
echo ""
;;
"prompt")
__prompt_git
echo ""
;;
"perf")
run_performance_test
;;
"states")
test_git_states
;;
"modify")
echo "Creating test modifications"
echo "change $(date)" >> test.txt
echo "new file $(date)" > "file_$(date +%s).txt"
log_success "Files modified"
;;
"clean")
git checkout -- . >/dev/null 2>&1
git clean -fd >/dev/null 2>&1
log_success "Working directory cleaned"
;;
"help")
echo "Available commands: status, prompt, perf, states, modify, clean, help, exit"
;;
"exit")
log_info "Exiting interactive mode"
break
;;
"")
# Empty command, continue
;;
*)
log_warn "Unknown command: $command (type 'help' for available commands)"
;;
esac
done
}
# Main execution
main() {
log_info "Starting HyperTerm Prompt Test Suite"
# Setup
setup_test_env
if ! load_hyperterm_functions; then
log_error "Failed to load HyperTerm functions"
exit 1
fi
# Run tests
test_individual_functions
echo ""
run_performance_test
echo ""
test_git_states
echo ""
# Interactive mode (only if not in CI or non-interactive mode)
if [[ "$1" != "--non-interactive" && "$1" != "-n" && -z "${CI:-}" ]]; then
log_info "All automated tests completed"
echo "Enter interactive mode? (y/N)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
interactive_mode
fi
else
log_info "Running in non-interactive mode, skipping interactive prompt"
fi
log_success "Test suite completed successfully"
}
# Trap cleanup on exit
trap cleanup EXIT
# Execute main function if script is run directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi