#!/usr/bin/env bash # published latest.json(로컬·원격)·설치 파일·tauri.conf 중 최대 +1 patch set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" WORK_TREE="${WORK_TREE:-$ROOT}" CONF="${WORK_TREE}/desktop/src-tauri/tauri.conf.json" LATEST="${WORK_TREE}/frontend/public/desktop/updates/latest.json" UPDATES_DIR="${WORK_TREE}/frontend/public/desktop/updates" BUILD_INFO="${WORK_TREE}/dist-desktop/build-info.json" RELEASE_DIR="${GC_DESKTOP_APP_RELEASE_DIR:-$WORK_TREE/data/desktop-releases}" PUBLISHED_LATEST_URL="${DESKTOP_PUBLISHED_LATEST_URL:-${DESKTOP_UPDATE_BASE_URL:-https://stock.exdev.co.kr/desktop/updates}/latest.json}" PUBLISHED_LATEST_URL="${PUBLISHED_LATEST_URL/http:\/\/exdev.co.kr/https://stock.exdev.co.kr}" PUBLISHED_LATEST_URL="${PUBLISHED_LATEST_URL/https:\/\/exdev.co.kr/https://stock.exdev.co.kr}" REMOTE_PUB_VER="" if REMOTE_JSON="$(curl -sf --connect-timeout 5 --max-time 12 "$PUBLISHED_LATEST_URL" 2>/dev/null)"; then REMOTE_PUB_VER="$(printf '%s' "$REMOTE_JSON" | node -e " let d=''; process.stdin.on('data',c=>d+=c); process.stdin.on('end',()=>{ try { console.log(JSON.parse(d).version||''); } catch { console.log(''); } }); " 2>/dev/null || true)" [[ -n "$REMOTE_PUB_VER" ]] && echo "[bump-desktop] remote latest.json → v${REMOTE_PUB_VER} (${PUBLISHED_LATEST_URL})" >&2 fi node -e " const fs = require('fs'); const path = require('path'); const confPath = process.argv[1]; const latestPath = process.argv[2]; const updatesDir = process.argv[3]; const buildInfoPath = process.argv[4]; const releaseDir = process.argv[5]; const remotePub = process.argv[6] || ''; const parse = v => String(v || '0.0.0').trim().replace(/^v/i, '').split('.').map(n => parseInt(n, 10) || 0); const cmp = (a, b) => { const pa = parse(a), pb = parse(b); const len = Math.max(pa.length, pb.length, 3); for (let i = 0; i < len; i++) { const d = (pa[i] || 0) - (pb[i] || 0); if (d) return d; } return 0; }; const maxVer = (cur, next) => (next && cmp(next, cur) > 0 ? next : cur); const conf = JSON.parse(fs.readFileSync(confPath, 'utf8')); let base = conf.version || '0.1.0'; if (remotePub) base = maxVer(base, remotePub); if (fs.existsSync(latestPath)) { try { const pub = JSON.parse(fs.readFileSync(latestPath, 'utf8')); if (pub.version) base = maxVer(base, pub.version); } catch { /* ignore */ } } const ignoreBuildInfo = process.env.DESKTOP_BUMP_IGNORE_BUILD_INFO === '1'; if (!ignoreBuildInfo && fs.existsSync(buildInfoPath)) { try { const bi = JSON.parse(fs.readFileSync(buildInfoPath, 'utf8')); if (bi.version) base = maxVer(base, bi.version); } catch { /* ignore */ } } if (fs.existsSync(updatesDir)) { for (const name of fs.readdirSync(updatesDir)) { const m = name.match(/[_-](\\d+\\.\\d+\\.\\d+)[_-]/); if (m) base = maxVer(base, m[1]); const m2 = name.match(/GoldenChart_(\\d+\\.\\d+\\.\\d+)/); if (m2) base = maxVer(base, m2[1]); } } if (releaseDir && fs.existsSync(releaseDir)) { for (const name of fs.readdirSync(releaseDir)) { const m = name.match(/GoldenChart[_-](\\d+\\.\\d+\\.\\d+)/i); if (m) base = maxVer(base, m[1]); } const releaseBuildInfo = path.join(releaseDir, 'build-info.json'); if (fs.existsSync(releaseBuildInfo)) { try { const bi = JSON.parse(fs.readFileSync(releaseBuildInfo, 'utf8')); if (bi.version) base = maxVer(base, bi.version); } catch { /* ignore */ } } } const parts = parse(base); while (parts.length < 3) parts.push(0); parts[2] += 1; const nv = parts.join('.'); console.error('[bump-desktop] max base v' + base + ' → v' + nv); conf.version = nv; fs.writeFileSync(confPath, JSON.stringify(conf, null, 2) + '\n'); const pkgPath = path.join(path.dirname(confPath), '..', 'package.json'); try { const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); pkg.version = nv; fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n'); } catch { /* ignore */ } console.log(nv); " "$CONF" "$LATEST" "$UPDATES_DIR" "$BUILD_INFO" "$RELEASE_DIR" "$REMOTE_PUB_VER"