zen-gitsync 1.5.2 → 1.5.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/package.json +1 -1
- package/src/gitCommit.js +4 -3
- package/src/utils/index.js +601 -596
package/package.json
CHANGED
package/src/gitCommit.js
CHANGED
|
@@ -28,9 +28,10 @@ function startCountdown(interval) {
|
|
|
28
28
|
const duration = formatDuration(remaining);
|
|
29
29
|
|
|
30
30
|
const message = [
|
|
31
|
-
chalk.green.bold('
|
|
32
|
-
chalk.
|
|
33
|
-
chalk.
|
|
31
|
+
`🕒 ${chalk.green.bold('倒计时')}`,
|
|
32
|
+
`工作目录: ${chalk.green(getCwd())}`,
|
|
33
|
+
`下次提交: ${chalk.blue(formattedTime)}`,
|
|
34
|
+
`剩余时间: ${chalk.yellow(duration)}`,
|
|
34
35
|
chalk.dim('按 Ctrl+C 终止进程')
|
|
35
36
|
].join('\n');
|
|
36
37
|
|
package/src/utils/index.js
CHANGED
|
@@ -1,596 +1,601 @@
|
|
|
1
|
-
// const chalk = require('chalk');
|
|
2
|
-
// const boxen = require('boxen');
|
|
3
|
-
// const message = chalk.blue('git diff') + '\n' +
|
|
4
|
-
// chalk.red('- line1') + '\n' +
|
|
5
|
-
// chalk.green('+ line2') + '\n' +
|
|
6
|
-
// chalk.cyan('@@ line diff @@');
|
|
7
|
-
//
|
|
8
|
-
// const options = {
|
|
9
|
-
// padding: 1,
|
|
10
|
-
// margin: 1,
|
|
11
|
-
// borderStyle: 'round', // 可以选择 'single', 'double', 'round' 等边框样式
|
|
12
|
-
// borderColor: 'yellow'
|
|
13
|
-
// };
|
|
14
|
-
//
|
|
15
|
-
// const boxedMessage = boxen(message, options);
|
|
16
|
-
// console.log(boxedMessage);
|
|
17
|
-
import stringWidth from 'string-width';
|
|
18
|
-
import Table from 'cli-table3';
|
|
19
|
-
import chalk from 'chalk';
|
|
20
|
-
import boxen from "boxen";
|
|
21
|
-
import {exec, execSync} from 'child_process'
|
|
22
|
-
import os from 'os'
|
|
23
|
-
import ora from "ora";
|
|
24
|
-
import readline from 'readline'
|
|
25
|
-
import path from 'path'
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const printTableWithHeaderUnderline = (head, content, style) => {
|
|
29
|
-
// 获取终端的列数(宽度)
|
|
30
|
-
const terminalWidth = process.stdout.columns;
|
|
31
|
-
|
|
32
|
-
// 计算表格的宽度,保证至少有 2 个字符留给边框
|
|
33
|
-
const tableWidth = terminalWidth - 2; // 左右边框和分隔符的宽度
|
|
34
|
-
|
|
35
|
-
// 计算每列的宽度
|
|
36
|
-
const colWidths = [tableWidth]; // 只有一列,因此宽度设置为终端宽度
|
|
37
|
-
|
|
38
|
-
if (!style) {
|
|
39
|
-
style = {
|
|
40
|
-
// head: ['cyan'], // 表头文字颜色为cyan
|
|
41
|
-
border: [chalk.reset()], // 边框颜色
|
|
42
|
-
compact: true, // 启用紧凑模式,去掉不必要的空白
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
// 创建表格实例
|
|
46
|
-
const table = new Table({
|
|
47
|
-
head: [head], // 只有一个表头
|
|
48
|
-
colWidths, // 使用动态计算的列宽
|
|
49
|
-
style: style,
|
|
50
|
-
wordWrap: true, // 启用自动换行
|
|
51
|
-
// chars: {
|
|
52
|
-
// 'top': '─',
|
|
53
|
-
// 'top-mid': '┬',
|
|
54
|
-
// 'bottom': '─',
|
|
55
|
-
// 'mid': '─',
|
|
56
|
-
// 'left': '│',
|
|
57
|
-
// 'right': '│'
|
|
58
|
-
// },
|
|
59
|
-
// chars: {
|
|
60
|
-
// 'top': '═', // 顶部边框使用长横线
|
|
61
|
-
// 'top-mid': '╤', // 顶部连接符
|
|
62
|
-
// 'top-left': '╔', // 左上角
|
|
63
|
-
// 'top-right': '╗', // 右上角
|
|
64
|
-
// 'bottom': '═', // 底部边框
|
|
65
|
-
// 'bottom-mid': '╧', // 底部连接符
|
|
66
|
-
// 'bottom-left': '╚',// 左下角
|
|
67
|
-
// 'bottom-right': '╝',// 右下角
|
|
68
|
-
// 'left': '║', // 左边框
|
|
69
|
-
// 'left-mid': '╟', // 左连接符
|
|
70
|
-
// 'mid': '═', // 中间分隔符
|
|
71
|
-
// 'mid-mid': '╪', // 中间连接符
|
|
72
|
-
// 'right': '║', // 右边框
|
|
73
|
-
// 'right-mid': '╢', // 右连接符
|
|
74
|
-
// 'middle': '│' // 中间内容的边界
|
|
75
|
-
// }
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// 向表格中添加不同颜色的行
|
|
79
|
-
// eg:
|
|
80
|
-
// table.push(
|
|
81
|
-
// [chalk.red('张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三')],
|
|
82
|
-
// [chalk.green('李四')],
|
|
83
|
-
// );
|
|
84
|
-
content.forEach(item => {
|
|
85
|
-
table.push([item]);
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
console.log(table.toString()); // 输出表格
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// printTableWithHeaderUnderline();
|
|
92
|
-
|
|
93
|
-
const colors = [
|
|
94
|
-
'\x1b[31m', // 红色
|
|
95
|
-
'\x1b[32m', // 绿色
|
|
96
|
-
'\x1b[33m', // 黄色
|
|
97
|
-
'\x1b[34m', // 蓝色
|
|
98
|
-
'\x1b[35m', // 紫色
|
|
99
|
-
'\x1b[36m', // 青色
|
|
100
|
-
];
|
|
101
|
-
|
|
102
|
-
function getRandomColor() {
|
|
103
|
-
return `\x1b[0m`;
|
|
104
|
-
// const randomIndex = Math.floor(Math.random() * colors.length);
|
|
105
|
-
// return colors[randomIndex];
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function resetColor() {
|
|
109
|
-
return '\x1b[0m';
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const calcColor = (commandLine, str) => {
|
|
113
|
-
let color = 'reset'
|
|
114
|
-
switch (commandLine) {
|
|
115
|
-
case 'git status':
|
|
116
|
-
if (str.startsWith('\t')) {
|
|
117
|
-
color = 'red'
|
|
118
|
-
if (str.startsWith('new file:')) {
|
|
119
|
-
color = 'red'
|
|
120
|
-
}
|
|
121
|
-
if (str.startsWith('modified:')) {
|
|
122
|
-
color = 'green'
|
|
123
|
-
}
|
|
124
|
-
if (str.startsWith('deleted:')) {
|
|
125
|
-
color = 'red'
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
break;
|
|
129
|
-
case 'git diff':
|
|
130
|
-
// if (str.startsWith('---')) {
|
|
131
|
-
// color = 'red'
|
|
132
|
-
// }
|
|
133
|
-
// if (str.startsWith('+++')) {
|
|
134
|
-
// color = 'green'
|
|
135
|
-
// }
|
|
136
|
-
// if (str.startsWith('@@ ')) {
|
|
137
|
-
// color = 'cyan'
|
|
138
|
-
// }
|
|
139
|
-
break;
|
|
140
|
-
}
|
|
141
|
-
return color
|
|
142
|
-
}
|
|
143
|
-
const tableLog = (commandLine, content, type) => {
|
|
144
|
-
let handle_commandLine = `> ${commandLine}`
|
|
145
|
-
let head = chalk.bold.blue(handle_commandLine)
|
|
146
|
-
let style = {
|
|
147
|
-
// head: ['cyan'], // 表头文字颜色为cyan
|
|
148
|
-
border: [chalk.reset()], // 边框颜色
|
|
149
|
-
compact: true, // 启用紧凑模式,去掉不必要的空白
|
|
150
|
-
}
|
|
151
|
-
switch (type) {
|
|
152
|
-
case 'error':
|
|
153
|
-
style.head = ['red'];
|
|
154
|
-
content = content.toString().split('\n')
|
|
155
|
-
head = chalk.bold.red(handle_commandLine)
|
|
156
|
-
break;
|
|
157
|
-
case 'common':
|
|
158
|
-
style.head = ['blue'];
|
|
159
|
-
content = content.split('\n')
|
|
160
|
-
break;
|
|
161
|
-
default:
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
content = content.map(item => {
|
|
165
|
-
let fontColor = calcColor(commandLine, item)
|
|
166
|
-
let row = item.replaceAll('\t', ' ')
|
|
167
|
-
return chalk[fontColor](row)
|
|
168
|
-
})
|
|
169
|
-
|
|
170
|
-
printTableWithHeaderUnderline(head, content, style)
|
|
171
|
-
}
|
|
172
|
-
const coloredLog = (...args) => {
|
|
173
|
-
// 获取参数内容
|
|
174
|
-
const commandLine = args[0];
|
|
175
|
-
const content = args[1];
|
|
176
|
-
const type = args[2] || 'common';
|
|
177
|
-
// console.log(`commandLine ==> `, commandLine)
|
|
178
|
-
// console.log(`content ==> `, content)
|
|
179
|
-
// console.log(`type ==> `, type)
|
|
180
|
-
tableLog(commandLine, content, type);
|
|
181
|
-
}
|
|
182
|
-
const errorLog = (commandLine, content) => {
|
|
183
|
-
// 使用 boxen 绘制带边框的消息
|
|
184
|
-
let msg = ` FAIL ${commandLine}
|
|
185
|
-
content: ${content} `
|
|
186
|
-
const message = chalk.red.bold(msg);
|
|
187
|
-
const box = boxen(message);
|
|
188
|
-
console.log(box); // 打印带有边框的消息
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
function execSyncGitCommand(command, options = {}) {
|
|
192
|
-
let {encoding = 'utf-8', maxBuffer = 30 * 1024 * 1024, head = command, log = true} = options
|
|
193
|
-
try {
|
|
194
|
-
let cwd = getCwd()
|
|
195
|
-
const output = execSync(command, {
|
|
196
|
-
env: {
|
|
197
|
-
...process.env,
|
|
198
|
-
// LANG: 'en_US.UTF-8', // Linux/macOS
|
|
199
|
-
// LC_ALL: 'en_US.UTF-8', // Linux/macOS
|
|
200
|
-
GIT_CONFIG_PARAMETERS: "'core.quotepath=false'" // 关闭路径转义
|
|
201
|
-
}, encoding, maxBuffer, cwd
|
|
202
|
-
})
|
|
203
|
-
if (options.spinner) {
|
|
204
|
-
options.spinner.stop();
|
|
205
|
-
}
|
|
206
|
-
let result = output.trim()
|
|
207
|
-
log && coloredLog(head, result)
|
|
208
|
-
return result
|
|
209
|
-
} catch (e) {
|
|
210
|
-
// console.log(`执行命令出错 ==> `, command, e)
|
|
211
|
-
log && coloredLog(command, e, 'error')
|
|
212
|
-
throw new Error(e)
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
function execGitCommand(command, options = {}) {
|
|
217
|
-
return new Promise((resolve, reject) => {
|
|
218
|
-
let {encoding = 'utf-8', maxBuffer = 30 * 1024 * 1024, head = command, log = true} = options
|
|
219
|
-
let cwd = getCwd()
|
|
220
|
-
|
|
221
|
-
// setTimeout(() => {
|
|
222
|
-
exec(command, {
|
|
223
|
-
env: {
|
|
224
|
-
...process.env,
|
|
225
|
-
// LANG: 'en_US.UTF-8', // Linux/macOS
|
|
226
|
-
// LC_ALL: 'en_US.UTF-8', // Linux/macOS
|
|
227
|
-
GIT_CONFIG_PARAMETERS: "'core.quotepath=false'" // 关闭路径转义
|
|
228
|
-
},
|
|
229
|
-
encoding,
|
|
230
|
-
maxBuffer,
|
|
231
|
-
cwd
|
|
232
|
-
}, (error, stdout, stderr) => {
|
|
233
|
-
if (options.spinner) {
|
|
234
|
-
options.spinner.stop();
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (stdout) {
|
|
238
|
-
log && coloredLog(head, stdout)
|
|
239
|
-
}
|
|
240
|
-
if (stderr) {
|
|
241
|
-
log && coloredLog(head, stderr)
|
|
242
|
-
}
|
|
243
|
-
if (error) {
|
|
244
|
-
log && coloredLog(head, error, 'error')
|
|
245
|
-
reject(error)
|
|
246
|
-
return
|
|
247
|
-
}
|
|
248
|
-
resolve({
|
|
249
|
-
stdout,
|
|
250
|
-
stderr
|
|
251
|
-
})
|
|
252
|
-
})
|
|
253
|
-
// }, 1000)
|
|
254
|
-
|
|
255
|
-
})
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const getCwd = () => {
|
|
259
|
-
const cwdArg = process.argv.find(arg => arg.startsWith('--path')) || process.argv.find(arg => arg.startsWith('--cwd'));
|
|
260
|
-
if (cwdArg) {
|
|
261
|
-
// console.log(`cwdArg ==> `, cwdArg)
|
|
262
|
-
const [, value] = cwdArg.split('=')
|
|
263
|
-
// console.log(`value ==> `, value)
|
|
264
|
-
return value || process.cwd()
|
|
265
|
-
}
|
|
266
|
-
return process.cwd()
|
|
267
|
-
}
|
|
268
|
-
const judgePlatform = () => {
|
|
269
|
-
// 判断是否是 Windows 系统
|
|
270
|
-
if (os.platform() === 'win32') {
|
|
271
|
-
try {
|
|
272
|
-
// 设置终端字符编码为 UTF-8
|
|
273
|
-
execSync('chcp 65001');
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
-
|
|
290
|
-
--
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
--
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
g
|
|
304
|
-
g
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
Linux/macOS:
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
process
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
//
|
|
463
|
-
|
|
464
|
-
head: '
|
|
465
|
-
log: false
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
//
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
//
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
//
|
|
485
|
-
//
|
|
486
|
-
//
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
1
|
+
// const chalk = require('chalk');
|
|
2
|
+
// const boxen = require('boxen');
|
|
3
|
+
// const message = chalk.blue('git diff') + '\n' +
|
|
4
|
+
// chalk.red('- line1') + '\n' +
|
|
5
|
+
// chalk.green('+ line2') + '\n' +
|
|
6
|
+
// chalk.cyan('@@ line diff @@');
|
|
7
|
+
//
|
|
8
|
+
// const options = {
|
|
9
|
+
// padding: 1,
|
|
10
|
+
// margin: 1,
|
|
11
|
+
// borderStyle: 'round', // 可以选择 'single', 'double', 'round' 等边框样式
|
|
12
|
+
// borderColor: 'yellow'
|
|
13
|
+
// };
|
|
14
|
+
//
|
|
15
|
+
// const boxedMessage = boxen(message, options);
|
|
16
|
+
// console.log(boxedMessage);
|
|
17
|
+
import stringWidth from 'string-width';
|
|
18
|
+
import Table from 'cli-table3';
|
|
19
|
+
import chalk from 'chalk';
|
|
20
|
+
import boxen from "boxen";
|
|
21
|
+
import {exec, execSync} from 'child_process'
|
|
22
|
+
import os from 'os'
|
|
23
|
+
import ora from "ora";
|
|
24
|
+
import readline from 'readline'
|
|
25
|
+
import path from 'path'
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
const printTableWithHeaderUnderline = (head, content, style) => {
|
|
29
|
+
// 获取终端的列数(宽度)
|
|
30
|
+
const terminalWidth = process.stdout.columns;
|
|
31
|
+
|
|
32
|
+
// 计算表格的宽度,保证至少有 2 个字符留给边框
|
|
33
|
+
const tableWidth = terminalWidth - 2; // 左右边框和分隔符的宽度
|
|
34
|
+
|
|
35
|
+
// 计算每列的宽度
|
|
36
|
+
const colWidths = [tableWidth]; // 只有一列,因此宽度设置为终端宽度
|
|
37
|
+
|
|
38
|
+
if (!style) {
|
|
39
|
+
style = {
|
|
40
|
+
// head: ['cyan'], // 表头文字颜色为cyan
|
|
41
|
+
border: [chalk.reset()], // 边框颜色
|
|
42
|
+
compact: true, // 启用紧凑模式,去掉不必要的空白
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// 创建表格实例
|
|
46
|
+
const table = new Table({
|
|
47
|
+
head: [head], // 只有一个表头
|
|
48
|
+
colWidths, // 使用动态计算的列宽
|
|
49
|
+
style: style,
|
|
50
|
+
wordWrap: true, // 启用自动换行
|
|
51
|
+
// chars: {
|
|
52
|
+
// 'top': '─',
|
|
53
|
+
// 'top-mid': '┬',
|
|
54
|
+
// 'bottom': '─',
|
|
55
|
+
// 'mid': '─',
|
|
56
|
+
// 'left': '│',
|
|
57
|
+
// 'right': '│'
|
|
58
|
+
// },
|
|
59
|
+
// chars: {
|
|
60
|
+
// 'top': '═', // 顶部边框使用长横线
|
|
61
|
+
// 'top-mid': '╤', // 顶部连接符
|
|
62
|
+
// 'top-left': '╔', // 左上角
|
|
63
|
+
// 'top-right': '╗', // 右上角
|
|
64
|
+
// 'bottom': '═', // 底部边框
|
|
65
|
+
// 'bottom-mid': '╧', // 底部连接符
|
|
66
|
+
// 'bottom-left': '╚',// 左下角
|
|
67
|
+
// 'bottom-right': '╝',// 右下角
|
|
68
|
+
// 'left': '║', // 左边框
|
|
69
|
+
// 'left-mid': '╟', // 左连接符
|
|
70
|
+
// 'mid': '═', // 中间分隔符
|
|
71
|
+
// 'mid-mid': '╪', // 中间连接符
|
|
72
|
+
// 'right': '║', // 右边框
|
|
73
|
+
// 'right-mid': '╢', // 右连接符
|
|
74
|
+
// 'middle': '│' // 中间内容的边界
|
|
75
|
+
// }
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// 向表格中添加不同颜色的行
|
|
79
|
+
// eg:
|
|
80
|
+
// table.push(
|
|
81
|
+
// [chalk.red('张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三张三')],
|
|
82
|
+
// [chalk.green('李四')],
|
|
83
|
+
// );
|
|
84
|
+
content.forEach(item => {
|
|
85
|
+
table.push([item]);
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
console.log(table.toString()); // 输出表格
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// printTableWithHeaderUnderline();
|
|
92
|
+
|
|
93
|
+
const colors = [
|
|
94
|
+
'\x1b[31m', // 红色
|
|
95
|
+
'\x1b[32m', // 绿色
|
|
96
|
+
'\x1b[33m', // 黄色
|
|
97
|
+
'\x1b[34m', // 蓝色
|
|
98
|
+
'\x1b[35m', // 紫色
|
|
99
|
+
'\x1b[36m', // 青色
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
function getRandomColor() {
|
|
103
|
+
return `\x1b[0m`;
|
|
104
|
+
// const randomIndex = Math.floor(Math.random() * colors.length);
|
|
105
|
+
// return colors[randomIndex];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function resetColor() {
|
|
109
|
+
return '\x1b[0m';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const calcColor = (commandLine, str) => {
|
|
113
|
+
let color = 'reset'
|
|
114
|
+
switch (commandLine) {
|
|
115
|
+
case 'git status':
|
|
116
|
+
if (str.startsWith('\t')) {
|
|
117
|
+
color = 'red'
|
|
118
|
+
if (str.startsWith('new file:')) {
|
|
119
|
+
color = 'red'
|
|
120
|
+
}
|
|
121
|
+
if (str.startsWith('modified:')) {
|
|
122
|
+
color = 'green'
|
|
123
|
+
}
|
|
124
|
+
if (str.startsWith('deleted:')) {
|
|
125
|
+
color = 'red'
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
case 'git diff':
|
|
130
|
+
// if (str.startsWith('---')) {
|
|
131
|
+
// color = 'red'
|
|
132
|
+
// }
|
|
133
|
+
// if (str.startsWith('+++')) {
|
|
134
|
+
// color = 'green'
|
|
135
|
+
// }
|
|
136
|
+
// if (str.startsWith('@@ ')) {
|
|
137
|
+
// color = 'cyan'
|
|
138
|
+
// }
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
return color
|
|
142
|
+
}
|
|
143
|
+
const tableLog = (commandLine, content, type) => {
|
|
144
|
+
let handle_commandLine = `> ${commandLine}`
|
|
145
|
+
let head = chalk.bold.blue(handle_commandLine)
|
|
146
|
+
let style = {
|
|
147
|
+
// head: ['cyan'], // 表头文字颜色为cyan
|
|
148
|
+
border: [chalk.reset()], // 边框颜色
|
|
149
|
+
compact: true, // 启用紧凑模式,去掉不必要的空白
|
|
150
|
+
}
|
|
151
|
+
switch (type) {
|
|
152
|
+
case 'error':
|
|
153
|
+
style.head = ['red'];
|
|
154
|
+
content = content.toString().split('\n')
|
|
155
|
+
head = chalk.bold.red(handle_commandLine)
|
|
156
|
+
break;
|
|
157
|
+
case 'common':
|
|
158
|
+
style.head = ['blue'];
|
|
159
|
+
content = content.split('\n')
|
|
160
|
+
break;
|
|
161
|
+
default:
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
content = content.map(item => {
|
|
165
|
+
let fontColor = calcColor(commandLine, item)
|
|
166
|
+
let row = item.replaceAll('\t', ' ')
|
|
167
|
+
return chalk[fontColor](row)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
printTableWithHeaderUnderline(head, content, style)
|
|
171
|
+
}
|
|
172
|
+
const coloredLog = (...args) => {
|
|
173
|
+
// 获取参数内容
|
|
174
|
+
const commandLine = args[0];
|
|
175
|
+
const content = args[1];
|
|
176
|
+
const type = args[2] || 'common';
|
|
177
|
+
// console.log(`commandLine ==> `, commandLine)
|
|
178
|
+
// console.log(`content ==> `, content)
|
|
179
|
+
// console.log(`type ==> `, type)
|
|
180
|
+
tableLog(commandLine, content, type);
|
|
181
|
+
}
|
|
182
|
+
const errorLog = (commandLine, content) => {
|
|
183
|
+
// 使用 boxen 绘制带边框的消息
|
|
184
|
+
let msg = ` FAIL ${commandLine}
|
|
185
|
+
content: ${content} `
|
|
186
|
+
const message = chalk.red.bold(msg);
|
|
187
|
+
const box = boxen(message);
|
|
188
|
+
console.log(box); // 打印带有边框的消息
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function execSyncGitCommand(command, options = {}) {
|
|
192
|
+
let {encoding = 'utf-8', maxBuffer = 30 * 1024 * 1024, head = command, log = true} = options
|
|
193
|
+
try {
|
|
194
|
+
let cwd = getCwd()
|
|
195
|
+
const output = execSync(command, {
|
|
196
|
+
env: {
|
|
197
|
+
...process.env,
|
|
198
|
+
// LANG: 'en_US.UTF-8', // Linux/macOS
|
|
199
|
+
// LC_ALL: 'en_US.UTF-8', // Linux/macOS
|
|
200
|
+
GIT_CONFIG_PARAMETERS: "'core.quotepath=false'" // 关闭路径转义
|
|
201
|
+
}, encoding, maxBuffer, cwd
|
|
202
|
+
})
|
|
203
|
+
if (options.spinner) {
|
|
204
|
+
options.spinner.stop();
|
|
205
|
+
}
|
|
206
|
+
let result = output.trim()
|
|
207
|
+
log && coloredLog(head, result)
|
|
208
|
+
return result
|
|
209
|
+
} catch (e) {
|
|
210
|
+
// console.log(`执行命令出错 ==> `, command, e)
|
|
211
|
+
log && coloredLog(command, e, 'error')
|
|
212
|
+
throw new Error(e)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function execGitCommand(command, options = {}) {
|
|
217
|
+
return new Promise((resolve, reject) => {
|
|
218
|
+
let {encoding = 'utf-8', maxBuffer = 30 * 1024 * 1024, head = command, log = true} = options
|
|
219
|
+
let cwd = getCwd()
|
|
220
|
+
|
|
221
|
+
// setTimeout(() => {
|
|
222
|
+
exec(command, {
|
|
223
|
+
env: {
|
|
224
|
+
...process.env,
|
|
225
|
+
// LANG: 'en_US.UTF-8', // Linux/macOS
|
|
226
|
+
// LC_ALL: 'en_US.UTF-8', // Linux/macOS
|
|
227
|
+
GIT_CONFIG_PARAMETERS: "'core.quotepath=false'" // 关闭路径转义
|
|
228
|
+
},
|
|
229
|
+
encoding,
|
|
230
|
+
maxBuffer,
|
|
231
|
+
cwd
|
|
232
|
+
}, (error, stdout, stderr) => {
|
|
233
|
+
if (options.spinner) {
|
|
234
|
+
options.spinner.stop();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (stdout) {
|
|
238
|
+
log && coloredLog(head, stdout)
|
|
239
|
+
}
|
|
240
|
+
if (stderr) {
|
|
241
|
+
log && coloredLog(head, stderr)
|
|
242
|
+
}
|
|
243
|
+
if (error) {
|
|
244
|
+
log && coloredLog(head, error, 'error')
|
|
245
|
+
reject(error)
|
|
246
|
+
return
|
|
247
|
+
}
|
|
248
|
+
resolve({
|
|
249
|
+
stdout,
|
|
250
|
+
stderr
|
|
251
|
+
})
|
|
252
|
+
})
|
|
253
|
+
// }, 1000)
|
|
254
|
+
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const getCwd = () => {
|
|
259
|
+
const cwdArg = process.argv.find(arg => arg.startsWith('--path')) || process.argv.find(arg => arg.startsWith('--cwd'));
|
|
260
|
+
if (cwdArg) {
|
|
261
|
+
// console.log(`cwdArg ==> `, cwdArg)
|
|
262
|
+
const [, value] = cwdArg.split('=')
|
|
263
|
+
// console.log(`value ==> `, value)
|
|
264
|
+
return value || process.cwd()
|
|
265
|
+
}
|
|
266
|
+
return process.cwd()
|
|
267
|
+
}
|
|
268
|
+
const judgePlatform = () => {
|
|
269
|
+
// 判断是否是 Windows 系统
|
|
270
|
+
if (os.platform() === 'win32') {
|
|
271
|
+
try {
|
|
272
|
+
// 设置终端字符编码为 UTF-8
|
|
273
|
+
execSync('chcp 65001');
|
|
274
|
+
execSync('git config --global core.autocrlf true');
|
|
275
|
+
// 设置Git不转义路径(避免中文显示为八进制)
|
|
276
|
+
execSync('git config --global core.quotepath false');
|
|
277
|
+
} catch (e) {
|
|
278
|
+
console.error('设置字符编码失败:', e.message);
|
|
279
|
+
}
|
|
280
|
+
}else{
|
|
281
|
+
execSync('git config --global core.autocrlf input');
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
const showHelp = () => {
|
|
285
|
+
const helpMessage = `
|
|
286
|
+
Usage: g [options]
|
|
287
|
+
|
|
288
|
+
Options:
|
|
289
|
+
-h, --help Show this help message
|
|
290
|
+
--set-default-message=<msg> Set default commit message
|
|
291
|
+
get-config Show current configuration
|
|
292
|
+
-y Auto commit with default message
|
|
293
|
+
-m <message> Commit message (use quotes if message contains spaces)
|
|
294
|
+
-m=<message> Commit message (use this form without spaces around '=')
|
|
295
|
+
--path=<path> Set custom working directory
|
|
296
|
+
--cwd=<path> Set custom working directory
|
|
297
|
+
--interval=<seconds> Set interval time for automatic commits (in seconds)
|
|
298
|
+
log Show git commit logs
|
|
299
|
+
--n=<number> Number of commits to show with --log
|
|
300
|
+
--no-diff Skip displaying git diff
|
|
301
|
+
|
|
302
|
+
Example:
|
|
303
|
+
g -m "Initial commit" Commit with a custom message
|
|
304
|
+
g -m=Fix-bug Commit with a custom message (no spaces around '=')
|
|
305
|
+
g -y Auto commit with the default message
|
|
306
|
+
g -y --interval=600 Commit every 10 minutes (600 seconds)
|
|
307
|
+
g --path=/path/to/repo Specify a custom working directory
|
|
308
|
+
g log Show recent commit logs
|
|
309
|
+
g log --n=5 Show the last 5 commits with --log
|
|
310
|
+
|
|
311
|
+
Add auto submit in package.json:
|
|
312
|
+
"scripts": {
|
|
313
|
+
"g:y": "g -y"
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
Run in the background across platforms:
|
|
317
|
+
Windows:
|
|
318
|
+
start /min cmd /k "g -y --path=your-folder --interval=600"
|
|
319
|
+
|
|
320
|
+
Linux/macOS:
|
|
321
|
+
nohup g -y --path=your-folder --interval=600 > git-autocommit.log 2>&1 &
|
|
322
|
+
|
|
323
|
+
Stop all monitoring processes:
|
|
324
|
+
Windows: Terminate the Node.js process in the Task Manager.
|
|
325
|
+
Linux/macOS:
|
|
326
|
+
pkill -f "g -y" # Terminate all auto-commit processes
|
|
327
|
+
ps aux | grep "g -y" # Find the specific process ID
|
|
328
|
+
kill [PID] # Terminate the specified process
|
|
329
|
+
`;
|
|
330
|
+
|
|
331
|
+
console.log(helpMessage);
|
|
332
|
+
process.exit();
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
function judgeLog() {
|
|
336
|
+
const logArg = process.argv.find(arg => arg === 'log');
|
|
337
|
+
if (logArg) {
|
|
338
|
+
printGitLog(); // 如果有 log 参数,打印 Git 提交记录
|
|
339
|
+
// 打印完成后退出
|
|
340
|
+
process.exit();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function judgeHelp() {
|
|
345
|
+
if (process.argv.includes('-h') || process.argv.includes('--help')) {
|
|
346
|
+
showHelp();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
async function printGitLog() {
|
|
351
|
+
let n = 20;
|
|
352
|
+
let logArg = process.argv.find(arg => arg.startsWith('--n='));
|
|
353
|
+
if (logArg) {
|
|
354
|
+
n = parseInt(logArg.split('=')[1], 10);
|
|
355
|
+
}
|
|
356
|
+
const logCommand = `git log -n ${n} --pretty=format:"%C(green)%h%C(reset) | %C(cyan)%an%C(reset) | %C(yellow)%ad%C(reset) | %C(blue)%D%C(reset) | %C(magenta)%s%C(reset)" --date=format:"%Y-%m-%d %H:%M" --graph --decorate --color`
|
|
357
|
+
try {
|
|
358
|
+
const logOutput = execSyncGitCommand(logCommand, {
|
|
359
|
+
head: `git log`
|
|
360
|
+
});
|
|
361
|
+
} catch (error) {
|
|
362
|
+
console.error('无法获取 Git 提交记录:', error.message);
|
|
363
|
+
}
|
|
364
|
+
// 打印完成后退出
|
|
365
|
+
process.exit();
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function exec_exit(exit) {
|
|
369
|
+
if (exit) {
|
|
370
|
+
process.exit()
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function judgeUnmerged(statusOutput) {
|
|
375
|
+
const hasUnmerged = statusOutput.includes('You have unmerged paths');
|
|
376
|
+
if (hasUnmerged) {
|
|
377
|
+
errorLog('错误', '存在未合并的文件,请先解决冲突')
|
|
378
|
+
process.exit(1);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function exec_push({exit, commitMessage}) {
|
|
383
|
+
// 执行 git push
|
|
384
|
+
// execSyncGitCommand(`git push`);
|
|
385
|
+
return new Promise((resolve, reject) => {
|
|
386
|
+
const spinner = ora('正在推送代码...').start();
|
|
387
|
+
execGitCommand('git push', {
|
|
388
|
+
spinner
|
|
389
|
+
}).then(({stdout, stderr}) => {
|
|
390
|
+
printCommitLog({commitMessage})
|
|
391
|
+
resolve({stdout, stderr})
|
|
392
|
+
})
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function printCommitLog({commitMessage}) {
|
|
397
|
+
try {
|
|
398
|
+
// 获取项目名称(取git仓库根目录名)
|
|
399
|
+
const projectRoot = execSyncGitCommand('git rev-parse --show-toplevel', {log: false});
|
|
400
|
+
const projectName = chalk.blueBright(path.basename(projectRoot.trim()));
|
|
401
|
+
|
|
402
|
+
// 获取当前提交hash(取前7位)
|
|
403
|
+
const commitHash = execSyncGitCommand('git rev-parse --short HEAD', {log: false}).trim();
|
|
404
|
+
const hashDisplay = chalk.yellow(commitHash);
|
|
405
|
+
|
|
406
|
+
// 获取分支信息
|
|
407
|
+
const branch = execSyncGitCommand('git branch --show-current', {log: false}).trim();
|
|
408
|
+
const branchDisplay = chalk.magenta(branch);
|
|
409
|
+
|
|
410
|
+
// 构建信息内容
|
|
411
|
+
const message = [
|
|
412
|
+
`${chalk.cyan.bold('Project:')} ${projectName}`,
|
|
413
|
+
`${chalk.cyan.bold('Commit:')} ${hashDisplay} ${chalk.dim('on')} ${branchDisplay}`,
|
|
414
|
+
`${chalk.cyan.bold('Message:')} ${chalk.reset(commitMessage)}`,
|
|
415
|
+
`${chalk.cyan.bold('Time:')} ${new Date().toLocaleString()}`
|
|
416
|
+
].join('\n');
|
|
417
|
+
|
|
418
|
+
// 使用boxen创建装饰框
|
|
419
|
+
const box = boxen(message, {
|
|
420
|
+
padding: 1,
|
|
421
|
+
margin: 1,
|
|
422
|
+
borderStyle: 'round',
|
|
423
|
+
borderColor: 'green',
|
|
424
|
+
title: chalk.bold.green('✅ COMMIT SUCCESS'),
|
|
425
|
+
titleAlignment: 'center',
|
|
426
|
+
float: 'left',
|
|
427
|
+
textAlignment: 'left'
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
console.log(box);
|
|
431
|
+
} catch (error) {
|
|
432
|
+
// 异常处理
|
|
433
|
+
const errorBox = boxen(chalk.red(`Failed to get commit details: ${error.message}`), {
|
|
434
|
+
borderColor: 'red',
|
|
435
|
+
padding: 1
|
|
436
|
+
});
|
|
437
|
+
console.log(errorBox);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
async function execPull() {
|
|
442
|
+
try {
|
|
443
|
+
// 检查是否需要拉取更新
|
|
444
|
+
const spinner = ora('正在拉取代码...').start();
|
|
445
|
+
await execGitCommand('git pull', {
|
|
446
|
+
spinner
|
|
447
|
+
})
|
|
448
|
+
} catch (e) {
|
|
449
|
+
console.log(chalk.yellow('⚠️ 拉取远程更新合并失败,可能存在冲突,请手动处理'));
|
|
450
|
+
throw Error(e)
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function delay(timeout) {
|
|
455
|
+
return new Promise(resolve => setTimeout(resolve, timeout));
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
async function judgeRemote() {
|
|
459
|
+
const spinner = ora('正在检查远程更新...').start();
|
|
460
|
+
try {
|
|
461
|
+
// 检查是否有远程更新
|
|
462
|
+
// 先获取远程最新状态
|
|
463
|
+
await execGitCommand('git remote update', {
|
|
464
|
+
head: 'Fetching remote updates',
|
|
465
|
+
log: false
|
|
466
|
+
});
|
|
467
|
+
// 检查是否需要 pull
|
|
468
|
+
const res = await execGitCommand('git rev-list HEAD..@{u} --count', {
|
|
469
|
+
head: 'Checking if behind remote',
|
|
470
|
+
log: false
|
|
471
|
+
});
|
|
472
|
+
const behindCount = res.stdout.trim()
|
|
473
|
+
const { green, black, bgGreen, white } = chalk;
|
|
474
|
+
// 如果本地落后于远程
|
|
475
|
+
if (parseInt(behindCount) > 0) {
|
|
476
|
+
try {
|
|
477
|
+
spinner.stop();
|
|
478
|
+
// const spinner_pull = ora('发现远程更新,正在拉取...').start();
|
|
479
|
+
await execPull()
|
|
480
|
+
|
|
481
|
+
// // 尝试使用 --ff-only 拉取更新
|
|
482
|
+
// const res = await execGitCommand('git pull --ff-only', {
|
|
483
|
+
// spinner: spinner_pull,
|
|
484
|
+
// head: 'Pulling updates'
|
|
485
|
+
// });
|
|
486
|
+
// console.log(
|
|
487
|
+
// bgGreen.white.bold(' SYNC ') +
|
|
488
|
+
// green` ➔ ` +
|
|
489
|
+
// chalk.blue.bold('远程仓库已同步') +
|
|
490
|
+
// green(' ✔')
|
|
491
|
+
// );
|
|
492
|
+
const message = '已成功同步远程更新'.split('').map((char, i) =>
|
|
493
|
+
chalk.rgb(0, 255 - i*10, 0)(char)
|
|
494
|
+
).join('');
|
|
495
|
+
|
|
496
|
+
console.log(chalk.bold(`✅ ${message}`));
|
|
497
|
+
} catch (pullError) {
|
|
498
|
+
// // 如果 --ff-only 拉取失败,尝试普通的 git pull
|
|
499
|
+
// console.log(chalk.yellow('⚠️ 无法快进合并,尝试普通合并...'));
|
|
500
|
+
// await this.execPull()
|
|
501
|
+
throw new Error(pullError)
|
|
502
|
+
}
|
|
503
|
+
} else {
|
|
504
|
+
spinner.stop();
|
|
505
|
+
const message = '本地已是最新'.split('').map((char, i) =>
|
|
506
|
+
chalk.rgb(0, 255 - i*10, 0)(char)
|
|
507
|
+
).join('');
|
|
508
|
+
console.log(chalk.bold(`✅ ${message}`));
|
|
509
|
+
}
|
|
510
|
+
} catch (e) {
|
|
511
|
+
// console.log(`e ==> `, e)
|
|
512
|
+
spinner.stop();
|
|
513
|
+
throw new Error(e)
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
async function execDiff() {
|
|
518
|
+
const no_diff = process.argv.find(arg => arg.startsWith('--no-diff'))
|
|
519
|
+
if (!no_diff) {
|
|
520
|
+
await execGitCommand('git diff --color=always', {
|
|
521
|
+
head: `git diff`
|
|
522
|
+
})
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
async function execAddAndCommit({statusOutput, commitMessage, exit}) {
|
|
527
|
+
// 检查 -m 参数(提交信息)
|
|
528
|
+
const commitMessageArg = process.argv.find(arg => arg.startsWith('-m'));
|
|
529
|
+
if (commitMessageArg) {
|
|
530
|
+
if (commitMessageArg.includes('=')) {
|
|
531
|
+
// 处理 -m=<message> 的情况
|
|
532
|
+
commitMessage = commitMessageArg.split('=')[1]?.replace(/^['"]|['"]$/g, '');
|
|
533
|
+
} else {
|
|
534
|
+
// 处理 -m <message> 的情况
|
|
535
|
+
const index = process.argv.indexOf(commitMessageArg);
|
|
536
|
+
if (index !== -1 && process.argv[index + 1]) {
|
|
537
|
+
commitMessage = process.argv[index + 1]?.replace(/^['"]|['"]$/g, '');
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// 检查命令行参数,判断是否有 -y 参数
|
|
543
|
+
const autoCommit = process.argv.includes('-y');
|
|
544
|
+
|
|
545
|
+
if (!autoCommit && !commitMessageArg) {
|
|
546
|
+
// 如果没有 -y 参数,则等待用户输入提交信息
|
|
547
|
+
const rl = readline.createInterface({
|
|
548
|
+
input: process.stdin,
|
|
549
|
+
output: process.stdout
|
|
550
|
+
})
|
|
551
|
+
|
|
552
|
+
function rlPromisify(fn) {
|
|
553
|
+
return async (...args) => {
|
|
554
|
+
return new Promise((resolve, reject) => fn(...args, resolve, reject))
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const question = rlPromisify(rl.question.bind(rl))
|
|
559
|
+
commitMessage = await question('请输入提交信息:') || commitMessage;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
statusOutput.includes('(use "git add') && await execGitCommand('git add .')
|
|
563
|
+
// 强制添加所有变更
|
|
564
|
+
// await execGitCommand('git add -A .');
|
|
565
|
+
|
|
566
|
+
// 提交前二次校验
|
|
567
|
+
const checkStatus = await execGitCommand('git status --porcelain', {log: false});
|
|
568
|
+
if (!checkStatus.stdout.trim()) {
|
|
569
|
+
console.log(chalk.yellow('⚠️ 没有检测到可提交的变更'));
|
|
570
|
+
// exec_exit(exit)
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// 执行 git commit
|
|
575
|
+
if (statusOutput.includes('Untracked files:') || statusOutput.includes('Changes not staged for commit') || statusOutput.includes('Changes to be committed')) {
|
|
576
|
+
await execGitCommand(`git commit -m "${commitMessage}"`)
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// 添加时间格式化函数
|
|
581
|
+
function formatDuration(ms) {
|
|
582
|
+
const totalSeconds = Math.floor(ms / 1000);
|
|
583
|
+
const days = Math.floor(totalSeconds / (3600 * 24));
|
|
584
|
+
const hours = Math.floor((totalSeconds % (3600 * 24)) / 3600);
|
|
585
|
+
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
586
|
+
const seconds = totalSeconds % 60;
|
|
587
|
+
|
|
588
|
+
return [
|
|
589
|
+
days && `${days}天`,
|
|
590
|
+
hours && `${hours}小时`,
|
|
591
|
+
minutes && `${minutes}分`,
|
|
592
|
+
`${seconds}秒`
|
|
593
|
+
].filter(Boolean).join('');
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
export {
|
|
597
|
+
coloredLog, errorLog, execSyncGitCommand,
|
|
598
|
+
execGitCommand, getCwd, judgePlatform, showHelp, judgeLog, printGitLog,
|
|
599
|
+
judgeHelp, exec_exit, judgeUnmerged, delay, formatDuration,
|
|
600
|
+
exec_push, execPull, judgeRemote, execDiff, execAddAndCommit
|
|
601
|
+
};
|