tui: add state-file path resolver (Windows + XDG)
Resolves the location of the cross-process TUI state file: - Windows: %LOCALAPPDATA%/codesys-mcp/tui-state.json - POSIX: $XDG_STATE_HOME/codesys-mcp/tui-state.json, falling back to $HOME/.local/state/codesys-mcp/tui-state.json Uses path.win32 / path.posix explicitly so the POSIX branches still produce POSIX-flavored paths when this runs on a Windows host (test machine), keeping the unit tests host-independent.
This commit is contained in:
parent
64ab4aeaae
commit
461bd10a73
2 changed files with 70 additions and 0 deletions
19
src/tui/shared/state-paths.ts
Normal file
19
src/tui/shared/state-paths.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
|
||||
const APP_DIR = 'codesys-mcp';
|
||||
const FILE_NAME = 'tui-state.json';
|
||||
|
||||
export function stateFilePath(): string {
|
||||
if (process.platform === 'win32') {
|
||||
const localAppData = process.env.LOCALAPPDATA;
|
||||
if (!localAppData) {
|
||||
throw new Error('LOCALAPPDATA is not set; cannot resolve TUI state file path');
|
||||
}
|
||||
return path.win32.join(localAppData, APP_DIR, FILE_NAME);
|
||||
}
|
||||
const xdg = process.env.XDG_STATE_HOME;
|
||||
const home = process.env.HOME ?? os.homedir();
|
||||
const base = xdg ?? path.posix.join(home, '.local', 'state');
|
||||
return path.posix.join(base, APP_DIR, FILE_NAME);
|
||||
}
|
||||
51
tests/tui/state-paths.test.ts
Normal file
51
tests/tui/state-paths.test.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||
import * as path from 'path';
|
||||
import { stateFilePath } from '../../src/tui/shared/state-paths.ts';
|
||||
|
||||
const ORIG_PLATFORM = Object.getOwnPropertyDescriptor(process, 'platform')!;
|
||||
const ORIG_ENV = { ...process.env };
|
||||
|
||||
function setPlatform(p: NodeJS.Platform) {
|
||||
Object.defineProperty(process, 'platform', { value: p, configurable: true });
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
process.env = { ...ORIG_ENV };
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
Object.defineProperty(process, 'platform', ORIG_PLATFORM);
|
||||
process.env = { ...ORIG_ENV };
|
||||
});
|
||||
|
||||
describe('stateFilePath', () => {
|
||||
it('uses %LOCALAPPDATA%/codesys-mcp/tui-state.json on Windows', () => {
|
||||
setPlatform('win32');
|
||||
process.env.LOCALAPPDATA = 'C:\\\\Users\\\\u\\\\AppData\\\\Local';
|
||||
const p = stateFilePath();
|
||||
expect(p).toBe(
|
||||
path.join('C:\\\\Users\\\\u\\\\AppData\\\\Local', 'codesys-mcp', 'tui-state.json')
|
||||
);
|
||||
});
|
||||
|
||||
it('uses $XDG_STATE_HOME/codesys-mcp/tui-state.json when set', () => {
|
||||
setPlatform('linux');
|
||||
process.env.XDG_STATE_HOME = '/tmp/xdg-state';
|
||||
const p = stateFilePath();
|
||||
expect(p).toBe('/tmp/xdg-state/codesys-mcp/tui-state.json');
|
||||
});
|
||||
|
||||
it('falls back to ~/.local/state on Linux without XDG_STATE_HOME', () => {
|
||||
setPlatform('linux');
|
||||
delete process.env.XDG_STATE_HOME;
|
||||
process.env.HOME = '/home/u';
|
||||
const p = stateFilePath();
|
||||
expect(p).toBe('/home/u/.local/state/codesys-mcp/tui-state.json');
|
||||
});
|
||||
|
||||
it('throws on Windows when LOCALAPPDATA is unset', () => {
|
||||
setPlatform('win32');
|
||||
delete process.env.LOCALAPPDATA;
|
||||
expect(() => stateFilePath()).toThrow(/LOCALAPPDATA/);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue