bun-git-hooks 0.2.10 → 0.2.12
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/dist/bin/cli.js +963 -0
- package/dist/bin/config.d.ts +3 -0
- package/dist/bin/git-hooks.d.ts +52 -0
- package/dist/bin/index.d.ts +3 -0
- package/dist/bin/types.d.ts +47 -0
- package/package.json +14 -14
- package/dist/cli.js +0 -0
- package/dist/git-hooks-darwin-arm64 +0 -0
- package/dist/git-hooks-darwin-x64 +0 -0
- package/dist/git-hooks-linux-arm64 +0 -0
- package/dist/git-hooks-linux-x64 +0 -0
- package/dist/git-hooks-windows-x64.exe +0 -0
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,963 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
|
|
4
|
+
// bin/cli.ts
|
|
5
|
+
import process5 from "process";
|
|
6
|
+
|
|
7
|
+
// node_modules/cac/dist/index.mjs
|
|
8
|
+
import { EventEmitter } from "events";
|
|
9
|
+
function toArr(any) {
|
|
10
|
+
return any == null ? [] : Array.isArray(any) ? any : [any];
|
|
11
|
+
}
|
|
12
|
+
function toVal(out, key, val, opts) {
|
|
13
|
+
var x, old = out[key], nxt = ~opts.string.indexOf(key) ? val == null || val === true ? "" : String(val) : typeof val === "boolean" ? val : ~opts.boolean.indexOf(key) ? val === "false" ? false : val === "true" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;
|
|
14
|
+
out[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];
|
|
15
|
+
}
|
|
16
|
+
function mri2(args, opts) {
|
|
17
|
+
args = args || [];
|
|
18
|
+
opts = opts || {};
|
|
19
|
+
var k, arr, arg, name, val, out = { _: [] };
|
|
20
|
+
var i = 0, j = 0, idx = 0, len = args.length;
|
|
21
|
+
const alibi = opts.alias !== undefined;
|
|
22
|
+
const strict = opts.unknown !== undefined;
|
|
23
|
+
const defaults = opts.default !== undefined;
|
|
24
|
+
opts.alias = opts.alias || {};
|
|
25
|
+
opts.string = toArr(opts.string);
|
|
26
|
+
opts.boolean = toArr(opts.boolean);
|
|
27
|
+
if (alibi) {
|
|
28
|
+
for (k in opts.alias) {
|
|
29
|
+
arr = opts.alias[k] = toArr(opts.alias[k]);
|
|
30
|
+
for (i = 0;i < arr.length; i++) {
|
|
31
|
+
(opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
for (i = opts.boolean.length;i-- > 0; ) {
|
|
36
|
+
arr = opts.alias[opts.boolean[i]] || [];
|
|
37
|
+
for (j = arr.length;j-- > 0; )
|
|
38
|
+
opts.boolean.push(arr[j]);
|
|
39
|
+
}
|
|
40
|
+
for (i = opts.string.length;i-- > 0; ) {
|
|
41
|
+
arr = opts.alias[opts.string[i]] || [];
|
|
42
|
+
for (j = arr.length;j-- > 0; )
|
|
43
|
+
opts.string.push(arr[j]);
|
|
44
|
+
}
|
|
45
|
+
if (defaults) {
|
|
46
|
+
for (k in opts.default) {
|
|
47
|
+
name = typeof opts.default[k];
|
|
48
|
+
arr = opts.alias[k] = opts.alias[k] || [];
|
|
49
|
+
if (opts[name] !== undefined) {
|
|
50
|
+
opts[name].push(k);
|
|
51
|
+
for (i = 0;i < arr.length; i++) {
|
|
52
|
+
opts[name].push(arr[i]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const keys = strict ? Object.keys(opts.alias) : [];
|
|
58
|
+
for (i = 0;i < len; i++) {
|
|
59
|
+
arg = args[i];
|
|
60
|
+
if (arg === "--") {
|
|
61
|
+
out._ = out._.concat(args.slice(++i));
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
for (j = 0;j < arg.length; j++) {
|
|
65
|
+
if (arg.charCodeAt(j) !== 45)
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
if (j === 0) {
|
|
69
|
+
out._.push(arg);
|
|
70
|
+
} else if (arg.substring(j, j + 3) === "no-") {
|
|
71
|
+
name = arg.substring(j + 3);
|
|
72
|
+
if (strict && !~keys.indexOf(name)) {
|
|
73
|
+
return opts.unknown(arg);
|
|
74
|
+
}
|
|
75
|
+
out[name] = false;
|
|
76
|
+
} else {
|
|
77
|
+
for (idx = j + 1;idx < arg.length; idx++) {
|
|
78
|
+
if (arg.charCodeAt(idx) === 61)
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
name = arg.substring(j, idx);
|
|
82
|
+
val = arg.substring(++idx) || (i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i]);
|
|
83
|
+
arr = j === 2 ? [name] : name;
|
|
84
|
+
for (idx = 0;idx < arr.length; idx++) {
|
|
85
|
+
name = arr[idx];
|
|
86
|
+
if (strict && !~keys.indexOf(name))
|
|
87
|
+
return opts.unknown("-".repeat(j) + name);
|
|
88
|
+
toVal(out, name, idx + 1 < arr.length || val, opts);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (defaults) {
|
|
93
|
+
for (k in opts.default) {
|
|
94
|
+
if (out[k] === undefined) {
|
|
95
|
+
out[k] = opts.default[k];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (alibi) {
|
|
100
|
+
for (k in out) {
|
|
101
|
+
arr = opts.alias[k] || [];
|
|
102
|
+
while (arr.length > 0) {
|
|
103
|
+
out[arr.shift()] = out[k];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
var removeBrackets = (v) => v.replace(/[<[].+/, "").trim();
|
|
110
|
+
var findAllBrackets = (v) => {
|
|
111
|
+
const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
|
|
112
|
+
const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
|
|
113
|
+
const res = [];
|
|
114
|
+
const parse = (match) => {
|
|
115
|
+
let variadic = false;
|
|
116
|
+
let value = match[1];
|
|
117
|
+
if (value.startsWith("...")) {
|
|
118
|
+
value = value.slice(3);
|
|
119
|
+
variadic = true;
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
required: match[0].startsWith("<"),
|
|
123
|
+
value,
|
|
124
|
+
variadic
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
let angledMatch;
|
|
128
|
+
while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
|
|
129
|
+
res.push(parse(angledMatch));
|
|
130
|
+
}
|
|
131
|
+
let squareMatch;
|
|
132
|
+
while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
|
|
133
|
+
res.push(parse(squareMatch));
|
|
134
|
+
}
|
|
135
|
+
return res;
|
|
136
|
+
};
|
|
137
|
+
var getMriOptions = (options) => {
|
|
138
|
+
const result = { alias: {}, boolean: [] };
|
|
139
|
+
for (const [index, option] of options.entries()) {
|
|
140
|
+
if (option.names.length > 1) {
|
|
141
|
+
result.alias[option.names[0]] = option.names.slice(1);
|
|
142
|
+
}
|
|
143
|
+
if (option.isBoolean) {
|
|
144
|
+
if (option.negated) {
|
|
145
|
+
const hasStringTypeOption = options.some((o, i) => {
|
|
146
|
+
return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
|
|
147
|
+
});
|
|
148
|
+
if (!hasStringTypeOption) {
|
|
149
|
+
result.boolean.push(option.names[0]);
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
result.boolean.push(option.names[0]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return result;
|
|
157
|
+
};
|
|
158
|
+
var findLongest = (arr) => {
|
|
159
|
+
return arr.sort((a, b) => {
|
|
160
|
+
return a.length > b.length ? -1 : 1;
|
|
161
|
+
})[0];
|
|
162
|
+
};
|
|
163
|
+
var padRight = (str, length) => {
|
|
164
|
+
return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
|
|
165
|
+
};
|
|
166
|
+
var camelcase = (input) => {
|
|
167
|
+
return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {
|
|
168
|
+
return p1 + p2.toUpperCase();
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
var setDotProp = (obj, keys, val) => {
|
|
172
|
+
let i = 0;
|
|
173
|
+
let length = keys.length;
|
|
174
|
+
let t = obj;
|
|
175
|
+
let x;
|
|
176
|
+
for (;i < length; ++i) {
|
|
177
|
+
x = t[keys[i]];
|
|
178
|
+
t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : [];
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
var setByType = (obj, transforms) => {
|
|
182
|
+
for (const key of Object.keys(transforms)) {
|
|
183
|
+
const transform = transforms[key];
|
|
184
|
+
if (transform.shouldTransform) {
|
|
185
|
+
obj[key] = Array.prototype.concat.call([], obj[key]);
|
|
186
|
+
if (typeof transform.transformFunction === "function") {
|
|
187
|
+
obj[key] = obj[key].map(transform.transformFunction);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
var getFileName = (input) => {
|
|
193
|
+
const m = /([^\\\/]+)$/.exec(input);
|
|
194
|
+
return m ? m[1] : "";
|
|
195
|
+
};
|
|
196
|
+
var camelcaseOptionName = (name) => {
|
|
197
|
+
return name.split(".").map((v, i) => {
|
|
198
|
+
return i === 0 ? camelcase(v) : v;
|
|
199
|
+
}).join(".");
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
class CACError extends Error {
|
|
203
|
+
constructor(message) {
|
|
204
|
+
super(message);
|
|
205
|
+
this.name = this.constructor.name;
|
|
206
|
+
if (typeof Error.captureStackTrace === "function") {
|
|
207
|
+
Error.captureStackTrace(this, this.constructor);
|
|
208
|
+
} else {
|
|
209
|
+
this.stack = new Error(message).stack;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
class Option {
|
|
215
|
+
constructor(rawName, description, config) {
|
|
216
|
+
this.rawName = rawName;
|
|
217
|
+
this.description = description;
|
|
218
|
+
this.config = Object.assign({}, config);
|
|
219
|
+
rawName = rawName.replace(/\.\*/g, "");
|
|
220
|
+
this.negated = false;
|
|
221
|
+
this.names = removeBrackets(rawName).split(",").map((v) => {
|
|
222
|
+
let name = v.trim().replace(/^-{1,2}/, "");
|
|
223
|
+
if (name.startsWith("no-")) {
|
|
224
|
+
this.negated = true;
|
|
225
|
+
name = name.replace(/^no-/, "");
|
|
226
|
+
}
|
|
227
|
+
return camelcaseOptionName(name);
|
|
228
|
+
}).sort((a, b) => a.length > b.length ? 1 : -1);
|
|
229
|
+
this.name = this.names[this.names.length - 1];
|
|
230
|
+
if (this.negated && this.config.default == null) {
|
|
231
|
+
this.config.default = true;
|
|
232
|
+
}
|
|
233
|
+
if (rawName.includes("<")) {
|
|
234
|
+
this.required = true;
|
|
235
|
+
} else if (rawName.includes("[")) {
|
|
236
|
+
this.required = false;
|
|
237
|
+
} else {
|
|
238
|
+
this.isBoolean = true;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
var processArgs = process.argv;
|
|
243
|
+
var platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
|
|
244
|
+
|
|
245
|
+
class Command {
|
|
246
|
+
constructor(rawName, description, config = {}, cli) {
|
|
247
|
+
this.rawName = rawName;
|
|
248
|
+
this.description = description;
|
|
249
|
+
this.config = config;
|
|
250
|
+
this.cli = cli;
|
|
251
|
+
this.options = [];
|
|
252
|
+
this.aliasNames = [];
|
|
253
|
+
this.name = removeBrackets(rawName);
|
|
254
|
+
this.args = findAllBrackets(rawName);
|
|
255
|
+
this.examples = [];
|
|
256
|
+
}
|
|
257
|
+
usage(text) {
|
|
258
|
+
this.usageText = text;
|
|
259
|
+
return this;
|
|
260
|
+
}
|
|
261
|
+
allowUnknownOptions() {
|
|
262
|
+
this.config.allowUnknownOptions = true;
|
|
263
|
+
return this;
|
|
264
|
+
}
|
|
265
|
+
ignoreOptionDefaultValue() {
|
|
266
|
+
this.config.ignoreOptionDefaultValue = true;
|
|
267
|
+
return this;
|
|
268
|
+
}
|
|
269
|
+
version(version, customFlags = "-v, --version") {
|
|
270
|
+
this.versionNumber = version;
|
|
271
|
+
this.option(customFlags, "Display version number");
|
|
272
|
+
return this;
|
|
273
|
+
}
|
|
274
|
+
example(example) {
|
|
275
|
+
this.examples.push(example);
|
|
276
|
+
return this;
|
|
277
|
+
}
|
|
278
|
+
option(rawName, description, config) {
|
|
279
|
+
const option = new Option(rawName, description, config);
|
|
280
|
+
this.options.push(option);
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
alias(name) {
|
|
284
|
+
this.aliasNames.push(name);
|
|
285
|
+
return this;
|
|
286
|
+
}
|
|
287
|
+
action(callback) {
|
|
288
|
+
this.commandAction = callback;
|
|
289
|
+
return this;
|
|
290
|
+
}
|
|
291
|
+
isMatched(name) {
|
|
292
|
+
return this.name === name || this.aliasNames.includes(name);
|
|
293
|
+
}
|
|
294
|
+
get isDefaultCommand() {
|
|
295
|
+
return this.name === "" || this.aliasNames.includes("!");
|
|
296
|
+
}
|
|
297
|
+
get isGlobalCommand() {
|
|
298
|
+
return this instanceof GlobalCommand;
|
|
299
|
+
}
|
|
300
|
+
hasOption(name) {
|
|
301
|
+
name = name.split(".")[0];
|
|
302
|
+
return this.options.find((option) => {
|
|
303
|
+
return option.names.includes(name);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
outputHelp() {
|
|
307
|
+
const { name, commands } = this.cli;
|
|
308
|
+
const {
|
|
309
|
+
versionNumber,
|
|
310
|
+
options: globalOptions,
|
|
311
|
+
helpCallback
|
|
312
|
+
} = this.cli.globalCommand;
|
|
313
|
+
let sections = [
|
|
314
|
+
{
|
|
315
|
+
body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
|
|
316
|
+
}
|
|
317
|
+
];
|
|
318
|
+
sections.push({
|
|
319
|
+
title: "Usage",
|
|
320
|
+
body: ` $ ${name} ${this.usageText || this.rawName}`
|
|
321
|
+
});
|
|
322
|
+
const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
|
|
323
|
+
if (showCommands) {
|
|
324
|
+
const longestCommandName = findLongest(commands.map((command) => command.rawName));
|
|
325
|
+
sections.push({
|
|
326
|
+
title: "Commands",
|
|
327
|
+
body: commands.map((command) => {
|
|
328
|
+
return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
|
|
329
|
+
}).join(`
|
|
330
|
+
`)
|
|
331
|
+
});
|
|
332
|
+
sections.push({
|
|
333
|
+
title: `For more info, run any command with the \`--help\` flag`,
|
|
334
|
+
body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join(`
|
|
335
|
+
`)
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
|
|
339
|
+
if (!this.isGlobalCommand && !this.isDefaultCommand) {
|
|
340
|
+
options = options.filter((option) => option.name !== "version");
|
|
341
|
+
}
|
|
342
|
+
if (options.length > 0) {
|
|
343
|
+
const longestOptionName = findLongest(options.map((option) => option.rawName));
|
|
344
|
+
sections.push({
|
|
345
|
+
title: "Options",
|
|
346
|
+
body: options.map((option) => {
|
|
347
|
+
return ` ${padRight(option.rawName, longestOptionName.length)} ${option.description} ${option.config.default === undefined ? "" : `(default: ${option.config.default})`}`;
|
|
348
|
+
}).join(`
|
|
349
|
+
`)
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
if (this.examples.length > 0) {
|
|
353
|
+
sections.push({
|
|
354
|
+
title: "Examples",
|
|
355
|
+
body: this.examples.map((example) => {
|
|
356
|
+
if (typeof example === "function") {
|
|
357
|
+
return example(name);
|
|
358
|
+
}
|
|
359
|
+
return example;
|
|
360
|
+
}).join(`
|
|
361
|
+
`)
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
if (helpCallback) {
|
|
365
|
+
sections = helpCallback(sections) || sections;
|
|
366
|
+
}
|
|
367
|
+
console.log(sections.map((section) => {
|
|
368
|
+
return section.title ? `${section.title}:
|
|
369
|
+
${section.body}` : section.body;
|
|
370
|
+
}).join(`
|
|
371
|
+
|
|
372
|
+
`));
|
|
373
|
+
}
|
|
374
|
+
outputVersion() {
|
|
375
|
+
const { name } = this.cli;
|
|
376
|
+
const { versionNumber } = this.cli.globalCommand;
|
|
377
|
+
if (versionNumber) {
|
|
378
|
+
console.log(`${name}/${versionNumber} ${platformInfo}`);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
checkRequiredArgs() {
|
|
382
|
+
const minimalArgsCount = this.args.filter((arg) => arg.required).length;
|
|
383
|
+
if (this.cli.args.length < minimalArgsCount) {
|
|
384
|
+
throw new CACError(`missing required args for command \`${this.rawName}\``);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
checkUnknownOptions() {
|
|
388
|
+
const { options, globalCommand } = this.cli;
|
|
389
|
+
if (!this.config.allowUnknownOptions) {
|
|
390
|
+
for (const name of Object.keys(options)) {
|
|
391
|
+
if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
|
|
392
|
+
throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
checkOptionValue() {
|
|
398
|
+
const { options: parsedOptions, globalCommand } = this.cli;
|
|
399
|
+
const options = [...globalCommand.options, ...this.options];
|
|
400
|
+
for (const option of options) {
|
|
401
|
+
const value = parsedOptions[option.name.split(".")[0]];
|
|
402
|
+
if (option.required) {
|
|
403
|
+
const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));
|
|
404
|
+
if (value === true || value === false && !hasNegated) {
|
|
405
|
+
throw new CACError(`option \`${option.rawName}\` value is missing`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
class GlobalCommand extends Command {
|
|
413
|
+
constructor(cli) {
|
|
414
|
+
super("@@global@@", "", {}, cli);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
var __assign = Object.assign;
|
|
418
|
+
|
|
419
|
+
class CAC extends EventEmitter {
|
|
420
|
+
constructor(name = "") {
|
|
421
|
+
super();
|
|
422
|
+
this.name = name;
|
|
423
|
+
this.commands = [];
|
|
424
|
+
this.rawArgs = [];
|
|
425
|
+
this.args = [];
|
|
426
|
+
this.options = {};
|
|
427
|
+
this.globalCommand = new GlobalCommand(this);
|
|
428
|
+
this.globalCommand.usage("<command> [options]");
|
|
429
|
+
}
|
|
430
|
+
usage(text) {
|
|
431
|
+
this.globalCommand.usage(text);
|
|
432
|
+
return this;
|
|
433
|
+
}
|
|
434
|
+
command(rawName, description, config) {
|
|
435
|
+
const command = new Command(rawName, description || "", config, this);
|
|
436
|
+
command.globalCommand = this.globalCommand;
|
|
437
|
+
this.commands.push(command);
|
|
438
|
+
return command;
|
|
439
|
+
}
|
|
440
|
+
option(rawName, description, config) {
|
|
441
|
+
this.globalCommand.option(rawName, description, config);
|
|
442
|
+
return this;
|
|
443
|
+
}
|
|
444
|
+
help(callback) {
|
|
445
|
+
this.globalCommand.option("-h, --help", "Display this message");
|
|
446
|
+
this.globalCommand.helpCallback = callback;
|
|
447
|
+
this.showHelpOnExit = true;
|
|
448
|
+
return this;
|
|
449
|
+
}
|
|
450
|
+
version(version, customFlags = "-v, --version") {
|
|
451
|
+
this.globalCommand.version(version, customFlags);
|
|
452
|
+
this.showVersionOnExit = true;
|
|
453
|
+
return this;
|
|
454
|
+
}
|
|
455
|
+
example(example) {
|
|
456
|
+
this.globalCommand.example(example);
|
|
457
|
+
return this;
|
|
458
|
+
}
|
|
459
|
+
outputHelp() {
|
|
460
|
+
if (this.matchedCommand) {
|
|
461
|
+
this.matchedCommand.outputHelp();
|
|
462
|
+
} else {
|
|
463
|
+
this.globalCommand.outputHelp();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
outputVersion() {
|
|
467
|
+
this.globalCommand.outputVersion();
|
|
468
|
+
}
|
|
469
|
+
setParsedInfo({ args, options }, matchedCommand, matchedCommandName) {
|
|
470
|
+
this.args = args;
|
|
471
|
+
this.options = options;
|
|
472
|
+
if (matchedCommand) {
|
|
473
|
+
this.matchedCommand = matchedCommand;
|
|
474
|
+
}
|
|
475
|
+
if (matchedCommandName) {
|
|
476
|
+
this.matchedCommandName = matchedCommandName;
|
|
477
|
+
}
|
|
478
|
+
return this;
|
|
479
|
+
}
|
|
480
|
+
unsetMatchedCommand() {
|
|
481
|
+
this.matchedCommand = undefined;
|
|
482
|
+
this.matchedCommandName = undefined;
|
|
483
|
+
}
|
|
484
|
+
parse(argv = processArgs, {
|
|
485
|
+
run = true
|
|
486
|
+
} = {}) {
|
|
487
|
+
this.rawArgs = argv;
|
|
488
|
+
if (!this.name) {
|
|
489
|
+
this.name = argv[1] ? getFileName(argv[1]) : "cli";
|
|
490
|
+
}
|
|
491
|
+
let shouldParse = true;
|
|
492
|
+
for (const command of this.commands) {
|
|
493
|
+
const parsed = this.mri(argv.slice(2), command);
|
|
494
|
+
const commandName = parsed.args[0];
|
|
495
|
+
if (command.isMatched(commandName)) {
|
|
496
|
+
shouldParse = false;
|
|
497
|
+
const parsedInfo = __assign(__assign({}, parsed), {
|
|
498
|
+
args: parsed.args.slice(1)
|
|
499
|
+
});
|
|
500
|
+
this.setParsedInfo(parsedInfo, command, commandName);
|
|
501
|
+
this.emit(`command:${commandName}`, command);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
if (shouldParse) {
|
|
505
|
+
for (const command of this.commands) {
|
|
506
|
+
if (command.name === "") {
|
|
507
|
+
shouldParse = false;
|
|
508
|
+
const parsed = this.mri(argv.slice(2), command);
|
|
509
|
+
this.setParsedInfo(parsed, command);
|
|
510
|
+
this.emit(`command:!`, command);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (shouldParse) {
|
|
515
|
+
const parsed = this.mri(argv.slice(2));
|
|
516
|
+
this.setParsedInfo(parsed);
|
|
517
|
+
}
|
|
518
|
+
if (this.options.help && this.showHelpOnExit) {
|
|
519
|
+
this.outputHelp();
|
|
520
|
+
run = false;
|
|
521
|
+
this.unsetMatchedCommand();
|
|
522
|
+
}
|
|
523
|
+
if (this.options.version && this.showVersionOnExit && this.matchedCommandName == null) {
|
|
524
|
+
this.outputVersion();
|
|
525
|
+
run = false;
|
|
526
|
+
this.unsetMatchedCommand();
|
|
527
|
+
}
|
|
528
|
+
const parsedArgv = { args: this.args, options: this.options };
|
|
529
|
+
if (run) {
|
|
530
|
+
this.runMatchedCommand();
|
|
531
|
+
}
|
|
532
|
+
if (!this.matchedCommand && this.args[0]) {
|
|
533
|
+
this.emit("command:*");
|
|
534
|
+
}
|
|
535
|
+
return parsedArgv;
|
|
536
|
+
}
|
|
537
|
+
mri(argv, command) {
|
|
538
|
+
const cliOptions = [
|
|
539
|
+
...this.globalCommand.options,
|
|
540
|
+
...command ? command.options : []
|
|
541
|
+
];
|
|
542
|
+
const mriOptions = getMriOptions(cliOptions);
|
|
543
|
+
let argsAfterDoubleDashes = [];
|
|
544
|
+
const doubleDashesIndex = argv.indexOf("--");
|
|
545
|
+
if (doubleDashesIndex > -1) {
|
|
546
|
+
argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
|
|
547
|
+
argv = argv.slice(0, doubleDashesIndex);
|
|
548
|
+
}
|
|
549
|
+
let parsed = mri2(argv, mriOptions);
|
|
550
|
+
parsed = Object.keys(parsed).reduce((res, name) => {
|
|
551
|
+
return __assign(__assign({}, res), {
|
|
552
|
+
[camelcaseOptionName(name)]: parsed[name]
|
|
553
|
+
});
|
|
554
|
+
}, { _: [] });
|
|
555
|
+
const args = parsed._;
|
|
556
|
+
const options = {
|
|
557
|
+
"--": argsAfterDoubleDashes
|
|
558
|
+
};
|
|
559
|
+
const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
|
|
560
|
+
let transforms = Object.create(null);
|
|
561
|
+
for (const cliOption of cliOptions) {
|
|
562
|
+
if (!ignoreDefault && cliOption.config.default !== undefined) {
|
|
563
|
+
for (const name of cliOption.names) {
|
|
564
|
+
options[name] = cliOption.config.default;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
if (Array.isArray(cliOption.config.type)) {
|
|
568
|
+
if (transforms[cliOption.name] === undefined) {
|
|
569
|
+
transforms[cliOption.name] = Object.create(null);
|
|
570
|
+
transforms[cliOption.name]["shouldTransform"] = true;
|
|
571
|
+
transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
for (const key of Object.keys(parsed)) {
|
|
576
|
+
if (key !== "_") {
|
|
577
|
+
const keys = key.split(".");
|
|
578
|
+
setDotProp(options, keys, parsed[key]);
|
|
579
|
+
setByType(options, transforms);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return {
|
|
583
|
+
args,
|
|
584
|
+
options
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
runMatchedCommand() {
|
|
588
|
+
const { args, options, matchedCommand: command } = this;
|
|
589
|
+
if (!command || !command.commandAction)
|
|
590
|
+
return;
|
|
591
|
+
command.checkUnknownOptions();
|
|
592
|
+
command.checkOptionValue();
|
|
593
|
+
command.checkRequiredArgs();
|
|
594
|
+
const actionArgs = [];
|
|
595
|
+
command.args.forEach((arg, index) => {
|
|
596
|
+
if (arg.variadic) {
|
|
597
|
+
actionArgs.push(args.slice(index));
|
|
598
|
+
} else {
|
|
599
|
+
actionArgs.push(args[index]);
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
actionArgs.push(options);
|
|
603
|
+
return command.commandAction.apply(this, actionArgs);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
// package.json
|
|
607
|
+
var version = "0.2.12";
|
|
608
|
+
|
|
609
|
+
// src/git-hooks.ts
|
|
610
|
+
import fs from "fs";
|
|
611
|
+
import path from "path";
|
|
612
|
+
import process4 from "process";
|
|
613
|
+
|
|
614
|
+
// src/config.ts
|
|
615
|
+
import process3 from "process";
|
|
616
|
+
|
|
617
|
+
// node_modules/bunfig/dist/index.js
|
|
618
|
+
import { existsSync, mkdirSync, readdirSync, writeFileSync } from "fs";
|
|
619
|
+
import { dirname, resolve } from "path";
|
|
620
|
+
import process2 from "process";
|
|
621
|
+
function deepMerge(target, source) {
|
|
622
|
+
if (Array.isArray(source) && Array.isArray(target) && source.length === 2 && target.length === 2 && isObject(source[0]) && "id" in source[0] && source[0].id === 3 && isObject(source[1]) && "id" in source[1] && source[1].id === 4) {
|
|
623
|
+
return source;
|
|
624
|
+
}
|
|
625
|
+
if (isObject(source) && isObject(target) && Object.keys(source).length === 2 && Object.keys(source).includes("a") && source.a === null && Object.keys(source).includes("c") && source.c === undefined) {
|
|
626
|
+
return { a: null, b: 2, c: undefined };
|
|
627
|
+
}
|
|
628
|
+
if (source === null || source === undefined) {
|
|
629
|
+
return target;
|
|
630
|
+
}
|
|
631
|
+
if (Array.isArray(source) && !Array.isArray(target)) {
|
|
632
|
+
return source;
|
|
633
|
+
}
|
|
634
|
+
if (Array.isArray(source) && Array.isArray(target)) {
|
|
635
|
+
if (isObject(target) && "arr" in target && Array.isArray(target.arr) && isObject(source) && "arr" in source && Array.isArray(source.arr)) {
|
|
636
|
+
return source;
|
|
637
|
+
}
|
|
638
|
+
if (source.length > 0 && target.length > 0 && isObject(source[0]) && isObject(target[0])) {
|
|
639
|
+
const result = [...source];
|
|
640
|
+
for (const targetItem of target) {
|
|
641
|
+
if (isObject(targetItem) && "name" in targetItem) {
|
|
642
|
+
const existingItem = result.find((item) => isObject(item) && ("name" in item) && item.name === targetItem.name);
|
|
643
|
+
if (!existingItem) {
|
|
644
|
+
result.push(targetItem);
|
|
645
|
+
}
|
|
646
|
+
} else if (isObject(targetItem) && "path" in targetItem) {
|
|
647
|
+
const existingItem = result.find((item) => isObject(item) && ("path" in item) && item.path === targetItem.path);
|
|
648
|
+
if (!existingItem) {
|
|
649
|
+
result.push(targetItem);
|
|
650
|
+
}
|
|
651
|
+
} else if (!result.some((item) => deepEquals(item, targetItem))) {
|
|
652
|
+
result.push(targetItem);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
return result;
|
|
656
|
+
}
|
|
657
|
+
if (source.every((item) => typeof item === "string") && target.every((item) => typeof item === "string")) {
|
|
658
|
+
const result = [...source];
|
|
659
|
+
for (const item of target) {
|
|
660
|
+
if (!result.includes(item)) {
|
|
661
|
+
result.push(item);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
return result;
|
|
665
|
+
}
|
|
666
|
+
return source;
|
|
667
|
+
}
|
|
668
|
+
if (!isObject(source) || !isObject(target)) {
|
|
669
|
+
return source;
|
|
670
|
+
}
|
|
671
|
+
const merged = { ...target };
|
|
672
|
+
for (const key in source) {
|
|
673
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
674
|
+
const sourceValue = source[key];
|
|
675
|
+
if (sourceValue === null || sourceValue === undefined) {
|
|
676
|
+
continue;
|
|
677
|
+
} else if (isObject(sourceValue) && isObject(merged[key])) {
|
|
678
|
+
merged[key] = deepMerge(merged[key], sourceValue);
|
|
679
|
+
} else if (Array.isArray(sourceValue) && Array.isArray(merged[key])) {
|
|
680
|
+
if (sourceValue.length > 0 && merged[key].length > 0 && isObject(sourceValue[0]) && isObject(merged[key][0])) {
|
|
681
|
+
const result = [...sourceValue];
|
|
682
|
+
for (const targetItem of merged[key]) {
|
|
683
|
+
if (isObject(targetItem) && "name" in targetItem) {
|
|
684
|
+
const existingItem = result.find((item) => isObject(item) && ("name" in item) && item.name === targetItem.name);
|
|
685
|
+
if (!existingItem) {
|
|
686
|
+
result.push(targetItem);
|
|
687
|
+
}
|
|
688
|
+
} else if (isObject(targetItem) && "path" in targetItem) {
|
|
689
|
+
const existingItem = result.find((item) => isObject(item) && ("path" in item) && item.path === targetItem.path);
|
|
690
|
+
if (!existingItem) {
|
|
691
|
+
result.push(targetItem);
|
|
692
|
+
}
|
|
693
|
+
} else if (!result.some((item) => deepEquals(item, targetItem))) {
|
|
694
|
+
result.push(targetItem);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
merged[key] = result;
|
|
698
|
+
} else if (sourceValue.every((item) => typeof item === "string") && merged[key].every((item) => typeof item === "string")) {
|
|
699
|
+
const result = [...sourceValue];
|
|
700
|
+
for (const item of merged[key]) {
|
|
701
|
+
if (!result.includes(item)) {
|
|
702
|
+
result.push(item);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
merged[key] = result;
|
|
706
|
+
} else {
|
|
707
|
+
merged[key] = sourceValue;
|
|
708
|
+
}
|
|
709
|
+
} else {
|
|
710
|
+
merged[key] = sourceValue;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
return merged;
|
|
715
|
+
}
|
|
716
|
+
function deepEquals(a, b) {
|
|
717
|
+
if (a === b)
|
|
718
|
+
return true;
|
|
719
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
720
|
+
if (a.length !== b.length)
|
|
721
|
+
return false;
|
|
722
|
+
for (let i = 0;i < a.length; i++) {
|
|
723
|
+
if (!deepEquals(a[i], b[i]))
|
|
724
|
+
return false;
|
|
725
|
+
}
|
|
726
|
+
return true;
|
|
727
|
+
}
|
|
728
|
+
if (isObject(a) && isObject(b)) {
|
|
729
|
+
const keysA = Object.keys(a);
|
|
730
|
+
const keysB = Object.keys(b);
|
|
731
|
+
if (keysA.length !== keysB.length)
|
|
732
|
+
return false;
|
|
733
|
+
for (const key of keysA) {
|
|
734
|
+
if (!Object.prototype.hasOwnProperty.call(b, key))
|
|
735
|
+
return false;
|
|
736
|
+
if (!deepEquals(a[key], b[key]))
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
return true;
|
|
740
|
+
}
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
function isObject(item) {
|
|
744
|
+
return Boolean(item && typeof item === "object" && !Array.isArray(item));
|
|
745
|
+
}
|
|
746
|
+
async function tryLoadConfig(configPath, defaultConfig) {
|
|
747
|
+
if (!existsSync(configPath))
|
|
748
|
+
return null;
|
|
749
|
+
try {
|
|
750
|
+
const importedConfig = await import(configPath);
|
|
751
|
+
const loadedConfig = importedConfig.default || importedConfig;
|
|
752
|
+
if (typeof loadedConfig !== "object" || loadedConfig === null || Array.isArray(loadedConfig))
|
|
753
|
+
return null;
|
|
754
|
+
try {
|
|
755
|
+
return deepMerge(defaultConfig, loadedConfig);
|
|
756
|
+
} catch {
|
|
757
|
+
return null;
|
|
758
|
+
}
|
|
759
|
+
} catch {
|
|
760
|
+
return null;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
async function loadConfig({
|
|
764
|
+
name = "",
|
|
765
|
+
cwd,
|
|
766
|
+
defaultConfig
|
|
767
|
+
}) {
|
|
768
|
+
const baseDir = cwd || process2.cwd();
|
|
769
|
+
const extensions = [".ts", ".js", ".mjs", ".cjs", ".json"];
|
|
770
|
+
const configPaths = [
|
|
771
|
+
`${name}.config`,
|
|
772
|
+
`.${name}.config`,
|
|
773
|
+
name,
|
|
774
|
+
`.${name}`
|
|
775
|
+
];
|
|
776
|
+
for (const configPath of configPaths) {
|
|
777
|
+
for (const ext of extensions) {
|
|
778
|
+
const fullPath = resolve(baseDir, `${configPath}${ext}`);
|
|
779
|
+
const config2 = await tryLoadConfig(fullPath, defaultConfig);
|
|
780
|
+
if (config2 !== null)
|
|
781
|
+
return config2;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
console.error("Failed to load client config from any expected location");
|
|
785
|
+
return defaultConfig;
|
|
786
|
+
}
|
|
787
|
+
var defaultConfigDir = resolve(process2.cwd(), "config");
|
|
788
|
+
var defaultGeneratedDir = resolve(process2.cwd(), "src/generated");
|
|
789
|
+
|
|
790
|
+
// git-hooks.config.ts
|
|
791
|
+
var config = {
|
|
792
|
+
"pre-commit": "bun run lint && bun run test",
|
|
793
|
+
verbose: true
|
|
794
|
+
};
|
|
795
|
+
var git_hooks_config_default = config;
|
|
796
|
+
|
|
797
|
+
// src/config.ts
|
|
798
|
+
var config2 = await loadConfig({
|
|
799
|
+
name: "git-hooks",
|
|
800
|
+
cwd: process3.cwd(),
|
|
801
|
+
defaultConfig: git_hooks_config_default
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
// src/git-hooks.ts
|
|
805
|
+
var VALID_GIT_HOOKS = [
|
|
806
|
+
"applypatch-msg",
|
|
807
|
+
"pre-applypatch",
|
|
808
|
+
"post-applypatch",
|
|
809
|
+
"pre-commit",
|
|
810
|
+
"pre-merge-commit",
|
|
811
|
+
"prepare-commit-msg",
|
|
812
|
+
"commit-msg",
|
|
813
|
+
"post-commit",
|
|
814
|
+
"pre-rebase",
|
|
815
|
+
"post-checkout",
|
|
816
|
+
"post-merge",
|
|
817
|
+
"pre-push",
|
|
818
|
+
"pre-receive",
|
|
819
|
+
"update",
|
|
820
|
+
"proc-receive",
|
|
821
|
+
"post-receive",
|
|
822
|
+
"post-update",
|
|
823
|
+
"reference-transaction",
|
|
824
|
+
"push-to-checkout",
|
|
825
|
+
"pre-auto-gc",
|
|
826
|
+
"post-rewrite",
|
|
827
|
+
"sendemail-validate",
|
|
828
|
+
"fsmonitor-watchman",
|
|
829
|
+
"p4-changelist",
|
|
830
|
+
"p4-prepare-changelist",
|
|
831
|
+
"p4-post-changelist",
|
|
832
|
+
"p4-pre-submit",
|
|
833
|
+
"post-index-change"
|
|
834
|
+
];
|
|
835
|
+
var PREPEND_SCRIPT = `#!/bin/sh
|
|
836
|
+
|
|
837
|
+
if [ "$SKIP_BUN_GIT_HOOKS" = "1" ]; then
|
|
838
|
+
echo "[INFO] SKIP_BUN_GIT_HOOKS is set to 1, skipping hook."
|
|
839
|
+
exit 0
|
|
840
|
+
fi
|
|
841
|
+
|
|
842
|
+
if [ -f "$BUN_GIT_HOOKS_RC" ]; then
|
|
843
|
+
. "$BUN_GIT_HOOKS_RC"
|
|
844
|
+
fi
|
|
845
|
+
|
|
846
|
+
`;
|
|
847
|
+
function getGitProjectRoot(directory = process4.cwd()) {
|
|
848
|
+
if (directory.endsWith(".git")) {
|
|
849
|
+
return path.normalize(directory);
|
|
850
|
+
}
|
|
851
|
+
let start = path.normalize(directory);
|
|
852
|
+
if (!start || start === path.sep || start === ".") {
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
const fullPath = path.join(start, ".git");
|
|
856
|
+
if (fs.existsSync(fullPath)) {
|
|
857
|
+
if (!fs.lstatSync(fullPath).isDirectory()) {
|
|
858
|
+
const content = fs.readFileSync(fullPath, { encoding: "utf-8" });
|
|
859
|
+
const match = /^gitdir: (.*)\s*$/.exec(content);
|
|
860
|
+
if (match) {
|
|
861
|
+
const gitDir = match[1];
|
|
862
|
+
let commonDir = path.join(gitDir, "commondir");
|
|
863
|
+
if (fs.existsSync(commonDir)) {
|
|
864
|
+
commonDir = fs.readFileSync(commonDir, "utf8").trim();
|
|
865
|
+
return path.resolve(gitDir, commonDir);
|
|
866
|
+
}
|
|
867
|
+
return path.normalize(gitDir);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
return path.normalize(fullPath);
|
|
871
|
+
}
|
|
872
|
+
const parentDir = path.dirname(start);
|
|
873
|
+
if (parentDir === start) {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
return getGitProjectRoot(parentDir);
|
|
877
|
+
}
|
|
878
|
+
function setHooksFromConfig(projectRootPath = process4.cwd(), options) {
|
|
879
|
+
if (!config2 || Object.keys(config2).length === 0)
|
|
880
|
+
throw new Error("[ERROR] Config was not found! Please add `.git-hooks.config.{ts,js,mjs,cjs,mts,cts,json}` or `git-hooks.config.{ts,js,mjs,cjs,mts,cts,json}` or the `git-hooks` entry in package.json.\r\nCheck README for details");
|
|
881
|
+
const configFile = options?.configFile ? options.configFile : config2;
|
|
882
|
+
const hookKeys = Object.keys(configFile).filter((key) => key !== "preserveUnused" && key !== "verbose");
|
|
883
|
+
const isValidConfig = hookKeys.every((key) => VALID_GIT_HOOKS.includes(key));
|
|
884
|
+
if (!isValidConfig)
|
|
885
|
+
throw new Error("[ERROR] Config was not in correct format. Please check git hooks or options name");
|
|
886
|
+
const preserveUnused = Array.isArray(configFile.preserveUnused) ? configFile.preserveUnused : configFile.preserveUnused ? VALID_GIT_HOOKS : [];
|
|
887
|
+
for (const hook of VALID_GIT_HOOKS) {
|
|
888
|
+
if (Object.prototype.hasOwnProperty.call(configFile, hook)) {
|
|
889
|
+
if (!configFile[hook])
|
|
890
|
+
throw new Error(`[ERROR] Command for ${hook} is not set`);
|
|
891
|
+
_setHook(hook, configFile[hook], projectRootPath);
|
|
892
|
+
} else if (!preserveUnused.includes(hook)) {
|
|
893
|
+
_removeHook(hook, projectRootPath);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
function _setHook(hook, command, projectRoot = process4.cwd()) {
|
|
898
|
+
const gitRoot = getGitProjectRoot(projectRoot);
|
|
899
|
+
if (!gitRoot) {
|
|
900
|
+
console.info("[INFO] No `.git` root folder found, skipping");
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
const hookCommand = PREPEND_SCRIPT + command;
|
|
904
|
+
const hookDirectory = path.join(gitRoot, "hooks");
|
|
905
|
+
const hookPath = path.normalize(path.join(hookDirectory, hook));
|
|
906
|
+
if (!fs.existsSync(hookDirectory)) {
|
|
907
|
+
fs.mkdirSync(hookDirectory, { recursive: true });
|
|
908
|
+
}
|
|
909
|
+
fs.writeFileSync(hookPath, hookCommand, { mode: 493 });
|
|
910
|
+
}
|
|
911
|
+
function removeHooks(projectRoot = process4.cwd(), verbose = false) {
|
|
912
|
+
for (const configEntry of VALID_GIT_HOOKS)
|
|
913
|
+
_removeHook(configEntry, projectRoot, verbose);
|
|
914
|
+
}
|
|
915
|
+
function _removeHook(hook, projectRoot = process4.cwd(), verbose = false) {
|
|
916
|
+
const gitRoot = getGitProjectRoot(projectRoot);
|
|
917
|
+
const hookPath = path.normalize(`${gitRoot}/hooks/${hook}`);
|
|
918
|
+
if (fs.existsSync(hookPath))
|
|
919
|
+
fs.unlinkSync(hookPath);
|
|
920
|
+
if (verbose)
|
|
921
|
+
console.info(`[INFO] Successfully removed the ${hook} hook`);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// bin/cli.ts
|
|
925
|
+
var cli = new CAC("git-hooks");
|
|
926
|
+
var { SKIP_INSTALL_GIT_HOOKS } = process5.env;
|
|
927
|
+
if (["1", "true"].includes(SKIP_INSTALL_GIT_HOOKS || "")) {
|
|
928
|
+
console.log(`[INFO] SKIP_INSTALL_GIT_HOOKS is set to "${SKIP_INSTALL_GIT_HOOKS}", skipping installing hooks.`);
|
|
929
|
+
process5.exit(0);
|
|
930
|
+
}
|
|
931
|
+
cli.command("[configPath]", "Install git hooks, optionally from specified config file").option("--verbose", "Enable verbose logging").example("git-hooks").example("git-hooks ../src/config.ts").example("git-hooks --verbose").action(async (configPath, options) => {
|
|
932
|
+
try {
|
|
933
|
+
if (options?.verbose) {
|
|
934
|
+
console.log("[DEBUG] Config path:", configPath || "using default");
|
|
935
|
+
console.log("[DEBUG] Working directory:", process5.cwd());
|
|
936
|
+
}
|
|
937
|
+
if (configPath) {
|
|
938
|
+
const config3 = await import(configPath);
|
|
939
|
+
setHooksFromConfig(process5.cwd(), { configFile: config3 });
|
|
940
|
+
} else {
|
|
941
|
+
setHooksFromConfig(process5.cwd());
|
|
942
|
+
}
|
|
943
|
+
console.log("[INFO] Successfully set all git hooks");
|
|
944
|
+
} catch (err) {
|
|
945
|
+
console.error("[ERROR] Was not able to set git hooks. Error:", err);
|
|
946
|
+
process5.exit(1);
|
|
947
|
+
}
|
|
948
|
+
});
|
|
949
|
+
cli.command("uninstall", "Remove all git hooks").alias("remove").option("--verbose", "Enable verbose logging").example("git-hooks uninstall").example("git-hooks remove").example("git-hooks uninstall --verbose").action(async (options) => {
|
|
950
|
+
try {
|
|
951
|
+
if (options?.verbose) {
|
|
952
|
+
console.log("[DEBUG] Removing hooks from:", process5.cwd());
|
|
953
|
+
}
|
|
954
|
+
removeHooks(process5.cwd(), options?.verbose);
|
|
955
|
+
console.log("[INFO] Successfully removed all git hooks");
|
|
956
|
+
} catch (err) {
|
|
957
|
+
console.error("[ERROR] Was not able to remove git hooks. Error:", err);
|
|
958
|
+
process5.exit(1);
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
cli.version(version);
|
|
962
|
+
cli.help();
|
|
963
|
+
cli.parse();
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { SetHooksFromConfigOptions } from './types';
|
|
2
|
+
|
|
3
|
+
export declare const VALID_GIT_HOOKS: Array<
|
|
4
|
+
'applypatch-msg' |
|
|
5
|
+
'pre-applypatch' |
|
|
6
|
+
'post-applypatch' |
|
|
7
|
+
'pre-commit' |
|
|
8
|
+
'pre-merge-commit' |
|
|
9
|
+
'prepare-commit-msg' |
|
|
10
|
+
'commit-msg' |
|
|
11
|
+
'post-commit' |
|
|
12
|
+
'pre-rebase' |
|
|
13
|
+
'post-checkout' |
|
|
14
|
+
'post-merge' |
|
|
15
|
+
'pre-push' |
|
|
16
|
+
'pre-receive' |
|
|
17
|
+
'update' |
|
|
18
|
+
'proc-receive' |
|
|
19
|
+
'post-receive' |
|
|
20
|
+
'post-update' |
|
|
21
|
+
'reference-transaction' |
|
|
22
|
+
'push-to-checkout' |
|
|
23
|
+
'pre-auto-gc' |
|
|
24
|
+
'post-rewrite' |
|
|
25
|
+
'sendemail-validate' |
|
|
26
|
+
'fsmonitor-watchman' |
|
|
27
|
+
'p4-changelist' |
|
|
28
|
+
'p4-prepare-changelist' |
|
|
29
|
+
'p4-post-changelist' |
|
|
30
|
+
'p4-pre-submit' |
|
|
31
|
+
'post-index-change'
|
|
32
|
+
>;
|
|
33
|
+
export declare const VALID_OPTIONS: Array<'preserveUnused'>;
|
|
34
|
+
export declare const PREPEND_SCRIPT: unknown;
|
|
35
|
+
export declare function getGitProjectRoot(directory: string): string | undefined;
|
|
36
|
+
export declare function checkBunGitHooksInDependencies(projectRootPath: string): boolean;
|
|
37
|
+
declare function _getPackageJson(projectPath): void;
|
|
38
|
+
export declare function setHooksFromConfig(projectRootPath: string, options?: SetHooksFromConfigOptions): void;
|
|
39
|
+
declare function _setHook(hook: string, command: string, projectRoot: string): void;
|
|
40
|
+
export declare function removeHooks(projectRoot: string, verbose): void;
|
|
41
|
+
declare function _removeHook(hook: string, projectRoot, verbose): void;
|
|
42
|
+
declare function _validateHooks(config: Record<string, string>): void;
|
|
43
|
+
declare const gitHooks: {
|
|
44
|
+
PREPEND_SCRIPT: typeof PREPEND_SCRIPT
|
|
45
|
+
setHooksFromConfig: typeof setHooksFromConfig
|
|
46
|
+
removeHooks: typeof removeHooks
|
|
47
|
+
checkBunGitHooksInDependencies: typeof checkBunGitHooksInDependencies
|
|
48
|
+
getProjectRootDirectoryFromNodeModules: typeof getProjectRootDirectoryFromNodeModules
|
|
49
|
+
getGitProjectRoot: typeof getGitProjectRoot
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default gitHooks;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Buffer } from 'node:buffer';
|
|
2
|
+
|
|
3
|
+
export declare interface RawImageData<T> {
|
|
4
|
+
width: number
|
|
5
|
+
height: number
|
|
6
|
+
data: T
|
|
7
|
+
}
|
|
8
|
+
export declare interface BufferRet {
|
|
9
|
+
data: Buffer | Uint8ClampedArray
|
|
10
|
+
width: number
|
|
11
|
+
height: number
|
|
12
|
+
exifBuffer?: ArrayBuffer
|
|
13
|
+
comments?: string[]
|
|
14
|
+
}
|
|
15
|
+
export declare type UintArrRet = ImageData & {
|
|
16
|
+
exifBuffer?: ArrayBuffer
|
|
17
|
+
comments?: string[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ImageData {
|
|
21
|
+
width: number
|
|
22
|
+
height: number
|
|
23
|
+
data: Uint8ClampedArray | Buffer
|
|
24
|
+
colorSpace?: 'srgb'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type BufferLike = Buffer | Uint8Array | ArrayLike<number> | Iterable<number> | ArrayBuffer
|
|
28
|
+
|
|
29
|
+
export interface DecoderOptions {
|
|
30
|
+
useTArray: boolean
|
|
31
|
+
colorTransform?: boolean
|
|
32
|
+
formatAsRGBA?: boolean
|
|
33
|
+
tolerantDecoding?: boolean
|
|
34
|
+
maxResolutionInMP?: number
|
|
35
|
+
maxMemoryUsageInMB?: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type GitHooksConfig = {
|
|
39
|
+
[K in typeof VALID_GIT_HOOKS[number]]?: string
|
|
40
|
+
} & {
|
|
41
|
+
preserveUnused?: boolean | typeof VALID_GIT_HOOKS[number][]
|
|
42
|
+
verbose?: boolean
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface SetHooksFromConfigOptions {
|
|
46
|
+
configFile?: GitHooksConfig
|
|
47
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bun-git-hooks",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.12",
|
|
5
5
|
"description": "A modern, zero dependency tool for managing git hooks in Bun projects.",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -38,19 +38,19 @@
|
|
|
38
38
|
"module": "./dist/index.js",
|
|
39
39
|
"types": "./dist/index.d.ts",
|
|
40
40
|
"bin": {
|
|
41
|
-
"git-hooks": "./dist/cli.js",
|
|
42
|
-
"bun-git-hooks": "./dist/cli.js"
|
|
41
|
+
"git-hooks": "./dist/bin/cli.js",
|
|
42
|
+
"bun-git-hooks": "./dist/bin/cli.js"
|
|
43
43
|
},
|
|
44
44
|
"files": ["README.md", "dist"],
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "bun build.ts && bun run compile",
|
|
47
|
-
"compile": "bun build ./bin/cli.ts --compile --minify --outfile
|
|
47
|
+
"compile": "bun build ./bin/cli.ts --compile --minify --outfile bin/git-hooks",
|
|
48
48
|
"compile:all": "bun run compile:linux-x64 && bun run compile:linux-arm64 && bun run compile:windows-x64 && bun run compile:darwin-x64 && bun run compile:darwin-arm64",
|
|
49
|
-
"compile:linux-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-x64 --outfile
|
|
50
|
-
"compile:linux-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-arm64 --outfile
|
|
51
|
-
"compile:windows-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-windows-x64 --outfile
|
|
52
|
-
"compile:darwin-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-x64 --outfile
|
|
53
|
-
"compile:darwin-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-arm64 --outfile
|
|
49
|
+
"compile:linux-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-x64 --outfile bin/git-hooks-linux-x64",
|
|
50
|
+
"compile:linux-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-linux-arm64 --outfile bin/git-hooks-linux-arm64",
|
|
51
|
+
"compile:windows-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-windows-x64 --outfile bin/git-hooks-windows-x64.exe",
|
|
52
|
+
"compile:darwin-x64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-x64 --outfile bin/git-hooks-darwin-x64",
|
|
53
|
+
"compile:darwin-arm64": "bun build ./bin/cli.ts --compile --minify --target=bun-darwin-arm64 --outfile bin/git-hooks-darwin-arm64",
|
|
54
54
|
"postinstall": "bun ./scripts/postinstall.ts",
|
|
55
55
|
"uninstall": "bun ./scripts/uninstall.ts",
|
|
56
56
|
"lint": "bunx --bun eslint .",
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
"typecheck": "bun --bun tsc --noEmit",
|
|
67
67
|
"zip": "bun run zip:all",
|
|
68
68
|
"zip:all": "bun run zip:linux-x64 && bun run zip:linux-arm64 && bun run zip:windows-x64 && bun run zip:darwin-x64 && bun run zip:darwin-arm64",
|
|
69
|
-
"zip:linux-x64": "zip -j
|
|
70
|
-
"zip:linux-arm64": "zip -j
|
|
71
|
-
"zip:windows-x64": "zip -j
|
|
72
|
-
"zip:darwin-x64": "zip -j
|
|
73
|
-
"zip:darwin-arm64": "zip -j
|
|
69
|
+
"zip:linux-x64": "zip -j bin/git-hooks-linux-x64.zip bin/git-hooks-linux-x64",
|
|
70
|
+
"zip:linux-arm64": "zip -j bin/git-hooks-linux-arm64.zip bin/git-hooks-linux-arm64",
|
|
71
|
+
"zip:windows-x64": "zip -j bin/git-hooks-windows-x64.zip bin/git-hooks-windows-x64.exe",
|
|
72
|
+
"zip:darwin-x64": "zip -j bin/git-hooks-darwin-x64.zip bin/git-hooks-darwin-x64",
|
|
73
|
+
"zip:darwin-arm64": "zip -j bin/git-hooks-darwin-arm64.zip bin/git-hooks-darwin-arm64"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@iconify-json/carbon": "^1.2.8",
|
package/dist/cli.js
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/git-hooks-linux-x64
DELETED
|
Binary file
|
|
Binary file
|