Files
Codewalkers/apps/server/git/project-clones.ts
Lukas May 34578d39c6 refactor: Restructure monorepo to apps/server/ and apps/web/ layout
Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt
standard monorepo conventions (apps/ for runnable apps, packages/
for reusable libraries). Update all config files, shared package
imports, test fixtures, and documentation to reflect new paths.

Key fixes:
- Update workspace config to ["apps/*", "packages/*"]
- Update tsconfig.json rootDir/include for apps/server/
- Add apps/web/** to vitest exclude list
- Update drizzle.config.ts schema path
- Fix ensure-schema.ts migration path detection (3 levels up in dev,
  2 levels up in dist)
- Fix tests/integration/cli-server.test.ts import paths
- Update packages/shared imports to apps/server/ paths
- Update all docs/ files with new paths
2026-03-03 11:22:53 +01:00

49 lines
1.6 KiB
TypeScript

/**
* Project Clone Management
*
* Ensures project repositories are cloned into the repos/ directory.
* These base clones are used as the source for git worktrees.
*/
import { join } from 'node:path';
import { access } from 'node:fs/promises';
import { cloneProject } from './clone.js';
import { createModuleLogger } from '../logger/index.js';
const log = createModuleLogger('git');
/**
* Derive the canonical clone directory for a project (relative to workspace root).
* Convention: repos/<sanitizedName>-<id>/
*/
export function getProjectCloneDir(projectName: string, projectId: string): string {
const sanitized = projectName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
return join('repos', `${sanitized}-${projectId}`);
}
/**
* Ensure a project's git repository is cloned to the workspace.
* Uses the canonical path: <workspaceRoot>/repos/<sanitizedName>-<id>/
*
* @param project - Project with id, name, and url
* @param workspaceRoot - Absolute path to the workspace root
* @returns Absolute path to the clone directory
*/
export async function ensureProjectClone(
project: { id: string; name: string; url: string },
workspaceRoot: string,
): Promise<string> {
const relPath = getProjectCloneDir(project.name, project.id);
const clonePath = join(workspaceRoot, relPath);
try {
await access(clonePath);
log.debug({ project: project.name, clonePath }, 'project clone already exists');
return clonePath;
} catch {
log.info({ project: project.name, url: project.url, clonePath }, 'cloning project for first time');
await cloneProject(project.url, clonePath);
return clonePath;
}
}