create-entity-server 0.0.9 → 0.0.23
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/bin/create.js +26 -8
- package/package.json +1 -1
- package/template/.env.example +20 -3
- package/template/configs/database.json +173 -10
- package/template/configs/jwt.json +1 -0
- package/template/configs/oauth.json +37 -0
- package/template/configs/push.json +26 -0
- package/template/entities/Account/account_audit.json +4 -5
- package/template/entities/README.md +4 -4
- package/template/entities/{Auth → System/Auth}/account.json +0 -14
- package/template/entities/System/system_audit_log.json +14 -8
- package/template/samples/README.md +43 -21
- package/template/samples/browser/entity-server-client.js +453 -0
- package/template/samples/browser/example.html +498 -0
- package/template/samples/entities/01_basic_fields.json +39 -0
- package/template/samples/entities/02_types_and_defaults.json +67 -0
- package/template/samples/entities/03_hash_and_unique.json +33 -0
- package/template/samples/entities/04_fk_and_composite_unique.json +29 -0
- package/template/samples/entities/05_cache.json +55 -0
- package/template/samples/entities/06_history_and_hard_delete.json +60 -0
- package/template/samples/entities/07_license_scope.json +52 -0
- package/template/samples/entities/08_hook_sql.json +52 -0
- package/template/samples/entities/09_hook_entity.json +65 -0
- package/template/samples/entities/10_hook_submit_delete.json +78 -0
- package/template/samples/entities/11_hook_webhook.json +84 -0
- package/template/samples/entities/12_hook_push.json +73 -0
- package/template/samples/entities/13_read_only.json +54 -0
- package/template/samples/entities/14_optimistic_lock.json +29 -0
- package/template/samples/entities/15_reset_defaults.json +94 -0
- package/template/samples/entities/16_isolated_license.json +62 -0
- package/template/samples/entities/README.md +91 -0
- package/template/samples/flutter/lib/entity_server_client.dart +261 -48
- package/template/samples/java/EntityServerClient.java +325 -61
- package/template/samples/java/EntityServerExample.java +4 -3
- package/template/samples/kotlin/EntityServerClient.kt +261 -45
- package/template/samples/node/src/EntityServerClient.js +348 -59
- package/template/samples/node/src/example.js +9 -9
- package/template/samples/php/ci4/Config/EntityServer.php +14 -0
- package/template/samples/php/ci4/Controllers/EntityController.php +202 -0
- package/template/samples/php/ci4/Controllers/ProductController.php +16 -76
- package/template/samples/php/ci4/Libraries/EntityServer.php +352 -60
- package/template/samples/php/laravel/Services/EntityServerService.php +245 -40
- package/template/samples/python/entity_server.py +287 -68
- package/template/samples/python/example.py +7 -6
- package/template/samples/react/src/example.tsx +41 -25
- package/template/samples/swift/EntityServerClient.swift +248 -37
- package/template/scripts/normalize-entities.sh +10 -10
- package/template/scripts/run.ps1 +12 -3
- package/template/scripts/run.sh +120 -37
- package/template/scripts/update-server.ps1 +160 -4
- package/template/scripts/update-server.sh +132 -4
- package/template/samples/react/src/api/entityServerClient.ts +0 -290
- package/template/samples/react/src/hooks/useEntity.ts +0 -105
- /package/template/entities/{Auth → System/Auth}/api_keys.json +0 -0
- /package/template/entities/{Auth → System/Auth}/license.json +0 -0
- /package/template/entities/{Auth → System/Auth}/rbac_roles.json +0 -0
package/template/scripts/run.sh
CHANGED
|
@@ -11,6 +11,10 @@ DATABASE_CONFIG="$PROJECT_ROOT/configs/database.json"
|
|
|
11
11
|
RUN_DIR="$PROJECT_ROOT/.run"
|
|
12
12
|
PID_FILE="$RUN_DIR/entity-server.pid"
|
|
13
13
|
STDOUT_LOG="$PROJECT_ROOT/logs/server.out.log"
|
|
14
|
+
SERVER_BIN="$PROJECT_ROOT/bin/entity-server"
|
|
15
|
+
if [ ! -f "$SERVER_BIN" ] && [ -f "$PROJECT_ROOT/entity-server" ]; then
|
|
16
|
+
SERVER_BIN="$PROJECT_ROOT/entity-server"
|
|
17
|
+
fi
|
|
14
18
|
|
|
15
19
|
mkdir -p "$RUN_DIR" "$PROJECT_ROOT/logs"
|
|
16
20
|
|
|
@@ -25,6 +29,22 @@ get_server_value() {
|
|
|
25
29
|
local fallback="$2"
|
|
26
30
|
local value
|
|
27
31
|
|
|
32
|
+
if [ "$key" = "port" ]; then
|
|
33
|
+
local env_port
|
|
34
|
+
env_port="${SERVER_PORT:-${PORT:-}}"
|
|
35
|
+
if [ -z "$env_port" ] && [ -f .env ]; then
|
|
36
|
+
env_port=$(grep '^SERVER_PORT=' .env | tail -n 1 | cut -d '=' -f2-)
|
|
37
|
+
if [ -z "$env_port" ]; then
|
|
38
|
+
env_port=$(grep '^PORT=' .env | tail -n 1 | cut -d '=' -f2-)
|
|
39
|
+
fi
|
|
40
|
+
fi
|
|
41
|
+
env_port=$(echo "$env_port" | tr -d '[:space:]')
|
|
42
|
+
if [[ "$env_port" =~ ^[0-9]+$ ]] && [ "$env_port" -gt 0 ]; then
|
|
43
|
+
echo "$env_port"
|
|
44
|
+
return
|
|
45
|
+
fi
|
|
46
|
+
fi
|
|
47
|
+
|
|
28
48
|
value=$(grep -E "\"$key\"[[:space:]]*:" "$SERVER_CONFIG" | head -n 1 | sed -E 's/.*:[[:space:]]*"?([^",}]+)"?.*/\1/')
|
|
29
49
|
value=$(echo "$value" | tr -d '[:space:]')
|
|
30
50
|
if [ -z "$value" ]; then
|
|
@@ -35,60 +55,61 @@ get_server_value() {
|
|
|
35
55
|
}
|
|
36
56
|
|
|
37
57
|
is_running() {
|
|
58
|
+
local port_pid
|
|
59
|
+
port_pid=$(find_pid_by_port)
|
|
60
|
+
|
|
38
61
|
if [ ! -f "$PID_FILE" ]; then
|
|
62
|
+
if [ -n "$port_pid" ] && kill -0 "$port_pid" 2>/dev/null; then
|
|
63
|
+
return 0
|
|
64
|
+
fi
|
|
39
65
|
return 1
|
|
40
66
|
fi
|
|
41
67
|
local pid
|
|
42
68
|
pid=$(cat "$PID_FILE" 2>/dev/null)
|
|
43
69
|
if [ -z "$pid" ]; then
|
|
70
|
+
if [ -n "$port_pid" ] && kill -0 "$port_pid" 2>/dev/null; then
|
|
71
|
+
return 0
|
|
72
|
+
fi
|
|
44
73
|
return 1
|
|
45
74
|
fi
|
|
46
|
-
kill -0 "$pid" 2>/dev/null
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
stop_server() {
|
|
50
|
-
if [ ! -f "$PID_FILE" ]; then
|
|
51
|
-
if [ "$LANGUAGE" = "en" ]; then
|
|
52
|
-
echo "ℹ️ Server is not running (pid file not found)."
|
|
53
|
-
else
|
|
54
|
-
echo "ℹ️ 서버가 실행 중이 아닙니다 (pid 파일 없음)."
|
|
55
|
-
fi
|
|
75
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
56
76
|
return 0
|
|
57
77
|
fi
|
|
58
78
|
|
|
59
|
-
|
|
60
|
-
pid=$(cat "$PID_FILE" 2>/dev/null)
|
|
61
|
-
if [ -z "$pid" ]; then
|
|
62
|
-
rm -f "$PID_FILE"
|
|
63
|
-
if [ "$LANGUAGE" = "en" ]; then
|
|
64
|
-
echo "ℹ️ Empty pid file removed."
|
|
65
|
-
else
|
|
66
|
-
echo "ℹ️ 비어있는 pid 파일을 정리했습니다."
|
|
67
|
-
fi
|
|
79
|
+
if [ -n "$port_pid" ] && kill -0 "$port_pid" 2>/dev/null; then
|
|
68
80
|
return 0
|
|
69
81
|
fi
|
|
70
82
|
|
|
83
|
+
return 1
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
find_pid_by_port() {
|
|
87
|
+
local port
|
|
88
|
+
port=$(get_server_value "port" "3400")
|
|
89
|
+
ss -ltnp 2>/dev/null | grep ":$port " | sed -n 's/.*pid=\([0-9]\+\).*/\1/p' | head -n 1
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
stop_pid_with_confirm() {
|
|
93
|
+
local pid="$1"
|
|
94
|
+
local reason="$2"
|
|
95
|
+
|
|
96
|
+
if [ -z "$pid" ]; then
|
|
97
|
+
return 1
|
|
98
|
+
fi
|
|
71
99
|
if ! kill -0 "$pid" 2>/dev/null; then
|
|
72
|
-
|
|
73
|
-
if [ "$LANGUAGE" = "en" ]; then
|
|
74
|
-
echo "ℹ️ Stale pid file removed (process not found)."
|
|
75
|
-
else
|
|
76
|
-
echo "ℹ️ 실행 중인 프로세스가 없어 stale pid 파일을 정리했습니다."
|
|
77
|
-
fi
|
|
78
|
-
return 0
|
|
100
|
+
return 1
|
|
79
101
|
fi
|
|
80
102
|
|
|
81
|
-
# 실행 중인 프로세스 정보 표시 후 확인
|
|
82
103
|
local proc_info
|
|
83
104
|
proc_info=$(ps -p "$pid" -o pid,user,etime,args --no-headers 2>/dev/null | head -1)
|
|
84
105
|
if [ "$LANGUAGE" = "en" ]; then
|
|
85
|
-
echo "Running process:"
|
|
106
|
+
echo "Running process ($reason):"
|
|
86
107
|
echo " PID USER ELAPSED COMMAND"
|
|
87
108
|
echo " $proc_info"
|
|
88
109
|
echo ""
|
|
89
110
|
read -r -p "Stop this process? [y/N]: " input
|
|
90
111
|
else
|
|
91
|
-
echo "실행 중인
|
|
112
|
+
echo "실행 중인 프로세스($reason):"
|
|
92
113
|
echo " PID USER 실행시간 COMMAND"
|
|
93
114
|
echo " $proc_info"
|
|
94
115
|
echo ""
|
|
@@ -128,16 +149,78 @@ stop_server() {
|
|
|
128
149
|
return 0
|
|
129
150
|
}
|
|
130
151
|
|
|
152
|
+
stop_server() {
|
|
153
|
+
if [ ! -f "$PID_FILE" ]; then
|
|
154
|
+
local port_pid
|
|
155
|
+
port_pid=$(find_pid_by_port)
|
|
156
|
+
if [ -n "$port_pid" ]; then
|
|
157
|
+
stop_pid_with_confirm "$port_pid" "port fallback"
|
|
158
|
+
return $?
|
|
159
|
+
fi
|
|
160
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
161
|
+
echo "ℹ️ Server is not running (pid file not found)."
|
|
162
|
+
else
|
|
163
|
+
echo "ℹ️ 서버가 실행 중이 아닙니다 (pid 파일 없음)."
|
|
164
|
+
fi
|
|
165
|
+
return 0
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
local pid
|
|
169
|
+
pid=$(cat "$PID_FILE" 2>/dev/null)
|
|
170
|
+
if [ -z "$pid" ]; then
|
|
171
|
+
rm -f "$PID_FILE"
|
|
172
|
+
local port_pid
|
|
173
|
+
port_pid=$(find_pid_by_port)
|
|
174
|
+
if [ -n "$port_pid" ]; then
|
|
175
|
+
stop_pid_with_confirm "$port_pid" "port fallback"
|
|
176
|
+
return $?
|
|
177
|
+
fi
|
|
178
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
179
|
+
echo "ℹ️ Empty pid file removed."
|
|
180
|
+
else
|
|
181
|
+
echo "ℹ️ 비어있는 pid 파일을 정리했습니다."
|
|
182
|
+
fi
|
|
183
|
+
return 0
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
if ! kill -0 "$pid" 2>/dev/null; then
|
|
187
|
+
rm -f "$PID_FILE"
|
|
188
|
+
local port_pid
|
|
189
|
+
port_pid=$(find_pid_by_port)
|
|
190
|
+
if [ -n "$port_pid" ]; then
|
|
191
|
+
stop_pid_with_confirm "$port_pid" "port fallback"
|
|
192
|
+
return $?
|
|
193
|
+
fi
|
|
194
|
+
if [ "$LANGUAGE" = "en" ]; then
|
|
195
|
+
echo "ℹ️ Stale pid file removed (process not found)."
|
|
196
|
+
else
|
|
197
|
+
echo "ℹ️ 실행 중인 프로세스가 없어 stale pid 파일을 정리했습니다."
|
|
198
|
+
fi
|
|
199
|
+
return 0
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
stop_pid_with_confirm "$pid" "pid file"
|
|
203
|
+
return $?
|
|
204
|
+
}
|
|
205
|
+
|
|
131
206
|
show_status() {
|
|
132
207
|
if is_running; then
|
|
133
|
-
|
|
208
|
+
local status_pid
|
|
209
|
+
status_pid=$(find_pid_by_port)
|
|
210
|
+
"$SERVER_BIN" banner-status RUNNING
|
|
134
211
|
if [ "$LANGUAGE" = "en" ]; then
|
|
212
|
+
if [ -n "$status_pid" ]; then
|
|
213
|
+
echo "PID: $status_pid (detected by port)"
|
|
214
|
+
fi
|
|
135
215
|
echo "Stop: ./run.sh stop"
|
|
136
216
|
else
|
|
217
|
+
if [ -n "$status_pid" ]; then
|
|
218
|
+
echo "PID: $status_pid (포트 기준 감지)"
|
|
219
|
+
fi
|
|
137
220
|
echo "중지: ./run.sh stop"
|
|
138
221
|
fi
|
|
139
222
|
else
|
|
140
|
-
|
|
223
|
+
"$SERVER_BIN" banner-status STOPPED
|
|
141
224
|
if [ "$LANGUAGE" = "en" ]; then
|
|
142
225
|
echo "Start: ./run.sh start"
|
|
143
226
|
else
|
|
@@ -210,11 +293,11 @@ if [ ! -f "$DATABASE_CONFIG" ]; then
|
|
|
210
293
|
exit 1
|
|
211
294
|
fi
|
|
212
295
|
|
|
213
|
-
if [ ! -f
|
|
296
|
+
if [ ! -f "$SERVER_BIN" ]; then
|
|
214
297
|
if [ "$LANGUAGE" = "en" ]; then
|
|
215
|
-
echo "❌ bin/entity-server
|
|
298
|
+
echo "❌ entity-server binary not found (bin/entity-server or ./entity-server)"
|
|
216
299
|
else
|
|
217
|
-
echo "❌ bin/entity-server
|
|
300
|
+
echo "❌ entity-server 바이너리 파일이 없습니다 (bin/entity-server 또는 ./entity-server)"
|
|
218
301
|
fi
|
|
219
302
|
exit 1
|
|
220
303
|
fi
|
|
@@ -241,7 +324,7 @@ case "$MODE" in
|
|
|
241
324
|
|
|
242
325
|
sed -E -i 's/("environment"[[:space:]]*:[[:space:]]*")[^"]+(")/\1development\2/' "$SERVER_CONFIG"
|
|
243
326
|
sed -E -i 's/("default"[[:space:]]*:[[:space:]]*")[^"]+(")/\1development\2/' "$DATABASE_CONFIG"
|
|
244
|
-
|
|
327
|
+
"$SERVER_BIN"
|
|
245
328
|
;;
|
|
246
329
|
|
|
247
330
|
start)
|
|
@@ -266,8 +349,8 @@ case "$MODE" in
|
|
|
266
349
|
sed -E -i 's/("environment"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$SERVER_CONFIG"
|
|
267
350
|
sed -E -i 's/("default"[[:space:]]*:[[:space:]]*")[^"]+(")/\1production\2/' "$DATABASE_CONFIG"
|
|
268
351
|
|
|
269
|
-
|
|
270
|
-
nohup
|
|
352
|
+
"$SERVER_BIN" banner
|
|
353
|
+
nohup "$SERVER_BIN" >> "$STDOUT_LOG" 2>&1 &
|
|
271
354
|
SERVER_PID=$!
|
|
272
355
|
echo "$SERVER_PID" > "$PID_FILE"
|
|
273
356
|
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
# update-server.ps1 — entity-server / entity-cli 바이너리 업데이트
|
|
1
|
+
# update-server.ps1 — entity-server / entity-cli 바이너리 및 파일 업데이트
|
|
2
2
|
#
|
|
3
3
|
# 사용법:
|
|
4
4
|
# .\scripts\update-server.ps1 # 도움말
|
|
5
5
|
# .\scripts\update-server.ps1 version # 현재 버전 + 최신 버전 확인
|
|
6
6
|
# .\scripts\update-server.ps1 latest # 최신 버전으로 업데이트
|
|
7
7
|
# .\scripts\update-server.ps1 1.5.0 # 특정 버전으로 업데이트
|
|
8
|
+
#
|
|
9
|
+
# 업데이트 대상:
|
|
10
|
+
# - 바이너리: entity-server, entity-cli
|
|
11
|
+
# - 파일: scripts/ samples/ (configs/ entities/ docs/ 제외)
|
|
8
12
|
|
|
9
13
|
param([string]$Action = "")
|
|
10
14
|
|
|
@@ -12,14 +16,75 @@ $ErrorActionPreference = "Stop"
|
|
|
12
16
|
|
|
13
17
|
$REPO = "ehfuse/entity-server"
|
|
14
18
|
$BINARIES = @("entity-server", "entity-cli")
|
|
19
|
+
$DIST_DIRS = @("scripts", "samples")
|
|
15
20
|
$PLATFORM = "windows"
|
|
16
21
|
$ARCH_TAG = "x64"
|
|
17
22
|
$ProjectRoot = Split-Path -Parent $PSScriptRoot
|
|
18
23
|
|
|
24
|
+
function Get-RunningServerPid {
|
|
25
|
+
$PidFile = Join-Path $ProjectRoot ".run\entity-server.pid"
|
|
26
|
+
if (Test-Path $PidFile) {
|
|
27
|
+
$pidValue = (Get-Content $PidFile -ErrorAction SilentlyContinue | Select-Object -First 1).Trim()
|
|
28
|
+
if ($pidValue -match '^\d+$') {
|
|
29
|
+
try {
|
|
30
|
+
$p = Get-Process -Id ([int]$pidValue) -ErrorAction Stop
|
|
31
|
+
if ($p) { return [int]$pidValue }
|
|
32
|
+
} catch {}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
$proc = Get-Process -Name "entity-server" -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
37
|
+
if ($proc) { return [int]$proc.Id }
|
|
38
|
+
return $null
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function Ensure-ServerStopped {
|
|
42
|
+
$pidValue = Get-RunningServerPid
|
|
43
|
+
if (-not $pidValue) { return }
|
|
44
|
+
|
|
45
|
+
Write-Host ""
|
|
46
|
+
Write-Host "⚠️ 현재 Entity Server가 실행 중입니다."
|
|
47
|
+
try {
|
|
48
|
+
$p = Get-Process -Id $pidValue -ErrorAction Stop
|
|
49
|
+
Write-Host ("PID: {0} Name: {1} Start: {2}" -f $p.Id, $p.ProcessName, $p.StartTime)
|
|
50
|
+
} catch {}
|
|
51
|
+
Write-Host ""
|
|
52
|
+
|
|
53
|
+
$answer = Read-Host "업데이트를 위해 서버를 중지할까요? [y/N]"
|
|
54
|
+
if ($answer -notmatch '^[Yy](es)?$') {
|
|
55
|
+
Write-Host "❌ 업데이트를 취소했습니다."
|
|
56
|
+
exit 1
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
$RunScript = Join-Path $ProjectRoot "scripts\run.ps1"
|
|
60
|
+
if (Test-Path $RunScript) {
|
|
61
|
+
try {
|
|
62
|
+
& $RunScript stop
|
|
63
|
+
} catch {}
|
|
64
|
+
} else {
|
|
65
|
+
try {
|
|
66
|
+
Stop-Process -Id $pidValue -Force -ErrorAction Stop
|
|
67
|
+
} catch {}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
Start-Sleep -Milliseconds 200
|
|
71
|
+
$still = Get-RunningServerPid
|
|
72
|
+
if ($still) {
|
|
73
|
+
Write-Host "❌ 서버 중지에 실패했습니다. 업데이트를 중단합니다."
|
|
74
|
+
exit 1
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
Write-Host "✅ 서버 중지 완료"
|
|
78
|
+
}
|
|
79
|
+
|
|
19
80
|
# ── 현재 버전 확인 ────────────────────────────────────────────────────────────
|
|
20
81
|
|
|
21
82
|
function Get-CurrentVer {
|
|
22
|
-
$BinPath = Join-Path $ProjectRoot "entity-server.exe"
|
|
83
|
+
$BinPath = Join-Path $ProjectRoot "bin\entity-server.exe"
|
|
84
|
+
if (-not (Test-Path $BinPath)) {
|
|
85
|
+
$LegacyBin = Join-Path $ProjectRoot "entity-server.exe"
|
|
86
|
+
if (Test-Path $LegacyBin) { $BinPath = $LegacyBin }
|
|
87
|
+
}
|
|
23
88
|
if (Test-Path $BinPath) {
|
|
24
89
|
try {
|
|
25
90
|
$out = & $BinPath --version 2>$null
|
|
@@ -47,6 +112,8 @@ function Install-Version([string]$TargetVer) {
|
|
|
47
112
|
$TargetVer = $TargetVer -replace '^v', ''
|
|
48
113
|
$CurrentVer = Get-CurrentVer
|
|
49
114
|
|
|
115
|
+
Ensure-ServerStopped
|
|
116
|
+
|
|
50
117
|
Write-Host ""
|
|
51
118
|
Write-Host "📦 entity-server v$TargetVer 다운로드 중... ($PLATFORM-$ARCH_TAG)"
|
|
52
119
|
Write-Host ""
|
|
@@ -54,7 +121,11 @@ function Install-Version([string]$TargetVer) {
|
|
|
54
121
|
foreach ($Bin in $BINARIES) {
|
|
55
122
|
$FileName = "$Bin-$PLATFORM-$ARCH_TAG.exe"
|
|
56
123
|
$Url = "https://github.com/$REPO/releases/download/v$TargetVer/$FileName"
|
|
57
|
-
$
|
|
124
|
+
$BinDir = Join-Path $ProjectRoot "bin"
|
|
125
|
+
if (-not (Test-Path $BinDir)) {
|
|
126
|
+
New-Item -ItemType Directory -Path $BinDir | Out-Null
|
|
127
|
+
}
|
|
128
|
+
$Dest = Join-Path $BinDir "$Bin.exe"
|
|
58
129
|
$Tmp = "$Dest.tmp"
|
|
59
130
|
|
|
60
131
|
Write-Host (" ↓ {0,-35}" -f $FileName) -NoNewline
|
|
@@ -71,22 +142,107 @@ function Install-Version([string]$TargetVer) {
|
|
|
71
142
|
}
|
|
72
143
|
}
|
|
73
144
|
|
|
145
|
+
Install-Dist $TargetVer
|
|
146
|
+
|
|
74
147
|
Write-Host ""
|
|
75
148
|
Write-Host "✅ 업데이트 완료: v$CurrentVer → v$TargetVer"
|
|
76
149
|
Write-Host " 서버를 재시작하면 새 버전이 적용됩니다."
|
|
77
150
|
}
|
|
78
151
|
|
|
152
|
+
# ── dist 파일 업데이트 (scripts / samples) ──────────────────────────────────
|
|
153
|
+
|
|
154
|
+
function Install-Dist([string]$TargetVer) {
|
|
155
|
+
$TargetVer = $TargetVer -replace '^v', ''
|
|
156
|
+
$FileName = "dist.tar.gz"
|
|
157
|
+
$Url = "https://github.com/$REPO/releases/download/v$TargetVer/$FileName"
|
|
158
|
+
$TmpTar = Join-Path $env:TEMP ("entity-server-dist-$TargetVer.tar.gz")
|
|
159
|
+
$TmpDir = Join-Path $env:TEMP ("entity-server-dist-$TargetVer")
|
|
160
|
+
|
|
161
|
+
Write-Host (" ↓ {0,-35}" -f $FileName) -NoNewline
|
|
162
|
+
try {
|
|
163
|
+
Invoke-WebRequest -Uri $Url -OutFile $TmpTar -UseBasicParsing
|
|
164
|
+
Write-Host "✓"
|
|
165
|
+
} catch {
|
|
166
|
+
Write-Host "✗ 실패 (업데이트 스킵)"
|
|
167
|
+
Write-Host " URL: $Url"
|
|
168
|
+
Write-Host " ⚠️ dist.tar.gz 가 릴리스에 없습니다. 바이너리만 업데이트됩니다."
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (Test-Path $TmpDir) {
|
|
173
|
+
Remove-Item -Recurse -Force $TmpDir
|
|
174
|
+
}
|
|
175
|
+
New-Item -ItemType Directory -Path $TmpDir | Out-Null
|
|
176
|
+
|
|
177
|
+
# tar.exe 사용 (Windows 10+/PowerShell 5+ 기본 포함 환경 가정)
|
|
178
|
+
$TarCmd = Get-Command tar -ErrorAction SilentlyContinue
|
|
179
|
+
if (-not $TarCmd) {
|
|
180
|
+
Write-Host " ⚠️ tar 명령을 찾지 못해 dist 동기화를 건너뜁니다."
|
|
181
|
+
if (Test-Path $TmpTar) { Remove-Item -Force $TmpTar }
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
& tar -xzf $TmpTar -C $TmpDir
|
|
187
|
+
} catch {
|
|
188
|
+
Write-Host " ⚠️ dist 압축 해제 실패: $_"
|
|
189
|
+
if (Test-Path $TmpTar) { Remove-Item -Force $TmpTar }
|
|
190
|
+
if (Test-Path $TmpDir) { Remove-Item -Recurse -Force $TmpDir }
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
$SrcRoot = $TmpDir
|
|
195
|
+
$HasTopLevel = $false
|
|
196
|
+
foreach ($Dir in $DIST_DIRS) {
|
|
197
|
+
if (Test-Path (Join-Path $TmpDir $Dir)) {
|
|
198
|
+
$HasTopLevel = $true
|
|
199
|
+
break
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (-not $HasTopLevel) {
|
|
204
|
+
$FirstSubdir = Get-ChildItem -Path $TmpDir -Directory | Select-Object -First 1
|
|
205
|
+
if ($FirstSubdir) {
|
|
206
|
+
$SrcRoot = $FirstSubdir.FullName
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
Write-Host ""
|
|
211
|
+
Write-Host " 파일 동기화 (configs/ entities/ docs/ 제외):"
|
|
212
|
+
foreach ($Dir in $DIST_DIRS) {
|
|
213
|
+
$Src = Join-Path $SrcRoot $Dir
|
|
214
|
+
$Dest = Join-Path $ProjectRoot $Dir
|
|
215
|
+
if (Test-Path $Src) {
|
|
216
|
+
if (Test-Path $Dest) {
|
|
217
|
+
Remove-Item -Recurse -Force $Dest
|
|
218
|
+
}
|
|
219
|
+
Copy-Item -Recurse -Force $Src $Dest
|
|
220
|
+
Write-Host (" ✔ {0,-20}" -f ("$Dir/"))
|
|
221
|
+
} else {
|
|
222
|
+
Write-Host (" – {0,-20} (릴리스에 없음, 스킵)" -f ("$Dir/"))
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (Test-Path $TmpTar) { Remove-Item -Force $TmpTar }
|
|
227
|
+
if (Test-Path $TmpDir) { Remove-Item -Recurse -Force $TmpDir }
|
|
228
|
+
}
|
|
229
|
+
|
|
79
230
|
# ── 서브커맨드 분기 ───────────────────────────────────────────────────────────
|
|
80
231
|
|
|
81
232
|
switch ($Action) {
|
|
82
233
|
"" {
|
|
83
|
-
Write-Host "update-server.ps1 — entity-server / entity-cli 바이너리 업데이트"
|
|
234
|
+
Write-Host "update-server.ps1 — entity-server / entity-cli 바이너리 및 파일 업데이트"
|
|
84
235
|
Write-Host ""
|
|
85
236
|
Write-Host "사용법:"
|
|
86
237
|
Write-Host " .\scripts\update-server.ps1 version 현재 버전 + 최신 버전 확인"
|
|
87
238
|
Write-Host " .\scripts\update-server.ps1 latest 최신 버전으로 업데이트"
|
|
88
239
|
Write-Host " .\scripts\update-server.ps1 <버전> 특정 버전으로 업데이트"
|
|
89
240
|
Write-Host ""
|
|
241
|
+
Write-Host "업데이트 대상:"
|
|
242
|
+
Write-Host " 바이너리 entity-server entity-cli"
|
|
243
|
+
Write-Host " 파일 scripts/ samples/"
|
|
244
|
+
Write-Host " 제외 configs/ entities/ docs/ (local 설정 보존)"
|
|
245
|
+
Write-Host ""
|
|
90
246
|
Write-Host "예시:"
|
|
91
247
|
Write-Host " .\scripts\update-server.ps1 version"
|
|
92
248
|
Write-Host " .\scripts\update-server.ps1 latest"
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# update-server.sh — entity-server / entity-cli 바이너리 업데이트
|
|
2
|
+
# update-server.sh — entity-server / entity-cli 바이너리 및 파일 업데이트
|
|
3
3
|
#
|
|
4
4
|
# 사용법:
|
|
5
5
|
# ./scripts/update-server.sh # 도움말
|
|
6
6
|
# ./scripts/update-server.sh version # 현재 버전 + 최신 버전 확인
|
|
7
7
|
# ./scripts/update-server.sh latest # 최신 버전으로 업데이트
|
|
8
8
|
# ./scripts/update-server.sh 1.5.0 # 특정 버전으로 업데이트
|
|
9
|
+
#
|
|
10
|
+
# 업데이트 대상:
|
|
11
|
+
# - 바이너리: entity-server, entity-cli
|
|
12
|
+
# - 파일: scripts/ samples/ (configs/ entities/ docs/ 제외)
|
|
9
13
|
|
|
10
14
|
set -e
|
|
11
15
|
|
|
@@ -13,6 +17,57 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
13
17
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
14
18
|
REPO="ehfuse/entity-server"
|
|
15
19
|
BINARIES=("entity-server" "entity-cli")
|
|
20
|
+
DIST_DIRS=("scripts" "samples")
|
|
21
|
+
|
|
22
|
+
_find_running_pid() {
|
|
23
|
+
local pid_file="$PROJECT_ROOT/.run/entity-server.pid"
|
|
24
|
+
if [ -f "$pid_file" ]; then
|
|
25
|
+
local pid
|
|
26
|
+
pid=$(cat "$pid_file" 2>/dev/null)
|
|
27
|
+
if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then
|
|
28
|
+
echo "$pid"
|
|
29
|
+
return 0
|
|
30
|
+
fi
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
pgrep -f "${PROJECT_ROOT}/(bin/)?entity-server( |$)" | head -n 1
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
_ensure_server_stopped() {
|
|
37
|
+
local pid
|
|
38
|
+
pid="$(_find_running_pid)"
|
|
39
|
+
|
|
40
|
+
if [ -z "$pid" ]; then
|
|
41
|
+
return 0
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
echo ""
|
|
45
|
+
echo "⚠️ 현재 Entity Server가 실행 중입니다."
|
|
46
|
+
ps -p "$pid" -o pid,etime,cmd --no-headers 2>/dev/null || true
|
|
47
|
+
echo ""
|
|
48
|
+
read -r -p "업데이트를 위해 서버를 중지할까요? [y/N]: " input
|
|
49
|
+
input=$(echo "$input" | tr '[:upper:]' '[:lower:]')
|
|
50
|
+
|
|
51
|
+
if [ "$input" != "y" ] && [ "$input" != "yes" ]; then
|
|
52
|
+
echo "❌ 업데이트를 취소했습니다."
|
|
53
|
+
exit 1
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
if [ -x "$PROJECT_ROOT/scripts/run.sh" ]; then
|
|
57
|
+
"$PROJECT_ROOT/scripts/run.sh" stop || true
|
|
58
|
+
else
|
|
59
|
+
kill "$pid" 2>/dev/null || true
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
sleep 0.2
|
|
63
|
+
pid="$(_find_running_pid)"
|
|
64
|
+
if [ -n "$pid" ]; then
|
|
65
|
+
echo "❌ 서버 중지에 실패했습니다. 업데이트를 중단합니다."
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
echo "✅ 서버 중지 완료"
|
|
70
|
+
}
|
|
16
71
|
|
|
17
72
|
# ── 플랫폼 감지 ───────────────────────────────────────────────────────────────
|
|
18
73
|
|
|
@@ -41,7 +96,10 @@ esac
|
|
|
41
96
|
# ── 현재 버전 확인 ────────────────────────────────────────────────────────────
|
|
42
97
|
|
|
43
98
|
_current_ver() {
|
|
44
|
-
local bin="$PROJECT_ROOT/entity-server"
|
|
99
|
+
local bin="$PROJECT_ROOT/bin/entity-server"
|
|
100
|
+
if [ ! -x "$bin" ] && [ -x "$PROJECT_ROOT/entity-server" ]; then
|
|
101
|
+
bin="$PROJECT_ROOT/entity-server"
|
|
102
|
+
fi
|
|
45
103
|
if [ -x "$bin" ]; then
|
|
46
104
|
"$bin" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "(알 수 없음)"
|
|
47
105
|
else
|
|
@@ -95,14 +153,19 @@ _install() {
|
|
|
95
153
|
local current_ver
|
|
96
154
|
current_ver="$(_current_ver)"
|
|
97
155
|
|
|
156
|
+
_ensure_server_stopped
|
|
157
|
+
|
|
98
158
|
echo ""
|
|
99
159
|
echo "📦 entity-server v${target_ver} 다운로드 중... (${PLATFORM}-${ARCH_TAG})"
|
|
100
160
|
echo ""
|
|
101
161
|
|
|
162
|
+
# 바이너리 다운로드
|
|
163
|
+
mkdir -p "$PROJECT_ROOT/bin"
|
|
164
|
+
|
|
102
165
|
for BIN in "${BINARIES[@]}"; do
|
|
103
166
|
local file="${BIN}-${PLATFORM}-${ARCH_TAG}"
|
|
104
167
|
local url="https://github.com/${REPO}/releases/download/v${target_ver}/${file}"
|
|
105
|
-
local dest="$PROJECT_ROOT/$BIN"
|
|
168
|
+
local dest="$PROJECT_ROOT/bin/$BIN"
|
|
106
169
|
|
|
107
170
|
printf " ↓ %-32s" "$file"
|
|
108
171
|
if _download "$url" "$dest" 2>/dev/null; then
|
|
@@ -114,24 +177,89 @@ _install() {
|
|
|
114
177
|
fi
|
|
115
178
|
done
|
|
116
179
|
|
|
180
|
+
# scripts / samples 업데이트
|
|
181
|
+
_install_dist "$target_ver"
|
|
182
|
+
|
|
117
183
|
echo ""
|
|
118
184
|
echo "✅ 업데이트 완료: v${current_ver} → v${target_ver}"
|
|
119
185
|
echo " 서버를 재시작하면 새 버전이 적용됩니다."
|
|
120
186
|
}
|
|
121
187
|
|
|
188
|
+
# ── dist 파일 업데이트 (scripts / samples) ──────────────────────────────────────
|
|
189
|
+
|
|
190
|
+
_install_dist() {
|
|
191
|
+
local target_ver="$1"
|
|
192
|
+
local file="dist.tar.gz"
|
|
193
|
+
local url="https://github.com/${REPO}/releases/download/v${target_ver}/${file}"
|
|
194
|
+
local tmp_tar="/tmp/entity-server-dist-${target_ver}.tar.gz"
|
|
195
|
+
local tmp_dir="/tmp/entity-server-dist-${target_ver}"
|
|
196
|
+
|
|
197
|
+
printf " ↓ %-32s" "$file"
|
|
198
|
+
if ! _download "$url" "$tmp_tar" 2>/dev/null; then
|
|
199
|
+
echo "✗ 실패 (업데이트 스킵)"
|
|
200
|
+
echo " URL: $url"
|
|
201
|
+
echo " ⚠️ dist.tar.gz 가 릴리스에 없익니다. 바이너리만 업데이트됨."
|
|
202
|
+
return 0
|
|
203
|
+
fi
|
|
204
|
+
echo "✓"
|
|
205
|
+
|
|
206
|
+
rm -rf "$tmp_dir"
|
|
207
|
+
mkdir -p "$tmp_dir"
|
|
208
|
+
tar -xzf "$tmp_tar" -C "$tmp_dir" 2>/dev/null
|
|
209
|
+
|
|
210
|
+
# 아카이브 내부 디렉토리 구조 자동 탐지 (top-level 또는 서브디렉토리)
|
|
211
|
+
local src_root="$tmp_dir"
|
|
212
|
+
local found_dir="false"
|
|
213
|
+
for dir in "${DIST_DIRS[@]}"; do
|
|
214
|
+
if [ -d "${tmp_dir}/${dir}" ]; then
|
|
215
|
+
found_dir="true"
|
|
216
|
+
break
|
|
217
|
+
fi
|
|
218
|
+
done
|
|
219
|
+
if [ "$found_dir" = "false" ]; then
|
|
220
|
+
# tar가 서브디렉토리 하나로 풌주는 경우 (예: entity-server-1.5.0/)
|
|
221
|
+
local subdir
|
|
222
|
+
subdir="$(ls -1 "$tmp_dir" | head -1)"
|
|
223
|
+
if [ -n "$subdir" ] && [ -d "${tmp_dir}/${subdir}" ]; then
|
|
224
|
+
src_root="${tmp_dir}/${subdir}"
|
|
225
|
+
fi
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
echo ""
|
|
229
|
+
echo " 파일 동기화 (configs/ entities/ 제외):"
|
|
230
|
+
for DIR in "${DIST_DIRS[@]}"; do
|
|
231
|
+
local src="${src_root}/${DIR}"
|
|
232
|
+
local dest="${PROJECT_ROOT}/${DIR}"
|
|
233
|
+
if [ -d "$src" ]; then
|
|
234
|
+
rm -rf "$dest"
|
|
235
|
+
cp -r "$src" "$dest"
|
|
236
|
+
printf " ✔ %-20s\n" "${DIR}/"
|
|
237
|
+
else
|
|
238
|
+
printf " – %-20s (릴리스에 없음, 스킵)\n" "${DIR}/"
|
|
239
|
+
fi
|
|
240
|
+
done
|
|
241
|
+
|
|
242
|
+
rm -rf "$tmp_dir" "$tmp_tar"
|
|
243
|
+
}
|
|
244
|
+
|
|
122
245
|
# ── 서브커맨드 분기 ───────────────────────────────────────────────────────────
|
|
123
246
|
|
|
124
247
|
ARG="${1:-}"
|
|
125
248
|
|
|
126
249
|
case "$ARG" in
|
|
127
250
|
"")
|
|
128
|
-
echo "update-server.sh — entity-server / entity-cli 바이너리 업데이트"
|
|
251
|
+
echo "update-server.sh — entity-server / entity-cli 바이너리 및 파일 업데이트"
|
|
129
252
|
echo ""
|
|
130
253
|
echo "사용법:"
|
|
131
254
|
echo " ./scripts/update-server.sh version 현재 버전 + 최신 버전 확인"
|
|
132
255
|
echo " ./scripts/update-server.sh latest 최신 버전으로 업데이트"
|
|
133
256
|
echo " ./scripts/update-server.sh <버전> 특정 버전으로 업데이트"
|
|
134
257
|
echo ""
|
|
258
|
+
echo "업데이트 대상:"
|
|
259
|
+
echo " 바이너리 entity-server entity-cli"
|
|
260
|
+
echo " 파일 scripts/ samples/"
|
|
261
|
+
echo " 제외 configs/ entities/ docs/ (local 설정 보존)"
|
|
262
|
+
echo ""
|
|
135
263
|
echo "예시:"
|
|
136
264
|
echo " ./scripts/update-server.sh version"
|
|
137
265
|
echo " ./scripts/update-server.sh latest"
|