wukong-gitlog-cli 0.0.1 → 0.0.3

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 CHANGED
@@ -2,6 +2,15 @@
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.3](https://github.com/tomatobybike/wukong-gitlog-cli/compare/v0.0.2...v0.0.3) (2025-11-26)
6
+
7
+
8
+ ### Features
9
+
10
+ * 🎸 gerrit ([76f71b8](https://github.com/tomatobybike/wukong-gitlog-cli/commit/76f71b8ab7b1636bee4c243fd670383268e1f771))
11
+
12
+ ### [0.0.2](https://github.com/tomatobybike/wukong-gitlog-cli/compare/v0.0.1...v0.0.2) (2025-11-26)
13
+
5
14
  ### 0.0.1 (2025-11-26)
6
15
 
7
16
 
package/README.md CHANGED
@@ -33,17 +33,15 @@ cd wukong-gitlog-cli
33
33
  npm install
34
34
  ```
35
35
 
36
- Run from the repo using Node:
37
-
38
- ```bash
39
- node ./src/cli.mjs --help
40
- ```
41
-
42
- (Optional) Install globally to run with a short command:
36
+ Install globally to run with a short command (recommended for CLI consumers):
43
37
 
44
38
  ```bash
39
+ # Install globally from the repo (for development):
45
40
  npm link
46
- # then you can run
41
+ # Or install via npm when published:
42
+ npm i -g wukong-gitlog-cli
43
+
44
+ # Then you can run the CLI globally:
47
45
  wukong-gitlog-cli --help
48
46
  ```
49
47
 
@@ -52,7 +50,7 @@ wukong-gitlog-cli --help
52
50
  ## Usage
53
51
 
54
52
  ```bash
55
- node ./src/cli.mjs [options]
53
+ wukong-gitlog-cli [options]
56
54
  ```
57
55
 
58
56
  Command-line options:
@@ -67,7 +65,9 @@ Command-line options:
67
65
  - `--format <type>` Output format: `text` | `excel` | `json` (default: `text`)
68
66
  - `--group-by <type>` Group commits by date: `day` | `month`
69
67
  - `--stats` Include a `Stats` sheet in the Excel export
70
- - `--gerrit <prefix>` Show Gerrit URL for each commit (supports templates `{{hash}}` and `{{changeId}}`; `{{changeId}}` falls back to `hash` when absent)
68
+ - `--gerrit-api <url>` Optional: Gerrit REST API base URL for resolving `{{changeNumber}}` (e.g. `https://gerrit.example.com/gerrit`)
69
+ - `--gerrit-auth <token>` Optional: Authorization for Gerrit REST API (either `user:pass` for Basic or token string for Bearer)
70
+ - `--gerrit <prefix>` Show Gerrit URL for each commit (supports templates `{{hash}}`, `{{changeId}}` and `{{changeNumber}}`; `{{changeId}}` falls back to `hash` when absent; `{{changeNumber}}` requires `--gerrit-api` and falls back to `changeId` or `hash`)
71
71
  - `--out <file>` Output file name (without path). Defaults: `commits.json` / `commits.txt` / `commits.xlsx`
72
72
  - `--out-dir <dir>` Output directory path — supports relative or absolute path, e.g., `--out-dir ../output`
73
73
  - `--out-parent` Place output in the parent directory's `output/` folder (same as `--out-dir ../output`)
@@ -83,7 +83,7 @@ Command-line options:
83
83
  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:
84
84
 
85
85
  ```bash
86
- node ./src/cli.mjs --gerrit "https://gerrit.example.com/c/project/+/{{hash}}" --limit 5 --format text
86
+ wukong-gitlog-cli --gerrit "https://gerrit.example.com/c/project/+/{{hash}}" --limit 5 --format text
87
87
  ```
88
88
 
89
89
  If `{{hash}}` is not present, the CLI will append the commit hash to the prefix with a `/` separator.
@@ -107,8 +107,9 @@ Note: `--out <file>` is the filename only and the directory used to store that f
107
107
  For example:
108
108
 
109
109
  ```bash
110
- node ./src/cli.mjs --out parent.json --out-parent
111
- node ./src/cli.mjs --out demo.txt --out-dir ../temp
110
+ # using globally installed CLI
111
+ wukong-gitlog-cli --out parent.json --out-parent
112
+ wukong-gitlog-cli --out demo.txt --out-dir ../temp
112
113
  ```
113
114
 
114
115
  ---
@@ -118,25 +119,38 @@ node ./src/cli.mjs --out demo.txt --out-dir ../temp
118
119
  Export as text, grouped by month, with Gerrit links:
119
120
 
120
121
  ```bash
121
- node ./src/cli.mjs --format text --group-by month --gerrit "https://gerrit.example.com/c/project/+/{{hash}}"
122
+ wukong-gitlog-cli --format text --group-by month --gerrit "https://gerrit.example.com/c/project/+/{{hash}}"
123
+ ```
124
+
125
+ // Resolve numeric change ID using Gerrit API (if available)
126
+ wukong-gitlog-cli --format text --group-by month --gerrit "https://gerrit.example.com/c/project/+/{{changeNumber}}" --gerrit-api <GERRIT_API_BASE_URL>
127
+
128
+ If your Gerrit requires authentication (HTTP Basic or token), use `--gerrit-auth`:
129
+
130
+ ```bash
131
+ # HTTP Basic: username:password
132
+ wukong-gitlog-cli --format text --gerrit "https://gerrit.example.com/c/project/+/{{changeNumber}}" --gerrit-api <GERRIT_API_BASE_URL> --gerrit-auth "username:password"
133
+
134
+ # Token (Bearer)
135
+ wukong-gitlog-cli --format text --gerrit "https://gerrit.example.com/c/project/+/{{changeNumber}}" --gerrit-api <GERRIT_API_BASE_URL> --gerrit-auth "MYTOKEN"
122
136
  ```
123
137
 
124
138
  Export to Excel with stats and Gerrit URLs:
125
139
 
126
140
  ```bash
127
- node ./src/cli.mjs --format excel --stats --gerrit "https://gerrit.example.com/c/project/+/{{hash}}"
141
+ wukong-gitlog-cli --format excel --stats --gerrit "https://gerrit.example.com/c/project/+/{{hash}}"
128
142
  ```
129
143
 
130
144
  Export raw JSON:
131
145
 
132
146
  ```bash
133
- node ./src/cli.mjs --json --out commits.json
147
+ wukong-gitlog-cli --json --out commits.json
134
148
  ```
135
149
 
136
150
  Export text to a custom directory (parent output folder):
137
151
 
138
152
  ```bash
139
- node ./src/cli.mjs --out-dir ../output --format text --limit 5 --out custom1.txt
153
+ wukong-gitlog-cli --out-dir ../output --format text --limit 5 --out custom1.txt
140
154
  ```
141
155
 
142
156
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wukong-gitlog-cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Advanced Git commit log exporter with Excel/JSON/TXT output, grouping, stats and CLI.",
5
5
  "keywords": [
6
6
  "git",
package/src/cli.mjs CHANGED
@@ -22,6 +22,8 @@ program
22
22
  .option('--group-by <type>', '按日期分组: day | month')
23
23
  .option('--stats', '输出每日统计数据')
24
24
  .option('--gerrit <prefix>', '显示 Gerrit 地址,支持在 prefix 中使用 {{hash}} 占位符')
25
+ .option('--gerrit-api <url>', '可选:Gerrit REST API 基础地址,用于解析 changeNumber,例如 `https://gerrit.example.com`')
26
+ .option('--gerrit-auth <tokenOrUserPass>', '可选:Gerrit API 授权,格式为 `user:pass` 或 `TOKEN`(表示 Bearer token)')
25
27
  .option('--out <file>', '输出文件名(不含路径)')
26
28
  .option('--out-dir <dir>', '自定义输出目录,支持相对路径或绝对路径,例如 `--out-dir ../output`')
27
29
  .option('--out-parent', '将输出目录放到当前工程的父目录的 `output/`(等同于 `--out-dir ../output`)')
@@ -40,8 +42,78 @@ const opts = program.opts();
40
42
  // --- Gerrit 地址处理(若提供) ---
41
43
  if (opts.gerrit) {
42
44
  const prefix = opts.gerrit;
45
+ // support optional changeNumber resolution via Gerrit REST API
46
+ const { gerritApi, gerritAuth } = opts;
43
47
  // create new array to avoid mutating function parameters (eslint: no-param-reassign)
44
- records = records.map(r => {
48
+ if (prefix.includes('{{changeNumber}}') && gerritApi) {
49
+ // async mapping to resolve changeNumber using Gerrit API
50
+ const cache = new Map();
51
+ const headers = {};
52
+ if (gerritAuth) {
53
+ if (gerritAuth.includes(':')) {
54
+ headers.Authorization = `Basic ${Buffer.from(gerritAuth).toString('base64')}`;
55
+ } else {
56
+ headers.Authorization = `Bearer ${gerritAuth}`;
57
+ }
58
+ }
59
+
60
+ const fetchGerritJson = async (url) => {
61
+ try {
62
+ const res = await fetch(url, { headers });
63
+ const txt = await res.text();
64
+ // Gerrit prepends )]}' to JSON responses — strip it
65
+ const jsonText = txt.replace(/^\)\]\}'\n/, '');
66
+ return JSON.parse(jsonText);
67
+ } catch (err) {
68
+ return null;
69
+ }
70
+ };
71
+
72
+ const resolveChangeNumber = async (r) => {
73
+ // try changeId first
74
+ if (r.changeId) {
75
+ if (cache.has(r.changeId)) return cache.get(r.changeId);
76
+ // try `changes/{changeId}/detail`
77
+ const url = `${gerritApi.replace(/\/$/, '')}/changes/${encodeURIComponent(r.changeId)}/detail`;
78
+ let j = await fetchGerritJson(url);
79
+ if (j && j._number) {
80
+ cache.set(r.changeId, j._number);
81
+ return j._number;
82
+ }
83
+ // fallback: query search
84
+ const url2 = `${gerritApi.replace(/\/$/, '')}/changes/?q=change:${encodeURIComponent(r.changeId)}`;
85
+ j = await fetchGerritJson(url2);
86
+ if (Array.isArray(j) && j.length > 0 && j[0]._number) {
87
+ cache.set(r.changeId, j[0]._number);
88
+ return j[0]._number;
89
+ }
90
+ }
91
+ // try commit hash
92
+ if (r.hash) {
93
+ if (cache.has(r.hash)) return cache.get(r.hash);
94
+ const url3 = `${gerritApi.replace(/\/$/, '')}/changes/?q=commit:${encodeURIComponent(r.hash)}`;
95
+ const j = await fetchGerritJson(url3);
96
+ if (Array.isArray(j) && j.length > 0 && j[0]._number) {
97
+ cache.set(r.hash, j[0]._number);
98
+ return j[0]._number;
99
+ }
100
+ }
101
+ return null;
102
+ };
103
+
104
+ records = await Promise.all(
105
+ records.map(async (r) => {
106
+ const changeNumber = await resolveChangeNumber(r);
107
+ const changeNumberOrFallback = changeNumber || r.changeId || r.hash;
108
+ const gerritUrl = prefix.replace('{{changeNumber}}', changeNumberOrFallback);
109
+ return { ...r, gerrit: gerritUrl };
110
+ })
111
+ );
112
+ } else if (prefix.includes('{{changeNumber}}') && !gerritApi) {
113
+ console.warn('prefix contains {{changeNumber}} but no --gerrit-api provided — falling back to changeId/hash');
114
+ records = records.map((r) => ({ ...r, gerrit: prefix.replace('{{changeNumber}}', r.changeId || r.hash) }));
115
+ } else {
116
+ records = records.map((r) => {
45
117
  let gerritUrl;
46
118
  if (prefix.includes('{{changeId}}')) {
47
119
  const changeId = r.changeId || r.hash;
@@ -54,7 +126,8 @@ const opts = program.opts();
54
126
  }
55
127
 
56
128
  return { ...r, gerrit: gerritUrl };
57
- });
129
+ });
130
+ }
58
131
  }
59
132
 
60
133
  // --- 分组 ---