better and simplified automatic update for macos
Massimo Melina committed
Mar 4, 2026 at 23:55 UTC
cc61fae0a093b234a09d6ad024721c066d9bdb94
2 files changed
+9
-30
src/const.ts
-10
@@ -12,16 +12,6 @@ export * from './cross-const'
12
export const API_VERSION = 12.97
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
-export const ARGS_FILE = join(homedir(), 'hfs-args')
17
-try {
18
- const s = fs.readFileSync(ARGS_FILE, 'utf-8')
19
- console.log('additional arguments', s)
20
- _.defaults(argv, minimist(JSON.parse(s)))
21
- fs.unlinkSync(ARGS_FILE)
22
-}
23
-catch {}
24
-
15
export const DEV = process.env.DEV ? 'DEV' : ''
16
export const ORIGINAL_CWD = process.cwd()
17
export const HFS_STARTED = new Date()
src/update.ts
+9
-20
@@ -1,14 +1,13 @@
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 { ARGS_FILE, HFS_REPO, IS_BINARY, IS_WINDOWS, IS_MAC, PREVIOUS_TAG, RUNNING_BETA } from './const'
4
+import { HFS_REPO, IS_BINARY, IS_WINDOWS, 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, writeFileSync } from 'fs'
8
+import { createReadStream, existsSync, renameSync, unlinkSync } from 'fs'
9
import { pluginsWatcher } from './plugins'
10
import { chmod, rename, writeFile, rm } from 'fs/promises'
11
-import open from 'open'
11
import { currentVersion, defineConfig, versionToScalar } from './config'
12
import { cmdEscape, RUNNING_AS_SERVICE } from './util-os'
13
import { onProcessExit } from './first'
@@ -145,7 +144,7 @@ export async function update(tagOrUrl: string='') {
144
}
145
const bin = process.execPath
146
const binPath = dirname(bin)
148
- const binFile = 'hfs' + (IS_WINDOWS ? '.exe' : '') // currently running bin could have been renamed
147
+ const binFile = 'hfs' + (IS_WINDOWS ? '.exe' : '') // the bin we are currently running could have been renamed
148
let newBinFile = binFile
149
do { newBinFile = 'new-' + newBinFile }
150
while (existsSync(join(binPath, newBinFile)))
@@ -194,22 +193,12 @@ if (argv.updating) { // we were launched with a temporary name, restore original
193
// have to relaunch with the new name, or otherwise the next update will fail with EBUSY on hfs.exe
194
console.log(`renamed binary file to "${argv.updating}" and now restarting`)
195
// if you change anything, be sure to test launching both double-clicking and in a terminal
197
- if (IS_WINDOWS) // windows-only; this method on Mac works only once, and without console
196
+ if (IS_WINDOWS) // windows-only; this method on Mac works only once, and without the console
197
onProcessExit(() =>
199
- launch(dest, ['--updated', '--cwd .']) ) // launch+sync here would cause old process to stay open, locking ports
200
- else if (IS_MAC) {
201
- // open() is the only consistent way that I could find working on macos preserving console input/output over relaunching,
202
- // and it doesn't let us pass cli arguments, so we pass them through a temp file consumed at the next startup.
203
- // 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"
204
- try { writeFileSync(ARGS_FILE, JSON.stringify(['--updated', '--cwd', process.cwd().replaceAll(' ', '\\ ')])) }
205
- catch {}
206
- void open(dest)
207
- }
208
- else { // linux and other *nix
209
- if (process.stdin.isTTY && process.stdout.isTTY) // in interactive terminals, block this bridge process on the restarted hfs so the terminal session stays attached
210
- spawnSync(dest, ['--updated', '--cwd', process.cwd()], { stdio: [0, 1, 2] })
211
- else
212
- spawn(dest, ['--updated', '--cwd', process.cwd()], { detached: true, stdio: 'ignore' }).unref()
213
- }
198
+ launch(dest, ['--updated', '--cwd .']) ) // launch+sync here would cause the old process to stay open, locking ports
199
+ else if (process.stdin.isTTY && process.stdout.isTTY) // keep interactive terminal users attached to the restarted process
200
+ spawnSync(dest, ['--updated', '--cwd', process.cwd()], { stdio: [0, 1, 2] })
201
+ else
202
+ spawn(dest, ['--updated', '--cwd', process.cwd()], { detached: true, stdio: 'ignore' }).unref()
203
process.exit()
204
}