UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

140 lines (137 loc) 4.86 kB
import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import _regeneratorRuntime from '@babel/runtime/regenerator'; import { _ as __awaiter } from '../tslib.es6-848120af.js'; import { execCommand } from '../node/node-command.mjs'; import { getChildProcess } from '../nodejs/child_process.mjs'; import { getFs } from '../nodejs/fs.mjs'; import { getPath } from '../nodejs/path.mjs'; import { getChalk } from '../third-party/chalk.mjs'; import '@babel/runtime/helpers/typeof'; /** * 异步执行命令,返回 stdout 字符串 */ function execAsync(command, cwd) { return new Promise(function (resolve) { var _getChildProcess = getChildProcess(), exec = _getChildProcess.exec; exec(command, { cwd: cwd, encoding: 'utf-8' }, function (err, stdout) { resolve(err ? '' : stdout || ''); }); }); } /** * 检查单个 git 仓库的状态(是否 clean、是否已 push) * @param {string} subDir - git 仓库目录路径 * @param {*} chalk - chalk 实例 */ function checkSingleRepo(subDir, chalk) { return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var _yield$Promise$all, _yield$Promise$all2, statusOutput, aheadCount, count; return _regeneratorRuntime.wrap(function (_context) { while (1) switch (_context.prev = _context.next) { case 0: _context.next = 1; return Promise.all([execAsync('git status --porcelain', subDir), execAsync('git rev-list --count @{u}..HEAD', subDir)]); case 1: _yield$Promise$all = _context.sent; _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 2); statusOutput = _yield$Promise$all2[0]; aheadCount = _yield$Promise$all2[1]; if (statusOutput.trim()) { console.log(chalk.red('[not clean] '), subDir); } count = parseInt(aheadCount.trim(), 10); if (count > 0) { console.log(chalk.blue('[not push]'), subDir); } case 2: case "end": return _context.stop(); } }, _callee); })); } /** * 异步并行检查目录下所有 git 仓库的工作区状态 * 相比同步版本,在仓库数量较多时有显著的性能提升 * @param dir - 要检查的父目录路径 * @example * ```ts * // 并行检查 ~/Documents/git 下所有子仓库 * await checkGitClean('/Users/foo/Documents/git'); * // 控制台会输出: * // [not clean] /Users/foo/Documents/git/repoA * // [not push] /Users/foo/Documents/git/repoB * ``` */ function checkGitClean(dir) { return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() { var fs, path, chalk, list, tasks; return _regeneratorRuntime.wrap(function (_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: fs = getFs(); path = getPath(); chalk = getChalk(); if (fs.existsSync(dir)) { _context2.next = 1; break; } console.error("Not Exist ".concat(dir)); return _context2.abrupt("return"); case 1: list = fs.readdirSync(dir); // 筛选出所有 git 仓库,并行检查 tasks = list.map(function (file) { return path.resolve(dir, file); }).filter(function (subDir) { return fs.existsSync(path.resolve(subDir, '.git')); }).map(function (subDir) { return checkSingleRepo(subDir, chalk); }); _context2.next = 2; return Promise.all(tasks); case 2: case "end": return _context2.stop(); } }, _callee2); })); } /** * 同步版本,保持向后兼容 * @param dir - 要检查的父目录路径 * @example * ```ts * checkGitCleanSync('/Users/foo/Documents/git'); * // 同步依次检查,仓库有变动或未推送会打印警告 * ``` */ function checkGitCleanSync(dir) { var fs = getFs(); var path = getPath(); var chalk = getChalk(); if (!fs.existsSync(dir)) { console.error("Not Exist ".concat(dir)); return; } var list = fs.readdirSync(dir); list.forEach(function (file) { var subDir = path.resolve(dir, file); var dotGit = path.resolve(subDir, '.git'); var isGitRepo = fs.existsSync(dotGit); if (isGitRepo) { var statusOutput = execCommand('git status --porcelain', subDir, 'pipe'); if (statusOutput.trim()) { console.log(chalk.red('[not clean] '), subDir); } var aheadCount = execCommand('git rev-list --count @{u}..HEAD 2>/dev/null || echo 0', subDir, 'pipe'); if (aheadCount.trim() && parseInt(aheadCount.trim(), 10) > 0) { console.log(chalk.blue('[not push]'), subDir); } } }); } export { checkGitClean, checkGitCleanSync };