mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
86 lines
2.3 KiB
TypeScript
86 lines
2.3 KiB
TypeScript
import fs from 'node:fs';
|
|
import { log } from '../log.js';
|
|
import { commandExists } from '../util.js';
|
|
import { resolveMainConfigPath } from '../config-path.js';
|
|
import type { LauncherCommandContext } from './context.js';
|
|
|
|
interface DoctorCommandDeps {
|
|
commandExists(command: string): boolean;
|
|
configExists(path: string): boolean;
|
|
resolveMainConfigPath(): string;
|
|
}
|
|
|
|
const defaultDeps: DoctorCommandDeps = {
|
|
commandExists,
|
|
configExists: fs.existsSync,
|
|
resolveMainConfigPath,
|
|
};
|
|
|
|
export function runDoctorCommand(
|
|
context: LauncherCommandContext,
|
|
deps: DoctorCommandDeps = defaultDeps,
|
|
): boolean {
|
|
const { args, appPath, mpvSocketPath, processAdapter } = context;
|
|
if (!args.doctor) {
|
|
return false;
|
|
}
|
|
|
|
const configPath = deps.resolveMainConfigPath();
|
|
const mpvFound = deps.commandExists('mpv');
|
|
const checks: Array<{ label: string; ok: boolean; detail: string }> = [
|
|
{
|
|
label: 'app binary',
|
|
ok: Boolean(appPath),
|
|
detail: appPath || 'not found (set SUBMINER_APPIMAGE_PATH)',
|
|
},
|
|
{
|
|
label: 'mpv',
|
|
ok: mpvFound,
|
|
detail: mpvFound ? 'found' : 'missing',
|
|
},
|
|
{
|
|
label: 'yt-dlp',
|
|
ok: deps.commandExists('yt-dlp'),
|
|
detail: deps.commandExists('yt-dlp') ? 'found' : 'missing (optional unless YouTube URLs)',
|
|
},
|
|
{
|
|
label: 'ffmpeg',
|
|
ok: deps.commandExists('ffmpeg'),
|
|
detail: deps.commandExists('ffmpeg')
|
|
? 'found'
|
|
: 'missing (optional unless subtitle generation)',
|
|
},
|
|
{
|
|
label: 'fzf',
|
|
ok: deps.commandExists('fzf'),
|
|
detail: deps.commandExists('fzf') ? 'found' : 'missing (optional if using rofi)',
|
|
},
|
|
{
|
|
label: 'rofi',
|
|
ok: deps.commandExists('rofi'),
|
|
detail: deps.commandExists('rofi') ? 'found' : 'missing (optional if using fzf)',
|
|
},
|
|
{
|
|
label: 'config',
|
|
ok: deps.configExists(configPath),
|
|
detail: configPath,
|
|
},
|
|
{
|
|
label: 'mpv socket path',
|
|
ok: true,
|
|
detail: mpvSocketPath,
|
|
},
|
|
];
|
|
|
|
const hasHardFailure = checks.some((entry) =>
|
|
entry.label === 'app binary' || entry.label === 'mpv' ? !entry.ok : false,
|
|
);
|
|
|
|
for (const check of checks) {
|
|
log(check.ok ? 'info' : 'warn', args.logLevel, `[doctor] ${check.label}: ${check.detail}`);
|
|
}
|
|
|
|
processAdapter.exit(hasHardFailure ? 1 : 0);
|
|
return true;
|
|
}
|