refactor(desktop): extract terminalLcCtype so the Linux locale rule is testable
The picked fix inlined the platform ternary inside terminalShellEnv(), which reads process.platform and can only be exercised by booting Electron. Lift it into a pure terminalLcCtype(env, platform) that takes the platform as data (root AGENTS.md: never fake the host OS) and pin the contract with one vitest: Linux reuses LANG, falls back to C.UTF-8, respects an explicit LC_CTYPE; macOS keeps the bare "UTF-8" it accepts. Red on origin/main (helper absent), green here.
This commit is contained in:
@@ -31,6 +31,21 @@ export interface TerminalIpcApi {
|
||||
disposeAllTerminalSessions: () => void
|
||||
}
|
||||
|
||||
// macOS accepts the bare charset name "UTF-8" as a locale; glibc does not, so
|
||||
// every Linux pane would print `bash: warning: setlocale: LC_CTYPE: cannot
|
||||
// change locale (UTF-8)`. Reuse the user's LANG there, else the glibc-guaranteed
|
||||
// C.UTF-8. Pure: the platform arrives as data so tests need not fake the host.
|
||||
export function terminalLcCtype(
|
||||
env: { LANG?: string; LC_CTYPE?: string },
|
||||
platform: NodeJS.Platform = process.platform
|
||||
): string {
|
||||
if (env.LC_CTYPE) {
|
||||
return env.LC_CTYPE
|
||||
}
|
||||
|
||||
return platform === 'darwin' ? 'UTF-8' : env.LANG || 'C.UTF-8'
|
||||
}
|
||||
|
||||
export function registerTerminalIpc({
|
||||
isWindows,
|
||||
findOnPath,
|
||||
@@ -156,10 +171,7 @@ export function registerTerminalIpc({
|
||||
delete env.COLORFGBG
|
||||
|
||||
env.COLORTERM = 'truecolor'
|
||||
// macOS accepts the bare charset name "UTF-8"; glibc does not, and bash
|
||||
// warns: setlocale: LC_CTYPE: cannot change locale (UTF-8). Prefer LANG or C.UTF-8 on Linux.
|
||||
env.LC_CTYPE =
|
||||
env.LC_CTYPE || (process.platform === 'darwin' ? 'UTF-8' : env.LANG || 'C.UTF-8')
|
||||
env.LC_CTYPE = terminalLcCtype(env)
|
||||
env.TERM = 'xterm-256color'
|
||||
env.TERM_PROGRAM = 'Hermes'
|
||||
env.TERM_PROGRAM_VERSION = app.getVersion()
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import { test, vi } from 'vitest'
|
||||
|
||||
// terminal-ipc.ts imports the Electron and native PTY modules at module scope;
|
||||
// neither loads under plain node, and this test only needs the pure locale helper.
|
||||
vi.mock('electron', () => ({ app: {}, ipcMain: {} }))
|
||||
vi.mock('node-pty', () => ({ default: {} }))
|
||||
|
||||
import { terminalLcCtype } from './terminal-ipc'
|
||||
|
||||
test('terminalLcCtype never hands glibc the bare "UTF-8" locale on Linux', () => {
|
||||
assert.equal(terminalLcCtype({ LANG: 'en_US.UTF-8' }, 'linux'), 'en_US.UTF-8')
|
||||
assert.equal(terminalLcCtype({}, 'linux'), 'C.UTF-8')
|
||||
assert.equal(terminalLcCtype({ LANG: 'en_US.UTF-8', LC_CTYPE: 'de_DE.UTF-8' }, 'linux'), 'de_DE.UTF-8')
|
||||
assert.equal(terminalLcCtype({ LANG: 'en_US.UTF-8' }, 'darwin'), 'UTF-8')
|
||||
})
|
||||
Reference in New Issue
Block a user