Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions lib/sley/sley.sh
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ _sley_changes() {
fi
}

_sley_dirty_counts_json() {
_sley_dirty_counts() {
local staged=0 unstaged=0 untracked=0 pending=0 line
# `SLEY_SKIP_UNTRACKED=1` disables the untracked-file walk in both repo
# types. This is mainly for bare Git worktrees rooted at large directories:
Expand Down Expand Up @@ -353,10 +353,38 @@ _sley_dirty_counts_json() {
fi
;;
esac

_SLEY_DIRTY_STAGED=$staged
_SLEY_DIRTY_PENDING=$pending
_SLEY_DIRTY_UNSTAGED=$unstaged
_SLEY_DIRTY_UNTRACKED=$untracked
}

_sley_dirty_counts_json_from_values() {
local staged="$1" pending="$2" unstaged="$3" untracked="$4"
printf '{"staged":%s,"pending":%s,"unstaged":%s,"untracked":%s}' \
"$staged" "$pending" "$unstaged" "$untracked"
}

_sley_dirty_from_counts() {
local staged="$1" pending="$2" unstaged="$3" untracked="$4"

if ((staged == 0 && pending == 0 && unstaged == 0 && untracked == 0)); then
printf 'false\n'
else
printf 'true\n'
fi
}

_sley_dirty_counts_json() {
_sley_dirty_counts || return $?
_sley_dirty_counts_json_from_values \
"$_SLEY_DIRTY_STAGED" \
"$_SLEY_DIRTY_PENDING" \
"$_SLEY_DIRTY_UNSTAGED" \
"$_SLEY_DIRTY_UNTRACKED"
}

_sley_status() {
_sley_init_repo || return $?
_sley_parse_scope "$@" || return $?
Expand Down Expand Up @@ -390,9 +418,19 @@ _sley_status() {
fi
;;
esac
counts=$(_sley_dirty_counts_json)
[[ "$counts" == '{"staged":0,"pending":0,"unstaged":0,"untracked":0}' ]] &&
dirty=false || dirty=true
_sley_dirty_counts || return $?
# Dirty state is derived from the numeric counts before display JSON is
# rendered, so changing the JSON field order cannot change control flow.
dirty=$(_sley_dirty_from_counts \
"$_SLEY_DIRTY_STAGED" \
"$_SLEY_DIRTY_PENDING" \
"$_SLEY_DIRTY_UNSTAGED" \
"$_SLEY_DIRTY_UNTRACKED")
counts=$(_sley_dirty_counts_json_from_values \
"$_SLEY_DIRTY_STAGED" \
"$_SLEY_DIRTY_PENDING" \
"$_SLEY_DIRTY_UNSTAGED" \
"$_SLEY_DIRTY_UNTRACKED")

if [[ "$_SLEY_SCOPE_JSON" == "1" ]]; then
_repo_require_json_encoder || return 2
Expand Down
16 changes: 16 additions & 0 deletions test/suites/sley-behavior-test
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,22 @@ _assert_contains "bare repo fallback: skip reports unsupported repo" "unsupporte

echo "=== sley: git status and changes ==="

dirty_decisions=$(
SLEY_REPO_ROOT="$SLEY_REPO_ROOT" bash --noprofile --norc -c '
source "$SLEY_REPO_ROOT/lib/sley/sley.sh"
printf "clean=%s\n" "$(_sley_dirty_from_counts 0 0 0 0)"
printf "staged=%s\n" "$(_sley_dirty_from_counts 1 0 0 0)"
printf "pending=%s\n" "$(_sley_dirty_from_counts 0 1 0 0)"
printf "unstaged=%s\n" "$(_sley_dirty_from_counts 0 0 1 0)"
printf "untracked=%s\n" "$(_sley_dirty_from_counts 0 0 0 1)"
'
)
_assert_contains "status dirty helper: clean counts are clean" "clean=false" "$dirty_decisions"
_assert_contains "status dirty helper: staged count is dirty" "staged=true" "$dirty_decisions"
_assert_contains "status dirty helper: pending count is dirty" "pending=true" "$dirty_decisions"
_assert_contains "status dirty helper: unstaged count is dirty" "unstaged=true" "$dirty_decisions"
_assert_contains "status dirty helper: untracked count is dirty" "untracked=true" "$dirty_decisions"

repo=$(_new_repo)
cat >"$repo/tracked.py" <<'EOF'
x = 1
Expand Down
Loading