import { detectDbContexts, findStartupProject, hasDotnetProject } from '../lib/detect-dbcontexts.js'; import { listMigrationsJson, dotnetAvailable, dotnetEfAvailable } from '../lib/ef-runner.js'; import type { AssemblyListing, ContextListing, ListResult, ListSpec } from './types.js'; export async function execute(spec: ListSpec): Promise { const warnings: string[] = []; if (!(await hasDotnetProject(spec.cwd))) { return { success: true, cwd: spec.cwd, kind: 'unknown', contexts: [], warnings: ['No .csproj found in worktree — nothing to list.'], }; } if (!(await dotnetAvailable())) { return { success: false, cwd: spec.cwd, kind: 'unknown', contexts: [], warnings, error: 'dotnet CLI is not available on PATH', }; } if (!(await dotnetEfAvailable())) { warnings.push('dotnet-ef tool is not installed globally — run: dotnet tool install --global dotnet-ef'); } const detection = await detectDbContexts(spec.cwd); const startupProject = await findStartupProject(spec.cwd); const out: ContextListing[] = []; for (const ctx of detection.contexts) { if (spec.contextName && ctx.name !== spec.contextName) continue; const assemblies: AssemblyListing[] = []; for (const asm of ctx.assemblies) { if (spec.assembly && asm.assemblyName !== spec.assembly) continue; const extraEnv = asm.provider ? { STUDIO_DESIGN_PROVIDER: capitalize(asm.provider) } : undefined; const result = await listMigrationsJson(spec.cwd, { context: ctx.name, projectPath: asm.csprojPath, startupProjectPath: startupProject ?? undefined, extraEnv, }); assemblies.push({ assemblyName: asm.assemblyName, csprojPath: asm.csprojPath, migrationsDir: asm.migrationsDir, provider: asm.provider, version: asm.version, migrations: result.migrations, error: result.success ? undefined : result.error, }); } out.push({ contextName: ctx.name, assemblies }); } return { success: true, cwd: detection.cwd, kind: detection.kind, contexts: out, warnings, }; } function capitalize(s: string): string { if (!s) return s; if (s.toLowerCase() === 'sqlserver') return 'SqlServer'; return s.charAt(0).toUpperCase() + s.slice(1); }