@herodevs/cli 0.2.0 → 0.2.1-rc2
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 +0 -7
- package/dist/commands/report/committers.d.ts +6 -3
- package/dist/commands/report/committers.js +109 -6
- package/dist/package.json +2 -10
- package/dist/shared/lib/version-update.js +3 -0
- package/oclif.manifest.json +10 -51
- package/package.json +2 -10
- package/dist/commands/tracker/init.d.ts +0 -8
- package/dist/commands/tracker/init.js +0 -16
- package/dist/commands/tracker/run.d.ts +0 -13
- package/dist/commands/tracker/run.js +0 -38
- package/dist/shared/tracker/default-config.d.ts +0 -3
- package/dist/shared/tracker/default-config.js +0 -19
- package/dist/shared/tracker/initialize.d.ts +0 -1
- package/dist/shared/tracker/initialize.js +0 -15
- package/dist/shared/tracker/models/aggregate-result.d.ts +0 -4
- package/dist/shared/tracker/models/aggregate-result.js +0 -2
- package/dist/shared/tracker/models/category-result.d.ts +0 -7
- package/dist/shared/tracker/models/category-result.js +0 -2
- package/dist/shared/tracker/models/category.d.ts +0 -9
- package/dist/shared/tracker/models/category.js +0 -2
- package/dist/shared/tracker/models/chart-config.d.ts +0 -24
- package/dist/shared/tracker/models/chart-config.js +0 -81
- package/dist/shared/tracker/models/config.d.ts +0 -8
- package/dist/shared/tracker/models/config.js +0 -2
- package/dist/shared/tracker/models/file-result.d.ts +0 -5
- package/dist/shared/tracker/models/file-result.js +0 -2
- package/dist/shared/tracker/models/process-result.d.ts +0 -6
- package/dist/shared/tracker/models/process-result.js +0 -2
- package/dist/shared/tracker/models/result.d.ts +0 -11
- package/dist/shared/tracker/models/result.js +0 -2
- package/dist/shared/tracker/models/total-result.d.ts +0 -4
- package/dist/shared/tracker/models/total-result.js +0 -2
- package/dist/shared/tracker/models/viz-dataset.d.ts +0 -4
- package/dist/shared/tracker/models/viz-dataset.js +0 -2
- package/dist/shared/tracker/models/viz-labels-datasets.d.ts +0 -5
- package/dist/shared/tracker/models/viz-labels-datasets.js +0 -2
- package/dist/shared/tracker/process-category.d.ts +0 -3
- package/dist/shared/tracker/process-category.js +0 -155
- package/dist/shared/tracker/process-config.d.ts +0 -3
- package/dist/shared/tracker/process-config.js +0 -16
- package/dist/shared/tracker/tracker-chart.d.ts +0 -14
- package/dist/shared/tracker/tracker-chart.js +0 -158
- package/dist/shared/tracker/util.d.ts +0 -20
- package/dist/shared/tracker/util.js +0 -92
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseCommand
|
|
1
|
+
import { BaseCommand } from '../../shared';
|
|
2
2
|
export declare class ReportCommitters extends BaseCommand<typeof ReportCommitters> {
|
|
3
3
|
static summary: string;
|
|
4
4
|
static usage: string;
|
|
@@ -7,10 +7,13 @@ export declare class ReportCommitters extends BaseCommand<typeof ReportCommitter
|
|
|
7
7
|
startDate: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
8
8
|
endDate: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
9
9
|
exclude: import("@oclif/core/lib/interfaces").OptionFlag<string[], import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
10
|
+
monthly: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
11
|
};
|
|
11
12
|
private _parseDateFlags;
|
|
12
13
|
private _parseGitLogEntries;
|
|
13
14
|
private _collapseAndSortCommitterInfo;
|
|
14
|
-
private
|
|
15
|
-
|
|
15
|
+
private parseMonthly;
|
|
16
|
+
private printCommitters;
|
|
17
|
+
private printMonthly;
|
|
18
|
+
run(): Promise<any>;
|
|
16
19
|
}
|
|
@@ -31,11 +31,44 @@ class ReportCommitters extends shared_1.BaseCommand {
|
|
|
31
31
|
Object.keys(hash).forEach((name) => {
|
|
32
32
|
sortable.push({ name, commits: hash[name] });
|
|
33
33
|
});
|
|
34
|
-
|
|
34
|
+
const committers = sortable.sort((a, b) => {
|
|
35
35
|
return b.commits.length - a.commits.length;
|
|
36
36
|
});
|
|
37
|
+
const monthly = this.parseMonthly(entries);
|
|
38
|
+
return { committers, monthly };
|
|
37
39
|
}
|
|
38
|
-
|
|
40
|
+
parseMonthly(entries) {
|
|
41
|
+
const monthly = [];
|
|
42
|
+
const dates = [new Date(this.flags.startDate), new Date(this.flags.endDate)];
|
|
43
|
+
const ival = {
|
|
44
|
+
start: (0, date_fns_1.min)(dates),
|
|
45
|
+
end: (0, date_fns_1.max)(dates)
|
|
46
|
+
};
|
|
47
|
+
const range = (0, date_fns_1.eachMonthOfInterval)(ival);
|
|
48
|
+
for (const idxr in range) {
|
|
49
|
+
const idx = parseInt(idxr);
|
|
50
|
+
if (idx + 1 >= range.length) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const [start, end] = [range[idx], range[idx + 1]];
|
|
54
|
+
const month = {
|
|
55
|
+
name: (0, date_fns_1.format)(start, 'LLLL yyyy'),
|
|
56
|
+
start, end,
|
|
57
|
+
committers: {}
|
|
58
|
+
};
|
|
59
|
+
for (const rec of entries) {
|
|
60
|
+
if ((0, date_fns_1.isWithinInterval)(new Date(rec.date), { start, end })) {
|
|
61
|
+
month.committers[rec.committer] = month.committers[rec.committer] || [];
|
|
62
|
+
month.committers[rec.committer].push({ hash: rec.commitHash, date: rec.date });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (Object.keys(month.committers).length > 0) {
|
|
66
|
+
monthly.push(month);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return monthly;
|
|
70
|
+
}
|
|
71
|
+
printCommitters(committers) {
|
|
39
72
|
if (!Object.keys(committers).length) {
|
|
40
73
|
this.log('NO COMMITTERS IN PERIOD');
|
|
41
74
|
}
|
|
@@ -49,15 +82,79 @@ class ReportCommitters extends shared_1.BaseCommand {
|
|
|
49
82
|
});
|
|
50
83
|
this.log('---------------------------------------------------\n');
|
|
51
84
|
}
|
|
85
|
+
printMonthly(md) {
|
|
86
|
+
if (!Object.keys(md).length) {
|
|
87
|
+
this.log('NO COMMITTERS IN PERIOD');
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const rows = md
|
|
91
|
+
.flatMap(r => {
|
|
92
|
+
return Object
|
|
93
|
+
.entries(r.committers)
|
|
94
|
+
.flatMap(([committer, commits]) => commits.flatMap(commit => ({ month: r.name, committer, commit })));
|
|
95
|
+
}).map(r => ({ ...r, flags: { newMonth: true, newCommitter: true } }));
|
|
96
|
+
// ugly flag hack for now
|
|
97
|
+
rows.forEach((r, idx) => {
|
|
98
|
+
let newMonth = true;
|
|
99
|
+
let newCommitter = true;
|
|
100
|
+
if (idx == 0 || r.month !== rows[idx - 1].month) {
|
|
101
|
+
// first row / new month? always show both
|
|
102
|
+
}
|
|
103
|
+
else if (r.committer !== rows[idx - 1].committer) {
|
|
104
|
+
// month's same but new committer
|
|
105
|
+
newMonth = false;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// show both
|
|
109
|
+
newMonth = false;
|
|
110
|
+
newCommitter = false;
|
|
111
|
+
}
|
|
112
|
+
r.flags = { newMonth, newCommitter };
|
|
113
|
+
});
|
|
114
|
+
const distinctCommitters = rows.reduce((arr, row) => arr.includes(row.committer) ? arr : [...arr, row.committer], []);
|
|
115
|
+
this.log('\n');
|
|
116
|
+
core_1.ux.table(rows, {
|
|
117
|
+
month: {
|
|
118
|
+
header: 'Month',
|
|
119
|
+
minWidth: 20,
|
|
120
|
+
get: row => row.flags.newMonth ? row.month : ''
|
|
121
|
+
},
|
|
122
|
+
committer: {
|
|
123
|
+
header: 'Contributor',
|
|
124
|
+
minWidth: 25,
|
|
125
|
+
get: row => row.flags.newCommitter ? row.committer : ''
|
|
126
|
+
},
|
|
127
|
+
commit: {
|
|
128
|
+
header: 'Commit SHA',
|
|
129
|
+
get: row => row.commit.hash,
|
|
130
|
+
minWidth: 15,
|
|
131
|
+
},
|
|
132
|
+
date: {
|
|
133
|
+
header: 'Commit Date',
|
|
134
|
+
get: row => row.commit.date,
|
|
135
|
+
minWidth: 20
|
|
136
|
+
},
|
|
137
|
+
// flags: {}
|
|
138
|
+
});
|
|
139
|
+
const unique = distinctCommitters.sort();
|
|
140
|
+
this.log(`\n\n\nThere were ${unique.length} contributors reported: ${unique.join(', ')}\n`);
|
|
141
|
+
}
|
|
142
|
+
// public async run(): Promise<flagType<typeof ReportCommitters>> {
|
|
52
143
|
async run() {
|
|
53
|
-
const { flags } =
|
|
144
|
+
const { flags } = this;
|
|
54
145
|
const dates = this._parseDateFlags(flags.startDate, flags.endDate);
|
|
55
146
|
const ignores = flags.exclude && flags.exclude.length ? `-- . "!(${flags.exclude.join('|')})"` : '';
|
|
56
147
|
const gitCommand = `git log --since "${dates[0]}" --until "${dates[1]}" --pretty=format:${gitOutputFormat} ${ignores}`;
|
|
57
148
|
const result = await (0, shared_1.run)(gitCommand);
|
|
58
|
-
const committers = this._collapseAndSortCommitterInfo(result.split('\n'));
|
|
59
|
-
|
|
60
|
-
|
|
149
|
+
const { committers, monthly } = this._collapseAndSortCommitterInfo(result.split('\n'));
|
|
150
|
+
if (flags.monthly) {
|
|
151
|
+
this.printMonthly(monthly);
|
|
152
|
+
return monthly;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
this.printCommitters(committers);
|
|
156
|
+
return committers;
|
|
157
|
+
}
|
|
61
158
|
}
|
|
62
159
|
}
|
|
63
160
|
exports.ReportCommitters = ReportCommitters;
|
|
@@ -84,4 +181,10 @@ ReportCommitters.flags = {
|
|
|
84
181
|
required: false,
|
|
85
182
|
// default: () => "" as any
|
|
86
183
|
}),
|
|
184
|
+
monthly: core_1.Flags.boolean({
|
|
185
|
+
char: 'm',
|
|
186
|
+
summary: 'Break down by calendar month, rather than by committer. (eg -m)',
|
|
187
|
+
required: false,
|
|
188
|
+
default: false
|
|
189
|
+
}),
|
|
87
190
|
};
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herodevs/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1-rc2",
|
|
4
4
|
"description": "HeroDevs CLI",
|
|
5
5
|
"author": "@herodevs",
|
|
6
6
|
"bin": {
|
|
@@ -22,17 +22,12 @@
|
|
|
22
22
|
"@oclif/core": "^2",
|
|
23
23
|
"@oclif/plugin-help": "^5",
|
|
24
24
|
"@oclif/plugin-plugins": "^3.2.0",
|
|
25
|
-
"chart.js": "^3.9.1",
|
|
26
|
-
"chart.js-image": "^6.1.3",
|
|
27
|
-
"chartjs-node-canvas": "^4.1.6",
|
|
28
|
-
"chartjs-plugin-autocolors": "^0.2.2",
|
|
29
|
-
"chartjs-plugin-datalabels": "^2.2.0",
|
|
30
25
|
"date-fns": "^2.30.0",
|
|
31
26
|
"get-json": "^1.0.1",
|
|
32
27
|
"git-last-commit": "^1.0.1",
|
|
33
28
|
"module-alias": "^2.2.3",
|
|
34
29
|
"shelljs": "^0.8.5",
|
|
35
|
-
"sloc": "^0.2
|
|
30
|
+
"sloc": "^0.3.2"
|
|
36
31
|
},
|
|
37
32
|
"devDependencies": {
|
|
38
33
|
"@oclif/test": "^2.4.4",
|
|
@@ -61,9 +56,6 @@
|
|
|
61
56
|
"topics": {
|
|
62
57
|
"report": {
|
|
63
58
|
"description": "Run reports for the current project (commands: committers)"
|
|
64
|
-
},
|
|
65
|
-
"tracker": {
|
|
66
|
-
"description": "Track project progress based upon lines of code (commands: init, run)"
|
|
67
59
|
}
|
|
68
60
|
}
|
|
69
61
|
},
|
|
@@ -19,6 +19,9 @@ async function getLatestVersion(pkgName) {
|
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
async function isVersionUpToDate(command, quietIfSuccessful = false) {
|
|
22
|
+
if (config_1.env.packageVersion === '0.0.0') {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
22
25
|
const latestVersion = await getLatestVersion(config_1.env.packageName);
|
|
23
26
|
if (latestVersion === config_1.env.packageVersion) {
|
|
24
27
|
if (!quietIfSuccessful) {
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.2.
|
|
2
|
+
"version": "0.2.1-rc2",
|
|
3
3
|
"commands": {
|
|
4
4
|
"report:committers": {
|
|
5
5
|
"id": "report:committers",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"summary": "Start Date (format: yyyy-MM-dd)",
|
|
42
42
|
"required": false,
|
|
43
43
|
"multiple": false,
|
|
44
|
-
"default": "2024-
|
|
44
|
+
"default": "2024-03-01"
|
|
45
45
|
},
|
|
46
46
|
"endDate": {
|
|
47
47
|
"name": "endDate",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"summary": "End Date (format: yyyy-MM-dd)",
|
|
51
51
|
"required": false,
|
|
52
52
|
"multiple": false,
|
|
53
|
-
"default": "2023-
|
|
53
|
+
"default": "2023-03-01"
|
|
54
54
|
},
|
|
55
55
|
"exclude": {
|
|
56
56
|
"name": "exclude",
|
|
@@ -59,55 +59,14 @@
|
|
|
59
59
|
"summary": "Path Exclusions (eg -x=\"./src/bin\" -x=\"./dist\")",
|
|
60
60
|
"required": false,
|
|
61
61
|
"multiple": true
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
"args": {}
|
|
65
|
-
},
|
|
66
|
-
"tracker:init": {
|
|
67
|
-
"id": "tracker:init",
|
|
68
|
-
"description": "Initialize the tracker configuration",
|
|
69
|
-
"strict": true,
|
|
70
|
-
"pluginName": "@herodevs/cli",
|
|
71
|
-
"pluginAlias": "@herodevs/cli",
|
|
72
|
-
"pluginType": "core",
|
|
73
|
-
"aliases": [],
|
|
74
|
-
"examples": [
|
|
75
|
-
"<%= config.bin %> <%= command.id %>"
|
|
76
|
-
],
|
|
77
|
-
"flags": {},
|
|
78
|
-
"args": {}
|
|
79
|
-
},
|
|
80
|
-
"tracker:run": {
|
|
81
|
-
"id": "tracker:run",
|
|
82
|
-
"description": "Run the tracker",
|
|
83
|
-
"strict": true,
|
|
84
|
-
"pluginName": "@herodevs/cli",
|
|
85
|
-
"pluginAlias": "@herodevs/cli",
|
|
86
|
-
"pluginType": "core",
|
|
87
|
-
"aliases": [],
|
|
88
|
-
"examples": [
|
|
89
|
-
"<%= config.bin %> <%= command.id %>"
|
|
90
|
-
],
|
|
91
|
-
"flags": {
|
|
92
|
-
"root": {
|
|
93
|
-
"name": "root",
|
|
94
|
-
"type": "option",
|
|
95
|
-
"char": "r",
|
|
96
|
-
"description": "root dir of the project",
|
|
97
|
-
"multiple": false
|
|
98
|
-
},
|
|
99
|
-
"config": {
|
|
100
|
-
"name": "config",
|
|
101
|
-
"type": "option",
|
|
102
|
-
"char": "c",
|
|
103
|
-
"description": "path to config file",
|
|
104
|
-
"multiple": false
|
|
105
62
|
},
|
|
106
|
-
"
|
|
107
|
-
"name": "
|
|
108
|
-
"type": "
|
|
109
|
-
"
|
|
110
|
-
"
|
|
63
|
+
"monthly": {
|
|
64
|
+
"name": "monthly",
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"char": "m",
|
|
67
|
+
"summary": "Break down by calendar month, rather than by committer. (eg -m)",
|
|
68
|
+
"required": false,
|
|
69
|
+
"allowNo": false
|
|
111
70
|
}
|
|
112
71
|
},
|
|
113
72
|
"args": {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herodevs/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1-rc2",
|
|
4
4
|
"description": "HeroDevs CLI",
|
|
5
5
|
"author": "@herodevs",
|
|
6
6
|
"bin": {
|
|
@@ -22,17 +22,12 @@
|
|
|
22
22
|
"@oclif/core": "^2",
|
|
23
23
|
"@oclif/plugin-help": "^5",
|
|
24
24
|
"@oclif/plugin-plugins": "^3.2.0",
|
|
25
|
-
"chart.js": "^3.9.1",
|
|
26
|
-
"chart.js-image": "^6.1.3",
|
|
27
|
-
"chartjs-node-canvas": "^4.1.6",
|
|
28
|
-
"chartjs-plugin-autocolors": "^0.2.2",
|
|
29
|
-
"chartjs-plugin-datalabels": "^2.2.0",
|
|
30
25
|
"date-fns": "^2.30.0",
|
|
31
26
|
"get-json": "^1.0.1",
|
|
32
27
|
"git-last-commit": "^1.0.1",
|
|
33
28
|
"module-alias": "^2.2.3",
|
|
34
29
|
"shelljs": "^0.8.5",
|
|
35
|
-
"sloc": "^0.2
|
|
30
|
+
"sloc": "^0.3.2"
|
|
36
31
|
},
|
|
37
32
|
"devDependencies": {
|
|
38
33
|
"@oclif/test": "^2.4.4",
|
|
@@ -61,9 +56,6 @@
|
|
|
61
56
|
"topics": {
|
|
62
57
|
"report": {
|
|
63
58
|
"description": "Run reports for the current project (commands: committers)"
|
|
64
|
-
},
|
|
65
|
-
"tracker": {
|
|
66
|
-
"description": "Track project progress based upon lines of code (commands: init, run)"
|
|
67
59
|
}
|
|
68
60
|
}
|
|
69
61
|
},
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TrackerInit = void 0;
|
|
4
|
-
const core_1 = require("@oclif/core");
|
|
5
|
-
const initialize_1 = require("../../shared/tracker/initialize");
|
|
6
|
-
const util_1 = require("../../shared/tracker/util");
|
|
7
|
-
class TrackerInit extends core_1.Command {
|
|
8
|
-
async run() {
|
|
9
|
-
(0, initialize_1.initialize)((0, util_1.getTheRootDirectory)(global.process.cwd()));
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
exports.TrackerInit = TrackerInit;
|
|
13
|
-
TrackerInit.description = 'Initialize the tracker configuration';
|
|
14
|
-
TrackerInit.examples = ['<%= config.bin %> <%= command.id %>'];
|
|
15
|
-
TrackerInit.flags = {};
|
|
16
|
-
TrackerInit.args = {};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
import { ChartConfig } from '../../shared/tracker/models/chart-config';
|
|
3
|
-
export declare class TrackerRun extends Command {
|
|
4
|
-
static description: string;
|
|
5
|
-
static examples: string[];
|
|
6
|
-
static flags: {
|
|
7
|
-
root: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
8
|
-
config: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
9
|
-
chart: import("@oclif/core/lib/interfaces").OptionFlag<ChartConfig, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
10
|
-
};
|
|
11
|
-
static args: {};
|
|
12
|
-
run(): Promise<void>;
|
|
13
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TrackerRun = void 0;
|
|
4
|
-
const core_1 = require("@oclif/core");
|
|
5
|
-
const path_1 = require("path");
|
|
6
|
-
const util_1 = require("../../shared/tracker/util");
|
|
7
|
-
const process_config_1 = require("../../shared/tracker/process-config");
|
|
8
|
-
const chart_config_1 = require("../../shared/tracker/models/chart-config");
|
|
9
|
-
class TrackerRun extends core_1.Command {
|
|
10
|
-
async run() {
|
|
11
|
-
const { flags } = await this.parse(TrackerRun);
|
|
12
|
-
const localRootDir = (0, util_1.getTheRootDirectory)(global.process.cwd());
|
|
13
|
-
const rootDirectory = flags.root ? (0, path_1.resolve)(flags.root) : localRootDir;
|
|
14
|
-
const config = (0, util_1.readConfig)(localRootDir, flags.config);
|
|
15
|
-
const results = await (0, process_config_1.processConfig)(config, rootDirectory);
|
|
16
|
-
(0, util_1.saveResults)(localRootDir, config.outputDir, results);
|
|
17
|
-
const allData = (0, util_1.getData)(localRootDir, config.outputDir);
|
|
18
|
-
const parentDir = (0, path_1.resolve)(localRootDir, config.outputDir);
|
|
19
|
-
const chartConfig = new chart_config_1.ChartConfig(flags.chart);
|
|
20
|
-
try {
|
|
21
|
-
await (0, util_1.createDataVizIn)(chartConfig, parentDir, allData);
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
console.log('Error creating visualization');
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
exports.TrackerRun = TrackerRun;
|
|
29
|
-
TrackerRun.description = 'Run the tracker';
|
|
30
|
-
TrackerRun.examples = ['<%= config.bin %> <%= command.id %>'];
|
|
31
|
-
TrackerRun.flags = {
|
|
32
|
-
root: core_1.Flags.string({ char: 'r', description: 'root dir of the project' }),
|
|
33
|
-
config: core_1.Flags.string({ char: 'c', description: 'path to config file' }),
|
|
34
|
-
chart: core_1.Flags.custom({
|
|
35
|
-
description: 'chart configuration',
|
|
36
|
-
})(),
|
|
37
|
-
};
|
|
38
|
-
TrackerRun.args = {};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const defaultConfig = {
|
|
4
|
-
categories: {
|
|
5
|
-
legacy: {
|
|
6
|
-
fileTypes: ['js', 'ts', 'html', 'css', 'scss', 'less'],
|
|
7
|
-
includes: ['./legacy'],
|
|
8
|
-
jsTsPairs: 'js',
|
|
9
|
-
},
|
|
10
|
-
modern: {
|
|
11
|
-
fileTypes: ['ts', 'html', 'css', 'scss', 'less'],
|
|
12
|
-
includes: ['./modern'],
|
|
13
|
-
jsTsPairs: 'ts',
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
ignorePatterns: ['node_modules'],
|
|
17
|
-
outputDir: 'hd-tracker',
|
|
18
|
-
};
|
|
19
|
-
exports.default = defaultConfig;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function initialize(rootDir: string): void;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.initialize = void 0;
|
|
4
|
-
const path_1 = require("path");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
const default_config_1 = require("./default-config");
|
|
7
|
-
function initialize(rootDir) {
|
|
8
|
-
const output = JSON.stringify(default_config_1.default, null, 2);
|
|
9
|
-
const dir = (0, path_1.join)(rootDir, "hd-tracker");
|
|
10
|
-
if (!(0, fs_1.existsSync)(dir)) {
|
|
11
|
-
(0, fs_1.mkdirSync)(dir);
|
|
12
|
-
}
|
|
13
|
-
(0, fs_1.writeFileSync)((0, path_1.join)(dir, "config.json"), output);
|
|
14
|
-
}
|
|
15
|
-
exports.initialize = initialize;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export declare class ChartConfig {
|
|
2
|
-
private _cliOptions;
|
|
3
|
-
private _perCategoryAndFileType;
|
|
4
|
-
private _perCategoryTotals;
|
|
5
|
-
private _width;
|
|
6
|
-
private _height;
|
|
7
|
-
private _bg;
|
|
8
|
-
private _title;
|
|
9
|
-
private _xAxisLabel;
|
|
10
|
-
private _yAxisLabel;
|
|
11
|
-
private _overwrite;
|
|
12
|
-
private _outFile;
|
|
13
|
-
get perCategoryAndFileType(): boolean;
|
|
14
|
-
get perCategoryTotals(): boolean;
|
|
15
|
-
get width(): number;
|
|
16
|
-
get height(): number;
|
|
17
|
-
get bg(): string;
|
|
18
|
-
get title(): string;
|
|
19
|
-
get xAxisLabel(): string;
|
|
20
|
-
get yAxisLabel(): string;
|
|
21
|
-
get overwrite(): boolean;
|
|
22
|
-
get outFile(): string;
|
|
23
|
-
constructor(_cliOptions?: ChartConfig);
|
|
24
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ChartConfig = void 0;
|
|
4
|
-
class ChartConfig {
|
|
5
|
-
get perCategoryAndFileType() {
|
|
6
|
-
// if false, use false; false !== undefined
|
|
7
|
-
return this._cliOptions.perCategoryAndFileType !== undefined ?
|
|
8
|
-
this._cliOptions.perCategoryAndFileType :
|
|
9
|
-
this._perCategoryAndFileType;
|
|
10
|
-
}
|
|
11
|
-
get perCategoryTotals() {
|
|
12
|
-
// if false, use false; false !== undefined
|
|
13
|
-
return this._cliOptions.perCategoryTotals !== undefined ?
|
|
14
|
-
this._cliOptions.perCategoryTotals :
|
|
15
|
-
this._perCategoryTotals;
|
|
16
|
-
}
|
|
17
|
-
get width() {
|
|
18
|
-
// if set and non-numeric
|
|
19
|
-
if (this._cliOptions.width !== undefined && isNaN(Number(this._cliOptions.width))) {
|
|
20
|
-
throw Error('--chart.width must be a number');
|
|
21
|
-
}
|
|
22
|
-
// if unset or numeric
|
|
23
|
-
return this._cliOptions.width !== undefined ?
|
|
24
|
-
this._cliOptions.width :
|
|
25
|
-
this._width;
|
|
26
|
-
}
|
|
27
|
-
get height() {
|
|
28
|
-
// if set and non-numeric
|
|
29
|
-
if (this._cliOptions.height !== undefined && isNaN(Number(this._cliOptions.height))) {
|
|
30
|
-
throw Error('--chart.height must be a number');
|
|
31
|
-
}
|
|
32
|
-
// if unset or numeric
|
|
33
|
-
return this._cliOptions.height !== undefined ?
|
|
34
|
-
this._cliOptions.height :
|
|
35
|
-
this._height;
|
|
36
|
-
}
|
|
37
|
-
get bg() {
|
|
38
|
-
return this._cliOptions.bg ?
|
|
39
|
-
this._cliOptions.bg :
|
|
40
|
-
this._bg;
|
|
41
|
-
}
|
|
42
|
-
get title() {
|
|
43
|
-
return this._cliOptions.title ?
|
|
44
|
-
this._cliOptions.title :
|
|
45
|
-
this._title;
|
|
46
|
-
}
|
|
47
|
-
get xAxisLabel() {
|
|
48
|
-
return this._cliOptions.xAxisLabel ?
|
|
49
|
-
this._cliOptions.xAxisLabel :
|
|
50
|
-
this._xAxisLabel;
|
|
51
|
-
}
|
|
52
|
-
get yAxisLabel() {
|
|
53
|
-
return this._cliOptions.yAxisLabel ?
|
|
54
|
-
this._cliOptions.yAxisLabel :
|
|
55
|
-
this._yAxisLabel;
|
|
56
|
-
}
|
|
57
|
-
get overwrite() {
|
|
58
|
-
return this._cliOptions.overwrite !== undefined ?
|
|
59
|
-
this._cliOptions.overwrite :
|
|
60
|
-
this._overwrite;
|
|
61
|
-
}
|
|
62
|
-
get outFile() {
|
|
63
|
-
return this._cliOptions.outFile ?
|
|
64
|
-
this._cliOptions.outFile :
|
|
65
|
-
this._outFile;
|
|
66
|
-
}
|
|
67
|
-
constructor(_cliOptions = {}) {
|
|
68
|
-
this._cliOptions = _cliOptions;
|
|
69
|
-
this._perCategoryAndFileType = false;
|
|
70
|
-
this._perCategoryTotals = true;
|
|
71
|
-
this._width = 1200;
|
|
72
|
-
this._height = 800;
|
|
73
|
-
this._bg = 'white';
|
|
74
|
-
this._title = 'Migration Progress LOC';
|
|
75
|
-
this._xAxisLabel = 'Date';
|
|
76
|
-
this._yAxisLabel = 'Totals';
|
|
77
|
-
this._overwrite = true;
|
|
78
|
-
this._outFile = 'viz.png';
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
exports.ChartConfig = ChartConfig;
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.processCategory = void 0;
|
|
4
|
-
const sloc = require("sloc");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
const path_1 = require("path");
|
|
7
|
-
function processCategory(rootDirectory, category, ignorePatterns) {
|
|
8
|
-
console.log(`Processing "${category.name}"...`);
|
|
9
|
-
const allFiles = category.includes.reduce((acc, include) => {
|
|
10
|
-
return [...acc, ...findAllFilesInDirectory((0, path_1.join)(rootDirectory, include))];
|
|
11
|
-
}, []);
|
|
12
|
-
const includedFiles = findIncludedFiles(category, ignorePatterns, allFiles);
|
|
13
|
-
console.log(` ${includedFiles.length} files...`);
|
|
14
|
-
const results = includedFiles.map(getFileStats);
|
|
15
|
-
const resultMap = aggregateResults(results);
|
|
16
|
-
const aggregatedResults = Object.values(resultMap).map((val) => val);
|
|
17
|
-
const totals = aggregatedResults.reduce((totals, curr) => ({
|
|
18
|
-
fileCount: totals.fileCount + curr.fileCount,
|
|
19
|
-
total: totals.total + curr.total,
|
|
20
|
-
source: totals.source + curr.source,
|
|
21
|
-
comment: totals.comment + curr.comment,
|
|
22
|
-
single: totals.single + curr.single,
|
|
23
|
-
block: totals.block + curr.block,
|
|
24
|
-
mixed: totals.mixed + curr.mixed,
|
|
25
|
-
empty: totals.empty + curr.empty,
|
|
26
|
-
todo: totals.todo + curr.todo,
|
|
27
|
-
blockEmpty: totals.blockEmpty + curr.blockEmpty,
|
|
28
|
-
}), {
|
|
29
|
-
fileCount: 0,
|
|
30
|
-
total: 0,
|
|
31
|
-
source: 0,
|
|
32
|
-
comment: 0,
|
|
33
|
-
single: 0,
|
|
34
|
-
block: 0,
|
|
35
|
-
mixed: 0,
|
|
36
|
-
empty: 0,
|
|
37
|
-
todo: 0,
|
|
38
|
-
blockEmpty: 0,
|
|
39
|
-
});
|
|
40
|
-
const final = {
|
|
41
|
-
name: category.name,
|
|
42
|
-
totals: totals,
|
|
43
|
-
fileTypes: aggregatedResults,
|
|
44
|
-
};
|
|
45
|
-
console.log(` ${final.totals.total} total lines`);
|
|
46
|
-
return final;
|
|
47
|
-
}
|
|
48
|
-
exports.processCategory = processCategory;
|
|
49
|
-
function aggregateResults(results) {
|
|
50
|
-
return results.reduce((acc, result) => {
|
|
51
|
-
const fileTypeResults = acc[result.fileType];
|
|
52
|
-
if (!fileTypeResults) {
|
|
53
|
-
acc[result.fileType] = {
|
|
54
|
-
fileType: result.fileType,
|
|
55
|
-
fileCount: 1,
|
|
56
|
-
total: result.total,
|
|
57
|
-
source: result.source,
|
|
58
|
-
comment: result.comment,
|
|
59
|
-
single: result.single,
|
|
60
|
-
block: result.block,
|
|
61
|
-
mixed: result.mixed,
|
|
62
|
-
empty: result.empty,
|
|
63
|
-
todo: result.todo,
|
|
64
|
-
blockEmpty: result.blockEmpty,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
acc[result.fileType] = {
|
|
69
|
-
fileType: result.fileType,
|
|
70
|
-
fileCount: fileTypeResults.fileCount + 1,
|
|
71
|
-
total: fileTypeResults.total + result.total,
|
|
72
|
-
source: fileTypeResults.source + result.source,
|
|
73
|
-
comment: fileTypeResults.comment + result.comment,
|
|
74
|
-
single: fileTypeResults.single + result.single,
|
|
75
|
-
block: fileTypeResults.block + result.block,
|
|
76
|
-
mixed: fileTypeResults.mixed + result.mixed,
|
|
77
|
-
empty: fileTypeResults.empty + result.empty,
|
|
78
|
-
todo: fileTypeResults.todo + result.todo,
|
|
79
|
-
blockEmpty: fileTypeResults.blockEmpty + result.blockEmpty,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return acc;
|
|
83
|
-
}, {});
|
|
84
|
-
}
|
|
85
|
-
function getFileStats(file) {
|
|
86
|
-
const contents = (0, fs_1.readFileSync)(file).toString('utf-8');
|
|
87
|
-
const fileType = getFileExt(file);
|
|
88
|
-
const stats = sloc(contents, fileType);
|
|
89
|
-
return {
|
|
90
|
-
path: file,
|
|
91
|
-
fileType: fileType,
|
|
92
|
-
...stats,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
function findIncludedFiles(category, ignorePatterns, allFiles) {
|
|
96
|
-
return allFiles
|
|
97
|
-
.filter((file) => {
|
|
98
|
-
var _a;
|
|
99
|
-
const ext = getFileExt(file);
|
|
100
|
-
let shouldBeIncluded = !!category.fileTypes.find((fileType) => fileType === ext);
|
|
101
|
-
if (shouldBeIncluded) {
|
|
102
|
-
ignorePatterns === null || ignorePatterns === void 0 ? void 0 : ignorePatterns.forEach((ignorePattern) => {
|
|
103
|
-
if (file.indexOf(ignorePattern) !== -1) {
|
|
104
|
-
shouldBeIncluded = false;
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
if (shouldBeIncluded) {
|
|
109
|
-
(_a = category.excludes) === null || _a === void 0 ? void 0 : _a.forEach((exclude) => {
|
|
110
|
-
if (file.indexOf(exclude) !== -1) {
|
|
111
|
-
shouldBeIncluded = false;
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
return shouldBeIncluded;
|
|
116
|
-
})
|
|
117
|
-
.filter((file, _index, files) => {
|
|
118
|
-
if (category.jsTsPairs === 'ignore' || category.jsTsPairs === undefined) {
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
const fileExtToKeep = category.jsTsPairs;
|
|
122
|
-
const ext = getFileExt(file);
|
|
123
|
-
const fileExtToDiscard = fileExtToKeep === 'js' ? 'ts' : 'js';
|
|
124
|
-
// if it is the extension to keep
|
|
125
|
-
// or if it is not the one to discard, we keep those files
|
|
126
|
-
if (fileExtToKeep === ext || fileExtToDiscard !== ext) {
|
|
127
|
-
return true;
|
|
128
|
-
}
|
|
129
|
-
// get the counterpart's extension
|
|
130
|
-
const counterpartExt = ext === 'js' ? 'ts' : 'js';
|
|
131
|
-
const parts = file.split('.');
|
|
132
|
-
parts[parts.length - 1] = counterpartExt;
|
|
133
|
-
const counterpartExists = files.filter((f) => f === parts.join('.')).length !== 0;
|
|
134
|
-
if (counterpartExists) {
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
return true;
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
function findAllFilesInDirectory(directory) {
|
|
141
|
-
const results = (0, fs_1.readdirSync)(directory);
|
|
142
|
-
const subfiles = results
|
|
143
|
-
.filter((result) => (0, fs_1.lstatSync)((0, path_1.join)(directory, result)).isDirectory())
|
|
144
|
-
.reduce((acc, subdir) => {
|
|
145
|
-
const files = findAllFilesInDirectory((0, path_1.join)(directory, subdir));
|
|
146
|
-
return [...acc, ...files];
|
|
147
|
-
}, []);
|
|
148
|
-
const files = results
|
|
149
|
-
.filter((result) => (0, fs_1.lstatSync)((0, path_1.join)(directory, result)).isFile())
|
|
150
|
-
.map((fileName) => (0, path_1.join)(directory, fileName));
|
|
151
|
-
return [...files, ...subfiles];
|
|
152
|
-
}
|
|
153
|
-
function getFileExt(file) {
|
|
154
|
-
return (0, path_1.extname)(file).replace(/\./g, '');
|
|
155
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.processConfig = void 0;
|
|
4
|
-
const process_category_1 = require("./process-category");
|
|
5
|
-
const util_1 = require("./util");
|
|
6
|
-
async function processConfig(config, rootDirectory) {
|
|
7
|
-
console.log(`Starting...`);
|
|
8
|
-
const categoryResults = Object.entries(config.categories).map(([name, category]) => (0, process_category_1.processCategory)(rootDirectory, { ...category, name }, config.ignorePatterns || []));
|
|
9
|
-
const commit = await (0, util_1.getGitCommit)();
|
|
10
|
-
return {
|
|
11
|
-
timestamp: commit.timestamp,
|
|
12
|
-
hash: commit.hash,
|
|
13
|
-
categories: categoryResults,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
exports.processConfig = processConfig;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { AggregateResult } from './models/aggregate-result';
|
|
2
|
-
import { ChartConfig } from './models/chart-config';
|
|
3
|
-
import { ProcessResult } from './models/process-result';
|
|
4
|
-
export declare class TrackerChart {
|
|
5
|
-
private _config;
|
|
6
|
-
private _allProcessResults;
|
|
7
|
-
private _dateFormat;
|
|
8
|
-
constructor(_config: ChartConfig, _allProcessResults: ProcessResult[], _dateFormat: string);
|
|
9
|
-
private getDataAndLabels;
|
|
10
|
-
private getTotalsPerFileTypePerCategory;
|
|
11
|
-
private getTotalsPerCategory;
|
|
12
|
-
private generateGraphImageFile;
|
|
13
|
-
writeTo(parentDirectory: string, graphablePropertyName?: keyof AggregateResult): Promise<void>;
|
|
14
|
-
}
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TrackerChart = void 0;
|
|
4
|
-
const path_1 = require("path");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
const date_fns_1 = require("date-fns");
|
|
7
|
-
const chartjs_node_canvas_1 = require("chartjs-node-canvas");
|
|
8
|
-
const ChartDataLabels = require("chartjs-plugin-datalabels");
|
|
9
|
-
const autocolors = require("chartjs-plugin-autocolors");
|
|
10
|
-
class TrackerChart {
|
|
11
|
-
constructor(_config, _allProcessResults, _dateFormat) {
|
|
12
|
-
this._config = _config;
|
|
13
|
-
this._allProcessResults = _allProcessResults;
|
|
14
|
-
this._dateFormat = _dateFormat;
|
|
15
|
-
}
|
|
16
|
-
getDataAndLabels(allJsonData, propName) {
|
|
17
|
-
if (this._config.perCategoryTotals) {
|
|
18
|
-
return this.getTotalsPerCategory(allJsonData, propName);
|
|
19
|
-
}
|
|
20
|
-
if (this._config.perCategoryAndFileType) {
|
|
21
|
-
return this.getTotalsPerFileTypePerCategory(allJsonData, propName);
|
|
22
|
-
}
|
|
23
|
-
return this.getTotalsPerCategory(allJsonData, propName);
|
|
24
|
-
}
|
|
25
|
-
getTotalsPerFileTypePerCategory(allJsonData, propName) {
|
|
26
|
-
const runs = {};
|
|
27
|
-
const allTypes = {};
|
|
28
|
-
allJsonData.forEach((jsonData, i) => {
|
|
29
|
-
runs[jsonData.hash] = jsonData.timestamp;
|
|
30
|
-
jsonData.categories.forEach((category) => {
|
|
31
|
-
category.fileTypes.forEach((t) => {
|
|
32
|
-
const label = `${category.name}: ${t.fileType}`;
|
|
33
|
-
if (!allTypes[label]) {
|
|
34
|
-
allTypes[label] = {
|
|
35
|
-
label,
|
|
36
|
-
data: []
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
allTypes[label].data[i] = t[propName];
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
const labels = Object.values(runs);
|
|
44
|
-
const datasets = Object.values(allTypes).map((t) => {
|
|
45
|
-
return {
|
|
46
|
-
...t,
|
|
47
|
-
fill: false,
|
|
48
|
-
tension: .1
|
|
49
|
-
};
|
|
50
|
-
});
|
|
51
|
-
return {
|
|
52
|
-
labels,
|
|
53
|
-
datasets,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
getTotalsPerCategory(allJsonData, propName) {
|
|
57
|
-
const runs = {};
|
|
58
|
-
const allTypes = {};
|
|
59
|
-
allJsonData.forEach((jsonData, i) => {
|
|
60
|
-
runs[jsonData.hash] = jsonData.timestamp;
|
|
61
|
-
jsonData.categories.forEach((category) => {
|
|
62
|
-
const label = category.name;
|
|
63
|
-
if (!allTypes[label]) {
|
|
64
|
-
allTypes[label] = {
|
|
65
|
-
label,
|
|
66
|
-
data: []
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
allTypes[label].data[i] = category.totals[propName];
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
const labels = Object.values(runs);
|
|
73
|
-
const datasets = Object.values(allTypes).map((t) => {
|
|
74
|
-
return {
|
|
75
|
-
...t,
|
|
76
|
-
fill: false,
|
|
77
|
-
tension: .1
|
|
78
|
-
};
|
|
79
|
-
});
|
|
80
|
-
return {
|
|
81
|
-
labels,
|
|
82
|
-
datasets,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
async generateGraphImageFile(parentDirectory, vizData) {
|
|
86
|
-
const outFile = (0, path_1.join)(parentDirectory, this._config.outFile);
|
|
87
|
-
if (this._config.overwrite && (0, fs_1.existsSync)(outFile)) {
|
|
88
|
-
(0, fs_1.rmSync)(outFile);
|
|
89
|
-
}
|
|
90
|
-
const dateFmt = this._dateFormat;
|
|
91
|
-
const configuration = {
|
|
92
|
-
type: 'line',
|
|
93
|
-
data: vizData,
|
|
94
|
-
options: {
|
|
95
|
-
elements: {
|
|
96
|
-
point: {
|
|
97
|
-
radius: 0
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
plugins: {
|
|
101
|
-
title: {
|
|
102
|
-
display: true,
|
|
103
|
-
text: this._config.title
|
|
104
|
-
},
|
|
105
|
-
autocolors: {
|
|
106
|
-
enabled: true,
|
|
107
|
-
mode: 'data',
|
|
108
|
-
},
|
|
109
|
-
scales: {
|
|
110
|
-
x: {
|
|
111
|
-
type: 'timeseries',
|
|
112
|
-
time: {
|
|
113
|
-
minUnit: 'week',
|
|
114
|
-
},
|
|
115
|
-
parsing: false,
|
|
116
|
-
title: {
|
|
117
|
-
display: true,
|
|
118
|
-
text: this._config.xAxisLabel
|
|
119
|
-
},
|
|
120
|
-
ticks: {
|
|
121
|
-
source: 'data',
|
|
122
|
-
callback: function (val) {
|
|
123
|
-
return (0, date_fns_1.format)((0, date_fns_1.parse)(this.getLabelForValue(val), dateFmt, new Date()), 'yyyy-MM-dd');
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
y: {
|
|
128
|
-
title: {
|
|
129
|
-
display: true,
|
|
130
|
-
text: this._config.yAxisLabel
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
try {
|
|
138
|
-
const pieChart = new chartjs_node_canvas_1.ChartJSNodeCanvas({
|
|
139
|
-
width: this._config.width,
|
|
140
|
-
height: this._config.height,
|
|
141
|
-
backgroundColour: this._config.bg,
|
|
142
|
-
plugins: {
|
|
143
|
-
modern: [ChartDataLabels, autocolors],
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
const result = await pieChart.renderToBuffer(configuration);
|
|
147
|
-
(0, fs_1.writeFileSync)(outFile, result);
|
|
148
|
-
}
|
|
149
|
-
catch (exc) {
|
|
150
|
-
console.error(exc);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
writeTo(parentDirectory, graphablePropertyName = 'total') {
|
|
154
|
-
const vizData = this.getDataAndLabels(this._allProcessResults, graphablePropertyName);
|
|
155
|
-
return this.generateGraphImageFile(parentDirectory, vizData);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
exports.TrackerChart = TrackerChart;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { Config } from './models/config';
|
|
2
|
-
import { ProcessResult } from './models/process-result';
|
|
3
|
-
import { AggregateResult } from './models/aggregate-result';
|
|
4
|
-
import { ChartConfig } from './models/chart-config';
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* exported alphabetized util functions ->
|
|
10
|
-
*
|
|
11
|
-
*/
|
|
12
|
-
export declare function createDataVizIn(chartConfig: ChartConfig, parentDirectory: string, allJsonData: ProcessResult[], graphablePropertyName?: keyof AggregateResult): Promise<void>;
|
|
13
|
-
export declare function getData(localRootDir: string, outputDir: string): any;
|
|
14
|
-
export declare function getGitCommit(): Promise<{
|
|
15
|
-
hash: string;
|
|
16
|
-
timestamp: string;
|
|
17
|
-
}>;
|
|
18
|
-
export declare function getTheRootDirectory(directory: string): string;
|
|
19
|
-
export declare function readConfig(rootDirectory: string, optionsPath?: string): Config;
|
|
20
|
-
export declare function saveResults(localRootDir: string, outputDir: string, results: ProcessResult): void;
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.saveResults = exports.readConfig = exports.getTheRootDirectory = exports.getGitCommit = exports.getData = exports.createDataVizIn = void 0;
|
|
4
|
-
const path_1 = require("path");
|
|
5
|
-
const fs_1 = require("fs");
|
|
6
|
-
const date_fns_1 = require("date-fns");
|
|
7
|
-
const git_last_commit_1 = require("git-last-commit");
|
|
8
|
-
const tracker_chart_1 = require("./tracker-chart");
|
|
9
|
-
const DATE_FORMAT = 'yyyy-MM-dd-HH-mm-ss-SSS';
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* internal alphabetized helper functions ->
|
|
15
|
-
*
|
|
16
|
-
*/
|
|
17
|
-
function formatDate(date) {
|
|
18
|
-
return (0, date_fns_1.format)(date, DATE_FORMAT);
|
|
19
|
-
}
|
|
20
|
-
function getDataFilePath(localRootDir, outputDir) {
|
|
21
|
-
return (0, path_1.resolve)((0, path_1.join)(localRootDir, outputDir, 'data.json'));
|
|
22
|
-
}
|
|
23
|
-
function getGitDate(date) {
|
|
24
|
-
return new Date(+date * 1000);
|
|
25
|
-
}
|
|
26
|
-
function getLastCommitAsPromise() {
|
|
27
|
-
return new Promise((resolve, reject) => {
|
|
28
|
-
(0, git_last_commit_1.getLastCommit)((err, commit) => {
|
|
29
|
-
if (err) {
|
|
30
|
-
reject(err);
|
|
31
|
-
}
|
|
32
|
-
resolve(commit);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* exported alphabetized util functions ->
|
|
41
|
-
*
|
|
42
|
-
*/
|
|
43
|
-
async function createDataVizIn(chartConfig, parentDirectory, allJsonData, graphablePropertyName = 'total') {
|
|
44
|
-
const chart = new tracker_chart_1.TrackerChart(chartConfig, allJsonData, DATE_FORMAT);
|
|
45
|
-
return chart.writeTo(parentDirectory, graphablePropertyName);
|
|
46
|
-
}
|
|
47
|
-
exports.createDataVizIn = createDataVizIn;
|
|
48
|
-
function getData(localRootDir, outputDir) {
|
|
49
|
-
const outputPath = getDataFilePath(localRootDir, outputDir);
|
|
50
|
-
let contents = '';
|
|
51
|
-
if ((0, fs_1.existsSync)(outputPath)) {
|
|
52
|
-
contents = (0, fs_1.readFileSync)(outputPath).toString('utf-8');
|
|
53
|
-
}
|
|
54
|
-
return contents === '' ? [] : JSON.parse(contents);
|
|
55
|
-
}
|
|
56
|
-
exports.getData = getData;
|
|
57
|
-
async function getGitCommit() {
|
|
58
|
-
const commit = await getLastCommitAsPromise();
|
|
59
|
-
return {
|
|
60
|
-
hash: commit.hash,
|
|
61
|
-
timestamp: formatDate(getGitDate(commit.committedOn)),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
exports.getGitCommit = getGitCommit;
|
|
65
|
-
function getTheRootDirectory(directory) {
|
|
66
|
-
if ((0, fs_1.existsSync)((0, path_1.join)(directory, 'package.json'))) {
|
|
67
|
-
return directory;
|
|
68
|
-
}
|
|
69
|
-
return getTheRootDirectory((0, path_1.resolve)((0, path_1.join)(directory, '..')));
|
|
70
|
-
}
|
|
71
|
-
exports.getTheRootDirectory = getTheRootDirectory;
|
|
72
|
-
function readConfig(rootDirectory, optionsPath) {
|
|
73
|
-
const path = optionsPath && (0, fs_1.existsSync)((0, path_1.join)(rootDirectory, optionsPath))
|
|
74
|
-
? (0, path_1.join)(rootDirectory, optionsPath)
|
|
75
|
-
: (0, path_1.join)(rootDirectory, 'hd-tracker', 'config.json');
|
|
76
|
-
const contents = (0, fs_1.readFileSync)(path).toString('utf-8');
|
|
77
|
-
return JSON.parse(contents);
|
|
78
|
-
}
|
|
79
|
-
exports.readConfig = readConfig;
|
|
80
|
-
function saveResults(localRootDir, outputDir, results) {
|
|
81
|
-
console.log('Outputting file');
|
|
82
|
-
const output = getData(localRootDir, outputDir);
|
|
83
|
-
if (!Array.isArray(output)) {
|
|
84
|
-
console.error('Invalid output file format');
|
|
85
|
-
}
|
|
86
|
-
output.push(results);
|
|
87
|
-
const outputPath = getDataFilePath(localRootDir, outputDir);
|
|
88
|
-
const outputText = JSON.stringify(output, null, 2);
|
|
89
|
-
(0, fs_1.writeFileSync)(outputPath, outputText);
|
|
90
|
-
console.log(`Output written to: ${outputPath}`);
|
|
91
|
-
}
|
|
92
|
-
exports.saveResults = saveResults;
|