mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-20 12:11:28 -07:00
fix(plugin): add lowercase linux binary fallbacks
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
id: TASK-162
|
id: TASK-162
|
||||||
title: Normalize packaged Linux paths to canonical SubMiner directories
|
title: Normalize packaged Linux paths to canonical SubMiner directories
|
||||||
status: In Progress
|
status: Done
|
||||||
assignee:
|
assignee:
|
||||||
- codex
|
- codex
|
||||||
created_date: '2026-03-11 08:28'
|
created_date: '2026-03-11 08:28'
|
||||||
updated_date: '2026-03-11 08:29'
|
updated_date: '2026-03-16 06:25'
|
||||||
labels:
|
labels:
|
||||||
- linux
|
- linux
|
||||||
- packaging
|
- packaging
|
||||||
@@ -30,10 +30,10 @@ Align packaged Linux path conventions so system-installed assets use canonical `
|
|||||||
|
|
||||||
## Acceptance Criteria
|
## Acceptance Criteria
|
||||||
<!-- AC:BEGIN -->
|
<!-- AC:BEGIN -->
|
||||||
- [ ] #1 Launcher/runtime path discovery prefers canonical packaged Linux locations that use `SubMiner` casing for shared data and config directories.
|
- [x] #1 Launcher/runtime path discovery prefers canonical packaged Linux locations that use `SubMiner` casing for shared data and config directories.
|
||||||
- [ ] #2 Tests cover the expected packaged Linux discovery paths for the AppImage and rofi theme search behavior.
|
- [x] #2 Tests cover the expected packaged Linux discovery paths for the AppImage and rofi theme search behavior.
|
||||||
- [ ] #3 User-facing docs reference the canonical packaged Linux locations consistently.
|
- [x] #3 User-facing docs reference the canonical packaged Linux locations consistently.
|
||||||
- [ ] #4 Lowercase names remain only where intentionally required for the launcher wrapper, rofi theme filename, and mpv Lua plugin/conf.
|
- [x] #4 Lowercase names remain only where intentionally required for the launcher wrapper, rofi theme filename, and mpv Lua plugin/conf.
|
||||||
<!-- AC:END -->
|
<!-- AC:END -->
|
||||||
|
|
||||||
## Implementation Plan
|
## Implementation Plan
|
||||||
@@ -44,4 +44,22 @@ Align packaged Linux path conventions so system-installed assets use canonical `
|
|||||||
3. Update plugin auto-detection comments and binary search defaults so packaged Linux paths stay consistent with launcher/runtime expectations.
|
3. Update plugin auto-detection comments and binary search defaults so packaged Linux paths stay consistent with launcher/runtime expectations.
|
||||||
4. Update user-facing docs to reference canonical SubMiner-cased config/share paths while keeping lowercase names only for the launcher wrapper, rofi theme filename, and mpv Lua plugin/conf.
|
4. Update user-facing docs to reference canonical SubMiner-cased config/share paths while keeping lowercase names only for the launcher wrapper, rofi theme filename, and mpv Lua plugin/conf.
|
||||||
5. Run targeted launcher tests plus docs checks.
|
5. Run targeted launcher tests plus docs checks.
|
||||||
|
|
||||||
|
Remaining work (2026-03-15):
|
||||||
|
- binary.lua: add lowercase fallback candidates /usr/bin/subminer and /usr/local/bin/subminer after existing title-case entries
|
||||||
|
- launcher tests: add findAppBinary Linux candidates and findRofiTheme /usr/share + /usr/local/share tests
|
||||||
<!-- SECTION:PLAN:END -->
|
<!-- SECTION:PLAN:END -->
|
||||||
|
|
||||||
|
## Implementation Notes
|
||||||
|
|
||||||
|
<!-- SECTION:NOTES:BEGIN -->
|
||||||
|
2026-03-15: Adding launcher tests for Linux packaged path discovery (findAppBinary + findRofiTheme). Implementing in mpv.test.ts and new picker.test.ts following node:test / assert/strict patterns from mpv.test.ts.
|
||||||
|
|
||||||
|
2026-03-15: AC#2 complete. Added findAppBinary tests (3) to launcher/mpv.test.ts and findRofiTheme tests (4) to new launcher/picker.test.ts. All 76 launcher tests pass. Added picker.test.ts to test:launcher:src script.
|
||||||
|
<!-- SECTION:NOTES:END -->
|
||||||
|
|
||||||
|
## Final Summary
|
||||||
|
|
||||||
|
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||||
|
## Completed changes\n\n### `plugin/subminer/binary.lua`\nAdded lowercase fallback candidates after existing title-case entries in the non-Windows `find_binary()` search list:\n- `/usr/local/bin/subminer` (after `/usr/local/bin/SubMiner`)\n- `/usr/bin/subminer` (after `/usr/bin/SubMiner`)\n\n### `plugin/subminer.conf`\nUpdated the comment documenting the Linux binary search list to include the two new lowercase candidates.\n\n### `launcher/mpv.test.ts`\nAdded 3 new tests for `findAppBinary` Linux candidates:\n- Resolves `~/.local/bin/SubMiner.AppImage` when it exists\n- Resolves `/opt/SubMiner/SubMiner.AppImage` when `~/.local/bin` candidate absent\n- Finds `subminer` on PATH when AppImage candidates absent\n\n### `launcher/picker.test.ts` (new file)\nAdded 4 tests for `findRofiTheme` Linux packaged paths:\n- Resolves `/usr/local/share/SubMiner/themes/subminer.rasi`\n- Resolves `/usr/share/SubMiner/themes/subminer.rasi` when `/usr/local/share` absent\n- Resolves `$XDG_DATA_HOME/SubMiner/themes/subminer.rasi` when set\n- Resolves `~/.local/share/SubMiner/themes/subminer.rasi` when `XDG_DATA_HOME` unset\n\n### `package.json`\nAdded `launcher/picker.test.ts` to `test:launcher:src` file list.\n\n## Verification\n- `launcher-plugin` lane: passed (76 launcher tests, 524 fast tests — all green)\n\n## Policy checks\n- Docs update required? No — docs already reflected canonical paths.\n- Changelog fragment required? Yes — user-visible fix to plugin binary auto-detection. Fragment should be added under `changes/`.
|
||||||
|
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
type: fixed
|
||||||
|
area: launcher
|
||||||
|
|
||||||
|
- Fixed mpv Lua plugin binary auto-detection on Linux to also search `/usr/bin/subminer` and `/usr/local/bin/subminer` (lowercase), matching the conventional Unix wrapper name used by packaged installs such as the AUR package.
|
||||||
@@ -2,11 +2,13 @@ import test from 'node:test';
|
|||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
import os from 'node:os';
|
||||||
import net from 'node:net';
|
import net from 'node:net';
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import type { Args } from './types';
|
import type { Args } from './types';
|
||||||
import {
|
import {
|
||||||
cleanupPlaybackSession,
|
cleanupPlaybackSession,
|
||||||
|
findAppBinary,
|
||||||
runAppCommandCaptureOutput,
|
runAppCommandCaptureOutput,
|
||||||
shouldResolveAniSkipMetadata,
|
shouldResolveAniSkipMetadata,
|
||||||
startOverlay,
|
startOverlay,
|
||||||
@@ -233,3 +235,72 @@ test('cleanupPlaybackSession preserves background app while stopping mpv-owned c
|
|||||||
fs.rmSync(dir, { recursive: true, force: true });
|
fs.rmSync(dir, { recursive: true, force: true });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── findAppBinary: Linux packaged path discovery ──────────────────────────────
|
||||||
|
|
||||||
|
function makeExecutable(filePath: string): void {
|
||||||
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||||
|
fs.writeFileSync(filePath, '#!/bin/sh\nexit 0\n');
|
||||||
|
fs.chmodSync(filePath, 0o755);
|
||||||
|
}
|
||||||
|
|
||||||
|
test('findAppBinary resolves ~/.local/bin/SubMiner.AppImage when it exists', () => {
|
||||||
|
const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-test-home-'));
|
||||||
|
const originalHomedir = os.homedir;
|
||||||
|
try {
|
||||||
|
os.homedir = () => baseDir;
|
||||||
|
const appImage = path.join(baseDir, '.local/bin/SubMiner.AppImage');
|
||||||
|
makeExecutable(appImage);
|
||||||
|
|
||||||
|
const result = findAppBinary('/some/other/path/subminer');
|
||||||
|
assert.equal(result, appImage);
|
||||||
|
} finally {
|
||||||
|
os.homedir = originalHomedir;
|
||||||
|
fs.rmSync(baseDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('findAppBinary resolves /opt/SubMiner/SubMiner.AppImage when ~/.local/bin candidate does not exist', () => {
|
||||||
|
const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-test-home-'));
|
||||||
|
const originalHomedir = os.homedir;
|
||||||
|
const originalAccessSync = fs.accessSync;
|
||||||
|
try {
|
||||||
|
os.homedir = () => baseDir;
|
||||||
|
// No ~/.local/bin/SubMiner.AppImage; patch accessSync so only /opt path is executable
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(fs as any).accessSync = (filePath: string, mode?: number): void => {
|
||||||
|
if (filePath === '/opt/SubMiner/SubMiner.AppImage') return;
|
||||||
|
throw Object.assign(new Error(`EACCES: ${filePath}`), { code: 'EACCES' });
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = findAppBinary('/some/other/path/subminer');
|
||||||
|
assert.equal(result, '/opt/SubMiner/SubMiner.AppImage');
|
||||||
|
} finally {
|
||||||
|
os.homedir = originalHomedir;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(fs as any).accessSync = originalAccessSync;
|
||||||
|
fs.rmSync(baseDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('findAppBinary finds subminer on PATH when AppImage candidates do not exist', () => {
|
||||||
|
const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-test-path-'));
|
||||||
|
const originalHomedir = os.homedir;
|
||||||
|
const originalPath = process.env.PATH;
|
||||||
|
try {
|
||||||
|
os.homedir = () => baseDir;
|
||||||
|
// No AppImage candidates in empty home dir; place subminer wrapper on PATH
|
||||||
|
const binDir = path.join(baseDir, 'bin');
|
||||||
|
const wrapperPath = path.join(binDir, 'subminer');
|
||||||
|
makeExecutable(wrapperPath);
|
||||||
|
process.env.PATH = `${binDir}${path.delimiter}${originalPath ?? ''}`;
|
||||||
|
|
||||||
|
// selfPath must differ from wrapperPath so the self-check does not exclude it
|
||||||
|
const result = findAppBinary(path.join(baseDir, 'launcher', 'subminer'));
|
||||||
|
assert.equal(result, wrapperPath);
|
||||||
|
} finally {
|
||||||
|
os.homedir = originalHomedir;
|
||||||
|
process.env.PATH = originalPath;
|
||||||
|
fs.rmSync(baseDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
90
launcher/picker.test.ts
Normal file
90
launcher/picker.test.ts
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import os from 'node:os';
|
||||||
|
import { findRofiTheme } from './picker';
|
||||||
|
|
||||||
|
// ── findRofiTheme: Linux packaged path discovery ──────────────────────────────
|
||||||
|
|
||||||
|
const ROFI_THEME_FILE = 'subminer.rasi';
|
||||||
|
|
||||||
|
function makeFile(filePath: string): void {
|
||||||
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||||
|
fs.writeFileSync(filePath, '/* theme */');
|
||||||
|
}
|
||||||
|
|
||||||
|
test('findRofiTheme resolves /usr/local/share/SubMiner/themes/subminer.rasi when it exists', () => {
|
||||||
|
const originalExistsSync = fs.existsSync;
|
||||||
|
const targetPath = `/usr/local/share/SubMiner/themes/${ROFI_THEME_FILE}`;
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(fs as any).existsSync = (filePath: unknown): boolean => {
|
||||||
|
if (filePath === targetPath) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = findRofiTheme('/usr/local/bin/subminer');
|
||||||
|
assert.equal(result, targetPath);
|
||||||
|
} finally {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(fs as any).existsSync = originalExistsSync;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('findRofiTheme resolves /usr/share/SubMiner/themes/subminer.rasi when /usr/local/share one does not exist', () => {
|
||||||
|
const originalExistsSync = fs.existsSync;
|
||||||
|
const localSharePath = `/usr/local/share/SubMiner/themes/${ROFI_THEME_FILE}`;
|
||||||
|
const sharePath = `/usr/share/SubMiner/themes/${ROFI_THEME_FILE}`;
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(fs as any).existsSync = (filePath: unknown): boolean => {
|
||||||
|
if (filePath === sharePath) return true;
|
||||||
|
if (filePath === localSharePath) return false;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = findRofiTheme('/usr/bin/subminer');
|
||||||
|
assert.equal(result, sharePath);
|
||||||
|
} finally {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(fs as any).existsSync = originalExistsSync;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('findRofiTheme resolves XDG_DATA_HOME/SubMiner/themes/subminer.rasi when set and file exists', () => {
|
||||||
|
const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-test-xdg-'));
|
||||||
|
const originalXdgDataHome = process.env.XDG_DATA_HOME;
|
||||||
|
try {
|
||||||
|
process.env.XDG_DATA_HOME = baseDir;
|
||||||
|
const themePath = path.join(baseDir, `SubMiner/themes/${ROFI_THEME_FILE}`);
|
||||||
|
makeFile(themePath);
|
||||||
|
|
||||||
|
const result = findRofiTheme('/usr/bin/subminer');
|
||||||
|
assert.equal(result, themePath);
|
||||||
|
} finally {
|
||||||
|
process.env.XDG_DATA_HOME = originalXdgDataHome;
|
||||||
|
fs.rmSync(baseDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('findRofiTheme resolves ~/.local/share/SubMiner/themes/subminer.rasi when XDG_DATA_HOME unset', () => {
|
||||||
|
const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-test-home-'));
|
||||||
|
const originalHomedir = os.homedir;
|
||||||
|
const originalXdgDataHome = process.env.XDG_DATA_HOME;
|
||||||
|
try {
|
||||||
|
os.homedir = () => baseDir;
|
||||||
|
delete process.env.XDG_DATA_HOME;
|
||||||
|
const themePath = path.join(baseDir, `.local/share/SubMiner/themes/${ROFI_THEME_FILE}`);
|
||||||
|
makeFile(themePath);
|
||||||
|
|
||||||
|
const result = findRofiTheme('/usr/bin/subminer');
|
||||||
|
assert.equal(result, themePath);
|
||||||
|
} finally {
|
||||||
|
os.homedir = originalHomedir;
|
||||||
|
if (originalXdgDataHome !== undefined) {
|
||||||
|
process.env.XDG_DATA_HOME = originalXdgDataHome;
|
||||||
|
}
|
||||||
|
fs.rmSync(baseDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"test:config:smoke:dist": "bun test dist/config/path-resolution.test.js",
|
"test:config:smoke:dist": "bun test dist/config/path-resolution.test.js",
|
||||||
"test:plugin:src": "lua scripts/test-plugin-start-gate.lua && lua scripts/test-plugin-binary-windows.lua",
|
"test:plugin:src": "lua scripts/test-plugin-start-gate.lua && lua scripts/test-plugin-binary-windows.lua",
|
||||||
"test:launcher:smoke:src": "bun test launcher/smoke.e2e.test.ts",
|
"test:launcher:smoke:src": "bun test launcher/smoke.e2e.test.ts",
|
||||||
"test:launcher:src": "bun test launcher/config.test.ts launcher/config-domain-parsers.test.ts launcher/mpv.test.ts launcher/parse-args.test.ts launcher/main.test.ts launcher/commands/command-modules.test.ts launcher/smoke.e2e.test.ts && bun run test:plugin:src",
|
"test:launcher:src": "bun test launcher/config.test.ts launcher/config-domain-parsers.test.ts launcher/mpv.test.ts launcher/picker.test.ts launcher/parse-args.test.ts launcher/main.test.ts launcher/commands/command-modules.test.ts launcher/smoke.e2e.test.ts && bun run test:plugin:src",
|
||||||
"test:core:src": "bun test src/cli/args.test.ts src/cli/help.test.ts src/shared/setup-state.test.ts src/core/services/cli-command.test.ts src/core/services/field-grouping-overlay.test.ts src/core/services/numeric-shortcut-session.test.ts src/core/services/secondary-subtitle.test.ts src/core/services/mpv-render-metrics.test.ts src/core/services/overlay-content-measurement.test.ts src/core/services/mpv-control.test.ts src/core/services/mpv.test.ts src/core/services/runtime-options-ipc.test.ts src/core/services/runtime-config.test.ts src/core/services/yomitan-extension-paths.test.ts src/core/services/config-hot-reload.test.ts src/core/services/discord-presence.test.ts src/core/services/tokenizer.test.ts src/core/services/tokenizer/annotation-stage.test.ts src/core/services/tokenizer/parser-selection-stage.test.ts src/core/services/tokenizer/parser-enrichment-stage.test.ts src/core/services/subsync.test.ts src/core/services/overlay-bridge.test.ts src/core/services/overlay-shortcut-handler.test.ts src/core/services/stats-window.test.ts src/core/services/mining.test.ts src/core/services/anki-jimaku.test.ts src/core/services/jimaku-download-path.test.ts src/core/services/jellyfin.test.ts src/core/services/jellyfin-remote.test.ts src/core/services/immersion-tracker-service.test.ts src/core/services/overlay-runtime-init.test.ts src/core/services/app-ready.test.ts src/core/services/startup-bootstrap.test.ts src/core/services/subtitle-processing-controller.test.ts src/core/services/anilist/anilist-update-queue.test.ts src/core/utils/shortcut-config.test.ts src/main/runtime/first-run-setup-plugin.test.ts src/main/runtime/first-run-setup-service.test.ts src/main/runtime/first-run-setup-window.test.ts src/main/runtime/tray-runtime.test.ts src/main/runtime/tray-main-actions.test.ts src/main/runtime/tray-main-deps.test.ts src/main/runtime/tray-runtime-handlers.test.ts src/main/runtime/cli-command-context-main-deps.test.ts src/main/runtime/app-ready-main-deps.test.ts src/renderer/error-recovery.test.ts src/renderer/subtitle-render.test.ts src/renderer/handlers/mouse.test.ts src/renderer/handlers/keyboard.test.ts src/renderer/modals/jimaku.test.ts src/subsync/utils.test.ts src/main/anilist-url-guard.test.ts src/window-trackers/hyprland-tracker.test.ts src/window-trackers/x11-tracker.test.ts src/window-trackers/windows-helper.test.ts src/window-trackers/windows-tracker.test.ts launcher/config.test.ts launcher/config-domain-parsers.test.ts launcher/parse-args.test.ts launcher/main.test.ts launcher/commands/command-modules.test.ts launcher/setup-gate.test.ts stats/src/lib/api-client.test.ts",
|
"test:core:src": "bun test src/cli/args.test.ts src/cli/help.test.ts src/shared/setup-state.test.ts src/core/services/cli-command.test.ts src/core/services/field-grouping-overlay.test.ts src/core/services/numeric-shortcut-session.test.ts src/core/services/secondary-subtitle.test.ts src/core/services/mpv-render-metrics.test.ts src/core/services/overlay-content-measurement.test.ts src/core/services/mpv-control.test.ts src/core/services/mpv.test.ts src/core/services/runtime-options-ipc.test.ts src/core/services/runtime-config.test.ts src/core/services/yomitan-extension-paths.test.ts src/core/services/config-hot-reload.test.ts src/core/services/discord-presence.test.ts src/core/services/tokenizer.test.ts src/core/services/tokenizer/annotation-stage.test.ts src/core/services/tokenizer/parser-selection-stage.test.ts src/core/services/tokenizer/parser-enrichment-stage.test.ts src/core/services/subsync.test.ts src/core/services/overlay-bridge.test.ts src/core/services/overlay-shortcut-handler.test.ts src/core/services/stats-window.test.ts src/core/services/mining.test.ts src/core/services/anki-jimaku.test.ts src/core/services/jimaku-download-path.test.ts src/core/services/jellyfin.test.ts src/core/services/jellyfin-remote.test.ts src/core/services/immersion-tracker-service.test.ts src/core/services/overlay-runtime-init.test.ts src/core/services/app-ready.test.ts src/core/services/startup-bootstrap.test.ts src/core/services/subtitle-processing-controller.test.ts src/core/services/anilist/anilist-update-queue.test.ts src/core/utils/shortcut-config.test.ts src/main/runtime/first-run-setup-plugin.test.ts src/main/runtime/first-run-setup-service.test.ts src/main/runtime/first-run-setup-window.test.ts src/main/runtime/tray-runtime.test.ts src/main/runtime/tray-main-actions.test.ts src/main/runtime/tray-main-deps.test.ts src/main/runtime/tray-runtime-handlers.test.ts src/main/runtime/cli-command-context-main-deps.test.ts src/main/runtime/app-ready-main-deps.test.ts src/renderer/error-recovery.test.ts src/renderer/subtitle-render.test.ts src/renderer/handlers/mouse.test.ts src/renderer/handlers/keyboard.test.ts src/renderer/modals/jimaku.test.ts src/subsync/utils.test.ts src/main/anilist-url-guard.test.ts src/window-trackers/hyprland-tracker.test.ts src/window-trackers/x11-tracker.test.ts src/window-trackers/windows-helper.test.ts src/window-trackers/windows-tracker.test.ts launcher/config.test.ts launcher/config-domain-parsers.test.ts launcher/parse-args.test.ts launcher/main.test.ts launcher/commands/command-modules.test.ts launcher/setup-gate.test.ts stats/src/lib/api-client.test.ts",
|
||||||
"test:core:dist": "bun test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command.test.js dist/core/services/ipc.test.js dist/core/services/anki-jimaku-ipc.test.js dist/core/services/field-grouping-overlay.test.js dist/core/services/numeric-shortcut-session.test.js dist/core/services/secondary-subtitle.test.js dist/core/services/mpv-render-metrics.test.js dist/core/services/overlay-content-measurement.test.js dist/core/services/mpv-control.test.js dist/core/services/mpv.test.js dist/core/services/runtime-options-ipc.test.js dist/core/services/runtime-config.test.js dist/core/services/yomitan-extension-paths.test.js dist/core/services/config-hot-reload.test.js dist/core/services/discord-presence.test.js dist/core/services/tokenizer.test.js dist/core/services/tokenizer/annotation-stage.test.js dist/core/services/tokenizer/parser-selection-stage.test.js dist/core/services/tokenizer/parser-enrichment-stage.test.js dist/core/services/subsync.test.js dist/core/services/overlay-bridge.test.js dist/core/services/overlay-manager.test.js dist/core/services/overlay-shortcut-handler.test.js dist/core/services/mining.test.js dist/core/services/anki-jimaku.test.js dist/core/services/jimaku-download-path.test.js dist/core/services/jellyfin.test.js dist/core/services/jellyfin-remote.test.js dist/core/services/immersion-tracker-service.test.js dist/core/services/overlay-runtime-init.test.js dist/core/services/app-ready.test.js dist/core/services/startup-bootstrap.test.js dist/core/services/subtitle-processing-controller.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/anilist/anilist-update-queue.test.js dist/renderer/error-recovery.test.js dist/renderer/subtitle-render.test.js dist/renderer/handlers/mouse.test.js dist/renderer/handlers/keyboard.test.js dist/renderer/modals/jimaku.test.js dist/subsync/utils.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/hyprland-tracker.test.js dist/window-trackers/x11-tracker.test.js dist/window-trackers/windows-helper.test.js dist/window-trackers/windows-tracker.test.js",
|
"test:core:dist": "bun test dist/cli/args.test.js dist/cli/help.test.js dist/core/services/cli-command.test.js dist/core/services/ipc.test.js dist/core/services/anki-jimaku-ipc.test.js dist/core/services/field-grouping-overlay.test.js dist/core/services/numeric-shortcut-session.test.js dist/core/services/secondary-subtitle.test.js dist/core/services/mpv-render-metrics.test.js dist/core/services/overlay-content-measurement.test.js dist/core/services/mpv-control.test.js dist/core/services/mpv.test.js dist/core/services/runtime-options-ipc.test.js dist/core/services/runtime-config.test.js dist/core/services/yomitan-extension-paths.test.js dist/core/services/config-hot-reload.test.js dist/core/services/discord-presence.test.js dist/core/services/tokenizer.test.js dist/core/services/tokenizer/annotation-stage.test.js dist/core/services/tokenizer/parser-selection-stage.test.js dist/core/services/tokenizer/parser-enrichment-stage.test.js dist/core/services/subsync.test.js dist/core/services/overlay-bridge.test.js dist/core/services/overlay-manager.test.js dist/core/services/overlay-shortcut-handler.test.js dist/core/services/mining.test.js dist/core/services/anki-jimaku.test.js dist/core/services/jimaku-download-path.test.js dist/core/services/jellyfin.test.js dist/core/services/jellyfin-remote.test.js dist/core/services/immersion-tracker-service.test.js dist/core/services/overlay-runtime-init.test.js dist/core/services/app-ready.test.js dist/core/services/startup-bootstrap.test.js dist/core/services/subtitle-processing-controller.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/anilist/anilist-update-queue.test.js dist/renderer/error-recovery.test.js dist/renderer/subtitle-render.test.js dist/renderer/handlers/mouse.test.js dist/renderer/handlers/keyboard.test.js dist/renderer/modals/jimaku.test.js dist/subsync/utils.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/hyprland-tracker.test.js dist/window-trackers/x11-tracker.test.js dist/window-trackers/windows-helper.test.js dist/window-trackers/windows-tracker.test.js",
|
||||||
"test:core:smoke:dist": "bun test dist/cli/help.test.js dist/core/services/runtime-config.test.js dist/core/services/ipc.test.js dist/core/services/overlay-manager.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/startup-bootstrap.test.js dist/renderer/error-recovery.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
|
"test:core:smoke:dist": "bun test dist/cli/help.test.js dist/core/services/runtime-config.test.js dist/core/services/ipc.test.js dist/core/services/overlay-manager.test.js dist/core/services/anilist/anilist-token-store.test.js dist/core/services/startup-bootstrap.test.js dist/renderer/error-recovery.test.js dist/main/anilist-url-guard.test.js dist/window-trackers/x11-tracker.test.js",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
# Auto-detection searches common locations, including:
|
# Auto-detection searches common locations, including:
|
||||||
# - macOS: /Applications/SubMiner.app/Contents/MacOS/SubMiner, ~/Applications/SubMiner.app/Contents/MacOS/SubMiner
|
# - macOS: /Applications/SubMiner.app/Contents/MacOS/SubMiner, ~/Applications/SubMiner.app/Contents/MacOS/SubMiner
|
||||||
# - Windows: %LOCALAPPDATA%\Programs\SubMiner\SubMiner.exe, %ProgramFiles%\SubMiner\SubMiner.exe
|
# - Windows: %LOCALAPPDATA%\Programs\SubMiner\SubMiner.exe, %ProgramFiles%\SubMiner\SubMiner.exe
|
||||||
# - Linux: ~/.local/bin/SubMiner.AppImage, /opt/SubMiner/SubMiner.AppImage, /usr/local/bin/SubMiner, /usr/bin/SubMiner
|
# - Linux: ~/.local/bin/SubMiner.AppImage, /opt/SubMiner/SubMiner.AppImage, /usr/local/bin/SubMiner, /usr/local/bin/subminer, /usr/bin/SubMiner, /usr/bin/subminer
|
||||||
binary_path=
|
binary_path=
|
||||||
|
|
||||||
# Path to mpv IPC socket (must match input-ipc-server in mpv.conf)
|
# Path to mpv IPC socket (must match input-ipc-server in mpv.conf)
|
||||||
|
|||||||
@@ -257,7 +257,9 @@ try {
|
|||||||
add_search_path(search_paths, utils.join_path(home, ".local", "bin", "SubMiner.AppImage"))
|
add_search_path(search_paths, utils.join_path(home, ".local", "bin", "SubMiner.AppImage"))
|
||||||
add_search_path(search_paths, "/opt/SubMiner/SubMiner.AppImage")
|
add_search_path(search_paths, "/opt/SubMiner/SubMiner.AppImage")
|
||||||
add_search_path(search_paths, "/usr/local/bin/SubMiner")
|
add_search_path(search_paths, "/usr/local/bin/SubMiner")
|
||||||
|
add_search_path(search_paths, "/usr/local/bin/subminer")
|
||||||
add_search_path(search_paths, "/usr/bin/SubMiner")
|
add_search_path(search_paths, "/usr/bin/SubMiner")
|
||||||
|
add_search_path(search_paths, "/usr/bin/subminer")
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, path in ipairs(search_paths) do
|
for _, path in ipairs(search_paths) do
|
||||||
|
|||||||
Reference in New Issue
Block a user