openspec-stat 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/README.zh-CN.md +28 -0
- package/dist/cjs/cli.js +12 -127
- package/dist/cjs/commands/init.d.ts +7 -0
- package/dist/cjs/commands/init.js +58 -0
- package/dist/cjs/commands/multi.d.ts +16 -0
- package/dist/cjs/commands/multi.js +172 -0
- package/dist/cjs/commands/single.d.ts +2 -0
- package/dist/cjs/commands/single.js +148 -0
- package/dist/cjs/formatters.d.ts +4 -4
- package/dist/cjs/formatters.js +128 -36
- package/dist/cjs/git-analyzer.d.ts +1 -0
- package/dist/cjs/git-analyzer.js +6 -0
- package/dist/cjs/i18n/locales/en.json +74 -1
- package/dist/cjs/i18n/locales/zh-CN.json +74 -1
- package/dist/cjs/multi/config-validator.d.ts +3 -0
- package/dist/cjs/multi/config-validator.js +130 -0
- package/dist/cjs/multi/config-wizard.d.ts +50 -0
- package/dist/cjs/multi/config-wizard.js +331 -0
- package/dist/cjs/multi/multi-repo-analyzer.d.ts +14 -0
- package/dist/cjs/multi/multi-repo-analyzer.js +210 -0
- package/dist/cjs/types.d.ts +46 -0
- package/dist/esm/cli.js +54 -139
- package/dist/esm/commands/init.d.ts +7 -0
- package/dist/esm/commands/init.js +49 -0
- package/dist/esm/commands/multi.d.ts +16 -0
- package/dist/esm/commands/multi.js +192 -0
- package/dist/esm/commands/single.d.ts +2 -0
- package/dist/esm/commands/single.js +162 -0
- package/dist/esm/formatters.d.ts +4 -4
- package/dist/esm/formatters.js +173 -52
- package/dist/esm/git-analyzer.d.ts +1 -0
- package/dist/esm/git-analyzer.js +104 -77
- package/dist/esm/i18n/locales/en.json +74 -1
- package/dist/esm/i18n/locales/zh-CN.json +74 -1
- package/dist/esm/multi/config-validator.d.ts +3 -0
- package/dist/esm/multi/config-validator.js +109 -0
- package/dist/esm/multi/config-wizard.d.ts +50 -0
- package/dist/esm/multi/config-wizard.js +535 -0
- package/dist/esm/multi/multi-repo-analyzer.d.ts +14 -0
- package/dist/esm/multi/multi-repo-analyzer.js +446 -0
- package/dist/esm/types.d.ts +46 -0
- package/package.json +1 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
3
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
4
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { loadConfig } from "../config.js";
|
|
7
|
+
import { GitAnalyzer } from "../git-analyzer.js";
|
|
8
|
+
import { StatsAggregator } from "../stats-aggregator.js";
|
|
9
|
+
import { OutputFormatter } from "../formatters.js";
|
|
10
|
+
import { getDefaultTimeRange, parseDateTime, parseBranches } from "../time-utils.js";
|
|
11
|
+
import { selectBranches } from "../branch-selector.js";
|
|
12
|
+
import { initI18n, t } from "../i18n/index.js";
|
|
13
|
+
export function runSingleRepoCommand(_x) {
|
|
14
|
+
return _runSingleRepoCommand.apply(this, arguments);
|
|
15
|
+
}
|
|
16
|
+
function _runSingleRepoCommand() {
|
|
17
|
+
_runSingleRepoCommand = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(options) {
|
|
18
|
+
var config, since, until, defaultRange, branches, analyzer, activeAuthors, commits, analyses, i, commit, analysis, aggregator, result, formatter;
|
|
19
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
20
|
+
while (1) switch (_context.prev = _context.next) {
|
|
21
|
+
case 0:
|
|
22
|
+
_context.prev = 0;
|
|
23
|
+
initI18n(options.lang);
|
|
24
|
+
console.log(chalk.blue(t('loading.config')));
|
|
25
|
+
_context.next = 5;
|
|
26
|
+
return loadConfig(options.config, options.repo);
|
|
27
|
+
case 5:
|
|
28
|
+
config = _context.sent;
|
|
29
|
+
if (options.since || options.until) {
|
|
30
|
+
since = options.since ? parseDateTime(options.since) : getDefaultTimeRange(config.defaultSinceHours, config.defaultUntilHours).since;
|
|
31
|
+
until = options.until ? parseDateTime(options.until) : getDefaultTimeRange(config.defaultSinceHours, config.defaultUntilHours).until;
|
|
32
|
+
} else {
|
|
33
|
+
defaultRange = getDefaultTimeRange(config.defaultSinceHours, config.defaultUntilHours);
|
|
34
|
+
since = defaultRange.since;
|
|
35
|
+
until = defaultRange.until;
|
|
36
|
+
}
|
|
37
|
+
if (!options.branches) {
|
|
38
|
+
_context.next = 11;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
branches = parseBranches(options.branches);
|
|
42
|
+
_context.next = 18;
|
|
43
|
+
break;
|
|
44
|
+
case 11:
|
|
45
|
+
if (!(options.interactive !== false)) {
|
|
46
|
+
_context.next = 17;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
_context.next = 14;
|
|
50
|
+
return selectBranches(options.repo, config.defaultBranches);
|
|
51
|
+
case 14:
|
|
52
|
+
branches = _context.sent;
|
|
53
|
+
_context.next = 18;
|
|
54
|
+
break;
|
|
55
|
+
case 17:
|
|
56
|
+
branches = config.defaultBranches || [];
|
|
57
|
+
case 18:
|
|
58
|
+
console.log(chalk.blue(t('info.timeRange', {
|
|
59
|
+
since: since.toLocaleString(),
|
|
60
|
+
until: until.toLocaleString()
|
|
61
|
+
})));
|
|
62
|
+
console.log(chalk.blue(t('info.branches', {
|
|
63
|
+
branches: branches.join(', ') || t('info.allBranches')
|
|
64
|
+
})));
|
|
65
|
+
analyzer = new GitAnalyzer(options.repo, config); // Fetch remote branches to ensure data is up-to-date
|
|
66
|
+
if (!(!options.noFetch && config.autoFetch !== false)) {
|
|
67
|
+
_context.next = 25;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
console.log(chalk.blue(t('loading.fetching')));
|
|
71
|
+
_context.next = 25;
|
|
72
|
+
return analyzer.fetchRemote();
|
|
73
|
+
case 25:
|
|
74
|
+
console.log(chalk.blue(t('loading.activeUsers')));
|
|
75
|
+
_context.next = 28;
|
|
76
|
+
return analyzer.getActiveAuthors(config.activeUserWeeks || 2);
|
|
77
|
+
case 28:
|
|
78
|
+
activeAuthors = _context.sent;
|
|
79
|
+
if (options.verbose) {
|
|
80
|
+
console.log(chalk.gray(t('info.activeUsers', {
|
|
81
|
+
weeks: String(config.activeUserWeeks || 2),
|
|
82
|
+
users: Array.from(activeAuthors).join(', ')
|
|
83
|
+
})));
|
|
84
|
+
}
|
|
85
|
+
console.log(chalk.blue(t('loading.analyzing')));
|
|
86
|
+
_context.next = 33;
|
|
87
|
+
return analyzer.getCommits(since, until, branches);
|
|
88
|
+
case 33:
|
|
89
|
+
commits = _context.sent;
|
|
90
|
+
if (!(commits.length === 0)) {
|
|
91
|
+
_context.next = 37;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
console.log(chalk.yellow(t('warning.noCommits')));
|
|
95
|
+
return _context.abrupt("return");
|
|
96
|
+
case 37:
|
|
97
|
+
console.log(chalk.blue(t('info.foundCommits', {
|
|
98
|
+
count: String(commits.length)
|
|
99
|
+
})));
|
|
100
|
+
analyses = [];
|
|
101
|
+
i = 0;
|
|
102
|
+
case 40:
|
|
103
|
+
if (!(i < commits.length)) {
|
|
104
|
+
_context.next = 50;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
commit = commits[i];
|
|
108
|
+
if (options.verbose && i % 10 === 0) {
|
|
109
|
+
console.log(chalk.gray(t('info.analysisProgress', {
|
|
110
|
+
current: String(i + 1),
|
|
111
|
+
total: String(commits.length)
|
|
112
|
+
})));
|
|
113
|
+
}
|
|
114
|
+
_context.next = 45;
|
|
115
|
+
return analyzer.analyzeCommit(commit);
|
|
116
|
+
case 45:
|
|
117
|
+
analysis = _context.sent;
|
|
118
|
+
if (analysis) {
|
|
119
|
+
analyses.push(analysis);
|
|
120
|
+
}
|
|
121
|
+
case 47:
|
|
122
|
+
i++;
|
|
123
|
+
_context.next = 40;
|
|
124
|
+
break;
|
|
125
|
+
case 50:
|
|
126
|
+
if (!(analyses.length === 0)) {
|
|
127
|
+
_context.next = 53;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
console.log(chalk.yellow(t('warning.noQualifyingCommits')));
|
|
131
|
+
return _context.abrupt("return");
|
|
132
|
+
case 53:
|
|
133
|
+
console.log(chalk.blue(t('info.qualifyingCommits', {
|
|
134
|
+
count: String(analyses.length)
|
|
135
|
+
})));
|
|
136
|
+
aggregator = new StatsAggregator(config, activeAuthors);
|
|
137
|
+
result = aggregator.aggregate(analyses, since, until, branches, options.author);
|
|
138
|
+
formatter = new OutputFormatter();
|
|
139
|
+
if (options.json) {
|
|
140
|
+
console.log(formatter.formatJSON(result));
|
|
141
|
+
} else if (options.csv) {
|
|
142
|
+
console.log(formatter.formatCSV(result));
|
|
143
|
+
} else if (options.markdown) {
|
|
144
|
+
console.log(formatter.formatMarkdown(result));
|
|
145
|
+
} else {
|
|
146
|
+
console.log(formatter.formatTable(result, options.verbose));
|
|
147
|
+
}
|
|
148
|
+
_context.next = 64;
|
|
149
|
+
break;
|
|
150
|
+
case 60:
|
|
151
|
+
_context.prev = 60;
|
|
152
|
+
_context.t0 = _context["catch"](0);
|
|
153
|
+
console.error(chalk.red(t('error.prefix')), _context.t0);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
case 64:
|
|
156
|
+
case "end":
|
|
157
|
+
return _context.stop();
|
|
158
|
+
}
|
|
159
|
+
}, _callee, null, [[0, 60]]);
|
|
160
|
+
}));
|
|
161
|
+
return _runSingleRepoCommand.apply(this, arguments);
|
|
162
|
+
}
|
package/dist/esm/formatters.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { StatsResult } from './types.js';
|
|
2
2
|
export declare class OutputFormatter {
|
|
3
|
-
formatTable(result: StatsResult, verbose?: boolean): string;
|
|
4
|
-
formatJSON(result: StatsResult): string;
|
|
5
|
-
formatCSV(result: StatsResult): string;
|
|
6
|
-
formatMarkdown(result: StatsResult): string;
|
|
3
|
+
formatTable(result: StatsResult, verbose?: boolean, showContributors?: boolean): string;
|
|
4
|
+
formatJSON(result: StatsResult, showContributors?: boolean): string;
|
|
5
|
+
formatCSV(result: StatsResult, showContributors?: boolean): string;
|
|
6
|
+
formatMarkdown(result: StatsResult, showContributors?: boolean): string;
|
|
7
7
|
}
|
package/dist/esm/formatters.js
CHANGED
|
@@ -18,6 +18,7 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
18
18
|
key: "formatTable",
|
|
19
19
|
value: function formatTable(result) {
|
|
20
20
|
var verbose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
21
|
+
var showContributors = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
21
22
|
var output = '';
|
|
22
23
|
output += chalk.bold(t('output.title'));
|
|
23
24
|
output += chalk.gray(t('output.timeRange', {
|
|
@@ -93,6 +94,42 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
93
94
|
var sortedAuthors = Array.from(result.authors.values()).sort(function (a, b) {
|
|
94
95
|
return b.commits - a.commits;
|
|
95
96
|
});
|
|
97
|
+
if (!showContributors) {
|
|
98
|
+
// Show only summary when showContributors is false
|
|
99
|
+
var totalAuthors = sortedAuthors.length;
|
|
100
|
+
var totalCommits = sortedAuthors.reduce(function (sum, s) {
|
|
101
|
+
return sum + s.commits;
|
|
102
|
+
}, 0);
|
|
103
|
+
var totalProposalsSet = new Set();
|
|
104
|
+
sortedAuthors.forEach(function (s) {
|
|
105
|
+
return s.openspecProposals.forEach(function (p) {
|
|
106
|
+
return totalProposalsSet.add(p);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
var totalFiles = sortedAuthors.reduce(function (sum, s) {
|
|
110
|
+
return sum + s.codeFilesChanged;
|
|
111
|
+
}, 0);
|
|
112
|
+
var totalAdditions = sortedAuthors.reduce(function (sum, s) {
|
|
113
|
+
return sum + s.additions;
|
|
114
|
+
}, 0);
|
|
115
|
+
var totalDeletions = sortedAuthors.reduce(function (sum, s) {
|
|
116
|
+
return sum + s.deletions;
|
|
117
|
+
}, 0);
|
|
118
|
+
var totalNetChanges = sortedAuthors.reduce(function (sum, s) {
|
|
119
|
+
return sum + s.netChanges;
|
|
120
|
+
}, 0);
|
|
121
|
+
var summaryTable = new Table({
|
|
122
|
+
head: [chalk.cyan(t('table.contributors')), chalk.cyan(t('table.commits')), chalk.cyan(t('table.proposals')), chalk.cyan(t('table.codeFiles')), chalk.cyan(t('table.additions')), chalk.cyan(t('table.deletions')), chalk.cyan(t('table.netChanges'))],
|
|
123
|
+
style: {
|
|
124
|
+
head: [],
|
|
125
|
+
border: []
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
summaryTable.push([totalAuthors.toString(), totalCommits.toString(), totalProposalsSet.size.toString(), totalFiles.toString(), chalk.green("+".concat(totalAdditions)), chalk.red("-".concat(totalDeletions)), totalNetChanges >= 0 ? chalk.green("+".concat(totalNetChanges)) : chalk.red("".concat(totalNetChanges))]);
|
|
129
|
+
output += summaryTable.toString() + '\n';
|
|
130
|
+
output += chalk.gray(t('output.contributorHint')) + '\n';
|
|
131
|
+
return output;
|
|
132
|
+
}
|
|
96
133
|
var _iterator2 = _createForOfIteratorHelper(sortedAuthors),
|
|
97
134
|
_step2;
|
|
98
135
|
try {
|
|
@@ -151,6 +188,8 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
151
188
|
}, {
|
|
152
189
|
key: "formatJSON",
|
|
153
190
|
value: function formatJSON(result) {
|
|
191
|
+
var showContributors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
192
|
+
var sortedAuthors = Array.from(result.authors.values());
|
|
154
193
|
var data = {
|
|
155
194
|
timeRange: {
|
|
156
195
|
since: result.timeRange.since.toISOString(),
|
|
@@ -189,8 +228,10 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
189
228
|
return sum + p.netChanges;
|
|
190
229
|
}, 0)
|
|
191
230
|
}
|
|
192
|
-
}
|
|
193
|
-
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
if (showContributors) {
|
|
234
|
+
data.authors = sortedAuthors.map(function (stats) {
|
|
194
235
|
var _stats$lastCommitDate;
|
|
195
236
|
return {
|
|
196
237
|
author: stats.author,
|
|
@@ -203,13 +244,40 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
203
244
|
netChanges: stats.netChanges,
|
|
204
245
|
lastCommitDate: (_stats$lastCommitDate = stats.lastCommitDate) === null || _stats$lastCommitDate === void 0 ? void 0 : _stats$lastCommitDate.toISOString()
|
|
205
246
|
};
|
|
206
|
-
})
|
|
207
|
-
}
|
|
247
|
+
});
|
|
248
|
+
} else {
|
|
249
|
+
var totalProposalsSet = new Set();
|
|
250
|
+
sortedAuthors.forEach(function (s) {
|
|
251
|
+
return s.openspecProposals.forEach(function (p) {
|
|
252
|
+
return totalProposalsSet.add(p);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
data.authorsSummary = {
|
|
256
|
+
totalContributors: sortedAuthors.length,
|
|
257
|
+
totalCommits: sortedAuthors.reduce(function (sum, s) {
|
|
258
|
+
return sum + s.commits;
|
|
259
|
+
}, 0),
|
|
260
|
+
totalProposals: totalProposalsSet.size,
|
|
261
|
+
totalCodeFiles: sortedAuthors.reduce(function (sum, s) {
|
|
262
|
+
return sum + s.codeFilesChanged;
|
|
263
|
+
}, 0),
|
|
264
|
+
totalAdditions: sortedAuthors.reduce(function (sum, s) {
|
|
265
|
+
return sum + s.additions;
|
|
266
|
+
}, 0),
|
|
267
|
+
totalDeletions: sortedAuthors.reduce(function (sum, s) {
|
|
268
|
+
return sum + s.deletions;
|
|
269
|
+
}, 0),
|
|
270
|
+
totalNetChanges: sortedAuthors.reduce(function (sum, s) {
|
|
271
|
+
return sum + s.netChanges;
|
|
272
|
+
}, 0)
|
|
273
|
+
};
|
|
274
|
+
}
|
|
208
275
|
return JSON.stringify(data, null, 2);
|
|
209
276
|
}
|
|
210
277
|
}, {
|
|
211
278
|
key: "formatCSV",
|
|
212
279
|
value: function formatCSV(result) {
|
|
280
|
+
var showContributors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
213
281
|
var rows = [];
|
|
214
282
|
|
|
215
283
|
// Proposal summary section
|
|
@@ -222,9 +290,9 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
222
290
|
_step4;
|
|
223
291
|
try {
|
|
224
292
|
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
225
|
-
var
|
|
226
|
-
var contributors = Array.from(
|
|
227
|
-
rows.push([
|
|
293
|
+
var _stats = _step4.value;
|
|
294
|
+
var contributors = Array.from(_stats.contributors).join(';');
|
|
295
|
+
rows.push([_stats.proposal, _stats.commits, "\"".concat(contributors, "\""), _stats.codeFilesChanged, _stats.additions, _stats.deletions, _stats.netChanges].join(','));
|
|
228
296
|
}
|
|
229
297
|
|
|
230
298
|
// Proposal totals
|
|
@@ -260,29 +328,53 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
260
328
|
|
|
261
329
|
// Author summary section
|
|
262
330
|
rows.push("\n# ".concat(t('output.authorSummary')));
|
|
263
|
-
rows.push("".concat(t('table.author'), ",").concat(t('table.period'), ",").concat(t('table.commits'), ",").concat(t('table.proposalsCount'), ",").concat(t('table.proposalsList'), ",").concat(t('table.codeFiles'), ",").concat(t('table.additions'), ",").concat(t('table.deletions'), ",").concat(t('table.netChanges'), ",").concat(t('table.lastCommitDate')));
|
|
264
331
|
var sortedAuthors = Array.from(result.authors.values()).sort(function (a, b) {
|
|
265
332
|
return b.commits - a.commits;
|
|
266
333
|
});
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
334
|
+
if (showContributors) {
|
|
335
|
+
rows.push("".concat(t('table.author'), ",").concat(t('table.period'), ",").concat(t('table.commits'), ",").concat(t('table.proposalsCount'), ",").concat(t('table.proposalsList'), ",").concat(t('table.codeFiles'), ",").concat(t('table.additions'), ",").concat(t('table.deletions'), ",").concat(t('table.netChanges'), ",").concat(t('table.lastCommitDate')));
|
|
336
|
+
var _iterator5 = _createForOfIteratorHelper(sortedAuthors),
|
|
337
|
+
_step5;
|
|
338
|
+
try {
|
|
339
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
340
|
+
var _stats$lastCommitDate2;
|
|
341
|
+
var stats = _step5.value;
|
|
342
|
+
var proposals = Array.from(stats.openspecProposals).join(';');
|
|
343
|
+
rows.push([stats.author, stats.statisticsPeriod || '-', stats.commits, stats.openspecProposals.size, "\"".concat(proposals, "\""), stats.codeFilesChanged, stats.additions, stats.deletions, stats.netChanges, ((_stats$lastCommitDate2 = stats.lastCommitDate) === null || _stats$lastCommitDate2 === void 0 ? void 0 : _stats$lastCommitDate2.toISOString()) || ''].join(','));
|
|
344
|
+
}
|
|
345
|
+
} catch (err) {
|
|
346
|
+
_iterator5.e(err);
|
|
347
|
+
} finally {
|
|
348
|
+
_iterator5.f();
|
|
275
349
|
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
350
|
+
} else {
|
|
351
|
+
rows.push("".concat(t('table.contributors'), ",").concat(t('table.commits'), ",").concat(t('table.proposals'), ",").concat(t('table.codeFiles'), ",").concat(t('table.additions'), ",").concat(t('table.deletions'), ",").concat(t('table.netChanges')));
|
|
352
|
+
var totalProposalsSet = new Set();
|
|
353
|
+
sortedAuthors.forEach(function (s) {
|
|
354
|
+
return s.openspecProposals.forEach(function (p) {
|
|
355
|
+
return totalProposalsSet.add(p);
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
rows.push([sortedAuthors.length, sortedAuthors.reduce(function (sum, s) {
|
|
359
|
+
return sum + s.commits;
|
|
360
|
+
}, 0), totalProposalsSet.size, sortedAuthors.reduce(function (sum, s) {
|
|
361
|
+
return sum + s.codeFilesChanged;
|
|
362
|
+
}, 0), sortedAuthors.reduce(function (sum, s) {
|
|
363
|
+
return sum + s.additions;
|
|
364
|
+
}, 0), sortedAuthors.reduce(function (sum, s) {
|
|
365
|
+
return sum + s.deletions;
|
|
366
|
+
}, 0), sortedAuthors.reduce(function (sum, s) {
|
|
367
|
+
return sum + s.netChanges;
|
|
368
|
+
}, 0)].join(','));
|
|
369
|
+
rows.push('');
|
|
370
|
+
rows.push("# ".concat(t('output.contributorHint')));
|
|
280
371
|
}
|
|
281
372
|
return rows.join('\n');
|
|
282
373
|
}
|
|
283
374
|
}, {
|
|
284
375
|
key: "formatMarkdown",
|
|
285
376
|
value: function formatMarkdown(result) {
|
|
377
|
+
var showContributors = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
286
378
|
var md = '';
|
|
287
379
|
md += t('markdown.title');
|
|
288
380
|
md += t('markdown.timeRange', {
|
|
@@ -311,9 +403,9 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
311
403
|
_step6;
|
|
312
404
|
try {
|
|
313
405
|
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
314
|
-
var
|
|
315
|
-
var contributors = Array.from(
|
|
316
|
-
md += "| ".concat(
|
|
406
|
+
var _stats3 = _step6.value;
|
|
407
|
+
var contributors = Array.from(_stats3.contributors).join(', ');
|
|
408
|
+
md += "| ".concat(_stats3.proposal, " | ").concat(_stats3.commits, " | ").concat(contributors, " | ").concat(_stats3.codeFilesChanged, " | +").concat(_stats3.additions, " | -").concat(_stats3.deletions, " | ").concat(_stats3.netChanges >= 0 ? '+' : '').concat(_stats3.netChanges, " |\n");
|
|
317
409
|
}
|
|
318
410
|
|
|
319
411
|
// Proposal totals
|
|
@@ -348,42 +440,71 @@ export var OutputFormatter = /*#__PURE__*/function () {
|
|
|
348
440
|
|
|
349
441
|
// Author summary
|
|
350
442
|
md += "\n## ".concat(t('output.authorSummary'), "\n\n");
|
|
351
|
-
md += "| ".concat(t('table.author'), " | ").concat(t('table.period'), " | ").concat(t('table.commits'), " | ").concat(t('table.proposals'), " | ").concat(t('table.codeFiles'), " | ").concat(t('table.additions'), " | ").concat(t('table.deletions'), " | ").concat(t('table.netChanges'), " |\n");
|
|
352
|
-
md += '|--------|--------|---------|-----------|------------|-----------|-----------|-------------|\n';
|
|
353
443
|
var sortedAuthors = Array.from(result.authors.values()).sort(function (a, b) {
|
|
354
444
|
return b.commits - a.commits;
|
|
355
445
|
});
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
446
|
+
if (showContributors) {
|
|
447
|
+
md += "| ".concat(t('table.author'), " | ").concat(t('table.period'), " | ").concat(t('table.commits'), " | ").concat(t('table.proposals'), " | ").concat(t('table.codeFiles'), " | ").concat(t('table.additions'), " | ").concat(t('table.deletions'), " | ").concat(t('table.netChanges'), " |\n");
|
|
448
|
+
md += '|--------|--------|---------|-----------|------------|-----------|-----------|-------------|\n';
|
|
449
|
+
var _iterator7 = _createForOfIteratorHelper(sortedAuthors),
|
|
450
|
+
_step7;
|
|
451
|
+
try {
|
|
452
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
453
|
+
var stats = _step7.value;
|
|
454
|
+
md += "| ".concat(stats.author, " | ").concat(stats.statisticsPeriod || '-', " | ").concat(stats.commits, " | ").concat(stats.openspecProposals.size, " | ").concat(stats.codeFilesChanged, " | +").concat(stats.additions, " | -").concat(stats.deletions, " | ").concat(stats.netChanges >= 0 ? '+' : '').concat(stats.netChanges, " |\n");
|
|
455
|
+
}
|
|
456
|
+
} catch (err) {
|
|
457
|
+
_iterator7.e(err);
|
|
458
|
+
} finally {
|
|
459
|
+
_iterator7.f();
|
|
362
460
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
for (var _i = 0, _Array$from = Array.from(_stats3.openspecProposals); _i < _Array$from.length; _i++) {
|
|
377
|
-
var proposal = _Array$from[_i];
|
|
378
|
-
md += "- ".concat(proposal, "\n");
|
|
461
|
+
md += t('markdown.proposalDetails');
|
|
462
|
+
var _iterator8 = _createForOfIteratorHelper(sortedAuthors),
|
|
463
|
+
_step8;
|
|
464
|
+
try {
|
|
465
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
466
|
+
var _stats2 = _step8.value;
|
|
467
|
+
if (_stats2.openspecProposals.size > 0) {
|
|
468
|
+
md += "### ".concat(_stats2.author, "\n\n");
|
|
469
|
+
for (var _i = 0, _Array$from = Array.from(_stats2.openspecProposals); _i < _Array$from.length; _i++) {
|
|
470
|
+
var proposal = _Array$from[_i];
|
|
471
|
+
md += "- ".concat(proposal, "\n");
|
|
472
|
+
}
|
|
473
|
+
md += '\n';
|
|
379
474
|
}
|
|
380
|
-
md += '\n';
|
|
381
475
|
}
|
|
476
|
+
} catch (err) {
|
|
477
|
+
_iterator8.e(err);
|
|
478
|
+
} finally {
|
|
479
|
+
_iterator8.f();
|
|
382
480
|
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
481
|
+
} else {
|
|
482
|
+
md += "| ".concat(t('table.contributors'), " | ").concat(t('table.commits'), " | ").concat(t('table.proposals'), " | ").concat(t('table.codeFiles'), " | ").concat(t('table.additions'), " | ").concat(t('table.deletions'), " | ").concat(t('table.netChanges'), " |\n");
|
|
483
|
+
md += '|------------|---------|-----------|------------|-----------|-----------|-------------|\n';
|
|
484
|
+
var totalProposalsSet = new Set();
|
|
485
|
+
sortedAuthors.forEach(function (s) {
|
|
486
|
+
return s.openspecProposals.forEach(function (p) {
|
|
487
|
+
return totalProposalsSet.add(p);
|
|
488
|
+
});
|
|
489
|
+
});
|
|
490
|
+
var totalAuthors = sortedAuthors.length;
|
|
491
|
+
var totalCommits = sortedAuthors.reduce(function (sum, s) {
|
|
492
|
+
return sum + s.commits;
|
|
493
|
+
}, 0);
|
|
494
|
+
var totalFiles = sortedAuthors.reduce(function (sum, s) {
|
|
495
|
+
return sum + s.codeFilesChanged;
|
|
496
|
+
}, 0);
|
|
497
|
+
var totalAdditions = sortedAuthors.reduce(function (sum, s) {
|
|
498
|
+
return sum + s.additions;
|
|
499
|
+
}, 0);
|
|
500
|
+
var totalDeletions = sortedAuthors.reduce(function (sum, s) {
|
|
501
|
+
return sum + s.deletions;
|
|
502
|
+
}, 0);
|
|
503
|
+
var totalNetChanges = sortedAuthors.reduce(function (sum, s) {
|
|
504
|
+
return sum + s.netChanges;
|
|
505
|
+
}, 0);
|
|
506
|
+
md += "| ".concat(totalAuthors, " | ").concat(totalCommits, " | ").concat(totalProposalsSet.size, " | ").concat(totalFiles, " | +").concat(totalAdditions, " | -").concat(totalDeletions, " | ").concat(totalNetChanges >= 0 ? '+' : '').concat(totalNetChanges, " |\n");
|
|
507
|
+
md += "\n*".concat(t('output.contributorHint'), "*\n");
|
|
387
508
|
}
|
|
388
509
|
return md;
|
|
389
510
|
}
|
|
@@ -3,6 +3,7 @@ export declare class GitAnalyzer {
|
|
|
3
3
|
private git;
|
|
4
4
|
private config;
|
|
5
5
|
constructor(repoPath: string, config: Config);
|
|
6
|
+
fetchRemote(): Promise<void>;
|
|
6
7
|
getCommits(since: Date, until: Date, branches: string[]): Promise<CommitInfo[]>;
|
|
7
8
|
getCommitBranches(commitHash: string, targetBranches: string[]): Promise<string[]>;
|
|
8
9
|
analyzeCommit(commit: CommitInfo): Promise<CommitAnalysis | null>;
|