mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-19 07:04:40 +00:00
chore: cleanup migrate from global code (#17292)
This commit is contained in:
@@ -1,12 +1,11 @@
|
|||||||
import z from "zod"
|
import z from "zod"
|
||||||
import { Filesystem } from "../util/filesystem"
|
import { Filesystem } from "../util/filesystem"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { Database, eq } from "../storage/db"
|
import { and, Database, eq } from "../storage/db"
|
||||||
import { ProjectTable } from "./project.sql"
|
import { ProjectTable } from "./project.sql"
|
||||||
import { SessionTable } from "../session/session.sql"
|
import { SessionTable } from "../session/session.sql"
|
||||||
import { Log } from "../util/log"
|
import { Log } from "../util/log"
|
||||||
import { Flag } from "@/flag/flag"
|
import { Flag } from "@/flag/flag"
|
||||||
import { work } from "../util/queue"
|
|
||||||
import { fn } from "@opencode-ai/util/fn"
|
import { fn } from "@opencode-ai/util/fn"
|
||||||
import { BusEvent } from "@/bus/bus-event"
|
import { BusEvent } from "@/bus/bus-event"
|
||||||
import { iife } from "@/util/iife"
|
import { iife } from "@/util/iife"
|
||||||
@@ -276,7 +275,13 @@ export namespace Project {
|
|||||||
// Runs on every startup because sessions created before git init
|
// Runs on every startup because sessions created before git init
|
||||||
// accumulate under "global" and need migrating whenever they appear.
|
// accumulate under "global" and need migrating whenever they appear.
|
||||||
if (data.id !== ProjectID.global) {
|
if (data.id !== ProjectID.global) {
|
||||||
await migrateFromGlobal(data.id, data.worktree)
|
Database.use((db) =>
|
||||||
|
db
|
||||||
|
.update(SessionTable)
|
||||||
|
.set({ project_id: data.id })
|
||||||
|
.where(and(eq(SessionTable.project_id, ProjectID.global), eq(SessionTable.directory, data.worktree)))
|
||||||
|
.run(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
GlobalBus.emit("event", {
|
GlobalBus.emit("event", {
|
||||||
payload: {
|
payload: {
|
||||||
@@ -311,28 +316,6 @@ export namespace Project {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
async function migrateFromGlobal(id: ProjectID, worktree: string) {
|
|
||||||
const row = Database.use((db) => db.select().from(ProjectTable).where(eq(ProjectTable.id, ProjectID.global)).get())
|
|
||||||
if (!row) return
|
|
||||||
|
|
||||||
const sessions = Database.use((db) =>
|
|
||||||
db.select().from(SessionTable).where(eq(SessionTable.project_id, ProjectID.global)).all(),
|
|
||||||
)
|
|
||||||
if (sessions.length === 0) return
|
|
||||||
|
|
||||||
log.info("migrating sessions from global", { newProjectID: id, worktree, count: sessions.length })
|
|
||||||
|
|
||||||
await work(10, sessions, async (row) => {
|
|
||||||
// Skip sessions that belong to a different directory
|
|
||||||
if (row.directory && row.directory !== worktree) return
|
|
||||||
|
|
||||||
log.info("migrating session", { sessionID: row.id, from: ProjectID.global, to: id })
|
|
||||||
Database.use((db) => db.update(SessionTable).set({ project_id: id }).where(eq(SessionTable.id, row.id)).run())
|
|
||||||
}).catch((error) => {
|
|
||||||
log.error("failed to migrate sessions from global to project", { error, projectId: id })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setInitialized(id: ProjectID) {
|
export function setInitialized(id: ProjectID) {
|
||||||
Database.use((db) =>
|
Database.use((db) =>
|
||||||
db
|
db
|
||||||
|
|||||||
@@ -100,14 +100,15 @@ describe("migrateFromGlobal", () => {
|
|||||||
expect(row!.project_id).toBe(project.id)
|
expect(row!.project_id).toBe(project.id)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("migrates sessions with empty directory", async () => {
|
test("does not claim sessions with empty directory", async () => {
|
||||||
await using tmp = await tmpdir({ git: true })
|
await using tmp = await tmpdir({ git: true })
|
||||||
const { project } = await Project.fromDirectory(tmp.path)
|
const { project } = await Project.fromDirectory(tmp.path)
|
||||||
expect(project.id).not.toBe(ProjectID.global)
|
expect(project.id).not.toBe(ProjectID.global)
|
||||||
|
|
||||||
ensureGlobal()
|
ensureGlobal()
|
||||||
|
|
||||||
// Legacy sessions may lack a directory value
|
// Legacy sessions may lack a directory value.
|
||||||
|
// Without a matching origin directory, they should remain global.
|
||||||
const id = uid()
|
const id = uid()
|
||||||
seed({ id, dir: "", project: ProjectID.global })
|
seed({ id, dir: "", project: ProjectID.global })
|
||||||
|
|
||||||
@@ -115,8 +116,7 @@ describe("migrateFromGlobal", () => {
|
|||||||
|
|
||||||
const row = Database.use((db) => db.select().from(SessionTable).where(eq(SessionTable.id, id)).get())
|
const row = Database.use((db) => db.select().from(SessionTable).where(eq(SessionTable.id, id)).get())
|
||||||
expect(row).toBeDefined()
|
expect(row).toBeDefined()
|
||||||
// Empty directory means "no known origin" — should be claimed
|
expect(row!.project_id).toBe(ProjectID.global)
|
||||||
expect(row!.project_id).toBe(project.id)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test("does not steal sessions from unrelated directories", async () => {
|
test("does not steal sessions from unrelated directories", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user