openmoneta-dev-kit 1.9.0 → 1.9.2
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/README.md +13 -34
- package/VERSION +1 -0
- package/install-opencode.ps1 +192 -0
- package/install-opencode.sh +168 -0
- package/install.ps1 +162 -0
- package/install.sh +172 -0
- package/package.json +11 -2
- package/scripts/init-project.sh +12 -6
- package/src/cli.js +3 -3
- package/src/commands/install.js +32 -32
- package/templates/AGENTS.md.tpl +1 -1
- package/templates/docs-INDEX.md.tpl +1 -0
- package/templates/plans-INDEX.md.tpl +1 -0
- package/uninstall.ps1 +86 -0
- package/uninstall.sh +93 -0
- package/update.ps1 +240 -0
- package/update.sh +265 -0
package/update.ps1
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# update.ps1 - Pull latest từ git remote, cài lại global, và sync project (Windows).
|
|
2
|
+
#
|
|
3
|
+
# Usage:
|
|
4
|
+
# .\update.ps1 # global + prompt sync current project
|
|
5
|
+
# .\update.ps1 -Yes # global + auto-sync. Skip nếu đã latest
|
|
6
|
+
# .\update.ps1 -Yes -Force # global + auto-sync, luôn cài lại
|
|
7
|
+
# .\update.ps1 -Check # chỉ check, không cài
|
|
8
|
+
# .\update.ps1 -Project C:\path # global + sync thêm project chỉ định
|
|
9
|
+
# .\update.ps1 -SkipProjects # global only (old behavior)
|
|
10
|
+
|
|
11
|
+
param(
|
|
12
|
+
[switch]$Yes,
|
|
13
|
+
[switch]$Force,
|
|
14
|
+
[switch]$Check,
|
|
15
|
+
[switch]$SkipProjects,
|
|
16
|
+
[string[]]$Project
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
$ErrorActionPreference = 'Stop'
|
|
20
|
+
$RepoDir = $PSScriptRoot
|
|
21
|
+
$OriginalPwd = (Get-Location).Path
|
|
22
|
+
Set-Location $RepoDir
|
|
23
|
+
|
|
24
|
+
Write-Host "==> OpenMoneta Dev Kit Updater (Windows)"
|
|
25
|
+
Write-Host " Repo: $RepoDir"
|
|
26
|
+
Write-Host ""
|
|
27
|
+
|
|
28
|
+
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
|
29
|
+
Write-Error "git chưa cài. Tải tại https://git-scm.com/download/win"
|
|
30
|
+
exit 1
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (-not (Test-Path '.git')) {
|
|
34
|
+
Write-Error "$RepoDir không phải git repo. Clone lại: git clone <repo-url> $RepoDir"
|
|
35
|
+
exit 1
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Helper: check if path is a valid OpenMoneta project
|
|
39
|
+
function Test-OpenMonetaProject {
|
|
40
|
+
param([string]$Dir)
|
|
41
|
+
if (-not (Test-Path "$Dir\docs\INDEX.md")) { return $false }
|
|
42
|
+
$absDir = (Resolve-Path $Dir -ErrorAction SilentlyContinue).Path
|
|
43
|
+
$absKit = (Resolve-Path $RepoDir -ErrorAction SilentlyContinue).Path
|
|
44
|
+
if ($absDir -eq $absKit) { return $false }
|
|
45
|
+
return $true
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Helper: sync one project
|
|
49
|
+
function Sync-Project {
|
|
50
|
+
param([string]$Dir)
|
|
51
|
+
$name = Split-Path $Dir -Leaf
|
|
52
|
+
|
|
53
|
+
Write-Host ""
|
|
54
|
+
Write-Host "──────────────────────────────────────────────"
|
|
55
|
+
Write-Host " Syncing project: $name"
|
|
56
|
+
Write-Host " Path: $Dir"
|
|
57
|
+
Write-Host "──────────────────────────────────────────────"
|
|
58
|
+
|
|
59
|
+
if (-not (Test-Path $Dir)) {
|
|
60
|
+
Write-Host " [!] Directory không tồn tại, skip."
|
|
61
|
+
return $false
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (-not (Test-OpenMonetaProject $Dir)) {
|
|
65
|
+
Write-Host " [!] Không phải OpenMoneta project (thiếu docs/INDEX.md), skip."
|
|
66
|
+
return $false
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
$initCmd = "bash `"$RepoDir\scripts\init-project.sh`" `"$Dir`""
|
|
70
|
+
|
|
71
|
+
if ($Yes) {
|
|
72
|
+
Write-Host " Running: $initCmd"
|
|
73
|
+
Invoke-Expression $initCmd
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
$ans = Read-Host " Sync project này? [Y/n]"
|
|
77
|
+
if ($ans -eq 'n' -or $ans -eq 'N') {
|
|
78
|
+
Write-Host " Skip."
|
|
79
|
+
return $true
|
|
80
|
+
}
|
|
81
|
+
Invoke-Expression $initCmd
|
|
82
|
+
}
|
|
83
|
+
return $true
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
# Helper: collect projects to sync
|
|
87
|
+
function Get-OpenMonetaProjects {
|
|
88
|
+
$found = @()
|
|
89
|
+
|
|
90
|
+
# Check current directory (if not the kit repo)
|
|
91
|
+
if (-not (Test-OpenMonetaProject $RepoDir)) {
|
|
92
|
+
if ((Test-OpenMonetaProject $OriginalPwd) -and (
|
|
93
|
+
(Resolve-Path $OriginalPwd -ErrorAction SilentlyContinue).Path -ne
|
|
94
|
+
(Resolve-Path $RepoDir -ErrorAction SilentlyContinue).Path)) {
|
|
95
|
+
$found += (Resolve-Path $OriginalPwd).Path
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Add --project paths
|
|
100
|
+
foreach ($p in $Project) {
|
|
101
|
+
if (Test-Path $p) {
|
|
102
|
+
$absP = (Resolve-Path $p).Path
|
|
103
|
+
if ($found -notcontains $absP) {
|
|
104
|
+
$found += $absP
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return $found
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# === Step 1: Git pull ===
|
|
113
|
+
$Status = git status --porcelain 2>$null
|
|
114
|
+
if ($Status) {
|
|
115
|
+
Write-Host "[WARNING] Có thay đổi local chưa commit:" -ForegroundColor Yellow
|
|
116
|
+
git status --short
|
|
117
|
+
Write-Host ""
|
|
118
|
+
$ans = Read-Host "Stash và tiếp tục? [y/N]"
|
|
119
|
+
if ($ans -notin @('y', 'Y', 'yes', 'YES')) {
|
|
120
|
+
Write-Host "Hủy."
|
|
121
|
+
exit 0
|
|
122
|
+
}
|
|
123
|
+
git stash push -m "auto-stash by update.ps1 $(Get-Date -Format 'yyyy-MM-ddTHH:mm:ssK')"
|
|
124
|
+
Write-Host "Đã stash. Khôi phục bằng: cd $RepoDir; git stash pop"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
$CurrentVersion = (Get-Content VERSION -Raw).Trim()
|
|
128
|
+
Write-Host "Version hiện tại: v$CurrentVersion"
|
|
129
|
+
|
|
130
|
+
Write-Host ""
|
|
131
|
+
Write-Host "==> git pull..."
|
|
132
|
+
$Branch = git rev-parse --abbrev-ref HEAD
|
|
133
|
+
git pull origin $Branch
|
|
134
|
+
|
|
135
|
+
$NewVersion = (Get-Content VERSION -Raw).Trim()
|
|
136
|
+
# === Step 1B: Check-only mode ===
|
|
137
|
+
if ($Check) {
|
|
138
|
+
if ($CurrentVersion -ne $NewVersion) {
|
|
139
|
+
Write-Host ""
|
|
140
|
+
Write-Host "🔔 Update available: v$CurrentVersion -> v$NewVersion"
|
|
141
|
+
Write-Host " Chạy: .\$RepoDir\update.ps1"
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
Write-Host ""
|
|
145
|
+
Write-Host "✅ Đã ở phiên bản mới nhất (v$CurrentVersion)."
|
|
146
|
+
}
|
|
147
|
+
exit 0
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
# === Step 1C: Skip if already latest (-Yes mode, no -Force) ===
|
|
151
|
+
if ($Yes -and -not $Force -and $CurrentVersion -eq $NewVersion) {
|
|
152
|
+
Write-Host ""
|
|
153
|
+
Write-Host "✅ Already at latest version (v$CurrentVersion), skipping reinstall."
|
|
154
|
+
Write-Host " Dùng -Force để cài lại bất kể version."
|
|
155
|
+
exit 0
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if ($CurrentVersion -eq $NewVersion) {
|
|
159
|
+
Write-Host ""
|
|
160
|
+
Write-Host "Đã ở phiên bản mới nhất (v$CurrentVersion). Vẫn cài lại để đảm bảo đồng bộ."
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
# === Step 2: Global install ===
|
|
164
|
+
Write-Host ""
|
|
165
|
+
Write-Host "==> Chạy install.ps1..."
|
|
166
|
+
& "$RepoDir\install.ps1" -Yes
|
|
167
|
+
|
|
168
|
+
Write-Host ""
|
|
169
|
+
Write-Host "✅ Global update hoàn tất: v$CurrentVersion -> v$NewVersion" -ForegroundColor Green
|
|
170
|
+
if ($CurrentVersion -ne $NewVersion) {
|
|
171
|
+
Write-Host ""
|
|
172
|
+
Write-Host "Xem CHANGELOG để biết thay đổi:"
|
|
173
|
+
Write-Host " Get-Content $RepoDir\CHANGELOG.md"
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
# === Step 3: Project sync ===
|
|
177
|
+
if ($SkipProjects) {
|
|
178
|
+
Write-Host ""
|
|
179
|
+
Write-Host "-SkipProjects: bỏ qua sync project."
|
|
180
|
+
Write-Host ""
|
|
181
|
+
Write-Host "Để sync project sau: bash $RepoDir\scripts\init-project.sh <path>"
|
|
182
|
+
exit 0
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
$Projects = Get-OpenMonetaProjects
|
|
186
|
+
|
|
187
|
+
if ($Projects.Count -eq 0) {
|
|
188
|
+
Write-Host ""
|
|
189
|
+
Write-Host "Không phát hiện project OpenMoneta nào."
|
|
190
|
+
if ($Project.Count -eq 0) {
|
|
191
|
+
Write-Host ""
|
|
192
|
+
Write-Host "Để sync project, chạy từ thư mục project hoặc dùng:"
|
|
193
|
+
Write-Host " .\$RepoDir\update.ps1 -Project C:\path\to\project"
|
|
194
|
+
Write-Host ""
|
|
195
|
+
Write-Host "Hoặc sync thủ công từng project:"
|
|
196
|
+
Write-Host " bash $RepoDir\scripts\init-project.sh <path>"
|
|
197
|
+
}
|
|
198
|
+
exit 0
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
Write-Host ""
|
|
202
|
+
Write-Host "================================================"
|
|
203
|
+
Write-Host " Phát hiện $($Projects.Count) project OpenMoneta"
|
|
204
|
+
Write-Host "================================================"
|
|
205
|
+
foreach ($proj in $Projects) {
|
|
206
|
+
$projName = Split-Path $proj -Leaf
|
|
207
|
+
Write-Host " - $projName ($proj)"
|
|
208
|
+
}
|
|
209
|
+
Write-Host ""
|
|
210
|
+
|
|
211
|
+
if ($Project.Count -eq 0 -and -not $Yes) {
|
|
212
|
+
$ans = Read-Host "Sync tất cả project đã phát hiện? [Y/n]"
|
|
213
|
+
if ($ans -eq 'n' -or $ans -eq 'N') {
|
|
214
|
+
Write-Host "Skip. Sync thủ công sau: bash $RepoDir\scripts\init-project.sh <path>"
|
|
215
|
+
exit 0
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
$SyncCount = 0
|
|
220
|
+
$SyncFail = 0
|
|
221
|
+
foreach ($proj in $Projects) {
|
|
222
|
+
if (Sync-Project $proj) {
|
|
223
|
+
$SyncCount++
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
$SyncFail++
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
Write-Host ""
|
|
231
|
+
Write-Host "================================================"
|
|
232
|
+
Write-Host "✅ Tất cả hoàn tất."
|
|
233
|
+
Write-Host " Global: v$CurrentVersion -> v$NewVersion"
|
|
234
|
+
Write-Host " Projects synced: $SyncCount"
|
|
235
|
+
if ($SyncFail -gt 0) {
|
|
236
|
+
Write-Host " Failed: $SyncFail"
|
|
237
|
+
}
|
|
238
|
+
Write-Host "================================================"
|
|
239
|
+
Write-Host ""
|
|
240
|
+
Write-Host "Restart Cursor để áp dụng changes."
|
package/update.sh
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# update.sh - Pull latest từ git remote, cài lại global, và sync project.
|
|
3
|
+
# Dùng cho macOS/Linux. Windows dùng update.ps1.
|
|
4
|
+
#
|
|
5
|
+
# Usage:
|
|
6
|
+
# bash update.sh # global + prompt sync current project
|
|
7
|
+
# bash update.sh --yes # global + auto-sync. Skip nếu đã latest
|
|
8
|
+
# bash update.sh --yes --force # global + auto-sync, luôn cài lại
|
|
9
|
+
# bash update.sh --check # chỉ check, không cài
|
|
10
|
+
# bash update.sh --project /path # global + sync thêm project chỉ định
|
|
11
|
+
# bash update.sh --skip-projects # global only (old behavior)
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
REPO_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
16
|
+
ORIGINAL_PWD="$(pwd)"
|
|
17
|
+
|
|
18
|
+
# === Parse args ===
|
|
19
|
+
AUTO_YES=0
|
|
20
|
+
SKIP_PROJECTS=0
|
|
21
|
+
FORCE=0
|
|
22
|
+
CHECK_ONLY=0
|
|
23
|
+
PROJECT_PATHS=()
|
|
24
|
+
|
|
25
|
+
for arg in "$@"; do
|
|
26
|
+
case "$arg" in
|
|
27
|
+
--yes|-y) AUTO_YES=1 ;;
|
|
28
|
+
--force) FORCE=1 ;;
|
|
29
|
+
--check) CHECK_ONLY=1 ;;
|
|
30
|
+
--skip-projects) SKIP_PROJECTS=1 ;;
|
|
31
|
+
--help|-h)
|
|
32
|
+
grep '^#' "$0" | sed 's/^# \?//' | head -17
|
|
33
|
+
exit 0
|
|
34
|
+
;;
|
|
35
|
+
--project)
|
|
36
|
+
shift
|
|
37
|
+
if [[ -n "${1:-}" && "${1:-}" != -* ]]; then
|
|
38
|
+
PROJECT_PATHS+=("$1")
|
|
39
|
+
fi
|
|
40
|
+
;;
|
|
41
|
+
*)
|
|
42
|
+
if [[ "$arg" != -* ]]; then
|
|
43
|
+
PROJECT_PATHS+=("$arg")
|
|
44
|
+
fi
|
|
45
|
+
;;
|
|
46
|
+
esac
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
cd "$REPO_DIR"
|
|
50
|
+
|
|
51
|
+
echo "==> OpenMoneta Dev Kit Updater"
|
|
52
|
+
echo " Repo: $REPO_DIR"
|
|
53
|
+
echo ""
|
|
54
|
+
|
|
55
|
+
if ! command -v git >/dev/null 2>&1; then
|
|
56
|
+
echo "[!] git chưa cài." >&2
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
if [[ ! -d ".git" ]]; then
|
|
61
|
+
echo "[!] $REPO_DIR không phải git repo. Clone lại:"
|
|
62
|
+
echo " git clone <repo-url> $REPO_DIR"
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# === Helper: check if path is a valid OpenMoneta project ===
|
|
67
|
+
is_openmoneta_project() {
|
|
68
|
+
local dir="$1"
|
|
69
|
+
[[ -d "$dir/docs" && -f "$dir/docs/INDEX.md" ]] || return 1
|
|
70
|
+
[[ "$(cd "$dir" 2>/dev/null && pwd -P || echo "")" != "$REPO_DIR" ]] || return 1
|
|
71
|
+
return 0
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# === Helper: sync one project ===
|
|
75
|
+
sync_project() {
|
|
76
|
+
local dir="$1"
|
|
77
|
+
local name
|
|
78
|
+
name="$(basename "$dir")"
|
|
79
|
+
|
|
80
|
+
echo ""
|
|
81
|
+
echo "──────────────────────────────────────────────"
|
|
82
|
+
echo " Syncing project: $name"
|
|
83
|
+
echo " Path: $dir"
|
|
84
|
+
echo "──────────────────────────────────────────────"
|
|
85
|
+
|
|
86
|
+
if [[ ! -d "$dir" ]]; then
|
|
87
|
+
echo " [!] Directory không tồn tại, skip."
|
|
88
|
+
return 1
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
if ! is_openmoneta_project "$dir"; then
|
|
92
|
+
echo " [!] Không phải OpenMoneta project (thiếu docs/INDEX.md), skip."
|
|
93
|
+
return 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
local init_cmd="bash \"$REPO_DIR/scripts/init-project.sh\" \"$dir\""
|
|
97
|
+
|
|
98
|
+
if [[ $AUTO_YES -eq 1 ]]; then
|
|
99
|
+
echo " Running: $init_cmd"
|
|
100
|
+
eval "$init_cmd"
|
|
101
|
+
else
|
|
102
|
+
read -r -p " Sync project này? [Y/n] " ans < /dev/tty
|
|
103
|
+
if [[ "$ans" == "n" || "$ans" == "N" ]]; then
|
|
104
|
+
echo " Skip."
|
|
105
|
+
return 0
|
|
106
|
+
fi
|
|
107
|
+
eval "$init_cmd"
|
|
108
|
+
fi
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
# === Helper: collect projects to sync ===
|
|
112
|
+
collect_projects() {
|
|
113
|
+
local found=()
|
|
114
|
+
|
|
115
|
+
if ! is_openmoneta_project "$REPO_DIR"; then
|
|
116
|
+
local abs_kit
|
|
117
|
+
abs_kit="$(cd "$REPO_DIR" && pwd -P)"
|
|
118
|
+
if is_openmoneta_project "$ORIGINAL_PWD" && [[ "$(cd "$ORIGINAL_PWD" && pwd -P)" != "$abs_kit" ]]; then
|
|
119
|
+
found+=("$ORIGINAL_PWD")
|
|
120
|
+
fi
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
for p in "${PROJECT_PATHS[@]}"; do
|
|
124
|
+
local abs_p
|
|
125
|
+
abs_p="$(cd "$p" 2>/dev/null && pwd -P 2>/dev/null || echo "")"
|
|
126
|
+
if [[ -n "$abs_p" && -d "$abs_p" ]]; then
|
|
127
|
+
local already=0
|
|
128
|
+
for f in "${found[@]}"; do
|
|
129
|
+
[[ "$f" == "$abs_p" ]] && already=1 && break
|
|
130
|
+
done
|
|
131
|
+
[[ $already -eq 0 ]] && found+=("$abs_p")
|
|
132
|
+
fi
|
|
133
|
+
done
|
|
134
|
+
|
|
135
|
+
printf '%s\n' "${found[@]}"
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# === Step 1: Git pull ===
|
|
139
|
+
if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
|
|
140
|
+
echo "[WARNING] Có thay đổi local chưa commit:"
|
|
141
|
+
git status --short
|
|
142
|
+
echo ""
|
|
143
|
+
read -r -p "Stash và tiếp tục? [y/N] " ans
|
|
144
|
+
if [[ "$ans" != "y" && "$ans" != "Y" ]]; then
|
|
145
|
+
echo "Hủy."
|
|
146
|
+
exit 0
|
|
147
|
+
fi
|
|
148
|
+
git stash push -m "auto-stash by update.sh $(date -Iseconds)"
|
|
149
|
+
echo "Đã stash. Khôi phục bằng: cd $REPO_DIR && git stash pop"
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
CURRENT_VERSION=$(cat VERSION 2>/dev/null || echo "unknown")
|
|
153
|
+
echo "Version hiện tại: v$CURRENT_VERSION"
|
|
154
|
+
|
|
155
|
+
echo ""
|
|
156
|
+
echo "==> git pull..."
|
|
157
|
+
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
158
|
+
git pull origin "$BRANCH"
|
|
159
|
+
|
|
160
|
+
NEW_VERSION=$(cat VERSION 2>/dev/null || echo "unknown")
|
|
161
|
+
# === Step 1B: Check-only mode ===
|
|
162
|
+
if [[ $CHECK_ONLY -eq 1 ]]; then
|
|
163
|
+
if [[ "$CURRENT_VERSION" != "$NEW_VERSION" ]]; then
|
|
164
|
+
echo ""
|
|
165
|
+
echo "🔔 Update available: v$CURRENT_VERSION → v$NEW_VERSION"
|
|
166
|
+
echo " Chạy: bash $REPO_DIR/update.sh"
|
|
167
|
+
exit 0
|
|
168
|
+
else
|
|
169
|
+
echo ""
|
|
170
|
+
echo "✅ Đã ở phiên bản mới nhất (v$CURRENT_VERSION)."
|
|
171
|
+
exit 0
|
|
172
|
+
fi
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# === Step 1C: Skip if already latest (--yes mode, no --force) ===
|
|
176
|
+
if [[ $AUTO_YES -eq 1 && $FORCE -eq 0 && "$CURRENT_VERSION" == "$NEW_VERSION" ]]; then
|
|
177
|
+
echo ""
|
|
178
|
+
echo "✅ Already at latest version (v$CURRENT_VERSION), skipping reinstall."
|
|
179
|
+
echo " Dùng --force để cài lại bất kể version."
|
|
180
|
+
exit 0
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
if [[ "$CURRENT_VERSION" == "$NEW_VERSION" ]]; then
|
|
184
|
+
echo ""
|
|
185
|
+
echo "Đã ở phiên bản mới nhất (v$CURRENT_VERSION). Vẫn cài lại để đảm bảo đồng bộ."
|
|
186
|
+
fi
|
|
187
|
+
|
|
188
|
+
# === Step 2: Global install ===
|
|
189
|
+
echo ""
|
|
190
|
+
echo "==> Chạy install.sh..."
|
|
191
|
+
bash "$REPO_DIR/install.sh" --yes
|
|
192
|
+
|
|
193
|
+
echo ""
|
|
194
|
+
echo "✅ Global update hoàn tất: v$CURRENT_VERSION → v$NEW_VERSION"
|
|
195
|
+
echo ""
|
|
196
|
+
if [[ "$CURRENT_VERSION" != "$NEW_VERSION" ]]; then
|
|
197
|
+
echo "Xem CHANGELOG để biết thay đổi:"
|
|
198
|
+
echo " cat $REPO_DIR/CHANGELOG.md"
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# === Step 3: Project sync ===
|
|
202
|
+
if [[ $SKIP_PROJECTS -eq 1 ]]; then
|
|
203
|
+
echo ""
|
|
204
|
+
echo "--skip-projects: bỏ qua sync project."
|
|
205
|
+
echo ""
|
|
206
|
+
echo "Để sync project sau: bash $REPO_DIR/scripts/init-project.sh /path/to/project"
|
|
207
|
+
exit 0
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
PROJECTS=$(collect_projects)
|
|
211
|
+
|
|
212
|
+
if [[ -z "$PROJECTS" ]]; then
|
|
213
|
+
echo ""
|
|
214
|
+
echo "Không phát hiện project OpenMoneta nào."
|
|
215
|
+
if [[ ${#PROJECT_PATHS[@]} -eq 0 ]]; then
|
|
216
|
+
echo ""
|
|
217
|
+
echo "Để sync project, chạy từ thư mục project hoặc dùng:"
|
|
218
|
+
echo " bash $REPO_DIR/update.sh --project /path/to/project"
|
|
219
|
+
echo ""
|
|
220
|
+
echo "Hoặc sync thủ công từng project:"
|
|
221
|
+
echo " bash $REPO_DIR/scripts/init-project.sh /path/to/project"
|
|
222
|
+
fi
|
|
223
|
+
exit 0
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
echo ""
|
|
227
|
+
echo "================================================"
|
|
228
|
+
echo " Phát hiện $(echo "$PROJECTS" | wc -l | tr -d ' ') project OpenMoneta"
|
|
229
|
+
echo "================================================"
|
|
230
|
+
while IFS= read -r proj; do
|
|
231
|
+
[[ -z "$proj" ]] && continue
|
|
232
|
+
echo " - $(basename "$proj") ($proj)"
|
|
233
|
+
done <<< "$PROJECTS"
|
|
234
|
+
echo ""
|
|
235
|
+
|
|
236
|
+
if [[ ${#PROJECT_PATHS[@]} -eq 0 && $AUTO_YES -eq 0 ]]; then
|
|
237
|
+
read -r -p "Sync tất cả project đã phát hiện? [Y/n] " ans < /dev/tty
|
|
238
|
+
if [[ "$ans" == "n" || "$ans" == "N" ]]; then
|
|
239
|
+
echo "Skip. Sync thủ công sau: bash $REPO_DIR/scripts/init-project.sh /path/to/project"
|
|
240
|
+
exit 0
|
|
241
|
+
fi
|
|
242
|
+
fi
|
|
243
|
+
|
|
244
|
+
SYNC_COUNT=0
|
|
245
|
+
SYNC_FAIL=0
|
|
246
|
+
while IFS= read -r proj; do
|
|
247
|
+
[[ -z "$proj" ]] && continue
|
|
248
|
+
if sync_project "$proj"; then
|
|
249
|
+
SYNC_COUNT=$((SYNC_COUNT + 1))
|
|
250
|
+
else
|
|
251
|
+
SYNC_FAIL=$((SYNC_FAIL + 1))
|
|
252
|
+
fi
|
|
253
|
+
done <<< "$PROJECTS"
|
|
254
|
+
|
|
255
|
+
echo ""
|
|
256
|
+
echo "================================================"
|
|
257
|
+
echo "✅ Tất cả hoàn tất."
|
|
258
|
+
echo " Global: v$CURRENT_VERSION → v$NEW_VERSION"
|
|
259
|
+
echo " Projects synced: $SYNC_COUNT"
|
|
260
|
+
if [[ $SYNC_FAIL -gt 0 ]]; then
|
|
261
|
+
echo " Failed: $SYNC_FAIL"
|
|
262
|
+
fi
|
|
263
|
+
echo "================================================"
|
|
264
|
+
echo ""
|
|
265
|
+
echo "Restart Cursor để áp dụng changes."
|