Refactor env vars: rename DATA_DIR to DATA_ROOT, add APP_URL

This commit is contained in:
Chris Wanstrath 2026-03-01 21:21:23 -08:00
parent baa3712fa2
commit c24c0fac45
4 changed files with 8 additions and 120 deletions

View File

@ -6,11 +6,12 @@ import { mkdir, readdir, rename, rm, stat } from 'fs/promises'
import { join, resolve } from 'path'
import type { Child } from 'hono/jsx'
const APP_URL = process.env.APP_URL!
const APPS_DIR = process.env.APPS_DIR!
const DATA_DIR = process.env.DATA_DIR!
const DATA_ROOT = process.env.DATA_ROOT!
const TOES_URL = process.env.TOES_URL!
const REPOS_DIR = resolve(DATA_DIR, 'repos')
const REPOS_DIR = resolve(DATA_ROOT, 'repos')
const VALID_NAME = /^[a-zA-Z0-9_-]+$/
const app = new Hype({ prettyHTML: false, layout: false })
@ -633,8 +634,7 @@ app.on('POST', ['/:repo{.+\\.git}/git-receive-pack', '/:repo/git-receive-pack'],
app.get('/', async c => {
const appName = c.req.query('app')
const host = c.req.header('host') ?? 'git.toes.local'
const baseUrl = `http://${host}`
const baseUrl = APP_URL
// When viewing a specific app, only show that app's repo
if (appName) {

View File

@ -21,9 +21,6 @@ REPOS_DIR="$DATA_DIR/repos"
cd "$DEST" && git checkout -- bun.lock && git pull origin main && bun install && rm -rf dist && bun run build
echo "=> Migrating apps to flat structure..."
bun run scripts/migrate.ts
echo "=> Syncing default apps..."
for app_dir in "$DEST"/apps/*/; do
app=$(basename "$app_dir")
@ -35,7 +32,7 @@ for app_dir in "$DEST"/apps/*/; do
(cd "$target" && bun install --frozen-lockfile 2>/dev/null || bun install)
done
echo "=> Initializing bare repos for shipped apps..."
echo "=> Initializing bare repos..."
mkdir -p "$REPOS_DIR"
for app_dir in "$DEST"/apps/*/; do
app=$(basename "$app_dir")

View File

@ -1,111 +0,0 @@
#!/usr/bin/env bun
// Migration script: converts apps from versioned directory structure
// (apps/<name>/<timestamp>/ with `current` symlink) to flat structure (apps/<name>/).
//
// Usage: bun run remote:migrate
//
// What it does:
// 1. Scans APPS_DIR for apps with a `current` symlink
// 2. Resolves the symlink to find the active version directory
// 3. Moves files from the active version into the app root (preserving node_modules/logs)
// 4. Removes old version directories and the symlink
//
// Safe to run multiple times -- skips apps already in flat structure.
import { existsSync, mkdirSync, readdirSync, renameSync, lstatSync, readlinkSync, rmSync } from 'fs'
import { join, resolve } from 'path'
const APPS_DIR = process.env.APPS_DIR ?? join(process.env.HOME!, 'apps')
const VERSION_RE = /^\d{8}-\d{6}$/
if (!existsSync(APPS_DIR)) {
console.error(`APPS_DIR does not exist: ${APPS_DIR}`)
process.exit(1)
}
const apps = readdirSync(APPS_DIR, { withFileTypes: true })
.filter(e => e.isDirectory())
.map(e => e.name)
let migrated = 0
let skipped = 0
for (const name of apps) {
const appDir = join(APPS_DIR, name)
const currentLink = join(appDir, 'current')
// Already flat -- has package.json at root with no current symlink
if (!existsSync(currentLink)) {
if (existsSync(join(appDir, 'package.json'))) {
skipped++
}
continue
}
// Verify it's actually a symlink
let stat
try {
stat = lstatSync(currentLink)
} catch {
continue
}
if (!stat.isSymbolicLink()) {
console.warn(` [skip] ${name}: 'current' exists but is not a symlink`)
skipped++
continue
}
// Resolve the symlink to get the active version directory
const target = readlinkSync(currentLink)
const activeDir = resolve(appDir, target)
if (!existsSync(activeDir)) {
console.warn(` [skip] ${name}: symlink target does not exist: ${target}`)
skipped++
continue
}
console.log(` [migrate] ${name} (active version: ${target})`)
// Collect all version directories and other entries
const entries = readdirSync(appDir, { withFileTypes: true })
const versionDirs = entries
.filter(e => e.isDirectory() && VERSION_RE.test(e.name) && e.name !== target)
.map(e => e.name)
// Remove old (non-active) version directories first
for (const ver of versionDirs) {
const verPath = join(appDir, ver)
rmSync(verPath, { recursive: true, force: true })
console.log(` removed old version: ${ver}`)
}
// Remove the current symlink
rmSync(currentLink)
// Move files from active version directory into app root
const activeEntries = readdirSync(activeDir)
for (const entry of activeEntries) {
const src = join(activeDir, entry)
const dest = join(appDir, entry)
// Skip if destination already exists (e.g. node_modules, logs at root level)
if (existsSync(dest)) {
console.log(` skip (exists): ${entry}`)
continue
}
renameSync(src, dest)
}
// Clean up the now-empty active version directory
rmSync(activeDir, { recursive: true, force: true })
migrated++
console.log(` done`)
}
console.log()
console.log(`Migration complete: ${migrated} migrated, ${skipped} skipped`)

View File

@ -16,6 +16,8 @@ export type { AppState } from '@types'
export const APPS_DIR = process.env.APPS_DIR ?? resolve(join(process.env.DATA_DIR ?? '.', 'apps'))
export const TOES_DIR = process.env.TOES_DIR ?? join(process.env.DATA_DIR ?? '.', 'toes')
const dataRoot = process.env.DATA_DIR ?? '.'
const defaultHost = process.env.NODE_ENV === 'production' ? LOCAL_HOST : 'localhost'
export const TOES_URL = process.env.TOES_URL ?? `http://${defaultHost}:${process.env.PORT || 3000}`
@ -622,7 +624,7 @@ async function runApp(dir: string, port: number) {
const proc = Bun.spawn(['bun', 'run', 'toes'], {
cwd,
env: { ...process.env, ...appEnv, PORT: String(port), NO_AUTOPORT: 'true', APP_URL: buildAppUrl(dir, TOES_URL), APPS_DIR, DATA_DIR: dataDir, TOES_DIR, TOES_URL },
env: { ...process.env, ...appEnv, PORT: String(port), NO_AUTOPORT: 'true', APP_URL: buildAppUrl(dir, TOES_URL), APPS_DIR, DATA_DIR: dataDir, DATA_ROOT: dataRoot, TOES_DIR, TOES_URL },
stdout: 'pipe',
stderr: 'pipe',
})