Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 1cad6c43041ff4e8aa812694aace18eee55baa75
parent 381be8f9a8108c46bd95b6ee032bcda6277190b9
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Mon, 28 Sep 2026 11:56:56 -0400

umtool: SONG_DATA and VIDEO_ROOT default from the home directory

song/paths.mjs: SONG_DIR ?? ~/.local/share/archilyzer/song, through
realpathSync so SONG_SCRATCH (dirname(SONG_DATA)) keeps pointing at the
real directory when that path is a symlink -- the supported way to keep
the data where it is. A path that does not exist is used as given.
spec.mjs and video-dir.mjs: VIDEO_ROOT ?? ~/reports/quartering-uh-song/
videos. The fixture comments and docs/cli.md say the new defaults.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Mumtool/docs/cli.md | 11++++++++++-
Mumtool/e2e/fixtures/make-fixture.mjs | 10+++++-----
Mumtool/e2e/fixtures/song-capabilities.mjs | 5+++--
Mumtool/song/paths.mjs | 29++++++++++++++++++++++++++---
Mumtool/song/spec.mjs | 6++++--
Mumtool/song/video-dir.mjs | 6++++--
6 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/umtool/docs/cli.md b/umtool/docs/cli.md @@ -37,7 +37,16 @@ projects answering to one name is reported, never resolved by picking one. ## Environment `REPORTS_DIR`, `SONG_REPORTS_DIR`, `SONG_DIR`, `CHANNELS_DIR`, `UMTOOL_INDEX_DIR` -— which is how it is tested against the e2e fixture. +— which is how it is tested against the e2e fixture. The path defaults +(`lib/paths.mjs`, `song/paths.mjs`): + +| Variable | Default | +|---|---| +| `SONG_DIR` | `~/.local/share/archilyzer/song`, through its realpath — a symlink there is the supported way to keep the data where it is | +| `SONG_REPORTS_DIR` | `~/reports/quartering-uh-song` | +| `REPORTS_DIR` | `~/reports` (the parent of `SONG_REPORTS_DIR` when that is set) | +| `CHANNELS_DIR` | `$TRANSCRIPTS_DIR/channels`, else the checkout's `transcripts/channels` (found by walking up from the cwd to `pnpm-workspace.yaml`) | +| `VIDEO_ROOT` (`song/spec.mjs`, `song/video-dir.mjs`) | `~/reports/quartering-uh-song/videos` | ## `check` is the one to run before every build diff --git a/umtool/e2e/fixtures/make-fixture.mjs b/umtool/e2e/fixtures/make-fixture.mjs @@ -26,9 +26,9 @@ import { songCapabilities } from "./song-capabilities.mjs"; const CODE = path.resolve(path.dirname(new URL(import.meta.url).pathname), "..", "..", "song"); const dest = path.resolve(process.argv[2] ?? path.join(process.cwd(), ".e2e-song")); -// A readdir that answers "nothing" instead of throwing. SONG_DATA's default is -// the job temp dir the corpus was mined into, which on most machines no longer -// exists — see the capabilities block below. +// A readdir that answers "nothing" instead of throwing. SONG_DATA's default +// (`~/.local/share/archilyzer/song`) does not exist on most machines — see the +// capabilities block below. const listDir = (p) => { try { return readdirSync(p); @@ -99,8 +99,8 @@ writeFileSync(path.join(dest, "code", "um-manifest.json"), JSON.stringify({ vers // -- a few candidates, from videos whose audio is actually present ------------ // // TOLERANT OF A MISSING SONG_DATA, and that is the whole point of the -// capabilities file below. `SONG_DIR`'s default is the job temp dir the corpus -// was mined into, which on most machines no longer exists — so this readdir +// capabilities file below. `SONG_DIR`'s default does not exist on most +// machines — so this readdir // used to throw and take the entire suite down before the test server started, // including the two dozen specs that have nothing to do with the song project. const cands = listDir(path.join(SONG_DATA, "cand2")).filter((f) => f.endsWith(".json")); diff --git a/umtool/e2e/fixtures/song-capabilities.mjs b/umtool/e2e/fixtures/song-capabilities.mjs @@ -5,8 +5,9 @@ import path from "node:path"; // readers. // // The 39 GB (`wav48/`, `asr/`, `media/`) is re-derivable from the archive and -// deliberately not in the repo. `SONG_DIR`'s default is the job temp dir the -// corpus was mined into, which on most machines no longer exists, so +// deliberately not in the repo. `SONG_DIR`'s default +// (`~/.local/share/archilyzer/song`, song/paths.mjs) is empty or absent on +// most machines, so // `make-fixture.mjs` builds an empty fixture and every spec that judges a clip // used to fail — LOUDLY, as a red suite, over a machine that never had the data // rather than over anything a change broke. Red that means "you are on a diff --git a/umtool/song/paths.mjs b/umtool/song/paths.mjs @@ -12,9 +12,32 @@ // SONG_DATA the bulk data, wherever it currently sits // // Point SONG_DIR at a copy to run the toolchain somewhere else. The default is -// the job temp dir the corpus was mined into, which is where it still is. +// ~/.local/share/archilyzer/song, and the data does NOT have to move there: a +// symlink is the supported way to keep it where it is, +// +// mkdir -p ~/.local/share/archilyzer +// ln -s <where the song data is> ~/.local/share/archilyzer/song +// +// SONG_DATA is that path's REALPATH, so lib/paths.mjs's SONG_SCRATCH +// (dirname(SONG_DATA), where render-poly.mjs writes its scratch and logs) keeps +// pointing at the real directory the data sits in, not at ~/.local/share. A +// path that does not exist has no realpath; it is used as given, so a machine +// with no song data still gets a SONG_DATA -- one every reader finds empty +// (e2e/fixtures/song-capabilities.mjs says which specs that skips). +import { realpathSync } from "node:fs"; +import os from "node:os"; import path from "node:path"; -export const SONG_DATA = path.resolve( - process.env.SONG_DIR ?? "/home/user/.claude/jobs/efbe67a7/tmp/song", +const requested = path.resolve( + process.env.SONG_DIR ?? path.join(os.homedir(), ".local", "share", "archilyzer", "song"), ); + +const realOrAsGiven = (p) => { + try { + return realpathSync(p); + } catch { + return p; + } +}; + +export const SONG_DATA = realOrAsGiven(requested); diff --git a/umtool/song/spec.mjs b/umtool/song/spec.mjs @@ -24,11 +24,13 @@ // keys are PRESERVED: this file is hand-edited, and silently dropping something // somebody typed is worse than ignoring it. // -// VIDEO_ROOT overrides where the song directories live. +// VIDEO_ROOT overrides where the song directories live (default +// ~/reports/quartering-uh-song/videos). import { readFileSync, writeFileSync, existsSync, readdirSync, statSync, renameSync, mkdirSync } from "node:fs"; +import os from "node:os"; import path from "node:path"; -const ROOT = process.env.VIDEO_ROOT ?? "/home/user/reports/quartering-uh-song/videos"; +const ROOT = process.env.VIDEO_ROOT ?? path.join(os.homedir(), "reports", "quartering-uh-song", "videos"); const argv = process.argv.slice(2); const file = (song) => path.join(ROOT, song, "spec.json"); diff --git a/umtool/song/video-dir.mjs b/umtool/song/video-dir.mjs @@ -45,12 +45,14 @@ // Recording is ADDITIVE: writing `wide.mp4` leaves every other entry alone, so a // builder that makes one cut at a time does not erase the other three. // -// VIDEO_ROOT overrides where the song directories live. +// VIDEO_ROOT overrides where the song directories live (default +// ~/reports/quartering-uh-song/videos). import { readFileSync, writeFileSync, mkdirSync, existsSync, statSync, readdirSync, renameSync } from "node:fs"; import { execFileSync } from "node:child_process"; +import os from "node:os"; import path from "node:path"; -const ROOT = process.env.VIDEO_ROOT ?? "/home/user/reports/quartering-uh-song/videos"; +const ROOT = process.env.VIDEO_ROOT ?? path.join(os.homedir(), "reports", "quartering-uh-song", "videos"); const argv = process.argv.slice(2); const take = (flag) => {