import chalk from 'chalk' import cp from 'child_process' import fs from 'fs-extra' import tmp from 'tmp' import paths from './config/paths' const exec = (cmd: string, opts?: cp.ExecSyncOptions) => cp.execSync(cmd, { encoding: 'utf-8', stdio: 'pipe', ...opts }) as string function validateSVNRoot(root: string) { const ls = exec(`svn ls ${root}`) return ['trunk', 'branches'].every((s) => ls.includes(s)) } interface WorkingCopyInfo { url: string branch: string revision: string author: string distBranchURL: string distBranchDirURL: string root: string } function getWorkingCopyInfo(): WorkingCopyInfo { exec(`svn up`) const url = exec(`svn info --show-item url`).trim() const revision = exec(`svn info --show-item last-changed-revision`).trim() const author = exec(`svn info --show-item last-changed-author`).trim() let branch = 'trunk' let root = url.replace(/\/trunk$/, '') if (url.includes('/branches/')) { branch = url.split('/').pop()! root = url.replace(/\/branches\/[^/]+$/, '') } let distBranchURL = root + '/branches/dist' let distBranchDirURL = distBranchURL + '/' + branch if (!validateSVNRoot(root)) { console.log(chalk.red('SVN目录不符合规则,必须包含 trunk branches')) process.exit(1) } return { url, branch, revision, author, distBranchURL, distBranchDirURL, root } } function copyDistToRepo(info: WorkingCopyInfo) { const tmpdir = tmp.dirSync().name try { exec(`svn ls ${info.distBranchDirURL} --depth empty`) } catch (error: any) { if (error.message.includes('non-existent')) { exec( `svn mkdir ${info.distBranchDirURL} --parents -m "[edu-scripts] create ${info.branch} dist"` ) } else { throw error } } exec(`svn co ${info.distBranchDirURL} ${tmpdir}`) try { exec(`svn rm * --force -q`, { cwd: tmpdir }) } catch {} fs.copySync(paths.dist, tmpdir) exec(`svn add * --force --auto-props --parents --depth infinity -q`, { cwd: tmpdir }) const msg = `[edu-scripts] commit ${info.branch} dist #${info.revision} @${info.author}` exec(`svn ci -m "${msg}"`, { cwd: tmpdir }) fs.removeSync(tmpdir) } interface CommitDistArgs { rmLocal?: boolean } export default async function commitDist(args: CommitDistArgs) { if (!fs.existsSync(paths.dist)) { console.log(chalk.red('未找到 dist 文件夹,请先 edu-scpirts build')) process.exit(1) } if (exec('svn st').trim().length) { console.log(chalk.red('似乎存在未提交的代码,请提交后重试。运行 svn st 查看具体信息')) process.exit(1) } const info = getWorkingCopyInfo() console.log( chalk.green( [ `分支: ${info.branch}`, `版本: ${info.revision}`, `作者: ${info.author}`, `地址: ${info.distBranchDirURL}`, ].join('\n') ) ) copyDistToRepo(info) if (args.rmLocal) { fs.removeSync(paths.dist) } console.log(chalk.green('提交完成')) }