unplugin-auto-git-log 0.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright © 2025-PRESENT Drswith (https://github.com/Drswith)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,285 @@
1
+ # unplugin-auto-git-log
2
+
3
+ [![Unit Test][unit-test-src]][unit-test-href]
4
+
5
+ Unplugin for automatically generating Git information (repo, branch, commit, etc.) in multiple output formats.
6
+
7
+ ## Features
8
+
9
+ - 📦 Automatically extract Git repository information
10
+ - 🎯 Support multiple output formats:
11
+ - JSON file
12
+ - Window global variable
13
+ - Environment variables (.env)
14
+ - TypeScript type definitions
15
+ - 🔧 Works with all major build tools (Vite, Webpack, Rollup, esbuild, Rspack, etc.)
16
+ - ⚙️ Configurable fields and output options
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm i -D unplugin-auto-git-log
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ <details>
27
+ <summary>Vite</summary><br>
28
+
29
+ ```ts
30
+ // vite.config.ts
31
+ import AutoGitLog from 'unplugin-auto-git-log/vite'
32
+
33
+ export default defineConfig({
34
+ plugins: [AutoGitLog()],
35
+ })
36
+ ```
37
+
38
+ <br></details>
39
+
40
+ <details>
41
+ <summary>Rollup</summary><br>
42
+
43
+ ```ts
44
+ // rollup.config.js
45
+ import AutoGitLog from 'unplugin-auto-git-log/rollup'
46
+
47
+ export default {
48
+ plugins: [AutoGitLog()],
49
+ }
50
+ ```
51
+
52
+ <br></details>
53
+
54
+ <details>
55
+ <summary>Rolldown / tsdown</summary><br>
56
+
57
+ ```ts
58
+ // rolldown.config.ts / tsdown.config.ts
59
+ import AutoGitLog from 'unplugin-auto-git-log/rolldown'
60
+
61
+ export default {
62
+ plugins: [AutoGitLog()],
63
+ }
64
+ ```
65
+
66
+ <br></details>
67
+
68
+ <details>
69
+ <summary>esbuild</summary><br>
70
+
71
+ ```ts
72
+ import { build } from 'esbuild'
73
+ import AutoGitLog from 'unplugin-auto-git-log/esbuild'
74
+
75
+ build({
76
+ plugins: [AutoGitLog()],
77
+ })
78
+ ```
79
+
80
+ <br></details>
81
+
82
+ <details>
83
+ <summary>Webpack</summary><br>
84
+
85
+ ```js
86
+ // webpack.config.js
87
+ import AutoGitLog from 'unplugin-auto-git-log/webpack'
88
+
89
+ export default {
90
+ /* ... */
91
+ plugins: [AutoGitLog()],
92
+ }
93
+ ```
94
+
95
+ <br></details>
96
+
97
+ <details>
98
+ <summary>Rspack</summary><br>
99
+
100
+ ```ts
101
+ // rspack.config.js
102
+ import AutoGitLog from 'unplugin-auto-git-log/rspack'
103
+
104
+ export default {
105
+ /* ... */
106
+ plugins: [AutoGitLog()],
107
+ }
108
+ ```
109
+
110
+ <br></details>
111
+
112
+ ## Configuration
113
+
114
+ ### Default Behavior
115
+
116
+ By default, the plugin will:
117
+
118
+ - **Be enabled** (`enable: true`)
119
+ - Extract all available Git fields (repo, branch, commit, commitShort, author, authorEmail, commitTime, commitMessage, isDirty)
120
+ - Generate a JSON file at your build output directory (e.g., `dist/git-log.json` for Vite)
121
+ - Automatically detect the output directory from your build tool configuration
122
+ - Run after build (`enforce: 'post'`)
123
+
124
+ You can use the plugin without any configuration:
125
+
126
+ ```ts
127
+ // vite.config.ts
128
+ import AutoGitLog from 'unplugin-auto-git-log/vite'
129
+
130
+ export default defineConfig({
131
+ plugins: [AutoGitLog()], // That's it!
132
+ })
133
+ ```
134
+
135
+ ### Advanced Configuration
136
+
137
+ ```ts
138
+ AutoGitLog({
139
+ // Enable/disable the plugin (default: true)
140
+ enable: true,
141
+
142
+ // Git fields to include (default: all)
143
+ fields: ['repo', 'branch', 'commit', 'commitShort', 'author', 'authorEmail', 'commitTime', 'commitMessage', 'isDirty'],
144
+
145
+ // Output options
146
+ outputs: {
147
+ // Generate JSON file (default: 'git-log.json' in output directory)
148
+ json: {
149
+ fileName: 'git-log.json', // Relative to build output directory
150
+ },
151
+
152
+ // Generate window global variable file (default: '__GIT_LOG__')
153
+ window: {
154
+ varName: '__GIT_LOG__',
155
+ console: true, // Log Git log to browser console
156
+ },
157
+
158
+ // Generate environment variables file (default: '.env.git')
159
+ env: {
160
+ prefix: '__GIT_',
161
+ file: '.env.git',
162
+ },
163
+
164
+ // Generate TypeScript type definitions (default: 'git-log.d.ts' in output directory)
165
+ types: {
166
+ fileName: 'git-log.d.ts', // Relative to build output directory
167
+ },
168
+ },
169
+
170
+ // Working directory (optional, defaults to process.cwd())
171
+ // cwd: './custom-path',
172
+
173
+ // Plugin execution timing
174
+ enforce: 'post', // 'pre' | 'post'
175
+ })
176
+ ```
177
+
178
+ ### Disable the Plugin
179
+
180
+ You can conditionally disable the plugin based on environment:
181
+
182
+ ```ts
183
+ import AutoGitLog from 'unplugin-auto-git-log/vite'
184
+ import { defineConfig } from 'vite'
185
+
186
+ export default defineConfig({
187
+ plugins: [
188
+ AutoGitLog({
189
+ enable: process.env.NODE_ENV === 'production', // Only enable in production
190
+ }),
191
+ ],
192
+ })
193
+ ```
194
+
195
+ Or completely disable it:
196
+
197
+ ```ts
198
+ AutoGitLog({
199
+ enable: false, // Plugin will not generate any files
200
+ })
201
+ ```
202
+
203
+ ## Git Fields
204
+
205
+ The following Git information can be extracted:
206
+
207
+ - `repo` - Repository URL
208
+ - `branch` - Current branch name
209
+ - `commit` - Full commit hash
210
+ - `commitShort` - Short commit hash (7 characters)
211
+ - `author` - Author name
212
+ - `authorEmail` - Author email
213
+ - `commitTime` - Commit timestamp
214
+ - `commitMessage` - Commit message
215
+ - `isDirty` - Whether the working directory has uncommitted changes
216
+
217
+ ## Output Examples
218
+
219
+ ### JSON Output
220
+
221
+ By default, the JSON file is generated at your build output directory (e.g., `dist/git-log.json`):
222
+
223
+ ```json
224
+ {
225
+ "repo": "https://github.com/user/repo.git",
226
+ "branch": "main",
227
+ "commit": "abc123def456...",
228
+ "commitShort": "abc123d",
229
+ "author": "John Doe",
230
+ "authorEmail": "john@example.com",
231
+ "commitTime": "2025-01-08T12:00:00.000Z",
232
+ "commitMessage": "feat: add new feature",
233
+ "isDirty": false
234
+ }
235
+ ```
236
+
237
+ ### Window Variable Output
238
+
239
+ When window output is enabled, the plugin will:
240
+
241
+ 1. Generate a JavaScript file (e.g., `dist/__GIT_LOG__.js`)
242
+ 2. Automatically inject a `<script>` tag into your HTML (Vite only)
243
+ 3. Optionally log Git log to browser console (with `console: true`)
244
+
245
+ You can then access the Git log anywhere in your code:
246
+
247
+ ```typescript
248
+ // In your browser code
249
+ console.log(window.__GIT_LOG__)
250
+ console.log(window.__GIT_LOG__.branch)
251
+ console.log(window.__GIT_LOG__.commit)
252
+ ```
253
+
254
+ The generated file (`__GIT_LOG__.js`) contains:
255
+
256
+ ```js
257
+ ;(function () {
258
+ if (typeof window !== 'undefined') {
259
+ window.__GIT_LOG__ = { /* git log */ }
260
+ }
261
+ })()
262
+ ```
263
+
264
+ ### Environment Variables (`.env.git`)
265
+
266
+ ```bash
267
+ __GIT_REPO=https://github.com/user/repo.git
268
+ __GIT_BRANCH=main
269
+ __GIT_COMMIT=abc123def456...
270
+ __GIT_COMMIT_SHORT=abc123d
271
+ __GIT_AUTHOR=John Doe
272
+ __GIT_AUTHOR_EMAIL=john@example.com
273
+ __GIT_COMMIT_TIME=2025-01-08T12:00:00.000Z
274
+ __GIT_COMMIT_MESSAGE=feat: add new feature
275
+ __GIT_IS_DIRTY=false
276
+ ```
277
+
278
+ ## License
279
+
280
+ [MIT](./LICENSE) License © 2025-PRESENT [Drswith](https://github.com/Drswith)
281
+
282
+ <!-- Badges -->
283
+
284
+ [unit-test-src]: https://github.com/Drswith/unplugin-auto-git-log/actions/workflows/unit-test.yml/badge.svg
285
+ [unit-test-href]: https://github.com/Drswith/unplugin-auto-git-log/actions/workflows/unit-test.yml
package/dist/api.d.mts ADDED
@@ -0,0 +1,2 @@
1
+ import { a as OutputOptions, c as generateEnvVars, d as generateTypeDefinitions, f as generateWindowVar, g as getGitLog, h as getAvailableFields, i as JsonOutputOptions, l as generateJson, m as GitLog, n as OptionsResolved, o as TypesOutputOptions, p as GitField, r as EnvOutputOptions, s as WindowOutputOptions, t as Options, u as generateOutputs } from "./options-B7zpW-6U.mjs";
2
+ export { type EnvOutputOptions, type GitField, type GitLog, type JsonOutputOptions, type Options, type OptionsResolved, type OutputOptions, type TypesOutputOptions, type WindowOutputOptions, generateEnvVars, generateJson, generateOutputs, generateTypeDefinitions, generateWindowVar, getAvailableFields, getGitLog };
package/dist/api.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import { a as generateWindowVar, i as generateTypeDefinitions, n as generateJson, o as getAvailableFields, r as generateOutputs, s as getGitLog, t as generateEnvVars } from "./outputs-CbT7SkvQ.mjs";
2
+
3
+ export { generateEnvVars, generateJson, generateOutputs, generateTypeDefinitions, generateWindowVar, getAvailableFields, getGitLog };
package/dist/cli.d.mts ADDED
@@ -0,0 +1,7 @@
1
+ //#region src/cli.d.ts
2
+ /**
3
+ * CLI 主函数
4
+ */
5
+ declare function runCLI(): void;
6
+ //#endregion
7
+ export { runCLI };
package/dist/cli.mjs ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ import { r as generateOutputs, s as getGitLog } from "./outputs-CbT7SkvQ.mjs";
3
+ import { readFileSync } from "node:fs";
4
+ import { resolve } from "node:path";
5
+ import process from "node:process";
6
+
7
+ //#region src/cli.ts
8
+ /**
9
+ * 解析命令行参数
10
+ */
11
+ function parseArgs() {
12
+ const args = process.argv.slice(2);
13
+ const options = {};
14
+ for (let i = 0; i < args.length; i++) {
15
+ const arg = args[i];
16
+ const nextArg = args[i + 1];
17
+ switch (arg) {
18
+ case "--fields":
19
+ case "-f":
20
+ if (nextArg) {
21
+ options.fields = nextArg.split(",").map((f) => f.trim());
22
+ i++;
23
+ }
24
+ break;
25
+ case "--cwd":
26
+ case "-C":
27
+ if (nextArg) {
28
+ options.cwd = nextArg;
29
+ i++;
30
+ }
31
+ break;
32
+ case "--config":
33
+ case "-c":
34
+ if (nextArg) {
35
+ try {
36
+ const configContent = readFileSync(resolve(nextArg), "utf8");
37
+ const config = JSON.parse(configContent);
38
+ Object.assign(options, config);
39
+ } catch (error) {
40
+ console.error(`无法读取配置文件: ${nextArg}`, error);
41
+ process.exit(1);
42
+ }
43
+ i++;
44
+ }
45
+ break;
46
+ case "--help":
47
+ case "-h":
48
+ console.log(`
49
+ 用法: unplugin-auto-git-log [选项]
50
+
51
+ 选项:
52
+ -f, --fields <fields> Git 字段列表,用逗号分隔 (例如: repo,branch,commit)
53
+ -C, --cwd <path> 工作目录路径
54
+ -c, --config <path> 配置文件路径 (JSON 格式)
55
+ -h, --help 显示帮助信息
56
+
57
+ 示例:
58
+ unplugin-auto-git-log --fields repo,branch,commit
59
+ unplugin-auto-git-log --config ./git-log.config.json
60
+ unplugin-auto-git-log --cwd ./src --fields repo,branch
61
+ `);
62
+ process.exit(0);
63
+ break;
64
+ default:
65
+ if (arg.startsWith("-")) console.warn(`未知选项: ${arg}`);
66
+ break;
67
+ }
68
+ }
69
+ return options;
70
+ }
71
+ /**
72
+ * CLI 主函数
73
+ */
74
+ function runCLI() {
75
+ const args = parseArgs();
76
+ const options = {
77
+ fields: args.fields || [
78
+ "repo",
79
+ "branch",
80
+ "commit",
81
+ "commitShort",
82
+ "author",
83
+ "authorEmail",
84
+ "commitTime",
85
+ "commitMessage",
86
+ "isDirty"
87
+ ],
88
+ outputs: args.outputs || { json: { fileName: "git-log.json" } },
89
+ cwd: args.cwd
90
+ };
91
+ try {
92
+ const gitLog = getGitLog(options.fields, options.cwd);
93
+ if (Object.keys(gitLog).length === 0) {
94
+ console.warn("警告: 未检测到 Git 仓库或无法获取 Git 日志");
95
+ process.exit(0);
96
+ }
97
+ if (options.outputs) {
98
+ generateOutputs(gitLog, options.outputs, options.cwd);
99
+ console.log("✓ Git 日志已生成");
100
+ } else console.log(JSON.stringify(gitLog, null, 2));
101
+ } catch (error) {
102
+ console.error("错误:", error);
103
+ process.exit(1);
104
+ }
105
+ }
106
+ if (import.meta.url !== void 0 && (import.meta.url.endsWith(process.argv[1]) || process.argv[1]?.includes("cli"))) runCLI();
107
+
108
+ //#endregion
109
+ export { runCLI };
@@ -0,0 +1,19 @@
1
+ import "./options-B7zpW-6U.mjs";
2
+ import { AutoGitLog } from "./index.mjs";
3
+
4
+ //#region src/esbuild.d.ts
5
+
6
+ /**
7
+ * Esbuild plugin
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { build } from 'esbuild'
12
+ * import AutoGitLog from 'unplugin-auto-git-log/esbuild'
13
+ *
14
+ * build({ plugins: [AutoGitLog()] })
15
+ ```
16
+ */
17
+ declare const esbuild: typeof AutoGitLog.esbuild;
18
+ //#endregion
19
+ export { esbuild as default, esbuild as "module.exports" };
@@ -0,0 +1,24 @@
1
+ import { t as AutoGitLog } from "./src-Bbcs1xDg.mjs";
2
+
3
+ //#region src/esbuild.ts
4
+ /**
5
+ * This entry file is for esbuild plugin.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Esbuild plugin
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { build } from 'esbuild'
15
+ * import AutoGitLog from 'unplugin-auto-git-log/esbuild'
16
+ *
17
+ * build({ plugins: [AutoGitLog()] })
18
+ ```
19
+ */
20
+ const esbuild = AutoGitLog.esbuild;
21
+ var esbuild_default = esbuild;
22
+
23
+ //#endregion
24
+ export { esbuild_default as default, esbuild as "module.exports" };
@@ -0,0 +1,21 @@
1
+ import "./options-B7zpW-6U.mjs";
2
+ import { AutoGitLog } from "./index.mjs";
3
+
4
+ //#region src/farm.d.ts
5
+
6
+ /**
7
+ * Farm plugin
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // farm.config.js
12
+ * import AutoGitLog from 'unplugin-auto-git-log/farm'
13
+ *
14
+ * export default {
15
+ * plugins: [AutoGitLog()],
16
+ * }
17
+ * ```
18
+ */
19
+ declare const farm: typeof AutoGitLog.farm;
20
+ //#endregion
21
+ export { farm as default, farm as "module.exports" };
package/dist/farm.mjs ADDED
@@ -0,0 +1,26 @@
1
+ import { t as AutoGitLog } from "./src-Bbcs1xDg.mjs";
2
+
3
+ //#region src/farm.ts
4
+ /**
5
+ * This entry file is for Farm plugin.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Farm plugin
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // farm.config.js
15
+ * import AutoGitLog from 'unplugin-auto-git-log/farm'
16
+ *
17
+ * export default {
18
+ * plugins: [AutoGitLog()],
19
+ * }
20
+ * ```
21
+ */
22
+ const farm = AutoGitLog.farm;
23
+ var farm_default = farm;
24
+
25
+ //#endregion
26
+ export { farm_default as default, farm as "module.exports" };
@@ -0,0 +1,7 @@
1
+ import { t as Options } from "./options-B7zpW-6U.mjs";
2
+ import { UnpluginInstance } from "unplugin";
3
+
4
+ //#region src/index.d.ts
5
+ declare const AutoGitLog: UnpluginInstance<Options | undefined, false>;
6
+ //#endregion
7
+ export { AutoGitLog };
package/dist/index.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import { t as AutoGitLog } from "./src-Bbcs1xDg.mjs";
2
+
3
+ export { AutoGitLog };
@@ -0,0 +1,72 @@
1
+ import { FilterPattern } from "unplugin";
2
+
3
+ //#region src/core/git.d.ts
4
+ type GitField = "repo" | "branch" | "commit" | "commitShort" | "author" | "authorEmail" | "commitTime" | "commitMessage" | "tag" | "isDirty" | "remoteUrl" | "root";
5
+ type GitLog = Record<string, string | boolean>;
6
+ /**
7
+ * 获取 Git 日志
8
+ */
9
+ declare function getGitLog(fields?: string[], cwd?: string): GitLog;
10
+ /**
11
+ * 获取所有可用的 Git 字段
12
+ */
13
+ declare function getAvailableFields(): GitField[];
14
+ //#endregion
15
+ //#region src/core/outputs.d.ts
16
+ interface JsonOutputOptions {
17
+ fileName?: string;
18
+ }
19
+ interface WindowOutputOptions {
20
+ varName?: string;
21
+ console?: boolean;
22
+ }
23
+ interface EnvOutputOptions {
24
+ prefix?: string;
25
+ file?: string;
26
+ }
27
+ interface TypesOutputOptions {
28
+ fileName?: string;
29
+ }
30
+ interface OutputOptions {
31
+ json?: JsonOutputOptions;
32
+ window?: WindowOutputOptions;
33
+ env?: EnvOutputOptions;
34
+ types?: TypesOutputOptions;
35
+ }
36
+ /**
37
+ * 生成 JSON 文件
38
+ */
39
+ declare function generateJson(gitLog: GitLog, options?: JsonOutputOptions, outputDir?: string): void;
40
+ /**
41
+ * 生成 window 全局变量文件
42
+ */
43
+ declare function generateWindowVar(gitLog: GitLog, options?: WindowOutputOptions, outputDir?: string): string;
44
+ /**
45
+ * 生成环境变量文件
46
+ */
47
+ declare function generateEnvVars(gitLog: GitLog, options?: EnvOutputOptions, outputDir?: string): void;
48
+ /**
49
+ * 生成 TypeScript 类型定义文件
50
+ */
51
+ declare function generateTypeDefinitions(gitLog: GitLog, options?: TypesOutputOptions, outputDir?: string): void;
52
+ /**
53
+ * 根据配置生成所有输出
54
+ */
55
+ declare function generateOutputs(gitLog: GitLog, outputOptions: OutputOptions, outputDir?: string): string | undefined;
56
+ //#endregion
57
+ //#region src/core/options.d.ts
58
+ interface Options {
59
+ include?: FilterPattern;
60
+ exclude?: FilterPattern;
61
+ enforce?: "pre" | "post" | undefined;
62
+ enable?: boolean;
63
+ fields?: GitField[] | string[];
64
+ outputs?: OutputOptions;
65
+ cwd?: string;
66
+ }
67
+ type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
68
+ type OptionsResolved = Overwrite<Required<Pick<Options, "include" | "exclude">>, Omit<Pick<Options, "enforce" | "enable" | "fields" | "outputs" | "cwd">, "outputs"> & {
69
+ outputs: OutputOptions;
70
+ }>;
71
+ //#endregion
72
+ export { OutputOptions as a, generateEnvVars as c, generateTypeDefinitions as d, generateWindowVar as f, getGitLog as g, getAvailableFields as h, JsonOutputOptions as i, generateJson as l, GitLog as m, OptionsResolved as n, TypesOutputOptions as o, GitField as p, EnvOutputOptions as r, WindowOutputOptions as s, Options as t, generateOutputs as u };
@@ -0,0 +1,209 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
3
+ import { basename, dirname, isAbsolute, resolve } from "node:path";
4
+
5
+ //#region src/core/git.ts
6
+ /**
7
+ * 检查当前目录是否是 Git 仓库
8
+ */
9
+ function isGitRepository(cwd) {
10
+ try {
11
+ return existsSync(cwd ? resolve(cwd, ".git") : ".git") || execSync("git rev-parse --git-dir", {
12
+ cwd,
13
+ encoding: "utf8",
14
+ stdio: "pipe"
15
+ }).trim() !== "";
16
+ } catch {
17
+ return false;
18
+ }
19
+ }
20
+ /**
21
+ * 安全执行 Git 命令
22
+ */
23
+ function execGitCommand(command, cwd) {
24
+ try {
25
+ return execSync(command, {
26
+ cwd,
27
+ encoding: "utf8",
28
+ stdio: "pipe"
29
+ }).trim();
30
+ } catch {
31
+ return "";
32
+ }
33
+ }
34
+ /**
35
+ * 获取 Git 仓库根目录
36
+ */
37
+ function getGitRoot(cwd) {
38
+ return execGitCommand("git rev-parse --show-toplevel", cwd);
39
+ }
40
+ /**
41
+ * 获取 Git 日志
42
+ */
43
+ function getGitLog(fields = [], cwd) {
44
+ const result = {};
45
+ if (!isGitRepository(cwd)) return result;
46
+ const gitRoot = getGitRoot(cwd);
47
+ for (const field of fields) switch (field) {
48
+ case "repo": {
49
+ const remoteUrl = execGitCommand("git config --get remote.origin.url", cwd);
50
+ if (remoteUrl) {
51
+ const match = remoteUrl.match(/(?:git@|https?:\/\/)(?:.*\/)?([^/]+?)(?:\.git)?$/);
52
+ result.repo = match ? match[1] : remoteUrl;
53
+ } else result.repo = gitRoot ? basename(gitRoot) : "";
54
+ break;
55
+ }
56
+ case "branch":
57
+ result.branch = execGitCommand("git rev-parse --abbrev-ref HEAD", cwd) || "";
58
+ break;
59
+ case "commit":
60
+ result.commit = execGitCommand("git rev-parse HEAD", cwd) || "";
61
+ break;
62
+ case "commitShort":
63
+ result.commitShort = execGitCommand("git rev-parse --short HEAD", cwd) || "";
64
+ break;
65
+ case "author":
66
+ result.author = execGitCommand("git log -1 --pretty=format:\"%an\"", cwd) || "";
67
+ break;
68
+ case "authorEmail":
69
+ result.authorEmail = execGitCommand("git log -1 --pretty=format:\"%ae\"", cwd) || "";
70
+ break;
71
+ case "commitTime":
72
+ result.commitTime = execGitCommand("git log -1 --pretty=format:\"%ci\"", cwd) || "";
73
+ break;
74
+ case "commitMessage":
75
+ result.commitMessage = execGitCommand("git log -1 --pretty=format:\"%s\"", cwd) || "";
76
+ break;
77
+ case "tag":
78
+ result.tag = execGitCommand("git describe --tags --exact-match HEAD 2>/dev/null", cwd) || "";
79
+ break;
80
+ case "isDirty":
81
+ result.isDirty = execGitCommand("git status --porcelain", cwd).length > 0;
82
+ break;
83
+ case "remoteUrl":
84
+ result.remoteUrl = execGitCommand("git config --get remote.origin.url", cwd) || "";
85
+ break;
86
+ case "root":
87
+ result.root = gitRoot || "";
88
+ break;
89
+ default:
90
+ if (field.startsWith("custom:")) result[field] = execGitCommand(field.replace(/^custom:/, ""), cwd) || "";
91
+ break;
92
+ }
93
+ return result;
94
+ }
95
+ /**
96
+ * 获取所有可用的 Git 字段
97
+ */
98
+ function getAvailableFields() {
99
+ return [
100
+ "repo",
101
+ "branch",
102
+ "commit",
103
+ "commitShort",
104
+ "author",
105
+ "authorEmail",
106
+ "commitTime",
107
+ "commitMessage",
108
+ "tag",
109
+ "isDirty",
110
+ "remoteUrl",
111
+ "root"
112
+ ];
113
+ }
114
+
115
+ //#endregion
116
+ //#region src/core/outputs.ts
117
+ /**
118
+ * 生成 JSON 文件内容
119
+ */
120
+ function generateJsonContent(gitLog) {
121
+ return JSON.stringify(gitLog, null, 2);
122
+ }
123
+ /**
124
+ * 生成 JSON 文件
125
+ */
126
+ function generateJson(gitLog, options = {}, outputDir) {
127
+ const fileName = options.fileName || "git-log.json";
128
+ const fullPath = outputDir && !isAbsolute(fileName) ? resolve(outputDir, fileName) : fileName;
129
+ mkdirSync(dirname(fullPath), { recursive: true });
130
+ writeFileSync(fullPath, generateJsonContent(gitLog), "utf8");
131
+ }
132
+ /**
133
+ * 生成 window 全局变量代码
134
+ */
135
+ function generateWindowVarContent(gitLog, options = {}) {
136
+ const varName = options.varName || "__GIT_LOG__";
137
+ return `(function() {
138
+ if (typeof window !== 'undefined') {
139
+ window.${varName} = ${JSON.stringify(gitLog, null, 2)};
140
+ ${options.console ? `console.log('[Git Log]', window.${varName});` : ""}
141
+ }
142
+ })();`;
143
+ }
144
+ /**
145
+ * 生成 window 全局变量文件
146
+ */
147
+ function generateWindowVar(gitLog, options = {}, outputDir) {
148
+ const fileName = `${options.varName || "__GIT_LOG__"}.js`;
149
+ const fullPath = outputDir ? resolve(outputDir, fileName) : fileName;
150
+ mkdirSync(dirname(fullPath), { recursive: true });
151
+ writeFileSync(fullPath, generateWindowVarContent(gitLog, options), "utf8");
152
+ return fileName;
153
+ }
154
+ /**
155
+ * 生成环境变量文件内容
156
+ */
157
+ function generateEnvVarsContent(gitLog, options = {}) {
158
+ const prefix = options.prefix || "__GIT_";
159
+ const lines = [];
160
+ for (const [key, value] of Object.entries(gitLog)) {
161
+ const envKey = `${prefix}${key.toUpperCase()}`;
162
+ const escapedValue = (typeof value === "string" ? value : String(value)).replaceAll("\"", String.raw`\"`);
163
+ lines.push(`${envKey}="${escapedValue}"`);
164
+ }
165
+ return lines.join("\n");
166
+ }
167
+ /**
168
+ * 生成环境变量文件
169
+ */
170
+ function generateEnvVars(gitLog, options = {}, outputDir) {
171
+ const filePath = options.file || ".env.git";
172
+ const fullPath = outputDir ? resolve(outputDir, filePath) : filePath;
173
+ mkdirSync(dirname(fullPath), { recursive: true });
174
+ writeFileSync(fullPath, generateEnvVarsContent(gitLog, options), "utf8");
175
+ }
176
+ /**
177
+ * 生成 TypeScript 类型定义文件内容
178
+ */
179
+ function generateTypeDefinitionsContent(gitLog) {
180
+ return `export interface GitLog {
181
+ ${Object.entries(gitLog).map(([key, value]) => {
182
+ return ` ${key}: ${typeof value === "boolean" ? "boolean" : "string"}`;
183
+ }).join("\n")}
184
+ }
185
+ `;
186
+ }
187
+ /**
188
+ * 生成 TypeScript 类型定义文件
189
+ */
190
+ function generateTypeDefinitions(gitLog, options = {}, outputDir) {
191
+ const fileName = options.fileName || "git-log.d.ts";
192
+ const fullPath = outputDir && !isAbsolute(fileName) ? resolve(outputDir, fileName) : fileName;
193
+ mkdirSync(dirname(fullPath), { recursive: true });
194
+ writeFileSync(fullPath, generateTypeDefinitionsContent(gitLog), "utf8");
195
+ }
196
+ /**
197
+ * 根据配置生成所有输出
198
+ */
199
+ function generateOutputs(gitLog, outputOptions, outputDir) {
200
+ let windowVarFileName;
201
+ if (outputOptions.json) generateJson(gitLog, outputOptions.json, outputDir);
202
+ if (outputOptions.window) windowVarFileName = generateWindowVar(gitLog, outputOptions.window, outputDir);
203
+ if (outputOptions.env) generateEnvVars(gitLog, outputOptions.env, outputDir);
204
+ if (outputOptions.types) generateTypeDefinitions(gitLog, outputOptions.types, outputDir);
205
+ return windowVarFileName;
206
+ }
207
+
208
+ //#endregion
209
+ export { generateWindowVar as a, generateTypeDefinitions as i, generateJson as n, getAvailableFields as o, generateOutputs as r, getGitLog as s, generateEnvVars as t };
@@ -0,0 +1,21 @@
1
+ import "./options-B7zpW-6U.mjs";
2
+ import { AutoGitLog } from "./index.mjs";
3
+
4
+ //#region src/rolldown.d.ts
5
+
6
+ /**
7
+ * Rolldown plugin
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // rolldown.config.js
12
+ * import AutoGitLog from 'unplugin-auto-git-log/rolldown'
13
+ *
14
+ * export default {
15
+ * plugins: [AutoGitLog()],
16
+ * }
17
+ * ```
18
+ */
19
+ declare const rolldown: typeof AutoGitLog.rolldown;
20
+ //#endregion
21
+ export { rolldown as default, rolldown as "module.exports" };
@@ -0,0 +1,26 @@
1
+ import { t as AutoGitLog } from "./src-Bbcs1xDg.mjs";
2
+
3
+ //#region src/rolldown.ts
4
+ /**
5
+ * This entry file is for Rolldown plugin.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Rolldown plugin
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // rolldown.config.js
15
+ * import AutoGitLog from 'unplugin-auto-git-log/rolldown'
16
+ *
17
+ * export default {
18
+ * plugins: [AutoGitLog()],
19
+ * }
20
+ * ```
21
+ */
22
+ const rolldown = AutoGitLog.rolldown;
23
+ var rolldown_default = rolldown;
24
+
25
+ //#endregion
26
+ export { rolldown_default as default, rolldown as "module.exports" };
@@ -0,0 +1,21 @@
1
+ import "./options-B7zpW-6U.mjs";
2
+ import { AutoGitLog } from "./index.mjs";
3
+
4
+ //#region src/rollup.d.ts
5
+
6
+ /**
7
+ * Rollup plugin
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // rollup.config.js
12
+ * import AutoGitLog from 'unplugin-auto-git-log/rollup'
13
+ *
14
+ * export default {
15
+ * plugins: [AutoGitLog()],
16
+ * }
17
+ * ```
18
+ */
19
+ declare const rollup: typeof AutoGitLog.rollup;
20
+ //#endregion
21
+ export { rollup as default, rollup as "module.exports" };
@@ -0,0 +1,26 @@
1
+ import { t as AutoGitLog } from "./src-Bbcs1xDg.mjs";
2
+
3
+ //#region src/rollup.ts
4
+ /**
5
+ * This entry file is for Rollup plugin.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Rollup plugin
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // rollup.config.js
15
+ * import AutoGitLog from 'unplugin-auto-git-log/rollup'
16
+ *
17
+ * export default {
18
+ * plugins: [AutoGitLog()],
19
+ * }
20
+ * ```
21
+ */
22
+ const rollup = AutoGitLog.rollup;
23
+ var rollup_default = rollup;
24
+
25
+ //#endregion
26
+ export { rollup_default as default, rollup as "module.exports" };
@@ -0,0 +1,21 @@
1
+ import "./options-B7zpW-6U.mjs";
2
+ import { AutoGitLog } from "./index.mjs";
3
+
4
+ //#region src/rspack.d.ts
5
+
6
+ /**
7
+ * Rspack plugin
8
+ *
9
+ * @example
10
+ * ```js
11
+ * // rspack.config.js
12
+ * import AutoGitLog from 'unplugin-auto-git-log/rspack'
13
+ *
14
+ * export default {
15
+ * plugins: [AutoGitLog()],
16
+ * }
17
+ * ```
18
+ */
19
+ declare const rspack: typeof AutoGitLog.rspack;
20
+ //#endregion
21
+ export { rspack as default, rspack as "module.exports" };
@@ -0,0 +1,26 @@
1
+ import { t as AutoGitLog } from "./src-Bbcs1xDg.mjs";
2
+
3
+ //#region src/rspack.ts
4
+ /**
5
+ * This entry file is for Rspack plugin.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Rspack plugin
11
+ *
12
+ * @example
13
+ * ```js
14
+ * // rspack.config.js
15
+ * import AutoGitLog from 'unplugin-auto-git-log/rspack'
16
+ *
17
+ * export default {
18
+ * plugins: [AutoGitLog()],
19
+ * }
20
+ * ```
21
+ */
22
+ const rspack = AutoGitLog.rspack;
23
+ var rspack_default = rspack;
24
+
25
+ //#endregion
26
+ export { rspack_default as default, rspack as "module.exports" };
@@ -0,0 +1,65 @@
1
+ import { r as generateOutputs, s as getGitLog } from "./outputs-CbT7SkvQ.mjs";
2
+ import { createUnplugin } from "unplugin";
3
+
4
+ //#region src/core/options.ts
5
+ const DEFAULT_FIELDS = [
6
+ "repo",
7
+ "branch",
8
+ "commit",
9
+ "commitShort",
10
+ "author",
11
+ "authorEmail",
12
+ "commitTime",
13
+ "commitMessage",
14
+ "isDirty"
15
+ ];
16
+ function resolveOptions(options = {}) {
17
+ return {
18
+ include: options.include || [/\.[cm]?[jt]sx?$/],
19
+ exclude: options.exclude || [/node_modules/],
20
+ enforce: "enforce" in options ? options.enforce : "post",
21
+ enable: options.enable !== void 0 ? options.enable : true,
22
+ fields: options.fields || DEFAULT_FIELDS,
23
+ outputs: options.outputs || {},
24
+ cwd: options.cwd
25
+ };
26
+ }
27
+
28
+ //#endregion
29
+ //#region src/index.ts
30
+ const AutoGitLog = createUnplugin((rawOptions = {}) => {
31
+ const options = resolveOptions(rawOptions);
32
+ let outputDir;
33
+ let windowVarFileName;
34
+ return {
35
+ name: "unplugin-auto-git-log",
36
+ enforce: options.enforce,
37
+ configResolved(config) {
38
+ if ("vite" in config) {
39
+ const viteConfig = config;
40
+ outputDir = viteConfig.build?.outDir || viteConfig.vite?.config?.build?.outDir;
41
+ } else if ("webpack" in config) outputDir = config.output?.path;
42
+ else if ("output" in config && typeof config.output === "object") outputDir = config.output?.dir;
43
+ if (!outputDir) outputDir = "dist";
44
+ },
45
+ buildEnd() {
46
+ if (!options.enable) return;
47
+ const gitLog = getGitLog(options.fields, options.cwd);
48
+ if (options.outputs && (options.outputs.json || options.outputs.window || options.outputs.env || options.outputs.types)) windowVarFileName = generateOutputs(gitLog, options.outputs, outputDir);
49
+ else generateOutputs(gitLog, { json: {} }, outputDir);
50
+ },
51
+ vite: { transformIndexHtml(html) {
52
+ if (options.outputs?.window && windowVarFileName) return {
53
+ html,
54
+ tags: [{
55
+ tag: "script",
56
+ attrs: { src: `/${windowVarFileName}` },
57
+ injectTo: "head"
58
+ }]
59
+ };
60
+ } }
61
+ };
62
+ });
63
+
64
+ //#endregion
65
+ export { AutoGitLog as t };
@@ -0,0 +1,21 @@
1
+ import "./options-B7zpW-6U.mjs";
2
+ import { AutoGitLog } from "./index.mjs";
3
+
4
+ //#region src/vite.d.ts
5
+
6
+ /**
7
+ * Vite plugin
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // vite.config.ts
12
+ * import AutoGitLog from 'unplugin-auto-git-log/vite'
13
+ *
14
+ * export default defineConfig({
15
+ * plugins: [AutoGitLog()],
16
+ * })
17
+ * ```
18
+ */
19
+ declare const vite: typeof AutoGitLog.vite;
20
+ //#endregion
21
+ export { vite as default, vite as "module.exports" };
package/dist/vite.mjs ADDED
@@ -0,0 +1,26 @@
1
+ import { t as AutoGitLog } from "./src-Bbcs1xDg.mjs";
2
+
3
+ //#region src/vite.ts
4
+ /**
5
+ * This entry file is for Vite plugin.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Vite plugin
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // vite.config.ts
15
+ * import AutoGitLog from 'unplugin-auto-git-log/vite'
16
+ *
17
+ * export default defineConfig({
18
+ * plugins: [AutoGitLog()],
19
+ * })
20
+ * ```
21
+ */
22
+ const vite = AutoGitLog.vite;
23
+ var vite_default = vite;
24
+
25
+ //#endregion
26
+ export { vite_default as default, vite as "module.exports" };
@@ -0,0 +1,21 @@
1
+ import "./options-B7zpW-6U.mjs";
2
+ import { AutoGitLog } from "./index.mjs";
3
+
4
+ //#region src/webpack.d.ts
5
+
6
+ /**
7
+ * Webpack plugin
8
+ *
9
+ * @example
10
+ * ```js
11
+ * // webpack.config.js
12
+ * import AutoGitLog from 'unplugin-auto-git-log/webpack'
13
+ *
14
+ * export default {
15
+ * plugins: [AutoGitLog()],
16
+ * }
17
+ * ```
18
+ */
19
+ declare const webpack: typeof AutoGitLog.webpack;
20
+ //#endregion
21
+ export { webpack as default, webpack as "module.exports" };
@@ -0,0 +1,26 @@
1
+ import { t as AutoGitLog } from "./src-Bbcs1xDg.mjs";
2
+
3
+ //#region src/webpack.ts
4
+ /**
5
+ * This entry file is for webpack plugin.
6
+ *
7
+ * @module
8
+ */
9
+ /**
10
+ * Webpack plugin
11
+ *
12
+ * @example
13
+ * ```js
14
+ * // webpack.config.js
15
+ * import AutoGitLog from 'unplugin-auto-git-log/webpack'
16
+ *
17
+ * export default {
18
+ * plugins: [AutoGitLog()],
19
+ * }
20
+ * ```
21
+ */
22
+ const webpack = AutoGitLog.webpack;
23
+ var webpack_default = webpack;
24
+
25
+ //#endregion
26
+ export { webpack_default as default, webpack as "module.exports" };
package/package.json ADDED
@@ -0,0 +1,101 @@
1
+ {
2
+ "name": "unplugin-auto-git-log",
3
+ "type": "module",
4
+ "version": "0.0.1",
5
+ "packageManager": "pnpm@10.27.0",
6
+ "description": "Unplugin for automatically generating Git information (repo, branch, commit, etc.) in multiple output formats.",
7
+ "author": "Drswith",
8
+ "license": "MIT",
9
+ "homepage": "https://github.com/Drswith/unplugin-auto-git-log#readme",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/Drswith/unplugin-auto-git-log.git"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/Drswith/unplugin-auto-git-log/issues"
16
+ },
17
+ "keywords": [
18
+ "unplugin",
19
+ "vite",
20
+ "webpack",
21
+ "rspack",
22
+ "rollup",
23
+ "rolldown",
24
+ "esbuild",
25
+ "farm",
26
+ "git",
27
+ "git-log",
28
+ "build-log",
29
+ "version-log"
30
+ ],
31
+ "exports": {
32
+ ".": "./dist/index.mjs",
33
+ "./api": "./dist/api.mjs",
34
+ "./cli": "./dist/cli.mjs",
35
+ "./esbuild": "./dist/esbuild.mjs",
36
+ "./farm": "./dist/farm.mjs",
37
+ "./rolldown": "./dist/rolldown.mjs",
38
+ "./rollup": "./dist/rollup.mjs",
39
+ "./rspack": "./dist/rspack.mjs",
40
+ "./vite": "./dist/vite.mjs",
41
+ "./webpack": "./dist/webpack.mjs",
42
+ "./package.json": "./package.json"
43
+ },
44
+ "main": "./dist/index.mjs",
45
+ "module": "./dist/index.mjs",
46
+ "types": "./dist/index.d.mts",
47
+ "typesVersions": {
48
+ "*": {
49
+ "*": [
50
+ "./dist/*.d.mts",
51
+ "./*"
52
+ ]
53
+ }
54
+ },
55
+ "bin": {
56
+ "unplugin-auto-git-log": "./dist/cli.mjs"
57
+ },
58
+ "files": [
59
+ "dist"
60
+ ],
61
+ "publishConfig": {
62
+ "access": "public",
63
+ "registry": "https://registry.npmjs.org"
64
+ },
65
+ "engines": {
66
+ "node": ">=20.19.0"
67
+ },
68
+ "scripts": {
69
+ "dev": "tsdown --watch",
70
+ "build": "tsdown",
71
+ "lint": "eslint .",
72
+ "lint:fix": "eslint . --fix",
73
+ "test": "vitest run",
74
+ "typecheck": "tsc --noEmit",
75
+ "release": "bumpp",
76
+ "prepublishOnly": "pnpm run build"
77
+ },
78
+ "dependencies": {
79
+ "unplugin": "^2.3.11"
80
+ },
81
+ "devDependencies": {
82
+ "@antfu/eslint-config": "^4.11.0",
83
+ "@sxzz/test-utils": "^0.5.15",
84
+ "@types/node": "^24.10.4",
85
+ "bumpp": "^10.3.2",
86
+ "eslint": "^9.39.2",
87
+ "eslint-plugin-format": "^1.0.1",
88
+ "lint-staged": "^15.5.0",
89
+ "simple-git-hooks": "^2.13.0",
90
+ "tsdown": "^0.18.4",
91
+ "typescript": "^5.9.3",
92
+ "vite": "^7.3.1",
93
+ "vitest": "^4.0.16"
94
+ },
95
+ "simple-git-hooks": {
96
+ "pre-commit": "pnpm lint-staged"
97
+ },
98
+ "lint-staged": {
99
+ "*": "eslint --fix"
100
+ }
101
+ }