desktop-service-sync.mjs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536
  1. import { join, resolve } from 'node:path'
  2. import { homedir } from 'node:os'
  3. import { createHash } from 'node:crypto'
  4. import { mkdirSync } from 'node:fs'
  5. import { LaunchAgentService, synchronizeDesktop, stopDesktopService } from './lib/service-update.mjs'
  6. // Losing the App's progress pipe must not interrupt a durable service transaction.
  7. process.stdout.on('error', error => { if (!['EPIPE', 'EIO'].includes(error.code)) process.exitCode = 1 })
  8. let input = ''
  9. for await (const bytes of process.stdin) { input += bytes; if (input.length > 32768) throw new Error('同步参数过大') }
  10. try {
  11. const options = JSON.parse(input)
  12. const home = resolve(options.home), port = Number(options.port)
  13. if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error('本机服务端口无效')
  14. mkdirSync(home, { recursive: true, mode: 0o700 })
  15. // Fixture mode isolates *all* service/update state, including launchd labels.
  16. const fixture = options.fixture === true
  17. const releaseRoot = fixture ? join(home, 'updates', 'fixture-releases') : join(homedir(), '.local', 'share', 'hermes-yaoyao')
  18. const label = fixture ? `cn.samien.yaoyao.sync-test.${createHash('sha256').update(home).digest('hex').slice(0, 16)}` : 'com.samien.hermes-yaoyao'
  19. const driver = new LaunchAgentService({ home, port, releaseRoot, label,
  20. plistPath: fixture ? join(home, 'updates', 'fixture-service.plist') : undefined,
  21. environment: options.environment,
  22. })
  23. if(options.action!==undefined&&!['sync','stop'].includes(options.action))throw new Error('本机服务操作无效')
  24. const onProgress = message => process.stdout.write(JSON.stringify({ message }) + '\n')
  25. const result = options.action==='stop'
  26. ? await stopDesktopService({home,driver,onProgress})
  27. : await synchronizeDesktop({ home, runtimeRoot: resolve(options.runtimeRoot), releaseRoot, driver, onProgress })
  28. const current = result.current
  29. process.stdout.write(JSON.stringify({ result: { action: result.action, current: current && {
  30. version: current.version, commit: current.commit, buildNumber: current.buildNumber, artifactDigest: current.artifactDigest,
  31. } } }) + '\n')
  32. } catch (error) {
  33. process.stdout.write(JSON.stringify({ error: error.message, code: error.code }) + '\n'); process.exitCode = 1
  34. }