source-updater.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // electron/modules/source-updater.ts - 包管理器源更新模块
  2. import * as os from 'os'
  3. import { execa } from 'execa'
  4. import { needsSourceUpdate, markSourceUpdated } from './utils'
  5. import logger from './logger'
  6. // 正在进行中的更新操作(用于防止并发重复更新)
  7. let aptUpdatePromise: Promise<void> | null = null
  8. /**
  9. * 检查 apt 源是否需要更新
  10. * @returns 是否需要更新
  11. */
  12. export function needsAptUpdate(): boolean {
  13. if (os.platform() !== 'linux') return false
  14. return needsSourceUpdate('apt')
  15. }
  16. /**
  17. * 标记 apt 源已更新
  18. */
  19. export function markAptUpdated(): void {
  20. markSourceUpdated('apt')
  21. logger.info('apt 源已更新')
  22. }
  23. /**
  24. * 更新 apt 源(Linux 专用,带缓存,1天内只更新一次)
  25. * 用于版本查询前的源更新
  26. * 注意:这个函数用于版本查询,实际安装时使用 installer.ts 中的 aptUpdate
  27. * 支持并发调用:多个调用会共享同一个更新操作
  28. */
  29. export async function updateAptSourceForQuery(): Promise<void> {
  30. if (os.platform() !== 'linux') return
  31. if (!needsSourceUpdate('apt')) {
  32. logger.info('apt 源已在缓存期内,跳过更新')
  33. return
  34. }
  35. // 如果已有更新操作在进行中,等待它完成
  36. if (aptUpdatePromise) {
  37. logger.info('apt 源更新已在进行中,等待完成...')
  38. return aptUpdatePromise
  39. }
  40. // 创建新的更新操作
  41. aptUpdatePromise = (async () => {
  42. try {
  43. logger.info('正在更新 apt 源...')
  44. // 使用 sudo 执行 apt update
  45. await execa('sudo', ['apt', 'update'], { stdio: 'pipe' })
  46. markSourceUpdated('apt')
  47. logger.info('apt 源更新完成')
  48. } catch (error) {
  49. logger.warn('apt 源更新失败,继续查询', error)
  50. // 即使更新失败也标记为已尝试,避免当天重复尝试
  51. markSourceUpdated('apt')
  52. } finally {
  53. aptUpdatePromise = null
  54. }
  55. })()
  56. return aptUpdatePromise
  57. }