From 782bb517b224966ec1b1459814edc6dc2a0a3243 Mon Sep 17 00:00:00 2001 From: Jonathan Gamble Date: Sat, 1 Feb 2025 11:12:39 -0600 Subject: [PATCH] remove fs-ext due to its deps, use kill(pid, 0) for instance lock --- .gitignore | 1 + ui/.build/package.json | 2 -- ui/.build/pnpm-lock.yaml | 26 -------------------------- ui/.build/src/env.ts | 1 + ui/.build/src/main.ts | 32 ++++++++++++++++++++++++-------- ui/.build/src/sync.ts | 1 + 6 files changed, 27 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index aa83f02eacd4e..30099d92059a5 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ dependency-graph.png dump.rdb RUNNING_PID +instance.lock .DS_Store # Eclipse auto-generated files diff --git a/ui/.build/package.json b/ui/.build/package.json index 26745db77bb49..4754dc47b03fc 100644 --- a/ui/.build/package.json +++ b/ui/.build/package.json @@ -14,14 +14,12 @@ "sass-embedded-win32-x64": "1.83.3" }, "dependencies": { - "@types/fs-ext": "^2.0.3", "@types/micromatch": "^4.0.9", "@types/node": "22.12.0", "@types/tinycolor2": "1.4.6", "esbuild": "0.24.2", "fast-glob": "3.3.3", "fast-xml-parser": "4.5.1", - "fs-ext": "^2.1.1", "micromatch": "4.0.8", "tinycolor2": "1.6.0", "typescript": "5.7.3" diff --git a/ui/.build/pnpm-lock.yaml b/ui/.build/pnpm-lock.yaml index 81a46a0496c8e..da5cb61f990e4 100644 --- a/ui/.build/pnpm-lock.yaml +++ b/ui/.build/pnpm-lock.yaml @@ -8,9 +8,6 @@ importers: .: dependencies: - '@types/fs-ext': - specifier: ^2.0.3 - version: 2.0.3 '@types/micromatch': specifier: ^4.0.9 version: 4.0.9 @@ -29,9 +26,6 @@ importers: fast-xml-parser: specifier: 4.5.1 version: 4.5.1 - fs-ext: - specifier: ^2.1.1 - version: 2.1.1 micromatch: specifier: 4.0.8 version: 4.0.8 @@ -228,9 +222,6 @@ packages: '@types/braces@3.0.5': resolution: {integrity: sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w==} - '@types/fs-ext@2.0.3': - resolution: {integrity: sha512-0j2F+laosJF2NTd2DVheQ5GvXo8ln9L175VwLPfbsppE33iYC+6gn6XlOQS0pGvZm2yrQ32/LRZh0As/7rCs2Q==} - '@types/micromatch@4.0.9': resolution: {integrity: sha512-7V+8ncr22h4UoYRLnLXSpTxjQrNUXtWHGeMPRJt1nULXI57G9bIcpyrHlmrQ7QK24EyyuXvYcSSWAM8GA9nqCg==} @@ -264,10 +255,6 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - fs-ext@2.1.1: - resolution: {integrity: sha512-/TrISPOFhCkbgIRWK9lzscRzwPCu0PqtCcvMc9jsHKBgZGoqA0VzhspVht5Zu8lxaXjIYIBWILHpRotYkCCcQA==} - engines: {node: '>= 8.0.0'} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -292,9 +279,6 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - nan@2.22.0: - resolution: {integrity: sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==} - picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} @@ -454,10 +438,6 @@ snapshots: '@types/braces@3.0.5': {} - '@types/fs-ext@2.0.3': - dependencies: - '@types/node': 22.12.0 - '@types/micromatch@4.0.9': dependencies: '@types/braces': 3.0.5 @@ -520,10 +500,6 @@ snapshots: dependencies: to-regex-range: 5.0.1 - fs-ext@2.1.1: - dependencies: - nan: 2.22.0 - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -543,8 +519,6 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - nan@2.22.0: {} - picomatch@2.3.1: {} queue-microtask@1.2.3: {} diff --git a/ui/.build/src/env.ts b/ui/.build/src/env.ts index 1b14e5c3f0841..920ba0881d337 100644 --- a/ui/.build/src/env.ts +++ b/ui/.build/src/env.ts @@ -16,6 +16,7 @@ export const env = new (class { readonly themeDir = p.join(this.uiDir, 'common', 'css', 'theme'); readonly themeGenDir = p.join(this.themeDir, 'gen'); readonly buildDir = p.join(this.uiDir, '.build'); + readonly lockFile = p.join(this.buildDir, 'instance.lock'); readonly cssTempDir = p.join(this.buildDir, 'build', 'css'); readonly buildSrcDir = p.join(this.uiDir, '.build', 'src'); readonly buildTempDir = p.join(this.buildDir, 'build'); diff --git a/ui/.build/src/main.ts b/ui/.build/src/main.ts index b09f4cfed5cad..56634ce8a3041 100644 --- a/ui/.build/src/main.ts +++ b/ui/.build/src/main.ts @@ -1,12 +1,12 @@ import ps from 'node:process'; import fs from 'node:fs'; -import { flockSync, constants } from 'fs-ext'; import { deepClean } from './clean.ts'; import { build } from './build.ts'; import { startConsole } from './console.ts'; import { env, errorMark } from './env.ts'; // main entry point +['SIGINT', 'SIGTERM', 'SIGHUP'].forEach(sig => ps.on(sig, () => ps.exit(2))); const args: Record = { '--tsc': '', @@ -112,17 +112,33 @@ if (argv.includes('--help') || oneDashArgs.includes('h')) { ps.exit(0); } -try { - const fd = fs.openSync(env.buildDir, 'r'); - ps.on('exit', () => fs.closeSync(fd)); - flockSync(fd, constants.LOCK_EX | constants.LOCK_NB); -} catch { - env.exit(`${errorMark} - Another instance is already running`); -} +instanceLock(); if (env.clean) { await deepClean(); if (argv.includes('--clean-exit')) ps.exit(0); } + startConsole(); build(argv.filter(x => !x.startsWith('-'))); + +function instanceLock(checkStale = true) { + try { + const fd = fs.openSync(env.lockFile, 'wx'); + fs.writeFileSync(fd, String(ps.pid), { flag: 'w' }); + fs.closeSync(fd); + console.log('ooya'); + ps.on('exit', () => fs.unlinkSync(env.lockFile)); + } catch { + const pid = parseInt(fs.readFileSync(env.lockFile, 'utf8'), 10); + if (!isNaN(pid) && pid > 0 && ps.platform !== 'win32') { + try { + ps.kill(pid, 0); + env.exit(`${errorMark} - Another instance is already running`); + } catch { + fs.unlinkSync(env.lockFile); // it's a craplet + if (checkStale) return instanceLock(false); + } + } + } +} diff --git a/ui/.build/src/sync.ts b/ui/.build/src/sync.ts index dbdb5173cab91..c8c3a6344976d 100644 --- a/ui/.build/src/sync.ts +++ b/ui/.build/src/sync.ts @@ -34,6 +34,7 @@ export async function sync(): Promise { } async function syncOne(absSrc: string, absDest: string): Promise { + // TODO are these stats unnecessary now? const [src, dest] = ( await Promise.allSettled([ fs.promises.stat(absSrc),