import type { CLIOptions } from "./list.ts"; import { scanAllDirectories, filterProjects } from "../../scanner/index.ts"; import { bunGitService } from "../../services/git.ts"; import { defaultGitHubService } from "../../services/github.ts"; import { ensureAuthenticated } from "../../github/auth.ts"; import { formatWarning, formatError, formatInfo, formatScanning, formatOperationItem, formatOperationSummary, } from "../formatters.ts"; /** * Setup projects: init git + create GitHub repo + push * For non-git projects and git projects without remotes */ export async function setupProjects(options: CLIOptions & { isPrivate?: boolean }): Promise { const { config, filter, isPrivate = true } = options; // Check GitHub auth - auto-login if not set const token = await ensureAuthenticated(); if (!token) { console.log(formatError("GitHub authentication required.")); console.log(formatInfo("Run 'gitforest login' to authenticate.")); process.exit(1); } console.log(formatScanning()); const projects = await scanAllDirectories(config); // Find eligible projects: non-git OR git without remote let eligibleProjects = projects.filter( (p) => p.type === "non-git" || (p.type === "git" && !p.status?.hasRemote) ); if (filter) { eligibleProjects = filterProjects(eligibleProjects, filter); } if (eligibleProjects.length === 0) { console.log(formatWarning("No projects need setup (all have remotes).")); return; } const nonGitCount = eligibleProjects.filter((p) => p.type === "non-git").length; const noRemoteCount = eligibleProjects.filter((p) => p.type === "git").length; console.log(formatInfo(`\nSetting up ${eligibleProjects.length} projects:`)); if (nonGitCount > 0) console.log(formatInfo(` - ${nonGitCount} non-git projects (will init)`)); if (noRemoteCount > 0) console.log(formatInfo(` - ${noRemoteCount} git projects without remote`)); console.log(formatInfo(` - Creating ${isPrivate ? "private" : "public"} repos\n`)); let initSuccess = 0; let createSuccess = 0; for (const project of eligibleProjects) { // Step 1: Init git if needed if (project.type === "non-git") { const initResult = await bunGitService.init(project.path); if (initResult.success) { initSuccess++; console.log(formatOperationItem(`${project.name} (init)`, true)); } else { console.log(formatOperationItem(`${project.name} (init)`, false, initResult.error)); continue; // Skip create if init failed } } // Step 2: Create GitHub repo (this also adds remote and pushes) const createResult = await defaultGitHubService.createRepo({ name: project.name, isPrivate, localPath: project.path, }); console.log(formatOperationItem(`${project.name} (create + push)`, createResult.success, createResult.error)); if (createResult.success) createSuccess++; } console.log(`\n${formatOperationSummary("Set up", createSuccess, eligibleProjects.length)}`); if (nonGitCount > 0) { console.log(formatInfo(` Git initialized: ${initSuccess}/${nonGitCount}`)); } }