1import fs from 'fs/promises' 3import { existsSync } from 'fs' 4import { execSync } from 'child_process' 18export const buildOssGitWorkingDir = async (destDir: string, opts: {skipMine?: boolean, skipReview?: boolean, skipScan?: boolean} = {}) => { 20 console.log(`Building oss git working dir (sha: ${shortSha})...`) 26 const ossAuthorResolved = ossHook?.ossAuthor || ossAuthor 28 await fs.rm(destDir, {recursive: true, force: true}) 29 await fs.mkdir(destDir, {recursive: true}) 37 const allFiles = (await getTrackedFiles(ossTrackedPaths)).filter(f => !ossExcludeFn || !ossExcludeFn(f)) 38 for (const relPath of allFiles) { 39 const displayPath = ossPathFwd(relPath) 40 const destFile = path.join(destDir, displayPath) 41 await fs.mkdir(path.dirname(destFile), {recursive: true}) 42 const srcAbs = path.join(ptDir, relPath) 43 const fileStat = await fs.stat(srcAbs).catch(() => null) 44 if (!fileStat?.isFile()) continue 45 const basename = path.basename(relPath) 46 if (basename === '.gitignore' && ossGitignore) { 47 await fs.writeFile(destFile, ossGitignore) 48 } else if (basename === 'pnpm-workspace.yaml' && filterPnpmWs) { 49 const raw = await fs.readFile(srcAbs, 'utf8') 50 await fs.writeFile(destFile, filterPnpmWs(raw)) 51 } else if (relPath === 'package.json' && generatePrunedPkg) { 52 const monorPkg = JSON.parse(await fs.readFile(srcAbs, 'utf8')) 53 const codeDirs = ossTrackedPaths.filter(p => p.endsWith('/')).map(p => path.join(ptDir, p)) 54 const prunedPkg = await generatePrunedPkg({monorPkg, codeDirs}) 55 await fs.writeFile(destFile, JSON.stringify(prunedPkg, null, 2) + '\n') 56 } else if (relPath === 'opencode.json' && transformOcJson) { 57 const raw = await fs.readFile(srcAbs, 'utf8') 58 await fs.writeFile(destFile, transformOcJson(ossReplaceFn ? ossReplaceFn(raw) : raw)) 60 const raw = await fs.readFile(srcAbs, 'utf8') 61 const transformed = ossReplaceFn ? ossReplaceFn(raw) : raw 62 await fs.writeFile(destFile, transformed) 64 await fs.copyFile(srcAbs, destFile) 66 if (fileStat.mode & 0o111) await fs.chmod(destFile, fileStat.mode) 69 console.log(`Generating pnpm-lock.yaml...`) 72 if (ossForbidStrA && !opts.skipScan) { 73 console.log(`Scanning oss export for forbidden strings...`) 74 const forbiddenHits: {path: string, needleStr: string, containingWord: string}[] = [] 75 const scanFile = async (filePath: string, displayPath: string) => { 76 const content = await fs.readFile(filePath, 'utf8').catch(() => null) 78 const hit = perFileGuardNeedle({needleStrA: ossForbidStrA, path: displayPath, contents: content, raiseOnFind: false}) 79 if (hit) forbiddenHits.push(hit) 81 for (const relPath of allFiles) { 82 const displayPath = ossPathFwd(relPath) 83 if (!isTextFile(relPath) || displayPath.endsWith('.d.ts')) continue 84 await scanFile(path.join(destDir, displayPath), displayPath) 86 await scanFile(path.join(destDir, 'pnpm-lock.yaml'), 'pnpm-lock.yaml') 87 if (forbiddenHits.length) { 88 console.error(`\nOSS export: ${forbiddenHits.length} forbidden string hit(s):`) 89 for (const h of forbiddenHits) console.error(` ${h.path}: "${h.needleStr}" in "${h.containingWord}"`) 90 throw new Error(`oss export failed: ${forbiddenHits.length} forbidden string(s) found`) 94 if (!opts.skipReview) { 95 const reviewResult = await llmReviewDir({dir: destDir, shortSha, reviewName: 'ossgit'}) 96 if (reviewResult.summary.abortedEarly || reviewResult.summary.failedChunkCount > 0) { 97 throw new Error(`oss review did not pass: ${reviewResult.summary.failedChunkCount} chunk(s) failed${reviewResult.summary.abortedEarly ? ' (aborted early)' : ''}`) 101 execSync('git init', {cwd: destDir, stdio: 'pipe'}) 102 execSync(`git config user.name "${ossEnsName}"`, {cwd: destDir, stdio: 'pipe'}) 103 execSync(`git config user.email "${ossEmail}"`, {cwd: destDir, stdio: 'pipe'}) 104 execSync('git add -A', {cwd: destDir, stdio: 'pipe'}) 105 const repoHeadSha = commitMineShaPrefix({cwd: destDir, msgBase: `oss export ${shortSha}`, tgtShaPrefix: opts.skipMine ? '' : ossRepoTgtShaPrefix}) 107 console.log(`Built ${shortPtPath(destDir)} (${allFiles.length} files, head ${repoHeadSha.slice(0, 12)})`) 111export const getOrBuildOssGitWorkingDir = async () => { 113 const cacheDir = path.join(ptTmpDir, `oss-git-workdir-${shortSha}`) 114 if (existsSync(path.join(cacheDir, '.git'))) return cacheDir 115 return buildOssGitWorkingDir(cacheDir) 118export const getOrBuildOssBenchWorkdir = async () => { 120 const cacheDir = path.join(ptTmpDir, `oss-bench-workdir-${shortSha}`) 121 if (existsSync(path.join(cacheDir, '.git'))) return cacheDir 122 return buildOssGitWorkingDir(cacheDir, {skipMine: true, skipReview: true, skipScan: true})