| 123456789101112131415161718192021222324252627282930313233343536373839404142434445 |
- import { existsSync } from 'node:fs'
- import { homedir } from 'node:os'
- import { join } from 'node:path'
- import { LaunchAgentService } from './service-update.mjs'
- import { defaultDataHome, legacyDataHome } from './data-home.mjs'
- import { migrateDataHome, rebaseDataPath } from './data-migration.mjs'
- export async function migrateManagedDataHome({ home, port = 15300, onProgress = () => {}, beforeMove }) {
- if (home !== defaultDataHome()) return
- const old = legacyDataHome(), releaseRoot = join(homedir(), '.local', 'share', 'hermes-yaoyao')
- let previous, driver
- if (existsSync(old)) {
- driver = new LaunchAgentService({ home: old, port, releaseRoot })
- previous = driver.snapshot()
- if (previous) {
- onProgress('正在等待旧服务空闲,准备迁移数据到 ~/.yaoyao…')
- await driver.quiesce(onProgress, 0)
- await driver.stop()
- }
- }
- try {
- if (existsSync(old)) await beforeMove?.(old)
- migrateDataHome(home)
- } catch (error) {
- if (previous && existsSync(old)) await driver.restore(previous)
- throw error
- }
- // Also recover a crash between the atomic rename and the LaunchAgent rewrite.
- if (!existsSync(home)) return
- const currentDriver = new LaunchAgentService({ home, port, releaseRoot })
- if (!previous && existsSync(join(home, '.data-home-migration.json')) && existsSync(currentDriver.plistPath)) {
- const { execFileSync } = await import('node:child_process')
- const plist = JSON.parse(execFileSync('/usr/bin/plutil', ['-convert', 'json', '-o', '-', currentDriver.plistPath], { encoding: 'utf8' }))
- if (plist.EnvironmentVariables?.HERMES_YAOYAO_HOME === old) previous = { plist, wasRunning: true }
- }
- if (previous) {
- for (const [key, value] of Object.entries(previous.plist.EnvironmentVariables ?? {})) previous.plist.EnvironmentVariables[key] = rebaseDataPath(value, old, home)
- previous.plist.EnvironmentVariables.HERMES_YAOYAO_HOME = home
- previous.plist.EnvironmentVariables.YAOYAO_HOME = home
- for (const field of ['StandardOutPath', 'StandardErrorPath']) previous.plist[field] = rebaseDataPath(previous.plist[field], old, home)
- currentDriver.writePlist(previous.plist)
- if (previous.wasRunning) { await currentDriver.boot(); await currentDriver.verify(undefined) }
- onProgress('账号、会话、文件和配置已迁移到 ~/.yaoyao')
- }
- }
|