wukong-gitlog-cli 0.0.8 → 0.0.10
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/CHANGELOG.md +10 -0
- package/README.md +4 -124
- package/doc/help.md +194 -0
- package/package.json +1 -1
- package/src/overtime.mjs +52 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.0.10](https://github.com/tomatobybike/wukong-gitlog-cli/compare/v0.0.9...v0.0.10) (2025-11-28)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* 🎸 each hour percent ([4f1a7e7](https://github.com/tomatobybike/wukong-gitlog-cli/commit/4f1a7e75a1c0d83c92aabf42e97932421c349b8d))
|
|
11
|
+
* 🎸 hourline ([9035ecb](https://github.com/tomatobybike/wukong-gitlog-cli/commit/9035ecb33295fa5f4ff64bbd9b9281c543247683))
|
|
12
|
+
|
|
13
|
+
### [0.0.9](https://github.com/tomatobybike/wukong-gitlog-cli/compare/v0.0.8...v0.0.9) (2025-11-28)
|
|
14
|
+
|
|
5
15
|
### [0.0.8](https://github.com/tomatobybike/wukong-gitlog-cli/compare/v0.0.7...v0.0.8) (2025-11-28)
|
|
6
16
|
|
|
7
17
|
|
package/README.md
CHANGED
|
@@ -92,20 +92,20 @@ Command-line options:
|
|
|
92
92
|
You can generate per-month and per-week outputs under `output/month/` and `output/week/` using the `--per-period-formats` option. Example:
|
|
93
93
|
|
|
94
94
|
```bash
|
|
95
|
-
|
|
95
|
+
wukong-gitlog-cli ./src/cli.mjs --overtime --limit 200 --format text --out commits.txt --per-period-formats csv,tab
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
Want per-period Excel outputs? Use `xlsx` along with `--per-period-excel-mode` for `sheets` or `files`:
|
|
99
99
|
|
|
100
100
|
```bash
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
wukong-gitlog-cli ./src/cli.mjs --overtime --limit 200 --format text --out commits.txt --per-period-formats csv,tab,xlsx --per-period-excel-mode sheets
|
|
102
|
+
wukong-gitlog-cli ./src/cli.mjs --overtime --limit 200 --format text --out commits.txt --per-period-formats xlsx --per-period-excel-mode files
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
If you'd like only per-period outputs and not the combined monthly/weekly summary files, add `--per-period-only`:
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
|
-
|
|
108
|
+
wukong-gitlog-cli ./src/cli.mjs --overtime --limit 200 --format text --out commits.txt --per-period-formats csv,tab,xlsx --per-period-only
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
|
|
@@ -188,132 +188,12 @@ wukong-gitlog-cli --out-dir ../output --format text --limit 5 --out custom1.txt
|
|
|
188
188
|
|
|
189
189
|
---
|
|
190
190
|
|
|
191
|
-
## Quick demo (npm scripts)
|
|
192
191
|
|
|
193
|
-
We provided a few convenient npm scripts to quickly run common scenarios. Run them from the project root:
|
|
194
|
-
|
|
195
|
-
```bash
|
|
196
|
-
# show help
|
|
197
|
-
npm run cli:help
|
|
198
|
-
|
|
199
|
-
# simple text export (commits.txt in ./output)
|
|
200
|
-
npm run cli:text-demo
|
|
201
|
-
|
|
202
|
-
# Excel export with stats (commits.xlsx + commits.txt in ./output)
|
|
203
|
-
npm run cli:excel-demo
|
|
204
|
-
|
|
205
|
-
# JSON export (commits.json in ./output)
|
|
206
|
-
npm run cli:json-demo
|
|
207
|
-
|
|
208
|
-
# Gerrit text export demo
|
|
209
|
-
npm run cli:gerrit-demo
|
|
210
|
-
# Gerrit Change-Id demo (use commit Change-Id to build Gerrit URLs when present)
|
|
211
|
-
npm run cli:gerrit-changeid-demo
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
If you prefer to write output outside the project (e.g., a parent `output/` folder), we also provide `npm` scripts that run with `--out-parent`:
|
|
215
|
-
|
|
216
|
-
```bash
|
|
217
|
-
# text export to parent `output/`
|
|
218
|
-
npm run cli:text-demo-parent
|
|
219
|
-
|
|
220
|
-
# excel export to parent `output/`
|
|
221
|
-
npm run cli:excel-demo-parent
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
Example text output (from `npm run cli:text-demo`):
|
|
225
|
-
|
|
226
|
-
```text
|
|
227
|
-
Hash | Author | Date | Message
|
|
228
|
-
---------------------------------------------------------------------------------------------------------------------
|
|
229
|
-
c5bdf9d4 | tom | 2025-11-25 | feat: 🎸 增加output目录
|
|
230
|
-
|
|
231
|
-
ea82531 | tom | 2025-11-25 | feat: 🎸 init
|
|
232
|
-
|
|
233
|
-
741de50 | tom | 2025-11-25 | first commit
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
You can also analyze overtime culture with the `--overtime` flag to get overall and per-person overtime submission rates (default work window is 09:00-18:00). Example:
|
|
237
192
|
|
|
238
193
|
```bash
|
|
239
194
|
wukong-gitlog-cli --overtime --limit 500
|
|
240
195
|
```
|
|
241
196
|
|
|
242
|
-
## Overtime demo scripts (npm)
|
|
243
|
-
|
|
244
|
-
Below are helpful npm scripts added for quickly running the overtime analysis with commonly used configurations. They are already present in `package.json` and can be run from the project root.
|
|
245
|
-
|
|
246
|
-
```bash
|
|
247
|
-
# Run a US-focused overtime text report using 10:00-19:00 work hours and a 12:00-13:00 lunch break
|
|
248
|
-
npm run cli:overtime-text-us
|
|
249
|
-
|
|
250
|
-
# Run a US-focused overtime text report and write the outputs into the project parent's output folder
|
|
251
|
-
npm run cli:overtime-text-us-parent
|
|
252
|
-
|
|
253
|
-
# Run a US-focused overtime text report and write the output into ../output (explicit --out-dir)
|
|
254
|
-
npm run cli:overtime-text-us-outdir
|
|
255
|
-
|
|
256
|
-
# Run a CN-focused overtime Excel report (default 9:00-18:00 work hours and 12:00-14:00 lunch)
|
|
257
|
-
npm run cli:overtime-excel-cn
|
|
258
|
-
|
|
259
|
-
# Run a CN-focused overtime Excel report and write outputs to parent output folder
|
|
260
|
-
npm run cli:overtime-excel-cn-parent
|
|
261
|
-
|
|
262
|
-
# Run a CN-focused overtime Excel report and write outputs to ../output via --out-dir
|
|
263
|
-
npm run cli:overtime-excel-cn-outdir
|
|
264
|
-
# Per-period CSV/Tab export: write per-period files to output/month/ and output/week/
|
|
265
|
-
npm run cli:overtime-per-period-csv-tab
|
|
266
|
-
# Per-period Excel export with sheet-per-period workbook
|
|
267
|
-
npm run cli:overtime-per-period-xlsx-sheets
|
|
268
|
-
# Per-period Excel export with one file per period
|
|
269
|
-
npm run cli:overtime-per-period-xlsx-files
|
|
270
|
-
# Per-period only (no consolidated monthly/weekly files)
|
|
271
|
-
npm run cli:overtime-per-period-only
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
Notes:
|
|
275
|
-
|
|
276
|
-
- Output files are written into `output/` by default. Use `--out-dir` or `--out-parent` to change output location.
|
|
277
|
-
- If you prefer different working hours or country codes, either modify the script in `package.json` or run the CLI manually with flags (e.g. `--work-start`, `--work-end`, `--lunch-start`, `--lunch-end`, `--country`).
|
|
278
|
-
|
|
279
|
-
Formatting note:
|
|
280
|
-
|
|
281
|
-
- The text report is formatted to align columns correctly even when commit messages or author names contain mixed Chinese and English characters (uses `string-width` for display-aware padding).
|
|
282
|
-
|
|
283
|
-
Example JSON output (from `npm run cli:json-demo`):
|
|
284
|
-
|
|
285
|
-
```json
|
|
286
|
-
[
|
|
287
|
-
{
|
|
288
|
-
"hash": "c5bdf9d4f52f39bd7d580318bafc8ba4b6c129bc",
|
|
289
|
-
"author": "tom",
|
|
290
|
-
"email": "",
|
|
291
|
-
"date": "2025-11-25 17:24:32 +0800",
|
|
292
|
-
"message": "feat: 🎸 增加output目录"
|
|
293
|
-
}
|
|
294
|
-
/* truncated... */
|
|
295
|
-
]
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
Example JSON output including `changeId`/`gerrit` when `--gerrit` uses `{{changeId}}` (if present in commit):
|
|
299
|
-
|
|
300
|
-
```json
|
|
301
|
-
[
|
|
302
|
-
{
|
|
303
|
-
"hash": "Iabc...",
|
|
304
|
-
"author": "tom",
|
|
305
|
-
"email": "",
|
|
306
|
-
"date": "2025-11-25 17:24:32 +0800",
|
|
307
|
-
"message": "feat: add feature",
|
|
308
|
-
"body": "feat: add feature\n\nChange-Id: Iabcd123456789",
|
|
309
|
-
"changeId": "Iabcd123456789",
|
|
310
|
-
"gerrit": "https://gerrit.example.com/c/project/+/Iabcd123456789"
|
|
311
|
-
}
|
|
312
|
-
]
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
---
|
|
316
|
-
|
|
317
197
|
## Notes & Developer Info
|
|
318
198
|
|
|
319
199
|
- The CLI prints helpful messages after exporting files and writes outputs to the `output/` folder in the repo root.
|
package/doc/help.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
### Per-period outputs
|
|
2
|
+
|
|
3
|
+
You can generate per-month and per-week outputs under `output/month/` and `output/week/` using the `--per-period-formats` option. Example:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
node ./src/cli.mjs --overtime --limit 200 --format text --out commits.txt --per-period-formats csv,tab
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Want per-period Excel outputs? Use `xlsx` along with `--per-period-excel-mode` for `sheets` or `files`:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
node ./src/cli.mjs --overtime --limit 200 --format text --out commits.txt --per-period-formats csv,tab,xlsx --per-period-excel-mode sheets
|
|
13
|
+
node ./src/cli.mjs --overtime --limit 200 --format text --out commits.txt --per-period-formats xlsx --per-period-excel-mode files
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
If you'd like only per-period outputs and not the combined monthly/weekly summary files, add `--per-period-only`:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
node ./src/cli.mjs --overtime --limit 200 --format text --out commits.txt --per-period-formats csv,tab,xlsx --per-period-only
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Gerrit support
|
|
25
|
+
|
|
26
|
+
Use the `--gerrit` option to include a Gerrit link for each commit. You can provide a template containing `{{hash}}` to place the full commit hash into the URL, for example:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
wukong-gitlog-cli --gerrit "https://gerrit.example.com/c/project/+/{{hash}}" --limit 5 --format text
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If `{{hash}}` is not present, the CLI will append the commit hash to the prefix with a `/` separator.
|
|
33
|
+
|
|
34
|
+
You can also use `{{changeId}}` in the template to reference Gerrit change id. The tool will try to extract a `Change-Id: I...` value from the commit body and replace `{{changeId}}` with it. If it can't find a `Change-Id`, the CLI will fall back to using the commit `hash`.
|
|
35
|
+
|
|
36
|
+
The Gerrit link will show up in:
|
|
37
|
+
|
|
38
|
+
- The text output if `--format text` (as a new `Gerrit` column)
|
|
39
|
+
- The Excel export as a `Gerrit` column if `--format excel`
|
|
40
|
+
- JSON output will include a `gerrit` field for each record when `--gerrit` is used
|
|
41
|
+
- JSON output will include a `gerrit` field for each record when `--gerrit` is used
|
|
42
|
+
- When `--gerrit` uses `{{changeId}}`, the CLI will try to extract `Change-Id:` from the commit body and include `changeId` and `body` in the JSON record. If no `Change-Id` is present, the CLI falls back to `hash` when forming the Gerrit URL.
|
|
43
|
+
|
|
44
|
+
Note: `--out <file>` is the filename only and the directory used to store that file depends on:
|
|
45
|
+
|
|
46
|
+
- The default directory `./output/` in the current working directory
|
|
47
|
+
- `--out-dir <dir>` to override the target folder (relative or absolute)
|
|
48
|
+
- `--out-parent` to write to the parent repository folder `../output/` (same as `--out-dir ../output`)
|
|
49
|
+
|
|
50
|
+
For example:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# using globally installed CLI
|
|
54
|
+
wukong-gitlog-cli --out parent.json --out-parent
|
|
55
|
+
wukong-gitlog-cli --out demo.txt --out-dir ../temp
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Examples
|
|
61
|
+
|
|
62
|
+
Export as text, grouped by month, with Gerrit links:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
wukong-gitlog-cli --format text --group-by month --gerrit "https://gerrit.example.com/c/project/+/{{hash}}"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Quick demo (npm scripts)
|
|
71
|
+
|
|
72
|
+
We provided a few convenient npm scripts to quickly run common scenarios. Run them from the project root:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# show help
|
|
76
|
+
npm run cli:help
|
|
77
|
+
|
|
78
|
+
# simple text export (commits.txt in ./output)
|
|
79
|
+
npm run cli:text-demo
|
|
80
|
+
|
|
81
|
+
# Excel export with stats (commits.xlsx + commits.txt in ./output)
|
|
82
|
+
npm run cli:excel-demo
|
|
83
|
+
|
|
84
|
+
# JSON export (commits.json in ./output)
|
|
85
|
+
npm run cli:json-demo
|
|
86
|
+
|
|
87
|
+
# Gerrit text export demo
|
|
88
|
+
npm run cli:gerrit-demo
|
|
89
|
+
# Gerrit Change-Id demo (use commit Change-Id to build Gerrit URLs when present)
|
|
90
|
+
npm run cli:gerrit-changeid-demo
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If you prefer to write output outside the project (e.g., a parent `output/` folder), we also provide `npm` scripts that run with `--out-parent`:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# text export to parent `output/`
|
|
97
|
+
npm run cli:text-demo-parent
|
|
98
|
+
|
|
99
|
+
# excel export to parent `output/`
|
|
100
|
+
npm run cli:excel-demo-parent
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Example text output (from `npm run cli:text-demo`):
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
Hash | Author | Date | Message
|
|
107
|
+
---------------------------------------------------------------------------------------------------------------------
|
|
108
|
+
c5bdf9d4 | tom | 2025-11-25 | feat: 🎸 增加output目录
|
|
109
|
+
|
|
110
|
+
ea82531 | tom | 2025-11-25 | feat: 🎸 init
|
|
111
|
+
|
|
112
|
+
741de50 | tom | 2025-11-25 | first commit
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
You can also analyze overtime culture with the `--overtime` flag to get overall and per-person overtime submission rates (default work window is 09:00-18:00). Example:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
wukong-gitlog-cli --overtime --limit 500
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Overtime demo scripts (npm)
|
|
122
|
+
|
|
123
|
+
Below are helpful npm scripts added for quickly running the overtime analysis with commonly used configurations. They are already present in `package.json` and can be run from the project root.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Run a US-focused overtime text report using 10:00-19:00 work hours and a 12:00-13:00 lunch break
|
|
127
|
+
npm run cli:overtime-text-us
|
|
128
|
+
|
|
129
|
+
# Run a US-focused overtime text report and write the outputs into the project parent's output folder
|
|
130
|
+
npm run cli:overtime-text-us-parent
|
|
131
|
+
|
|
132
|
+
# Run a US-focused overtime text report and write the output into ../output (explicit --out-dir)
|
|
133
|
+
npm run cli:overtime-text-us-outdir
|
|
134
|
+
|
|
135
|
+
# Run a CN-focused overtime Excel report (default 9:00-18:00 work hours and 12:00-14:00 lunch)
|
|
136
|
+
npm run cli:overtime-excel-cn
|
|
137
|
+
|
|
138
|
+
# Run a CN-focused overtime Excel report and write outputs to parent output folder
|
|
139
|
+
npm run cli:overtime-excel-cn-parent
|
|
140
|
+
|
|
141
|
+
# Run a CN-focused overtime Excel report and write outputs to ../output via --out-dir
|
|
142
|
+
npm run cli:overtime-excel-cn-outdir
|
|
143
|
+
# Per-period CSV/Tab export: write per-period files to output/month/ and output/week/
|
|
144
|
+
npm run cli:overtime-per-period-csv-tab
|
|
145
|
+
# Per-period Excel export with sheet-per-period workbook
|
|
146
|
+
npm run cli:overtime-per-period-xlsx-sheets
|
|
147
|
+
# Per-period Excel export with one file per period
|
|
148
|
+
npm run cli:overtime-per-period-xlsx-files
|
|
149
|
+
# Per-period only (no consolidated monthly/weekly files)
|
|
150
|
+
npm run cli:overtime-per-period-only
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Notes:
|
|
154
|
+
|
|
155
|
+
- Output files are written into `output/` by default. Use `--out-dir` or `--out-parent` to change output location.
|
|
156
|
+
- If you prefer different working hours or country codes, either modify the script in `package.json` or run the CLI manually with flags (e.g. `--work-start`, `--work-end`, `--lunch-start`, `--lunch-end`, `--country`).
|
|
157
|
+
|
|
158
|
+
Formatting note:
|
|
159
|
+
|
|
160
|
+
- The text report is formatted to align columns correctly even when commit messages or author names contain mixed Chinese and English characters (uses `string-width` for display-aware padding).
|
|
161
|
+
|
|
162
|
+
Example JSON output (from `npm run cli:json-demo`):
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
[
|
|
166
|
+
{
|
|
167
|
+
"hash": "c5bdf9d4f52f39bd7d580318bafc8ba4b6c129bc",
|
|
168
|
+
"author": "tom",
|
|
169
|
+
"email": "",
|
|
170
|
+
"date": "2025-11-25 17:24:32 +0800",
|
|
171
|
+
"message": "feat: 🎸 增加output目录"
|
|
172
|
+
}
|
|
173
|
+
/* truncated... */
|
|
174
|
+
]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Example JSON output including `changeId`/`gerrit` when `--gerrit` uses `{{changeId}}` (if present in commit):
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
[
|
|
181
|
+
{
|
|
182
|
+
"hash": "Iabc...",
|
|
183
|
+
"author": "tom",
|
|
184
|
+
"email": "",
|
|
185
|
+
"date": "2025-11-25 17:24:32 +0800",
|
|
186
|
+
"message": "feat: add feature",
|
|
187
|
+
"body": "feat: add feature\n\nChange-Id: Iabcd123456789",
|
|
188
|
+
"changeId": "Iabcd123456789",
|
|
189
|
+
"gerrit": "https://gerrit.example.com/c/project/+/Iabcd123456789"
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
package/package.json
CHANGED
package/src/overtime.mjs
CHANGED
|
@@ -64,6 +64,8 @@ export function analyzeOvertime(records, opts = {}) {
|
|
|
64
64
|
hd.init('CN');
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
// 新增:每小时分布统计
|
|
68
|
+
const hourlyCommits = Array(24).fill(0);
|
|
67
69
|
records.forEach((r) => {
|
|
68
70
|
const dt = parseCommitDate(r.date);
|
|
69
71
|
if (!dt || !dt.isValid()) return; // skip
|
|
@@ -72,6 +74,12 @@ export function analyzeOvertime(records, opts = {}) {
|
|
|
72
74
|
const isHoliday = !!hd.isHoliday(dt.toDate());
|
|
73
75
|
const isNonWork = isWeekend(dt) || isHoliday;
|
|
74
76
|
|
|
77
|
+
// 每小时分布
|
|
78
|
+
const hour = dt.hour();
|
|
79
|
+
if (hour >= 0 && hour < 24) {
|
|
80
|
+
hourlyCommits[hour]++;
|
|
81
|
+
}
|
|
82
|
+
|
|
75
83
|
if (outside) {
|
|
76
84
|
outsideWorkCount++;
|
|
77
85
|
// 记录最新的加班提交
|
|
@@ -134,6 +142,8 @@ export function analyzeOvertime(records, opts = {}) {
|
|
|
134
142
|
// sort perAuthor by outsideWorkRate desc
|
|
135
143
|
perAuthor.sort((a, b) => b.outsideWorkRate - a.outsideWorkRate || b.total - a.total);
|
|
136
144
|
|
|
145
|
+
// 新增:每小时分布百分比
|
|
146
|
+
const hourlyPercent = hourlyCommits.map(v => total ? +(v / total).toFixed(3) : 0);
|
|
137
147
|
return {
|
|
138
148
|
total,
|
|
139
149
|
outsideWorkCount,
|
|
@@ -148,16 +158,18 @@ export function analyzeOvertime(records, opts = {}) {
|
|
|
148
158
|
latestOutsideCommit: latestOutsideCommit || null,
|
|
149
159
|
startHour,
|
|
150
160
|
endHour,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
161
|
+
lunchStart,
|
|
162
|
+
lunchEnd,
|
|
163
|
+
country,
|
|
164
|
+
holidayCount,
|
|
165
|
+
holidayRate: total ? +(holidayCount / total).toFixed(3) : 0,
|
|
166
|
+
hourlyCommits,
|
|
167
|
+
hourlyPercent,
|
|
156
168
|
};
|
|
157
169
|
}
|
|
158
170
|
|
|
159
171
|
export function renderOvertimeText(stats) {
|
|
160
|
-
const { total, outsideWorkCount, nonWorkdayCount, holidayCount, outsideWorkRate, nonWorkdayRate, holidayRate, perAuthor, startHour, endHour, lunchStart, lunchEnd, country } = stats;
|
|
172
|
+
const { total, outsideWorkCount, nonWorkdayCount, holidayCount, outsideWorkRate, nonWorkdayRate, holidayRate, perAuthor, startHour, endHour, lunchStart, lunchEnd, country, hourlyCommits = [], hourlyPercent = [] } = stats;
|
|
161
173
|
const { startCommit, endCommit, latestCommit, latestOutsideCommit } = stats;
|
|
162
174
|
const lines = [];
|
|
163
175
|
|
|
@@ -206,6 +218,18 @@ export function renderOvertimeText(stats) {
|
|
|
206
218
|
lines.push(`下班时间(工作时间外)提交数:${outsideWorkCount},占比:${(outsideWorkRate * 100).toFixed(1)}%`);
|
|
207
219
|
lines.push(`非工作日(周末)提交数:${nonWorkdayCount},占比:${(nonWorkdayRate * 100).toFixed(1)}%`);
|
|
208
220
|
lines.push('');
|
|
221
|
+
lines.push('每小时分布(提交数/占比):');
|
|
222
|
+
const hourLine = ' Hour | Count | Percent';
|
|
223
|
+
lines.push(hourLine);
|
|
224
|
+
lines.push(' -----|-------|--------');
|
|
225
|
+
for (let h = 0; h < 24; h++) {
|
|
226
|
+
const cnt = hourlyCommits[h] || 0;
|
|
227
|
+
if (cnt > 0) {
|
|
228
|
+
const pct = hourlyPercent[h] ? (hourlyPercent[h] * 100).toFixed(1) : '0.0';
|
|
229
|
+
lines.push(` ${String(h).padStart(2, '0')} | ${String(cnt).padStart(5, ' ')} | ${pct.padStart(6, ' ')}%`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
lines.push('');
|
|
209
233
|
lines.push('按人员统计:');
|
|
210
234
|
// header
|
|
211
235
|
const header = ` ${padDisplayEnd('Name', cols.name)} | ${padDisplayStart('总数', cols.total)} | ${padDisplayStart('下班外数', cols.outside)} | ${padDisplayStart('下班外占比', cols.outsideRate)} | ${padDisplayStart('非工作日数', cols.nonWork)} | ${padDisplayStart('非工作日占比', cols.nonWorkRate)} | ${padDisplayStart('假日数', cols.holiday)} | ${padDisplayStart('假日占比', cols.holidayRate)}`;
|
|
@@ -224,7 +248,7 @@ export function renderOvertimeText(stats) {
|
|
|
224
248
|
}
|
|
225
249
|
|
|
226
250
|
export function renderOvertimeTab(stats) {
|
|
227
|
-
const { total, outsideWorkCount, nonWorkdayCount, holidayCount, outsideWorkRate, nonWorkdayRate, holidayRate, perAuthor, startHour, endHour, lunchStart, lunchEnd, country } = stats;
|
|
251
|
+
const { total, outsideWorkCount, nonWorkdayCount, holidayCount, outsideWorkRate, nonWorkdayRate, holidayRate, perAuthor, startHour, endHour, lunchStart, lunchEnd, country, hourlyCommits = [], hourlyPercent = [] } = stats;
|
|
228
252
|
const { startCommit, endCommit, latestCommit, latestOutsideCommit } = stats;
|
|
229
253
|
const rows = [];
|
|
230
254
|
rows.push(`总提交数:\t${total}`);
|
|
@@ -236,6 +260,16 @@ export function renderOvertimeTab(stats) {
|
|
|
236
260
|
rows.push(`下班时间(工作时间外)提交数:\t${outsideWorkCount}\t占比:\t${(outsideWorkRate * 100).toFixed(1)}%`);
|
|
237
261
|
rows.push(`非工作日(周末)提交数:\t${nonWorkdayCount}\t占比:\t${(nonWorkdayRate * 100).toFixed(1)}%`);
|
|
238
262
|
rows.push('');
|
|
263
|
+
rows.push('每小时分布(提交数/占比):');
|
|
264
|
+
rows.push(['Hour', 'Count', 'Percent'].join('\t'));
|
|
265
|
+
for (let h = 0; h < 24; h++) {
|
|
266
|
+
const cnt = hourlyCommits[h] || 0;
|
|
267
|
+
if (cnt > 0) {
|
|
268
|
+
const pct = hourlyPercent[h] ? (hourlyPercent[h] * 100).toFixed(1) : '0.0';
|
|
269
|
+
rows.push([String(h).padStart(2, '0'), cnt, `${pct}%`].join('\t'));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
rows.push('');
|
|
239
273
|
rows.push(['Name', '总数', '下班外数', '下班外占比', '非工作日数', '非工作日占比', '假日数', '假日占比'].join('\t'));
|
|
240
274
|
perAuthor.forEach((p) => {
|
|
241
275
|
rows.push([p.name || '-', p.total, p.outsideWorkCount, `${(p.outsideWorkRate * 100).toFixed(1)}%`, p.nonWorkdayCount, `${(p.nonWorkdayRate * 100).toFixed(1)}%`, p.holidayCount || 0, `${((p.holidayCount || 0) / p.total * 100).toFixed(1)}%`].join('\t'));
|
|
@@ -252,12 +286,22 @@ function escapeCsv(v) {
|
|
|
252
286
|
}
|
|
253
287
|
|
|
254
288
|
export function renderOvertimeCsv(stats) {
|
|
255
|
-
const { perAuthor, latestOutsideCommit, country } = stats;
|
|
289
|
+
const { perAuthor, latestOutsideCommit, country, hourlyCommits = [], hourlyPercent = [], total = 0 } = stats;
|
|
256
290
|
const rows = [];
|
|
257
291
|
if (latestOutsideCommit) {
|
|
258
292
|
rows.push(`# 加班最晚的一次提交,Hash,Author,Date,Message`);
|
|
259
293
|
rows.push(`# ,${escapeCsv(latestOutsideCommit.hash)},${escapeCsv(latestOutsideCommit.author)},${escapeCsv(formatDateForCountry(latestOutsideCommit.date, country))},${escapeCsv(latestOutsideCommit.message)}`);
|
|
260
294
|
}
|
|
295
|
+
rows.push('');
|
|
296
|
+
rows.push('Hour,Count,Percent');
|
|
297
|
+
for (let h = 0; h < 24; h++) {
|
|
298
|
+
const cnt = hourlyCommits[h] || 0;
|
|
299
|
+
if (cnt > 0) {
|
|
300
|
+
const pct = hourlyPercent[h] ? (hourlyPercent[h] * 100).toFixed(1) : '0.0';
|
|
301
|
+
rows.push(`${h.toString().padStart(2, '0')},${cnt},${pct}%`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
rows.push('');
|
|
261
305
|
rows.push('Name,Total,OutsideCount,OutsideRate,NonWorkdayCount,NonWorkdayRate,HolidayCount,HolidayRate');
|
|
262
306
|
perAuthor.forEach((p) => {
|
|
263
307
|
rows.push(`${escapeCsv(p.name)},${p.total},${p.outsideWorkCount},${(p.outsideWorkRate * 100).toFixed(1)}%,${p.nonWorkdayCount},${(p.nonWorkdayRate * 100).toFixed(1)}%,${p.holidayCount || 0},${((p.holidayCount || 0) / p.total * 100).toFixed(1)}%`);
|