Skip to content

Instantly share code, notes, and snippets.

@bcantoni
Last active April 20, 2026 15:34
Show Gist options
  • Select an option

  • Save bcantoni/7f5a6c55cb1a2b4ae40a0c0acd05e145 to your computer and use it in GitHub Desktop.

Select an option

Save bcantoni/7f5a6c55cb1a2b4ae40a0c0acd05e145 to your computer and use it in GitHub Desktop.
Analyze subdirectories and show key development details at a glance.
#!/usr/bin/env bash
usage() {
cat <<EOF
Usage: glance <directory>
Analyze subdirectories and show key development details at a glance.
Columns: Name, Git, URL, Changes, Last Commit, Last Changed, Size
EOF
exit 0
}
[[ $# -eq 0 || "$1" == "-h" ]] && usage
TARGET="${1%/}"
if [[ ! -d "$TARGET" ]]; then
echo "Error: '$TARGET' is not a directory" >&2
exit 1
fi
IS_MAC=false
[[ "$(uname)" == "Darwin" ]] && IS_MAC=true
transform_git_url() {
local url="$1"
url="${url%.git}"
if [[ "$url" =~ ^git@ ]]; then
url="${url#git@}"
url="https://${url/://}"
fi
echo "$url"
}
format_epoch() {
local epoch="$1"
if $IS_MAC; then
date -r "$epoch" "+%Y-%m-%d" 2>/dev/null || echo "-"
else
date -d "@$epoch" "+%Y-%m-%d" 2>/dev/null || echo "-"
fi
}
last_modified() {
local dir="$1"
local epoch
if $IS_MAC; then
epoch=$(find "$dir" -type f -not -path '*/.*' -print0 2>/dev/null | xargs -0 stat -f "%m" 2>/dev/null | sort -rn | head -1)
else
epoch=$(find "$dir" -type f -not -path '*/.*' -printf "%T@\n" 2>/dev/null | sort -rn | head -1 | cut -d. -f1)
fi
if [[ -n "$epoch" ]]; then
format_epoch "$epoch"
else
echo "-"
fi
}
dir_size() {
du -sh "$1" 2>/dev/null | cut -f1 || echo "-"
}
HEADERS=("NAME" "GIT" "URL" "CHANGES" "LAST COMMIT" "LAST CHANGED" "SIZE")
rows=()
while IFS= read -r -d '' subdir; do
name=$(basename "$subdir")
git_val="no"
url_val="-"
changes_val="-"
commit_val="-"
if [[ -d "$subdir/.git" ]]; then
git_val="yes"
raw_url=$(git -C "$subdir" remote get-url origin 2>/dev/null || true)
if [[ -n "$raw_url" ]]; then
url_val=$(transform_git_url "$raw_url")
fi
if [[ -z "$(git -C "$subdir" status --porcelain 2>/dev/null)" ]]; then
changes_val="no"
else
changes_val="yes"
fi
commit_epoch=$(git -C "$subdir" log -1 --format="%ct" 2>/dev/null || true)
if [[ -n "$commit_epoch" ]]; then
commit_val=$(format_epoch "$commit_epoch")
fi
fi
changed_val=$(last_modified "$subdir")
size_val=$(dir_size "$subdir")
rows+=("$name|$git_val|$url_val|$changes_val|$commit_val|$changed_val|$size_val")
done < <(find "$TARGET" -maxdepth 1 -mindepth 1 -type d -not -name '.*' -print0 | sort -z)
if [[ ${#rows[@]} -eq 0 ]]; then
echo "No subdirectories found in '$TARGET'"
exit 0
fi
ncols=${#HEADERS[@]}
widths=()
for h in "${HEADERS[@]}"; do
widths+=(${#h})
done
for row in "${rows[@]}"; do
IFS='|' read -ra fields <<< "$row"
for i in "${!fields[@]}"; do
len=${#fields[$i]}
if [[ $len -gt ${widths[$i]} ]]; then
widths[$i]=$len
fi
done
done
header_line=""
sep_line=""
for i in "${!HEADERS[@]}"; do
w=${widths[$i]}
pad=$(printf '%*s' "$w" '')
header_line+=$(printf "%-${w}s" "${HEADERS[$i]}")
sep_line+="${pad// /-}"
if [[ $i -lt $((ncols - 1)) ]]; then
header_line+=" "
sep_line+=" "
fi
done
echo "$header_line"
echo "$sep_line"
for row in "${rows[@]}"; do
IFS='|' read -ra fields <<< "$row"
line=""
for i in "${!fields[@]}"; do
line+=$(printf "%-${widths[$i]}s" "${fields[$i]}")
if [[ $i -lt $((ncols - 1)) ]]; then
line+=" "
fi
done
echo "$line"
done
@bcantoni

Copy link
Copy Markdown
Author

Spec by me, code from Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment