@samitouri / QOSami-HFS / commits / 6f9d4984

fix: (regression beta) update on mac was no longer working

Massimo Melina committed Mar 11, 2026 at 15:50 UTC 6f9d4984a0966ba3292ef8c90395d21abf3ef73f
2 files changed +33 -7
src/const.ts
+14
@@ -12,6 +12,20 @@ export * from './cross-const'
12 export const API_VERSION = 13
13 export const COMPATIBLE_API_VERSION = 1 // the day we break with the past, we'll update this
14
15 +// you can add arguments with this file, currently used for the update process on mac/linux.
16 +// we are using homedir because it's the only stable path both the old and new process can agree on (open() doesn't preserve cwd)
17 +export const ARGS_FILE = join(homedir(), 'hfs-args')
18 +try {
19 + const s = fs.readFileSync(ARGS_FILE, 'utf-8')
20 + console.log('additional arguments', s)
21 + _.defaults(argv, minimist(JSON.parse(s)))
22 + fs.unlinkSync(ARGS_FILE)
23 +}
24 +catch(e: any) {
25 + if (e?.code !== 'ENOENT')
26 + console.error(ARGS_FILE, String(e))
27 +}
28 +
29 export const DEV = process.env.DEV ? 'DEV' : ''
30 export const ORIGINAL_CWD = process.cwd()
31 export const HFS_STARTED = new Date()
src/update.ts
+19 -7
@@ -1,13 +1,14 @@
1 // This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3 import { apiGithubPaginated, getProjectInfo, getRepoInfo } from './github'
4 -import { HFS_REPO, IS_BINARY, IS_WINDOWS, PREVIOUS_TAG, RUNNING_BETA } from './const'
4 +import { ARGS_FILE, HFS_REPO, IS_BINARY, IS_WINDOWS, IS_MAC, PREVIOUS_TAG, RUNNING_BETA } from './const'
5 import { dirname, join } from 'path'
6 import { spawn, spawnSync } from 'child_process'
7 import { DAY, exists, debounceAsync, unzip, prefix, xlate, HOUR, httpStream, statWithTimeout } from './misc'
8 -import { createReadStream, existsSync, renameSync, unlinkSync } from 'fs'
8 +import { createReadStream, existsSync, renameSync, unlinkSync, writeFileSync } from 'fs'
9 import { pluginsWatcher } from './plugins'
10 import { chmod, rename, writeFile, rm } from 'fs/promises'
11 +import open from 'open'
12 import { currentVersion, defineConfig, versionToScalar } from './config'
13 import { cmdEscape, RUNNING_AS_SERVICE } from './util-os'
14 import { onProcessExit } from './first'
@@ -189,12 +190,23 @@ if (argv.updating) { // we were launched with a temporary name, restore original
190 // have to relaunch with the new name, or otherwise the next update will fail with EBUSY on hfs.exe
191 console.log(`renamed binary file to "${argv.updating}" and now restarting`)
192 // if you change anything, be sure to test launching both double-clicking and in a terminal
192 - if (IS_WINDOWS) // windows-only; this method on Mac works only once, and without the console
193 + if (IS_WINDOWS) // windows-only; this method on mac+linux works only once, and without the console
194 onProcessExit(() =>
195 spawn(cmdEscape(dest), ['--updated', '--cwd .'], { detached: true, shell: true, stdio: [0,1,2] }) ) // launch+sync here would cause the old process to stay open, locking ports
195 - else if (process.stdin.isTTY && process.stdout.isTTY) // keep interactive terminal users attached to the restarted process
196 - spawnSync(dest, ['--updated', '--cwd', process.cwd()], { stdio: [0, 1, 2] })
197 - else
198 - spawn(dest, ['--updated', '--cwd', process.cwd()], { detached: true, stdio: 'ignore' }).unref()
196 + else if (IS_MAC) {
197 + // open() is the only consistent way that I could find working on macos preserving console input/output over relaunching,
198 + // and it doesn't let us pass cli arguments, so we pass them through a temp file consumed at the next startup.
199 + // For the record, on mac you can: write "./hfs arg1 arg2" to /tmp/tmp.sh with 0o700, and then spawn "open -a Terminal /tmp/tmp.sh"
200 + try { writeFileSync(ARGS_FILE, JSON.stringify(['--updated', '--cwd', process.cwd()])) }
201 + catch {}
202 + console.log('open-ing')
203 + void open(dest)
204 + }
205 + else { // linux and other *nix
206 + if (process.stdin.isTTY && process.stdout.isTTY) // in interactive terminals, block this bridge process on the restarted hfs so the terminal session stays attached
207 + spawnSync(dest, ['--updated', '--cwd', process.cwd()], { stdio: [0, 1, 2] })
208 + else
209 + spawn(dest, ['--updated', '--cwd', process.cwd()], { detached: true, stdio: 'ignore' }).unref()
210 + }
211 process.exit()
212 }