@pjmendonca/devflow 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +526 -0
- package/LICENSE +21 -0
- package/README.md +620 -0
- package/bin/devflow-checkpoint.js +10 -0
- package/bin/devflow-collab.js +10 -0
- package/bin/devflow-cost.js +10 -0
- package/bin/devflow-create-persona.js +10 -0
- package/bin/devflow-init.js +10 -0
- package/bin/devflow-memory.js +10 -0
- package/bin/devflow-new-doc.js +10 -0
- package/bin/devflow-personalize.js +10 -0
- package/bin/devflow-setup-checkpoint.js +10 -0
- package/bin/devflow-story.js +10 -0
- package/bin/devflow-tech-debt.js +10 -0
- package/bin/devflow-validate-overrides.js +10 -0
- package/bin/devflow-validate.js +10 -0
- package/bin/devflow-version.js +10 -0
- package/lib/constants.js +30 -0
- package/lib/exec-python.js +78 -0
- package/lib/python-check.js +178 -0
- package/package.json +64 -0
- package/tooling/.automation/agents/architect.md +135 -0
- package/tooling/.automation/agents/ba.md +70 -0
- package/tooling/.automation/agents/dev.md +79 -0
- package/tooling/.automation/agents/maintainer.md +97 -0
- package/tooling/.automation/agents/pm.md +116 -0
- package/tooling/.automation/agents/reviewer.md +141 -0
- package/tooling/.automation/agents/sm.md +61 -0
- package/tooling/.automation/agents/writer.md +193 -0
- package/tooling/.automation/config.ps1.template +61 -0
- package/tooling/.automation/config.sh.template +48 -0
- package/tooling/.automation/memory/.gitkeep +6 -0
- package/tooling/.automation/memory/knowledge/kg_integration-test.json +94 -0
- package/tooling/.automation/memory/knowledge/kg_test-story.json +300 -0
- package/tooling/.automation/memory/shared/shared_integration-test.json +30 -0
- package/tooling/.automation/memory/shared/shared_test-story.json +78 -0
- package/tooling/.automation/overrides/templates/README.md +113 -0
- package/tooling/.automation/overrides/templates/architect/README.md +27 -0
- package/tooling/.automation/overrides/templates/architect/cloud-native.yaml +92 -0
- package/tooling/.automation/overrides/templates/architect/enterprise-architect.yaml +85 -0
- package/tooling/.automation/overrides/templates/architect/pragmatic-minimalist.yaml +88 -0
- package/tooling/.automation/overrides/templates/ba/README.md +27 -0
- package/tooling/.automation/overrides/templates/ba/agile-storyteller.yaml +86 -0
- package/tooling/.automation/overrides/templates/ba/domain-expert.yaml +91 -0
- package/tooling/.automation/overrides/templates/ba/requirements-engineer.yaml +89 -0
- package/tooling/.automation/overrides/templates/dev/README.md +32 -0
- package/tooling/.automation/overrides/templates/dev/junior-mentored.yaml +39 -0
- package/tooling/.automation/overrides/templates/dev/performance-engineer.yaml +43 -0
- package/tooling/.automation/overrides/templates/dev/rapid-prototyper.yaml +52 -0
- package/tooling/.automation/overrides/templates/dev/security-focused.yaml +43 -0
- package/tooling/.automation/overrides/templates/dev/senior-fullstack.yaml +39 -0
- package/tooling/.automation/overrides/templates/maintainer/README.md +27 -0
- package/tooling/.automation/overrides/templates/maintainer/devops-maintainer.yaml +113 -0
- package/tooling/.automation/overrides/templates/maintainer/legacy-steward.yaml +94 -0
- package/tooling/.automation/overrides/templates/maintainer/oss-maintainer.yaml +94 -0
- package/tooling/.automation/overrides/templates/pm/README.md +27 -0
- package/tooling/.automation/overrides/templates/pm/agile-pm.yaml +91 -0
- package/tooling/.automation/overrides/templates/pm/hybrid-delivery.yaml +87 -0
- package/tooling/.automation/overrides/templates/pm/traditional-pm.yaml +91 -0
- package/tooling/.automation/overrides/templates/reviewer/README.md +11 -0
- package/tooling/.automation/overrides/templates/reviewer/mentoring-reviewer.yaml +45 -0
- package/tooling/.automation/overrides/templates/reviewer/quick-sanity.yaml +50 -0
- package/tooling/.automation/overrides/templates/reviewer/thorough-critic.yaml +48 -0
- package/tooling/.automation/overrides/templates/sm/README.md +11 -0
- package/tooling/.automation/overrides/templates/sm/agile-coach.yaml +52 -0
- package/tooling/.automation/overrides/templates/sm/startup-pm.yaml +50 -0
- package/tooling/.automation/overrides/templates/sm/technical-lead.yaml +47 -0
- package/tooling/.automation/overrides/templates/user-profile.template.yaml +62 -0
- package/tooling/.automation/overrides/templates/writer/README.md +27 -0
- package/tooling/.automation/overrides/templates/writer/api-documentarian.yaml +99 -0
- package/tooling/.automation/overrides/templates/writer/docs-as-code.yaml +108 -0
- package/tooling/.automation/overrides/templates/writer/user-guide-author.yaml +100 -0
- package/tooling/completions/DevflowCompletion.ps1 +213 -0
- package/tooling/completions/_run-story +116 -0
- package/tooling/completions/run-story-completion.bash +136 -0
- package/tooling/docs/DOC-STANDARD.md +717 -0
- package/tooling/docs/sprint-status.yaml.template +24 -0
- package/tooling/docs/templates/bug-report.md +234 -0
- package/tooling/docs/templates/migration-spec.md +274 -0
- package/tooling/docs/templates/refactor-spec.md +86 -0
- package/tooling/docs/templates/tech-debt.md +86 -0
- package/tooling/scripts/context_checkpoint.py +556 -0
- package/tooling/scripts/cost_dashboard.py +617 -0
- package/tooling/scripts/create-persona.py +690 -0
- package/tooling/scripts/create-persona.sh +435 -0
- package/tooling/scripts/init-project-workflow.ps1 +651 -0
- package/tooling/scripts/init-project-workflow.py +70 -0
- package/tooling/scripts/init-project-workflow.sh +746 -0
- package/tooling/scripts/lib/__init__.py +35 -0
- package/tooling/scripts/lib/agent_handoff.py +526 -0
- package/tooling/scripts/lib/agent_router.py +698 -0
- package/tooling/scripts/lib/checkpoint-integration.ps1 +245 -0
- package/tooling/scripts/lib/checkpoint-integration.sh +191 -0
- package/tooling/scripts/lib/claude-cli.ps1 +952 -0
- package/tooling/scripts/lib/claude-cli.sh +1293 -0
- package/tooling/scripts/lib/cost_config.py +222 -0
- package/tooling/scripts/lib/cost_display.py +443 -0
- package/tooling/scripts/lib/cost_tracker.py +710 -0
- package/tooling/scripts/lib/currency_converter.py +328 -0
- package/tooling/scripts/lib/errors.py +438 -0
- package/tooling/scripts/lib/override-loader.sh +286 -0
- package/tooling/scripts/lib/pair_programming.py +589 -0
- package/tooling/scripts/lib/shared_memory.py +637 -0
- package/tooling/scripts/lib/swarm_orchestrator.py +689 -0
- package/tooling/scripts/memory_summarize.py +324 -0
- package/tooling/scripts/new-doc.ps1 +405 -0
- package/tooling/scripts/new-doc.py +93 -0
- package/tooling/scripts/new-doc.sh +534 -0
- package/tooling/scripts/personalize_agent.py +385 -0
- package/tooling/scripts/rollback-migration.sh +540 -0
- package/tooling/scripts/run-collab.ps1 +251 -0
- package/tooling/scripts/run-collab.py +605 -0
- package/tooling/scripts/run-collab.sh +110 -0
- package/tooling/scripts/run-story.ps1 +490 -0
- package/tooling/scripts/run-story.py +387 -0
- package/tooling/scripts/run-story.sh +467 -0
- package/tooling/scripts/setup-checkpoint-service.ps1 +219 -0
- package/tooling/scripts/setup-checkpoint-service.py +87 -0
- package/tooling/scripts/setup-checkpoint-service.sh +236 -0
- package/tooling/scripts/tech-debt-tracker.py +608 -0
- package/tooling/scripts/update_version.py +244 -0
- package/tooling/scripts/validate-overrides.py +511 -0
- package/tooling/scripts/validate-overrides.sh +432 -0
- package/tooling/scripts/validate_setup.py +539 -0
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
################################################################################
|
|
3
|
+
# Rollback Migration - Automated Migration Rollback
|
|
4
|
+
#
|
|
5
|
+
# This script provides automated rollback capabilities for migrations.
|
|
6
|
+
# It can:
|
|
7
|
+
# - Create rollback checkpoints before migrations
|
|
8
|
+
# - Execute rollback steps defined in migration specs
|
|
9
|
+
# - Restore from git-based checkpoints
|
|
10
|
+
# - Handle dependency rollbacks
|
|
11
|
+
#
|
|
12
|
+
# Usage:
|
|
13
|
+
# ./rollback-migration.sh <migration-id> # Rollback a migration
|
|
14
|
+
# ./rollback-migration.sh <migration-id> --dry-run # Preview rollback
|
|
15
|
+
# ./rollback-migration.sh <migration-id> --force # Force rollback
|
|
16
|
+
# ./rollback-migration.sh --list # List rollback points
|
|
17
|
+
# ./rollback-migration.sh --create <name> # Create rollback point
|
|
18
|
+
#
|
|
19
|
+
################################################################################
|
|
20
|
+
|
|
21
|
+
set -e
|
|
22
|
+
|
|
23
|
+
# Colors
|
|
24
|
+
RED='\033[0;31m'
|
|
25
|
+
GREEN='\033[0;32m'
|
|
26
|
+
YELLOW='\033[1;33m'
|
|
27
|
+
BLUE='\033[0;34m'
|
|
28
|
+
CYAN='\033[0;36m'
|
|
29
|
+
BOLD='\033[1m'
|
|
30
|
+
NC='\033[0m'
|
|
31
|
+
|
|
32
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
33
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
34
|
+
ROLLBACK_DIR="$PROJECT_ROOT/.automation/rollbacks"
|
|
35
|
+
CHECKPOINTS_DIR="$PROJECT_ROOT/.automation/checkpoints"
|
|
36
|
+
MIGRATIONS_DIR="$PROJECT_ROOT/docs/migrations"
|
|
37
|
+
|
|
38
|
+
################################################################################
|
|
39
|
+
# Helper Functions
|
|
40
|
+
################################################################################
|
|
41
|
+
|
|
42
|
+
print_header() {
|
|
43
|
+
echo ""
|
|
44
|
+
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
|
|
45
|
+
echo -e "${CYAN} MIGRATION ROLLBACK TOOL${NC}"
|
|
46
|
+
echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}"
|
|
47
|
+
echo ""
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
error() {
|
|
51
|
+
echo -e "${RED}✗ ERROR:${NC} $1"
|
|
52
|
+
exit 1
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
warning() {
|
|
56
|
+
echo -e "${YELLOW}⚠ WARNING:${NC} $1"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
success() {
|
|
60
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
info() {
|
|
64
|
+
echo -e "${BLUE}ℹ${NC} $1"
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
confirm() {
|
|
68
|
+
local message="$1"
|
|
69
|
+
echo -e "${YELLOW}$message${NC}"
|
|
70
|
+
echo -n "Continue? [y/N] "
|
|
71
|
+
read -r response
|
|
72
|
+
[[ "$response" =~ ^[Yy]$ ]]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
################################################################################
|
|
76
|
+
# Rollback Point Management
|
|
77
|
+
################################################################################
|
|
78
|
+
|
|
79
|
+
# Create a rollback point
|
|
80
|
+
create_rollback_point() {
|
|
81
|
+
local name="$1"
|
|
82
|
+
local timestamp=$(date '+%Y%m%d_%H%M%S')
|
|
83
|
+
local rollback_name="${timestamp}_${name}"
|
|
84
|
+
local rollback_path="$ROLLBACK_DIR/$rollback_name"
|
|
85
|
+
|
|
86
|
+
mkdir -p "$rollback_path"
|
|
87
|
+
|
|
88
|
+
echo -e "${CYAN}Creating rollback point: $rollback_name${NC}"
|
|
89
|
+
|
|
90
|
+
# Save git state
|
|
91
|
+
local current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
92
|
+
local current_commit=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
|
|
93
|
+
local has_changes=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
|
|
94
|
+
|
|
95
|
+
# Create manifest
|
|
96
|
+
cat > "$rollback_path/manifest.json" << EOF
|
|
97
|
+
{
|
|
98
|
+
"name": "$name",
|
|
99
|
+
"created": "$(date -Iseconds)",
|
|
100
|
+
"branch": "$current_branch",
|
|
101
|
+
"commit": "$current_commit",
|
|
102
|
+
"has_uncommitted_changes": $([[ $has_changes -gt 0 ]] && echo "true" || echo "false"),
|
|
103
|
+
"type": "migration-rollback"
|
|
104
|
+
}
|
|
105
|
+
EOF
|
|
106
|
+
|
|
107
|
+
# Save uncommitted changes if any
|
|
108
|
+
if [[ $has_changes -gt 0 ]]; then
|
|
109
|
+
info "Saving uncommitted changes..."
|
|
110
|
+
git stash push -m "rollback-$rollback_name" --include-untracked 2>/dev/null || true
|
|
111
|
+
git stash show -p > "$rollback_path/uncommitted.patch" 2>/dev/null || true
|
|
112
|
+
git stash pop 2>/dev/null || true
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
# Save package state
|
|
116
|
+
if [[ -f "$PROJECT_ROOT/package.json" ]]; then
|
|
117
|
+
cp "$PROJECT_ROOT/package.json" "$rollback_path/"
|
|
118
|
+
info "Saved package.json"
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
if [[ -f "$PROJECT_ROOT/package-lock.json" ]]; then
|
|
122
|
+
cp "$PROJECT_ROOT/package-lock.json" "$rollback_path/"
|
|
123
|
+
info "Saved package-lock.json"
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
if [[ -f "$PROJECT_ROOT/pubspec.yaml" ]]; then
|
|
127
|
+
cp "$PROJECT_ROOT/pubspec.yaml" "$rollback_path/"
|
|
128
|
+
info "Saved pubspec.yaml"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
if [[ -f "$PROJECT_ROOT/pubspec.lock" ]]; then
|
|
132
|
+
cp "$PROJECT_ROOT/pubspec.lock" "$rollback_path/"
|
|
133
|
+
info "Saved pubspec.lock"
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
if [[ -f "$PROJECT_ROOT/requirements.txt" ]]; then
|
|
137
|
+
cp "$PROJECT_ROOT/requirements.txt" "$rollback_path/"
|
|
138
|
+
info "Saved requirements.txt"
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
success "Rollback point created: $rollback_path"
|
|
142
|
+
echo "$rollback_name"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
# List available rollback points
|
|
146
|
+
list_rollback_points() {
|
|
147
|
+
echo -e "${BOLD}Available Rollback Points:${NC}"
|
|
148
|
+
echo ""
|
|
149
|
+
|
|
150
|
+
if [[ ! -d "$ROLLBACK_DIR" ]] || [[ -z "$(ls -A "$ROLLBACK_DIR" 2>/dev/null)" ]]; then
|
|
151
|
+
info "No rollback points found."
|
|
152
|
+
return 0
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
printf "%-25s %-20s %-15s %s\n" "NAME" "CREATED" "COMMIT" "BRANCH"
|
|
156
|
+
printf "%s\n" "$(printf '─%.0s' {1..80})"
|
|
157
|
+
|
|
158
|
+
for dir in "$ROLLBACK_DIR"/*/; do
|
|
159
|
+
if [[ -d "$dir" ]]; then
|
|
160
|
+
local name=$(basename "$dir")
|
|
161
|
+
local manifest="$dir/manifest.json"
|
|
162
|
+
|
|
163
|
+
if [[ -f "$manifest" ]]; then
|
|
164
|
+
local created=$(grep '"created"' "$manifest" | sed 's/.*: *"\([^"]*\)".*/\1/' | cut -c1-19)
|
|
165
|
+
local commit=$(grep '"commit"' "$manifest" | sed 's/.*: *"\([^"]*\)".*/\1/' | cut -c1-8)
|
|
166
|
+
local branch=$(grep '"branch"' "$manifest" | sed 's/.*: *"\([^"]*\)".*/\1/')
|
|
167
|
+
|
|
168
|
+
printf "%-25s %-20s %-15s %s\n" "$name" "$created" "$commit" "$branch"
|
|
169
|
+
fi
|
|
170
|
+
fi
|
|
171
|
+
done
|
|
172
|
+
echo ""
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
# Delete old rollback points (keep last N)
|
|
176
|
+
cleanup_rollback_points() {
|
|
177
|
+
local keep="${1:-10}"
|
|
178
|
+
|
|
179
|
+
if [[ ! -d "$ROLLBACK_DIR" ]]; then
|
|
180
|
+
return 0
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
local count=$(ls -d "$ROLLBACK_DIR"/*/ 2>/dev/null | wc -l | tr -d ' ')
|
|
184
|
+
|
|
185
|
+
if [[ $count -gt $keep ]]; then
|
|
186
|
+
local to_delete=$((count - keep))
|
|
187
|
+
info "Cleaning up $to_delete old rollback point(s)..."
|
|
188
|
+
|
|
189
|
+
ls -d "$ROLLBACK_DIR"/*/ 2>/dev/null | head -n "$to_delete" | while read dir; do
|
|
190
|
+
rm -rf "$dir"
|
|
191
|
+
success "Deleted: $(basename "$dir")"
|
|
192
|
+
done
|
|
193
|
+
fi
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
################################################################################
|
|
197
|
+
# Rollback Execution
|
|
198
|
+
################################################################################
|
|
199
|
+
|
|
200
|
+
# Find migration spec file
|
|
201
|
+
find_migration_spec() {
|
|
202
|
+
local migration_id="$1"
|
|
203
|
+
|
|
204
|
+
# Search in common locations
|
|
205
|
+
local search_paths=(
|
|
206
|
+
"$MIGRATIONS_DIR/${migration_id}.md"
|
|
207
|
+
"$PROJECT_ROOT/docs/${migration_id}.md"
|
|
208
|
+
"$PROJECT_ROOT/tooling/docs/migrations/${migration_id}.md"
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
for path in "${search_paths[@]}"; do
|
|
212
|
+
if [[ -f "$path" ]]; then
|
|
213
|
+
echo "$path"
|
|
214
|
+
return 0
|
|
215
|
+
fi
|
|
216
|
+
done
|
|
217
|
+
|
|
218
|
+
# Search by pattern
|
|
219
|
+
local found=$(find "$PROJECT_ROOT" -name "*${migration_id}*.md" -path "*/migrations/*" 2>/dev/null | head -1)
|
|
220
|
+
if [[ -n "$found" ]]; then
|
|
221
|
+
echo "$found"
|
|
222
|
+
return 0
|
|
223
|
+
fi
|
|
224
|
+
|
|
225
|
+
return 1
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
# Parse rollback steps from migration spec
|
|
229
|
+
parse_rollback_steps() {
|
|
230
|
+
local spec_file="$1"
|
|
231
|
+
|
|
232
|
+
# Extract rollback steps section
|
|
233
|
+
awk '/^### Rollback Steps/,/^##[^#]/' "$spec_file" 2>/dev/null | \
|
|
234
|
+
grep -E '^\s*[0-9]+\.' | \
|
|
235
|
+
sed 's/^\s*[0-9]*\.\s*//'
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
# Execute git-based rollback
|
|
239
|
+
rollback_to_commit() {
|
|
240
|
+
local commit="$1"
|
|
241
|
+
local dry_run="$2"
|
|
242
|
+
|
|
243
|
+
if [[ "$dry_run" == "true" ]]; then
|
|
244
|
+
info "Would reset to commit: $commit"
|
|
245
|
+
git log --oneline -1 "$commit"
|
|
246
|
+
return 0
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
info "Rolling back to commit: $commit"
|
|
250
|
+
|
|
251
|
+
# Check for uncommitted changes
|
|
252
|
+
if [[ -n "$(git status --porcelain)" ]]; then
|
|
253
|
+
warning "You have uncommitted changes. These will be stashed."
|
|
254
|
+
git stash push -m "pre-rollback-$(date +%s)"
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
# Perform rollback
|
|
258
|
+
git checkout "$commit" -- .
|
|
259
|
+
success "Rolled back to commit: $commit"
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
# Rollback from a rollback point
|
|
263
|
+
rollback_from_point() {
|
|
264
|
+
local point_name="$1"
|
|
265
|
+
local dry_run="$2"
|
|
266
|
+
local point_path="$ROLLBACK_DIR/$point_name"
|
|
267
|
+
|
|
268
|
+
if [[ ! -d "$point_path" ]]; then
|
|
269
|
+
error "Rollback point not found: $point_name"
|
|
270
|
+
fi
|
|
271
|
+
|
|
272
|
+
local manifest="$point_path/manifest.json"
|
|
273
|
+
if [[ ! -f "$manifest" ]]; then
|
|
274
|
+
error "Invalid rollback point (no manifest): $point_name"
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
local commit=$(grep '"commit"' "$manifest" | sed 's/.*: *"\([^"]*\)".*/\1/')
|
|
278
|
+
|
|
279
|
+
echo ""
|
|
280
|
+
info "Rollback Point Details:"
|
|
281
|
+
cat "$manifest" | grep -E '"(name|created|branch|commit)"' | sed 's/^/ /'
|
|
282
|
+
echo ""
|
|
283
|
+
|
|
284
|
+
if [[ "$dry_run" == "true" ]]; then
|
|
285
|
+
info "[DRY RUN] Would restore from rollback point: $point_name"
|
|
286
|
+
|
|
287
|
+
if [[ -f "$point_path/package.json" ]]; then
|
|
288
|
+
info "[DRY RUN] Would restore package.json"
|
|
289
|
+
fi
|
|
290
|
+
if [[ -f "$point_path/pubspec.yaml" ]]; then
|
|
291
|
+
info "[DRY RUN] Would restore pubspec.yaml"
|
|
292
|
+
fi
|
|
293
|
+
|
|
294
|
+
return 0
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
if ! confirm "This will rollback to the saved state. Continue?"; then
|
|
298
|
+
info "Rollback cancelled."
|
|
299
|
+
return 0
|
|
300
|
+
fi
|
|
301
|
+
|
|
302
|
+
# Restore files
|
|
303
|
+
if [[ -f "$point_path/package.json" ]]; then
|
|
304
|
+
cp "$point_path/package.json" "$PROJECT_ROOT/"
|
|
305
|
+
success "Restored package.json"
|
|
306
|
+
fi
|
|
307
|
+
|
|
308
|
+
if [[ -f "$point_path/package-lock.json" ]]; then
|
|
309
|
+
cp "$point_path/package-lock.json" "$PROJECT_ROOT/"
|
|
310
|
+
success "Restored package-lock.json"
|
|
311
|
+
fi
|
|
312
|
+
|
|
313
|
+
if [[ -f "$point_path/pubspec.yaml" ]]; then
|
|
314
|
+
cp "$point_path/pubspec.yaml" "$PROJECT_ROOT/"
|
|
315
|
+
success "Restored pubspec.yaml"
|
|
316
|
+
fi
|
|
317
|
+
|
|
318
|
+
if [[ -f "$point_path/pubspec.lock" ]]; then
|
|
319
|
+
cp "$point_path/pubspec.lock" "$PROJECT_ROOT/"
|
|
320
|
+
success "Restored pubspec.lock"
|
|
321
|
+
fi
|
|
322
|
+
|
|
323
|
+
if [[ -f "$point_path/requirements.txt" ]]; then
|
|
324
|
+
cp "$point_path/requirements.txt" "$PROJECT_ROOT/"
|
|
325
|
+
success "Restored requirements.txt"
|
|
326
|
+
fi
|
|
327
|
+
|
|
328
|
+
# Rollback git if commit is available
|
|
329
|
+
if [[ -n "$commit" && "$commit" != "unknown" ]]; then
|
|
330
|
+
info "Rolling back git state..."
|
|
331
|
+
rollback_to_commit "$commit" "false"
|
|
332
|
+
fi
|
|
333
|
+
|
|
334
|
+
# Reinstall dependencies
|
|
335
|
+
echo ""
|
|
336
|
+
info "Dependencies may need to be reinstalled:"
|
|
337
|
+
if [[ -f "$PROJECT_ROOT/package.json" ]]; then
|
|
338
|
+
echo " npm install"
|
|
339
|
+
fi
|
|
340
|
+
if [[ -f "$PROJECT_ROOT/pubspec.yaml" ]]; then
|
|
341
|
+
echo " flutter pub get"
|
|
342
|
+
fi
|
|
343
|
+
if [[ -f "$PROJECT_ROOT/requirements.txt" ]]; then
|
|
344
|
+
echo " pip install -r requirements.txt"
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
echo ""
|
|
348
|
+
success "Rollback complete!"
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
# Main rollback function for migrations
|
|
352
|
+
rollback_migration() {
|
|
353
|
+
local migration_id="$1"
|
|
354
|
+
local dry_run="$2"
|
|
355
|
+
local force="$3"
|
|
356
|
+
|
|
357
|
+
echo -e "${BOLD}Rolling back migration: $migration_id${NC}"
|
|
358
|
+
echo ""
|
|
359
|
+
|
|
360
|
+
# Look for a rollback point for this migration
|
|
361
|
+
local rollback_point=$(ls -d "$ROLLBACK_DIR"/*"$migration_id"* 2>/dev/null | tail -1)
|
|
362
|
+
|
|
363
|
+
if [[ -n "$rollback_point" && -d "$rollback_point" ]]; then
|
|
364
|
+
info "Found rollback point: $(basename "$rollback_point")"
|
|
365
|
+
rollback_from_point "$(basename "$rollback_point")" "$dry_run"
|
|
366
|
+
return 0
|
|
367
|
+
fi
|
|
368
|
+
|
|
369
|
+
# Look for migration spec with rollback instructions
|
|
370
|
+
local spec_file=$(find_migration_spec "$migration_id")
|
|
371
|
+
|
|
372
|
+
if [[ -n "$spec_file" ]]; then
|
|
373
|
+
info "Found migration spec: $spec_file"
|
|
374
|
+
|
|
375
|
+
local steps=$(parse_rollback_steps "$spec_file")
|
|
376
|
+
|
|
377
|
+
if [[ -n "$steps" ]]; then
|
|
378
|
+
echo ""
|
|
379
|
+
echo -e "${BOLD}Rollback Steps:${NC}"
|
|
380
|
+
echo "$steps" | nl
|
|
381
|
+
echo ""
|
|
382
|
+
|
|
383
|
+
if [[ "$dry_run" == "true" ]]; then
|
|
384
|
+
info "[DRY RUN] Would execute the above rollback steps"
|
|
385
|
+
return 0
|
|
386
|
+
fi
|
|
387
|
+
|
|
388
|
+
if ! confirm "Execute these rollback steps?"; then
|
|
389
|
+
info "Rollback cancelled."
|
|
390
|
+
return 0
|
|
391
|
+
fi
|
|
392
|
+
|
|
393
|
+
# Execute steps (basic implementation - just displays them)
|
|
394
|
+
info "Please execute the following steps manually:"
|
|
395
|
+
echo "$steps" | nl
|
|
396
|
+
else
|
|
397
|
+
warning "No rollback steps found in migration spec"
|
|
398
|
+
fi
|
|
399
|
+
else
|
|
400
|
+
warning "No migration spec found for: $migration_id"
|
|
401
|
+
fi
|
|
402
|
+
|
|
403
|
+
# Offer git-based rollback
|
|
404
|
+
echo ""
|
|
405
|
+
info "You can also rollback using git:"
|
|
406
|
+
echo " 1. Find the commit before the migration:"
|
|
407
|
+
echo " git log --oneline --all | head -20"
|
|
408
|
+
echo ""
|
|
409
|
+
echo " 2. Rollback to that commit:"
|
|
410
|
+
echo " git checkout <commit> -- ."
|
|
411
|
+
echo ""
|
|
412
|
+
echo " 3. Or use this tool with a specific rollback point:"
|
|
413
|
+
echo " ./rollback-migration.sh --list"
|
|
414
|
+
echo " ./rollback-migration.sh --restore <point-name>"
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
################################################################################
|
|
418
|
+
# Main
|
|
419
|
+
################################################################################
|
|
420
|
+
|
|
421
|
+
print_usage() {
|
|
422
|
+
echo "Usage: ./rollback-migration.sh <migration-id> [options]"
|
|
423
|
+
echo ""
|
|
424
|
+
echo "Commands:"
|
|
425
|
+
echo " <migration-id> Rollback a specific migration"
|
|
426
|
+
echo " --list List available rollback points"
|
|
427
|
+
echo " --create <name> Create a new rollback point"
|
|
428
|
+
echo " --restore <point> Restore from a specific rollback point"
|
|
429
|
+
echo " --cleanup [keep-count] Delete old rollback points (default: keep 10)"
|
|
430
|
+
echo ""
|
|
431
|
+
echo "Options:"
|
|
432
|
+
echo " --dry-run Preview rollback without executing"
|
|
433
|
+
echo " --force Force rollback without confirmation"
|
|
434
|
+
echo " --help Show this help message"
|
|
435
|
+
echo ""
|
|
436
|
+
echo "Examples:"
|
|
437
|
+
echo " ./rollback-migration.sh react-18 # Rollback react-18 migration"
|
|
438
|
+
echo " ./rollback-migration.sh react-18 --dry-run # Preview the rollback"
|
|
439
|
+
echo " ./rollback-migration.sh --create before-upgrade # Create rollback point"
|
|
440
|
+
echo " ./rollback-migration.sh --list # List rollback points"
|
|
441
|
+
echo ""
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
main() {
|
|
445
|
+
local command=""
|
|
446
|
+
local dry_run="false"
|
|
447
|
+
local force="false"
|
|
448
|
+
local create_name=""
|
|
449
|
+
local restore_point=""
|
|
450
|
+
local cleanup_keep=""
|
|
451
|
+
|
|
452
|
+
# Parse arguments
|
|
453
|
+
while [[ $# -gt 0 ]]; do
|
|
454
|
+
case "$1" in
|
|
455
|
+
--list|-l)
|
|
456
|
+
command="list"
|
|
457
|
+
;;
|
|
458
|
+
--create|-c)
|
|
459
|
+
command="create"
|
|
460
|
+
shift
|
|
461
|
+
create_name="$1"
|
|
462
|
+
;;
|
|
463
|
+
--restore|-r)
|
|
464
|
+
command="restore"
|
|
465
|
+
shift
|
|
466
|
+
restore_point="$1"
|
|
467
|
+
;;
|
|
468
|
+
--cleanup)
|
|
469
|
+
command="cleanup"
|
|
470
|
+
shift
|
|
471
|
+
if [[ "$1" =~ ^[0-9]+$ ]]; then
|
|
472
|
+
cleanup_keep="$1"
|
|
473
|
+
else
|
|
474
|
+
# Not a number, don't consume
|
|
475
|
+
cleanup_keep="10"
|
|
476
|
+
continue
|
|
477
|
+
fi
|
|
478
|
+
;;
|
|
479
|
+
--dry-run)
|
|
480
|
+
dry_run="true"
|
|
481
|
+
;;
|
|
482
|
+
--force|-f)
|
|
483
|
+
force="true"
|
|
484
|
+
;;
|
|
485
|
+
--help|-h)
|
|
486
|
+
print_usage
|
|
487
|
+
exit 0
|
|
488
|
+
;;
|
|
489
|
+
-*)
|
|
490
|
+
error "Unknown option: $1"
|
|
491
|
+
;;
|
|
492
|
+
*)
|
|
493
|
+
if [[ -z "$command" ]]; then
|
|
494
|
+
command="rollback"
|
|
495
|
+
fi
|
|
496
|
+
[[ -z "$migration_id" ]] && migration_id="$1"
|
|
497
|
+
;;
|
|
498
|
+
esac
|
|
499
|
+
shift
|
|
500
|
+
done
|
|
501
|
+
|
|
502
|
+
print_header
|
|
503
|
+
|
|
504
|
+
# Ensure rollback directory exists
|
|
505
|
+
mkdir -p "$ROLLBACK_DIR"
|
|
506
|
+
|
|
507
|
+
case "$command" in
|
|
508
|
+
list)
|
|
509
|
+
list_rollback_points
|
|
510
|
+
;;
|
|
511
|
+
create)
|
|
512
|
+
if [[ -z "$create_name" ]]; then
|
|
513
|
+
error "Please provide a name for the rollback point"
|
|
514
|
+
fi
|
|
515
|
+
create_rollback_point "$create_name"
|
|
516
|
+
;;
|
|
517
|
+
restore)
|
|
518
|
+
if [[ -z "$restore_point" ]]; then
|
|
519
|
+
error "Please provide a rollback point name"
|
|
520
|
+
fi
|
|
521
|
+
rollback_from_point "$restore_point" "$dry_run"
|
|
522
|
+
;;
|
|
523
|
+
cleanup)
|
|
524
|
+
cleanup_rollback_points "${cleanup_keep:-10}"
|
|
525
|
+
;;
|
|
526
|
+
rollback)
|
|
527
|
+
if [[ -z "$migration_id" ]]; then
|
|
528
|
+
print_usage
|
|
529
|
+
exit 1
|
|
530
|
+
fi
|
|
531
|
+
rollback_migration "$migration_id" "$dry_run" "$force"
|
|
532
|
+
;;
|
|
533
|
+
*)
|
|
534
|
+
print_usage
|
|
535
|
+
exit 1
|
|
536
|
+
;;
|
|
537
|
+
esac
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
main "$@"
|