Compare commits
No commits in common. "e8318f68b0a9185f73df034f737c4d7bac98b008" and "38d5b1c7191382d3919ed6f68ca005aaacb7de09" have entirely different histories.
e8318f68b0
...
38d5b1c719
|
|
@ -1,7 +1,8 @@
|
||||||
|
import { join } from "path"
|
||||||
import { existsSync } from "fs"
|
import { existsSync } from "fs"
|
||||||
|
import { unlink } from "fs/promises"
|
||||||
import * as git from "../git.ts"
|
import * as git from "../git.ts"
|
||||||
import * as state from "../state.ts"
|
import * as state from "../state.ts"
|
||||||
import { unlinkSessionSymlink } from "./helpers.ts"
|
|
||||||
|
|
||||||
export async function action() {
|
export async function action() {
|
||||||
const root = await git.repoRoot()
|
const root = await git.repoRoot()
|
||||||
|
|
@ -22,7 +23,7 @@ export async function action() {
|
||||||
|
|
||||||
for (const s of stale) {
|
for (const s of stale) {
|
||||||
await state.removeSession(root, s.branch)
|
await state.removeSession(root, s.branch)
|
||||||
await unlinkSessionSymlink(root, s.branch)
|
await unlink(join(root, '.sandlot', s.branch)).catch(() => {})
|
||||||
console.log(`✔ Removed stale session: ${s.branch}`)
|
console.log(`✔ Removed stale session: ${s.branch}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { basename, dirname, join } from "path"
|
import { basename, join } from "path"
|
||||||
import { homedir } from "os"
|
import { homedir } from "os"
|
||||||
import { mkdir, rmdir, symlink, unlink } from "fs/promises"
|
import { mkdir, symlink, unlink } from "fs/promises"
|
||||||
import { $ } from "bun"
|
import { $ } from "bun"
|
||||||
import * as git from "../git.ts"
|
import * as git from "../git.ts"
|
||||||
import * as vm from "../vm.ts"
|
import * as vm from "../vm.ts"
|
||||||
|
|
@ -9,21 +9,6 @@ import { spinner } from "../spinner.ts"
|
||||||
import { die } from "../fmt.ts"
|
import { die } from "../fmt.ts"
|
||||||
import type { Session } from "../state.ts"
|
import type { Session } from "../state.ts"
|
||||||
|
|
||||||
/** Remove a .sandlot/<branch> symlink and prune empty parent dirs up to .sandlot/. */
|
|
||||||
export async function unlinkSessionSymlink(root: string, branch: string): Promise<void> {
|
|
||||||
const sandlotDir = join(root, '.sandlot')
|
|
||||||
const symlinkPath = join(sandlotDir, branch)
|
|
||||||
await unlink(symlinkPath).catch(() => {})
|
|
||||||
|
|
||||||
// Walk up from the symlink's parent, removing empty dirs, stopping at .sandlot/ itself
|
|
||||||
let dir = dirname(symlinkPath)
|
|
||||||
while (dir !== sandlotDir) {
|
|
||||||
const ok = await rmdir(dir).then(() => true, () => false)
|
|
||||||
if (!ok) break
|
|
||||||
dir = dirname(dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Look up a session by branch, dying if it doesn't exist. */
|
/** Look up a session by branch, dying if it doesn't exist. */
|
||||||
export async function requireSession(branch: string): Promise<{ root: string; session: Session }> {
|
export async function requireSession(branch: string): Promise<{ root: string; session: Session }> {
|
||||||
const root = await git.repoRoot()
|
const root = await git.repoRoot()
|
||||||
|
|
@ -50,13 +35,12 @@ export async function ensureSession(branch: string): Promise<{ root: string; ses
|
||||||
const worktreeAbs = join(homedir(), '.sandlot', basename(root), branch)
|
const worktreeAbs = join(homedir(), '.sandlot', basename(root), branch)
|
||||||
try {
|
try {
|
||||||
await git.createWorktree(branch, worktreeAbs, root)
|
await git.createWorktree(branch, worktreeAbs, root)
|
||||||
const symlinkPath = join(root, '.sandlot', branch)
|
await mkdir(join(root, '.sandlot'), { recursive: true })
|
||||||
await mkdir(dirname(symlinkPath), { recursive: true })
|
await symlink(worktreeAbs, join(root, '.sandlot', branch))
|
||||||
await symlink(worktreeAbs, symlinkPath)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Clean up on failure — but do NOT delete the branch (it already existed)
|
// Clean up on failure — but do NOT delete the branch (it already existed)
|
||||||
await git.removeWorktree(worktreeAbs, root).catch(() => {})
|
await git.removeWorktree(worktreeAbs, root).catch(() => {})
|
||||||
await unlinkSessionSymlink(root, branch)
|
await unlink(join(root, '.sandlot', branch)).catch(() => {})
|
||||||
die(`Failed to recreate session: ${(err as Error).message ?? err}`)
|
die(`Failed to recreate session: ${(err as Error).message ?? err}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +60,8 @@ export async function teardownSession(root: string, branch: string, worktree: st
|
||||||
await git.removeWorktree(worktree, root)
|
await git.removeWorktree(worktree, root)
|
||||||
.catch((e) => console.warn(`⚠ Failed to remove worktree: ${e.message}`))
|
.catch((e) => console.warn(`⚠ Failed to remove worktree: ${e.message}`))
|
||||||
|
|
||||||
await unlinkSessionSymlink(root, branch)
|
await unlink(join(root, '.sandlot', branch))
|
||||||
|
.catch(() => {}) // symlink may not exist
|
||||||
|
|
||||||
await state.removeSession(root, branch)
|
await state.removeSession(root, branch)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { basename, dirname, join } from "path"
|
import { basename, join } from "path"
|
||||||
import { homedir } from "os"
|
import { homedir } from "os"
|
||||||
import { mkdir, symlink } from "fs/promises"
|
import { mkdir, symlink, unlink } from "fs/promises"
|
||||||
import * as git from "../git.ts"
|
import * as git from "../git.ts"
|
||||||
import * as vm from "../vm.ts"
|
import * as vm from "../vm.ts"
|
||||||
import * as state from "../state.ts"
|
import * as state from "../state.ts"
|
||||||
|
|
@ -8,7 +8,7 @@ import { spinner } from "../spinner.ts"
|
||||||
import { die } from "../fmt.ts"
|
import { die } from "../fmt.ts"
|
||||||
import { requireApiKey } from "../env.ts"
|
import { requireApiKey } from "../env.ts"
|
||||||
import { renderMarkdown } from "../markdown.ts"
|
import { renderMarkdown } from "../markdown.ts"
|
||||||
import { saveChanges, unlinkSessionSymlink } from "./helpers.ts"
|
import { saveChanges } from "./helpers.ts"
|
||||||
|
|
||||||
const ADJECTIVES = [
|
const ADJECTIVES = [
|
||||||
"calm", "bold", "warm", "cool", "keen", "soft", "fast", "wild", "fair", "rare",
|
"calm", "bold", "warm", "cool", "keen", "soft", "fast", "wild", "fair", "rare",
|
||||||
|
|
@ -99,9 +99,8 @@ export async function action(
|
||||||
const spin = spinner("Creating worktree", branch)
|
const spin = spinner("Creating worktree", branch)
|
||||||
try {
|
try {
|
||||||
await git.createWorktree(branch, worktreeAbs, root)
|
await git.createWorktree(branch, worktreeAbs, root)
|
||||||
const symlinkPath = join(root, '.sandlot', branch)
|
await mkdir(join(root, '.sandlot'), { recursive: true })
|
||||||
await mkdir(dirname(symlinkPath), { recursive: true })
|
await symlink(worktreeAbs, join(root, '.sandlot', branch))
|
||||||
await symlink(worktreeAbs, symlinkPath)
|
|
||||||
|
|
||||||
spin.text = "Starting container"
|
spin.text = "Starting container"
|
||||||
await vm.ensure((msg) => { spin.text = msg })
|
await vm.ensure((msg) => { spin.text = msg })
|
||||||
|
|
@ -110,7 +109,7 @@ export async function action(
|
||||||
spin.fail(String((err as Error).message ?? err))
|
spin.fail(String((err as Error).message ?? err))
|
||||||
await git.removeWorktree(worktreeAbs, root).catch(() => {})
|
await git.removeWorktree(worktreeAbs, root).catch(() => {})
|
||||||
await git.deleteLocalBranch(branch, root).catch(() => {})
|
await git.deleteLocalBranch(branch, root).catch(() => {})
|
||||||
await unlinkSessionSymlink(root, branch)
|
await unlink(join(root, '.sandlot', branch)).catch(() => {})
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user