UNPKG

code996

Version:

通过分析 Git commit 的时间分布,计算出项目的'996指数'

226 lines 9.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnalyzeExecutor = void 0; const chalk_1 = __importDefault(require("chalk")); const ora_1 = __importDefault(require("ora")); const git_collector_1 = require("../../git/git-collector"); const git_parser_1 = require("../../git/git-parser"); const terminal_1 = require("../../utils/terminal"); const report_1 = require("./report"); const commit_guard_1 = require("../common/commit-guard"); /** 分析执行器,集中处理采集、解析与渲染流程 */ class AnalyzeExecutor { /** 执行分析的主流程 */ static async execute(path, options) { try { const collector = new git_collector_1.GitCollector(); // 计算时间范围:优先使用用户输入,其次按最后一次提交回溯365天,最后退回到当前时间 const { since: effectiveSince, until: effectiveUntil, mode: rangeMode, note: rangeNote, } = await resolveTimeRange({ collector, path, options }); // 显示分析开始信息 console.log(chalk_1.default.blue('🔍 分析仓库:'), path || process.cwd()); switch (rangeMode) { case 'all-time': console.log(chalk_1.default.blue('📅 时间范围:'), '所有时间'); break; case 'custom': console.log(chalk_1.default.blue('📅 时间范围:'), `${effectiveSince}${effectiveUntil}`); break; case 'auto-last-commit': console.log(chalk_1.default.blue('📅 时间范围:'), `${effectiveSince}${effectiveUntil}${rangeNote ? `(${rangeNote})` : ''}`); break; default: console.log(chalk_1.default.blue('📅 时间范围:'), `${effectiveSince}${effectiveUntil}(按当前日期回溯)`); } console.log(); let authorFilter; if (options.self) { authorFilter = await resolveAuthorFilter(collector, path); console.log(chalk_1.default.blue('🙋 作者过滤:'), authorFilter.displayLabel); console.log(); } // 构建统一的 Git 采集参数,保证所有步骤使用一致的过滤条件 const collectOptions = { path, since: effectiveSince, until: effectiveUntil, authorPattern: authorFilter?.pattern, }; // 在正式分析前,先检查 commit 样本量是否达到最低要求 const hasEnoughCommits = await (0, commit_guard_1.ensureCommitSamples)(collector, collectOptions, 20, '分析'); if (!hasEnoughCommits) { return; } // 创建进度指示器 const spinner = (0, ora_1.default)('📦 开始分析').start(); // 步骤1: 数据采集 const rawData = await collector.collect(collectOptions); spinner.text = '⚙️ 正在解析数据...'; spinner.render(); // 步骤2: 数据解析与验证 const parsedData = git_parser_1.GitParser.parseGitData(rawData, undefined, effectiveSince, effectiveUntil); const validation = git_parser_1.GitParser.validateData(parsedData); if (!validation.isValid) { spinner.fail('数据验证失败'); console.log(chalk_1.default.red('❌ 发现以下错误:')); validation.errors.forEach((error) => { console.log(` ${chalk_1.default.red('•')} ${error}`); }); process.exit(1); } spinner.text = '📈 正在计算996指数...'; spinner.render(); // 步骤3: 计算996指数 const result = git_parser_1.GitParser.calculate996Index(parsedData); spinner.succeed('分析完成!'); console.log(); // 若未指定时间范围,尝试回填实际的首尾提交时间 let actualSince; let actualUntil; if (!options.since && !options.until && !options.allTime) { try { actualSince = await collector.getFirstCommitDate(collectOptions); actualUntil = await collector.getLastCommitDate(collectOptions); } catch { console.log(chalk_1.default.yellow('⚠️ 无法获取实际时间范围,将使用默认显示')); } } printResults(result, parsedData, rawData, options, effectiveSince, effectiveUntil, rangeMode); } catch (error) { console.error(chalk_1.default.red('❌ 分析失败:'), error.message); process.exit(1); } } } exports.AnalyzeExecutor = AnalyzeExecutor; async function resolveTimeRange({ collector, path, options, }) { if (options.allTime) { // --all-time 时不传 since 和 until,让 git 返回所有数据 return { mode: 'all-time', }; } // 处理 --year 参数 if (options.year) { const yearRange = parseYearOption(options.year); if (yearRange) { return { since: yearRange.since, until: yearRange.until, mode: 'custom', note: yearRange.note, }; } } if (options.since || options.until) { const fallback = (0, terminal_1.calculateTimeRange)(false); return { since: options.since || fallback.since, until: options.until || fallback.until, mode: 'custom', }; } const baseOptions = { path, }; try { const lastCommitDate = await collector.getLastCommitDate(baseOptions); if (lastCommitDate) { const untilDate = toUTCDate(lastCommitDate); const sinceDate = new Date(untilDate.getTime()); sinceDate.setUTCDate(sinceDate.getUTCDate() - 365); const baseline = Date.UTC(1970, 0, 1); if (sinceDate.getTime() < baseline) { sinceDate.setTime(baseline); } return { since: formatUTCDate(sinceDate), until: formatUTCDate(untilDate), mode: 'auto-last-commit', note: '以最后一次提交为基准回溯365天', }; } } catch { } const fallback = (0, terminal_1.calculateTimeRange)(false); return { since: fallback.since, until: fallback.until, mode: 'fallback', }; } /** * 当启用 --self 时解析当前 Git 用户的信息,生成作者过滤正则 */ async function resolveAuthorFilter(collector, path) { const authorInfo = await collector.resolveSelfAuthor(path); return { pattern: authorInfo.pattern, displayLabel: authorInfo.displayLabel, }; } /** 解析 --year 参数,支持单年和年份范围 */ function parseYearOption(yearStr) { // 去除空格 yearStr = yearStr.trim(); // 匹配年份范围格式:2023-2025 const rangeMatch = yearStr.match(/^(\d{4})-(\d{4})$/); if (rangeMatch) { const startYear = parseInt(rangeMatch[1], 10); const endYear = parseInt(rangeMatch[2], 10); // 验证年份合法性 if (startYear < 1970 || endYear < 1970 || startYear > endYear) { console.error(chalk_1.default.red('❌ 年份格式错误: 起始年份不能大于结束年份,且年份必须 >= 1970')); process.exit(1); } return { since: `${startYear}-01-01`, until: `${endYear}-12-31`, note: `${startYear}-${endYear}年`, }; } // 匹配单年格式:2025 const singleMatch = yearStr.match(/^(\d{4})$/); if (singleMatch) { const year = parseInt(singleMatch[1], 10); // 验证年份合法性 if (year < 1970) { console.error(chalk_1.default.red('❌ 年份格式错误: 年份必须 >= 1970')); process.exit(1); } return { since: `${year}-01-01`, until: `${year}-12-31`, note: `${year}年`, }; } // 格式不正确 console.error(chalk_1.default.red('❌ 年份格式错误: 请使用 YYYY 格式(如 2025)或 YYYY-YYYY 格式(如 2023-2025)')); process.exit(1); } function toUTCDate(dateStr) { const [year, month, day] = dateStr.split('-').map((value) => parseInt(value, 10)); return new Date(Date.UTC(year, (month || 1) - 1, day || 1)); } function formatUTCDate(date) { const year = date.getUTCFullYear(); const month = String(date.getUTCMonth() + 1).padStart(2, '0'); const day = String(date.getUTCDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } /** 输出核心结果、时间分布与统计信息 */ function printResults(result, parsedData, rawData, options, since, until, rangeMode) { (0, report_1.printCoreResults)(result, rawData, options, since, until, rangeMode); (0, report_1.printDetailedAnalysis)(result, parsedData); // 新增:详细分析 (0, report_1.printWorkTimeSummary)(parsedData); (0, report_1.printTimeDistribution)(parsedData); (0, report_1.printWeekdayOvertime)(parsedData); (0, report_1.printWeekendOvertime)(parsedData); (0, report_1.printLateNightAnalysis)(parsedData); (0, report_1.printRecommendation)(result, parsedData); } //# sourceMappingURL=analyze.js.map