Files
privacy.sexy/tests/checks/desktop-runtime-errors/check-desktop-runtime-errors/app/app-logs.ts
undergroundwires 949fac1a7c Refactor to enforce strictNullChecks
This commit applies `strictNullChecks` to the entire codebase to improve
maintainability and type safety. Key changes include:

- Remove some explicit null-checks where unnecessary.
- Add necessary null-checks.
- Refactor static factory functions for a more functional approach.
- Improve some test names and contexts for better debugging.
- Add unit tests for any additional logic introduced.
- Refactor `createPositionFromRegexFullMatch` to its own function as the
  logic is reused.
- Prefer `find` prefix on functions that may return `undefined` and
  `get` prefix for those that always return a value.
2023-11-12 22:54:00 +01:00

98 lines
3.2 KiB
TypeScript

import { unlink, readFile } from 'fs/promises';
import { join } from 'path';
import { log, die, LogLevel } from '../utils/log';
import { exists } from '../utils/io';
import { SupportedPlatform, CURRENT_PLATFORM } from '../utils/platform';
import { getAppName } from '../utils/npm';
const LOG_FILE_NAMES = ['main', 'renderer'];
export async function clearAppLogFiles(
projectDir: string,
): Promise<void> {
if (!projectDir) { throw new Error('missing project directory'); }
await Promise.all(LOG_FILE_NAMES.map(async (logFileName) => {
const logPath = await determineLogPath(projectDir, logFileName);
if (!logPath || !await exists(logPath)) {
log(`Skipping clearing logs, log file does not exist: ${logPath}.`);
return;
}
try {
await unlink(logPath);
log(`Successfully cleared the log file at: ${logPath}.`);
} catch (error) {
die(`Failed to clear the log file at: ${logPath}. Reason: ${error}`);
}
}));
}
export async function readAppLogFile(
projectDir: string,
logFileName: string,
): Promise<AppLogFileResult> {
if (!projectDir) { throw new Error('missing project directory'); }
const logPath = await determineLogPath(projectDir, logFileName);
if (!logPath || !await exists(logPath)) {
log(`No log file at: ${logPath}`, LogLevel.Warn);
return {
logFilePath: logPath,
};
}
const logContent = await readLogFile(logPath);
return {
logFileContent: logContent,
logFilePath: logPath,
};
}
interface AppLogFileResult {
readonly logFilePath: string;
readonly logFileContent?: string;
}
async function determineLogPath(
projectDir: string,
logFileName: string,
): Promise<string> {
if (!projectDir) { throw new Error('missing project directory'); }
if (!LOG_FILE_NAMES.includes(logFileName)) { throw new Error(`unknown log file name: ${logFileName}`); }
const appName = await getAppName(projectDir);
if (!appName) {
return die('App name not found.');
}
const logFilePaths: {
readonly [K in SupportedPlatform]: () => string;
} = {
[SupportedPlatform.macOS]: () => {
if (!process.env.HOME) {
throw new Error('HOME environment variable is not defined');
}
return join(process.env.HOME, 'Library', 'Logs', appName, `${logFileName}.log`);
},
[SupportedPlatform.Linux]: () => {
if (!process.env.HOME) {
throw new Error('HOME environment variable is not defined');
}
return join(process.env.HOME, '.config', appName, 'logs', `${logFileName}.log`);
},
[SupportedPlatform.Windows]: () => {
if (!process.env.USERPROFILE) {
throw new Error('USERPROFILE environment variable is not defined');
}
return join(process.env.USERPROFILE, 'AppData', 'Roaming', appName, 'logs', `${logFileName}.log`);
},
};
const logFilePath = logFilePaths[CURRENT_PLATFORM]?.();
if (!logFilePath) {
log(`Cannot determine log path, unsupported OS: ${SupportedPlatform[CURRENT_PLATFORM]}`, LogLevel.Warn);
}
return logFilePath;
}
async function readLogFile(
logFilePath: string,
): Promise<string | undefined> {
const content = await readFile(logFilePath, 'utf-8');
return content?.trim().length > 0 ? content : undefined;
}