Skip to content

Commit 6acab47

Browse files
committed
feat(gitutils): ✨ list workspace directories and affected workspaces
1 parent ed2465e commit 6acab47

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

src/gitutils/_git-workspaces.sh

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/sh
2+
3+
# Function to print help and manage arguments
4+
eval $(
5+
zz_args "List workspace directories and affected workspaces" $0 "$@" <<-help
6+
r range range Git range to check for affected workspaces (prints only affected workspaces)
7+
help
8+
)
9+
10+
#### Go to repository root
11+
cd "$(git rev-parse --show-toplevel)"
12+
13+
list_workspace_dirs() {
14+
if [ -f "package.json" ] && command -v jq >/dev/null 2>&1; then
15+
local workspaces
16+
workspaces=$(jq -r '.workspaces[]? // empty' package.json 2>/dev/null || true)
17+
18+
if [ -n "$workspaces" ]; then
19+
echo "$workspaces" | while read -r workspace_pattern; do
20+
if echo "$workspace_pattern" | grep -q '\*'; then
21+
# Expand simple glob patterns like "packages/*" or "src/*"
22+
find . -path "./$workspace_pattern" -type d -mindepth 1 -maxdepth 2 2>/dev/null || true
23+
else
24+
if [ -d "$workspace_pattern" ]; then
25+
echo "./$workspace_pattern"
26+
fi
27+
fi
28+
done
29+
return 0
30+
fi
31+
fi
32+
33+
# Fallback: list all immediate subdirectories
34+
find . -mindepth 1 -maxdepth 1 -type d
35+
}
36+
37+
get_affected_workspaces() {
38+
local range="$1"
39+
40+
# If no range provided, nothing to do
41+
if [ -z "$range" ]; then
42+
return 0
43+
fi
44+
45+
# Get all changed files in the range and determine which workspaces they belong to
46+
git log --name-only --pretty=format: "$range" 2>/dev/null \
47+
| while read -r line; do
48+
if [ -n "$line" ]; then
49+
# This is a file path, check which workspace it belongs to
50+
list_workspace_dirs | while read -r workspace_dir; do
51+
workspace_dir_clean=$(echo "$workspace_dir" | sed 's|^./||')
52+
if echo "$line" | grep -q "^$workspace_dir_clean/"; then
53+
echo "$workspace_dir"
54+
fi
55+
done
56+
# Check for root-level files (not in any workspace subdirectory)
57+
if ! echo "$line" | grep -q "/"; then
58+
echo "."
59+
fi
60+
fi
61+
done
62+
}
63+
64+
# Main execution logic
65+
if [ -n "$range" ]; then
66+
get_affected_workspaces "$range" | sort -u
67+
else
68+
list_workspace_dirs
69+
fi

0 commit comments

Comments
 (0)