Files
my-pi/pi-rtk-optimizer/src/rtk-command-environment.ts
T

78 lines
2.3 KiB
TypeScript

import { join } from "node:path";
import { splitLeadingEnvAssignments } from "./shell-env-prefix.js";
const RTK_DB_PATH_ENV_NAME = "RTK_DB_PATH";
const SINGLE_QUOTED_SHELL_VALUE_PATTERN = "'(?:'\\\\''|[^'])*'";
const SHELL_ENV_VALUE_PATTERN = `(?:"[^"]*"|${SINGLE_QUOTED_SHELL_VALUE_PATTERN}|[^\\s;]+)`;
const RTK_DB_PATH_ASSIGNMENT_PATTERN = new RegExp(
`(?:^|\\s)RTK_DB_PATH=${SHELL_ENV_VALUE_PATTERN}(?=\\s|$)`,
);
const RTK_DB_PATH_EXPORT_PATTERN = new RegExp(`^export\\s+RTK_DB_PATH=${SHELL_ENV_VALUE_PATTERN}(?=\\s*(?:;|$))`);
function resolveTemporaryDirectory(): string {
if (process.platform === "win32") {
const windowsTempDir = process.env.TEMP ?? process.env.TMP;
if (windowsTempDir && windowsTempDir.trim()) {
return windowsTempDir;
}
const localAppData = process.env.LOCALAPPDATA;
if (localAppData && localAppData.trim()) {
return join(localAppData, "Temp");
}
const userProfile = process.env.USERPROFILE;
if (userProfile && userProfile.trim()) {
return join(userProfile, "AppData", "Local", "Temp");
}
const systemRoot = process.env.SystemRoot ?? process.env.WINDIR;
if (systemRoot && systemRoot.trim()) {
return join(systemRoot, "Temp");
}
return "C:/Windows/Temp";
}
const posixTempDir = process.env.TMPDIR ?? process.env.TMP;
if (posixTempDir && posixTempDir.trim()) {
return posixTempDir;
}
return "/tmp";
}
function getTemporaryRtkHistoryDbPath(): string {
return join(resolveTemporaryDirectory(), "pi-rtk-optimizer", "history.db");
}
function quoteForShellEnv(value: string): string {
const normalizedValue = process.platform === "win32" ? value.replace(/\\/g, "/") : value;
return `'${normalizedValue.replace(/'/g, `'\\''`)}'`;
}
function hasLeadingRtkDbPathAssignment(command: string): boolean {
const trimmed = command.trimStart();
return (
RTK_DB_PATH_ASSIGNMENT_PATTERN.test(splitLeadingEnvAssignments(trimmed).envPrefix) ||
RTK_DB_PATH_EXPORT_PATTERN.test(trimmed)
);
}
function hasInheritedRtkDbPath(): boolean {
return Boolean(process.env[RTK_DB_PATH_ENV_NAME]?.trim());
}
export function applyRtkCommandEnvironment(command: string): string {
if (!command.trim()) {
return command;
}
if (hasLeadingRtkDbPathAssignment(command) || hasInheritedRtkDbPath()) {
return command;
}
return `export ${RTK_DB_PATH_ENV_NAME}=${quoteForShellEnv(getTemporaryRtkHistoryDbPath())}; ${command}`;
}