forked from github/spec-kit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup-plan.sh
More file actions
172 lines (158 loc) · 5.95 KB
/
setup-plan.sh
File metadata and controls
172 lines (158 loc) · 5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/env bash
set -e
# Parse command line arguments
JSON_MODE=false
SCAN_DEPTH=""
ARGS=()
for arg in "$@"; do
case "$arg" in
--json)
JSON_MODE=true
;;
--scan-depth)
# Next argument is the depth value — handled below
SCAN_DEPTH="__NEXT__"
;;
--help|-h)
echo "Usage: $0 [--json] [--scan-depth N]"
echo " --json Output results in JSON format"
echo " --scan-depth N Max directory depth for nested repo discovery (default: 2)"
echo " --help Show this help message"
exit 0
;;
*)
if [ "$SCAN_DEPTH" = "__NEXT__" ]; then
SCAN_DEPTH="$arg"
else
ARGS+=("$arg")
fi
;;
esac
done
# Validate --scan-depth argument
if [ "$SCAN_DEPTH" = "__NEXT__" ]; then
echo "ERROR: --scan-depth requires a positive integer value" >&2
exit 1
fi
if [ -n "$SCAN_DEPTH" ]; then
case "$SCAN_DEPTH" in
''|*[!0-9]*|0)
echo "ERROR: --scan-depth must be a positive integer, got '$SCAN_DEPTH'" >&2
exit 1
;;
esac
fi
# Get script directory and load common functions
SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"
# Get all paths and variables from common functions
_paths_output=$(get_feature_paths) || { echo "ERROR: Failed to resolve feature paths" >&2; exit 1; }
eval "$_paths_output"
unset _paths_output
# Check if we're on a proper feature branch (only for git repos)
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
# Ensure the feature directory exists
mkdir -p "$FEATURE_DIR"
# Copy plan template if it exists
TEMPLATE=$(resolve_template "plan-template" "$REPO_ROOT") || true
if [[ -n "$TEMPLATE" ]] && [[ -f "$TEMPLATE" ]]; then
cp "$TEMPLATE" "$IMPL_PLAN"
echo "Copied plan template to $IMPL_PLAN"
else
echo "Warning: Plan template not found"
# Create a basic plan file if template doesn't exist
touch "$IMPL_PLAN"
fi
# Discover nested independent git repositories (for AI agent to analyze)
NESTED_REPOS_JSON="[]"
if [ "$HAS_GIT" = true ]; then
INIT_OPTIONS="$REPO_ROOT/.specify/init-options.json"
explicit_repos=()
config_depth=""
# Read explicit nested_repos and nested_repo_scan_depth from init-options.json if available
if [ -f "$INIT_OPTIONS" ]; then
if has_jq; then
while IFS= read -r rp; do
[ -n "$rp" ] && explicit_repos+=("$rp")
done < <(jq -r '.nested_repos // [] | .[]' "$INIT_OPTIONS" 2>/dev/null)
_cd=$(jq -r '.nested_repo_scan_depth // empty' "$INIT_OPTIONS" 2>/dev/null)
[ -n "$_cd" ] && config_depth="$_cd"
else
_py=$(command -v python3 2>/dev/null || command -v python 2>/dev/null || echo "")
if [ -n "$_py" ]; then
while IFS= read -r rp; do
rp="${rp%$'\r'}"
[ -n "$rp" ] && explicit_repos+=("$rp")
done < <("$_py" -c "import json,sys
try:
[print(p) for p in json.load(open(sys.argv[1])).get('nested_repos',[])]
except: pass" "$INIT_OPTIONS" 2>/dev/null)
_cd=$("$_py" -c "import json,sys
try:
v=json.load(open(sys.argv[1])).get('nested_repo_scan_depth')
if v is not None: print(v)
except: pass" "$INIT_OPTIONS" 2>/dev/null)
_cd="${_cd%$'\r'}"
[ -n "$_cd" ] && config_depth="$_cd"
fi
fi
fi
# Priority: CLI --scan-depth > init-options nested_repo_scan_depth > default 2
# Validate config_depth the same way as --scan-depth (must be positive integer)
if [ -n "$config_depth" ]; then
case "$config_depth" in
''|*[!0-9]*|0)
echo "WARNING: nested_repo_scan_depth in init-options.json must be a positive integer, got '$config_depth' — using default" >&2
config_depth=""
;;
esac
fi
scan_depth="${SCAN_DEPTH:-${config_depth:-2}}"
if [ ${#explicit_repos[@]} -gt 0 ]; then
nested_repos=$(find_nested_git_repos "$REPO_ROOT" "$scan_depth" "${explicit_repos[@]}") || nested_repos=""
else
nested_repos=$(find_nested_git_repos "$REPO_ROOT" "$scan_depth") || nested_repos=""
fi
if [ -n "$nested_repos" ]; then
NESTED_REPOS_JSON="["
first=true
while IFS= read -r nested_path; do
[ -z "$nested_path" ] && continue
nested_path="${nested_path%/}"
rel_path="${nested_path#"$REPO_ROOT/"}"
rel_path="${rel_path%/}"
if [ "$first" = true ]; then
first=false
else
NESTED_REPOS_JSON+=","
fi
NESTED_REPOS_JSON+="{\"path\":\"$(json_escape "$rel_path")\"}"
done <<< "$nested_repos"
NESTED_REPOS_JSON+="]"
fi
fi
# Output results
if $JSON_MODE; then
if has_jq; then
jq -cn \
--arg feature_spec "$FEATURE_SPEC" \
--arg impl_plan "$IMPL_PLAN" \
--arg specs_dir "$FEATURE_DIR" \
--arg branch "$CURRENT_BRANCH" \
--arg has_git "$HAS_GIT" \
--argjson nested_repos "$NESTED_REPOS_JSON" \
'{FEATURE_SPEC:$feature_spec,IMPL_PLAN:$impl_plan,SPECS_DIR:$specs_dir,BRANCH:$branch,HAS_GIT:$has_git,NESTED_REPOS:$nested_repos}'
else
printf '{"FEATURE_SPEC":"%s","IMPL_PLAN":"%s","SPECS_DIR":"%s","BRANCH":"%s","HAS_GIT":"%s","NESTED_REPOS":%s}\n' \
"$(json_escape "$FEATURE_SPEC")" "$(json_escape "$IMPL_PLAN")" "$(json_escape "$FEATURE_DIR")" "$(json_escape "$CURRENT_BRANCH")" "$(json_escape "$HAS_GIT")" "$NESTED_REPOS_JSON"
fi
else
echo "FEATURE_SPEC: $FEATURE_SPEC"
echo "IMPL_PLAN: $IMPL_PLAN"
echo "SPECS_DIR: $FEATURE_DIR"
echo "BRANCH: $CURRENT_BRANCH"
echo "HAS_GIT: $HAS_GIT"
if [ "$NESTED_REPOS_JSON" != "[]" ]; then
echo "NESTED_REPOS: $NESTED_REPOS_JSON"
fi
fi