git-push-time 1.1.2 → 1.1.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/.github/workflows/npm-publish.yml +59 -32
- package/README.md +1 -1
- package/bin/index.js +322 -339
- package/lib/commands/edit-time.js +141 -141
- package/lib/commands/fix.js +113 -113
- package/lib/commands/github.js +429 -445
- package/lib/commands/pull.js +90 -90
- package/lib/commands/push.js +720 -720
- package/lib/config.js +220 -220
- package/lib/fix.js +286 -286
- package/lib/git.js +525 -516
- package/lib/github.js +322 -322
- package/lib/secrets.js +92 -92
- package/lib/ui.js +1060 -1063
- package/lib/utils.js +120 -120
- package/package.json +36 -36
package/bin/index.js
CHANGED
|
@@ -1,339 +1,322 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import chalk from 'chalk';
|
|
5
|
-
import fs from 'fs';
|
|
6
|
-
import path from 'path';
|
|
7
|
-
import { fileURLToPath } from 'url';
|
|
8
|
-
import { checkGitInstalled, getCurrentBranch, getDashboardGitStatus } from '../lib/git.js';
|
|
9
|
-
import { getCurrentGitHubUser } from '../lib/github.js';
|
|
10
|
-
import { runPushWizard } from '../lib/commands/push.js';
|
|
11
|
-
import { runPullCommand } from '../lib/commands/pull.js';
|
|
12
|
-
import { runEditCommitTimeCommand } from '../lib/commands/edit-time.js';
|
|
13
|
-
import { runFixCommand } from '../lib/commands/fix.js';
|
|
14
|
-
import {
|
|
15
|
-
runGitHubMenu,
|
|
16
|
-
promptCreateRepo,
|
|
17
|
-
showUserRepos,
|
|
18
|
-
} from '../lib/commands/github.js';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
printBanner,
|
|
22
|
-
printDashboardStatus,
|
|
23
|
-
printGitMissing,
|
|
24
|
-
printCancelled,
|
|
25
|
-
styleCliHelp
|
|
26
|
-
} from '../lib/ui.js';
|
|
27
|
-
|
|
28
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
-
const __dirname = path.dirname(__filename);
|
|
30
|
-
|
|
31
|
-
function getPackageVersion() {
|
|
32
|
-
try {
|
|
33
|
-
const raw = fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8');
|
|
34
|
-
return JSON.parse(raw).version || '1.1.0';
|
|
35
|
-
} catch {
|
|
36
|
-
return '1.1.0';
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const VERSION = getPackageVersion();
|
|
41
|
-
|
|
42
|
-
function isExitPromptError(err) {
|
|
43
|
-
const msg = String(err?.message || '');
|
|
44
|
-
return (
|
|
45
|
-
err?.name === 'ExitPromptError' ||
|
|
46
|
-
msg.includes('User force closed the prompt') ||
|
|
47
|
-
msg.includes('SIGINT')
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Kiểm tra xem lệnh có được gọi "trần" (không flag/subcommand nào) hay không.
|
|
53
|
-
*/
|
|
54
|
-
function isBareInvocation(options = {}) {
|
|
55
|
-
return (
|
|
56
|
-
!options.repo &&
|
|
57
|
-
!options.message &&
|
|
58
|
-
!options.date &&
|
|
59
|
-
!options.branch &&
|
|
60
|
-
!options.dir &&
|
|
61
|
-
!options.force &&
|
|
62
|
-
!options.fix
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Menu chính khi chạy `git-push-time` không truyền flag
|
|
68
|
-
*/
|
|
69
|
-
async function promptMainMenu() {
|
|
70
|
-
return await selectBox({
|
|
71
|
-
message: 'Bảng điều khiển tác vụ chính',
|
|
72
|
-
hint: '↑↓ di chuyển · Enter chọn thao tác · Esc thoát',
|
|
73
|
-
pageSize: 10,
|
|
74
|
-
choices: [
|
|
75
|
-
{
|
|
76
|
-
name: `${chalk.hex('#38BDF8').bold('
|
|
77
|
-
value: 'push',
|
|
78
|
-
description: '
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: `${chalk.hex('#A78BFA').bold('
|
|
82
|
-
value: 'github',
|
|
83
|
-
description: '
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
name: `${chalk.hex('#34D399').bold('
|
|
87
|
-
value: 'pull',
|
|
88
|
-
description: 'Pull an toàn với fast-forward hoặc rebase, tránh conflict',
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
name: `${chalk.hex('#FBBF24').bold('
|
|
92
|
-
value: 'edit-time',
|
|
93
|
-
description: 'Viết lại ngày giờ cho các commit đã tạo (Backdate commit)',
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: `${chalk.hex('#F43F5E').bold('
|
|
97
|
-
value: 'fix',
|
|
98
|
-
description: 'Quét file .env/secrets, gỡ khỏi commit và cập nhật .gitignore',
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
name: `${chalk.hex('#64748B').bold('
|
|
102
|
-
value: 'exit',
|
|
103
|
-
},
|
|
104
|
-
],
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Vòng lặp Menu chính (không đệ quy — callback back chỉ trả sentinel)
|
|
110
|
-
*/
|
|
111
|
-
async function runMainMenuLoop(initialOptions = {}) {
|
|
112
|
-
while (true) {
|
|
113
|
-
const cwd = process.cwd();
|
|
114
|
-
let branch = 'main';
|
|
115
|
-
try {
|
|
116
|
-
branch = getCurrentBranch(cwd);
|
|
117
|
-
} catch {}
|
|
118
|
-
let ghStatus = { authenticated: false };
|
|
119
|
-
try {
|
|
120
|
-
ghStatus = await getCurrentGitHubUser();
|
|
121
|
-
} catch {
|
|
122
|
-
ghStatus = { authenticated: false };
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const gitStatus = getDashboardGitStatus(cwd);
|
|
126
|
-
printDashboardStatus({
|
|
127
|
-
targetDir: cwd,
|
|
128
|
-
currentBranch: branch,
|
|
129
|
-
githubUser: ghStatus.authenticated ? ghStatus.user : null,
|
|
130
|
-
remoteUrl: gitStatus.remoteUrl,
|
|
131
|
-
changes: gitStatus.changes,
|
|
132
|
-
lastCommit: gitStatus.lastCommit,
|
|
133
|
-
version: VERSION,
|
|
134
|
-
});
|
|
135
|
-
let action;
|
|
136
|
-
try {
|
|
137
|
-
action = await promptMainMenu();
|
|
138
|
-
} catch (err) {
|
|
139
|
-
if (isExitPromptError(err)) {
|
|
140
|
-
printCancelled();
|
|
141
|
-
process.exit(0);
|
|
142
|
-
}
|
|
143
|
-
throw err;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (action === 'exit') {
|
|
147
|
-
printCancelled();
|
|
148
|
-
process.exit(0);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
if (action === 'push') {
|
|
153
|
-
const res = await runPushWizard(initialOptions, async () => 'back');
|
|
154
|
-
// 'back' = user muốn về menu → tiếp tục loop; ngược lại push xong thì thoát
|
|
155
|
-
if (res === 'back') continue;
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (action === 'github') {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
program
|
|
241
|
-
.
|
|
242
|
-
.description('
|
|
243
|
-
.
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
.
|
|
250
|
-
.
|
|
251
|
-
.option('--
|
|
252
|
-
.action(async (opts) => {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
.
|
|
279
|
-
.
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
.
|
|
287
|
-
.
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
.command('
|
|
295
|
-
.description('
|
|
296
|
-
.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
.
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
.
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
.option('-C, --dir <path>', 'Thư mục repo cần pull (Mặc định: thư mục hiện tại)')
|
|
324
|
-
.action(async (remote, branch, opts) => {
|
|
325
|
-
printBanner(VERSION);
|
|
326
|
-
await runPullCommand(remote || 'origin', branch, opts || {});
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
// LỆNH EDIT-TIME
|
|
330
|
-
program
|
|
331
|
-
.command('edit-time')
|
|
332
|
-
.description('Sửa thời gian của commit lịch sử (Backdate commit hash)')
|
|
333
|
-
.option('-C, --dir <path>', 'Thư mục repo (Mặc định: thư mục hiện tại)')
|
|
334
|
-
.action(async (opts) => {
|
|
335
|
-
printBanner(VERSION);
|
|
336
|
-
await runEditCommitTimeCommand(opts);
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
program.parse(process.argv);
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import { checkGitInstalled, getCurrentBranch, getDashboardGitStatus } from '../lib/git.js';
|
|
9
|
+
import { getCurrentGitHubUser } from '../lib/github.js';
|
|
10
|
+
import { runPushWizard } from '../lib/commands/push.js';
|
|
11
|
+
import { runPullCommand } from '../lib/commands/pull.js';
|
|
12
|
+
import { runEditCommitTimeCommand } from '../lib/commands/edit-time.js';
|
|
13
|
+
import { runFixCommand } from '../lib/commands/fix.js';
|
|
14
|
+
import {
|
|
15
|
+
runGitHubMenu,
|
|
16
|
+
promptCreateRepo,
|
|
17
|
+
showUserRepos,
|
|
18
|
+
} from '../lib/commands/github.js';
|
|
19
|
+
import { selectBox } from '../lib/prompt-helpers.js';
|
|
20
|
+
import {
|
|
21
|
+
printBanner,
|
|
22
|
+
printDashboardStatus,
|
|
23
|
+
printGitMissing,
|
|
24
|
+
printCancelled,
|
|
25
|
+
styleCliHelp
|
|
26
|
+
} from '../lib/ui.js';
|
|
27
|
+
|
|
28
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
29
|
+
const __dirname = path.dirname(__filename);
|
|
30
|
+
|
|
31
|
+
function getPackageVersion() {
|
|
32
|
+
try {
|
|
33
|
+
const raw = fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8');
|
|
34
|
+
return JSON.parse(raw).version || '1.1.0';
|
|
35
|
+
} catch {
|
|
36
|
+
return '1.1.0';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const VERSION = getPackageVersion();
|
|
41
|
+
|
|
42
|
+
function isExitPromptError(err) {
|
|
43
|
+
const msg = String(err?.message || '');
|
|
44
|
+
return (
|
|
45
|
+
err?.name === 'ExitPromptError' ||
|
|
46
|
+
msg.includes('User force closed the prompt') ||
|
|
47
|
+
msg.includes('SIGINT')
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Kiểm tra xem lệnh có được gọi "trần" (không flag/subcommand nào) hay không.
|
|
53
|
+
*/
|
|
54
|
+
function isBareInvocation(options = {}) {
|
|
55
|
+
return (
|
|
56
|
+
!options.repo &&
|
|
57
|
+
!options.message &&
|
|
58
|
+
!options.date &&
|
|
59
|
+
!options.branch &&
|
|
60
|
+
!options.dir &&
|
|
61
|
+
!options.force &&
|
|
62
|
+
!options.fix
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Menu chính khi chạy `git-push-time` không truyền flag
|
|
68
|
+
*/
|
|
69
|
+
async function promptMainMenu() {
|
|
70
|
+
return await selectBox({
|
|
71
|
+
message: 'Bảng điều khiển tác vụ chính',
|
|
72
|
+
hint: '↑↓ di chuyển · Enter chọn thao tác · Esc thoát',
|
|
73
|
+
pageSize: 10,
|
|
74
|
+
choices: [
|
|
75
|
+
{
|
|
76
|
+
name: `${chalk.hex('#38BDF8').bold('PUSH')} ${chalk.hex('#334155')('·')} ${chalk.hex('#F1F5F9')('Đẩy project lên repository')}`,
|
|
77
|
+
value: 'push',
|
|
78
|
+
description: 'Chọn hoặc tạo repository, rà secret và push',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: `${chalk.hex('#A78BFA').bold('GITHUB')} ${chalk.hex('#334155')('·')} ${chalk.hex('#CBD5E1')('Tài khoản và repository')}`,
|
|
82
|
+
value: 'github',
|
|
83
|
+
description: 'Đăng nhập, đổi tài khoản và duyệt repo GitHub',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: `${chalk.hex('#34D399').bold('PULL')} ${chalk.hex('#334155')('·')} ${chalk.hex('#CBD5E1')('Cập nhật từ remote')}`,
|
|
87
|
+
value: 'pull',
|
|
88
|
+
description: 'Pull an toàn với fast-forward hoặc rebase, tránh conflict',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: `${chalk.hex('#FBBF24').bold('EDIT TIME')} ${chalk.hex('#334155')('·')} ${chalk.hex('#CBD5E1')('Sửa thời gian commit')}`,
|
|
92
|
+
value: 'edit-time',
|
|
93
|
+
description: 'Viết lại ngày giờ cho các commit đã tạo (Backdate commit)',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: `${chalk.hex('#F43F5E').bold('SECURITY')} ${chalk.hex('#334155')('·')} ${chalk.hex('#CBD5E1')('Rà soát secret')}`,
|
|
97
|
+
value: 'fix',
|
|
98
|
+
description: 'Quét file .env/secrets, gỡ khỏi commit và cập nhật .gitignore',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: `${chalk.hex('#64748B').bold('THOÁT')} ${chalk.hex('#334155')('·')} ${chalk.hex('#64748B')('Đóng chương trình')}`,
|
|
102
|
+
value: 'exit',
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Vòng lặp Menu chính (không đệ quy — callback back chỉ trả sentinel)
|
|
110
|
+
*/
|
|
111
|
+
async function runMainMenuLoop(initialOptions = {}) {
|
|
112
|
+
while (true) {
|
|
113
|
+
const cwd = process.cwd();
|
|
114
|
+
let branch = 'main';
|
|
115
|
+
try {
|
|
116
|
+
branch = getCurrentBranch(cwd);
|
|
117
|
+
} catch {}
|
|
118
|
+
let ghStatus = { authenticated: false };
|
|
119
|
+
try {
|
|
120
|
+
ghStatus = await getCurrentGitHubUser();
|
|
121
|
+
} catch {
|
|
122
|
+
ghStatus = { authenticated: false };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const gitStatus = getDashboardGitStatus(cwd);
|
|
126
|
+
printDashboardStatus({
|
|
127
|
+
targetDir: cwd,
|
|
128
|
+
currentBranch: branch,
|
|
129
|
+
githubUser: ghStatus.authenticated ? ghStatus.user : null,
|
|
130
|
+
remoteUrl: gitStatus.remoteUrl,
|
|
131
|
+
changes: gitStatus.changes,
|
|
132
|
+
lastCommit: gitStatus.lastCommit,
|
|
133
|
+
version: VERSION,
|
|
134
|
+
});
|
|
135
|
+
let action;
|
|
136
|
+
try {
|
|
137
|
+
action = await promptMainMenu();
|
|
138
|
+
} catch (err) {
|
|
139
|
+
if (isExitPromptError(err)) {
|
|
140
|
+
printCancelled();
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (action === 'exit') {
|
|
147
|
+
printCancelled();
|
|
148
|
+
process.exit(0);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
if (action === 'push') {
|
|
153
|
+
const res = await runPushWizard(initialOptions, async () => 'back');
|
|
154
|
+
// 'back' = user muốn về menu → tiếp tục loop; ngược lại push xong thì thoát
|
|
155
|
+
if (res === 'back') continue;
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (action === 'github') {
|
|
160
|
+
await runGitHubMenu();
|
|
161
|
+
} else if (action === 'pull') {
|
|
162
|
+
await runPullCommand('origin', undefined, { fromMenu: true });
|
|
163
|
+
} else if (action === 'edit-time') {
|
|
164
|
+
await runEditCommitTimeCommand({ fromMenu: true });
|
|
165
|
+
} else if (action === 'fix') {
|
|
166
|
+
await runFixCommand({ fromMenu: true });
|
|
167
|
+
}
|
|
168
|
+
} catch (err) {
|
|
169
|
+
if (isExitPromptError(err)) {
|
|
170
|
+
printCancelled();
|
|
171
|
+
process.exit(0);
|
|
172
|
+
}
|
|
173
|
+
throw err;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Mỗi tác vụ trở về cùng dashboard; không cần thêm một menu
|
|
177
|
+
// "tiếp tục / quay lại" sau menu hành động.
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async function main(options = {}) {
|
|
182
|
+
printBanner(VERSION);
|
|
183
|
+
|
|
184
|
+
if (!checkGitInstalled()) {
|
|
185
|
+
printGitMissing();
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const isInteractive = !options.yes;
|
|
190
|
+
|
|
191
|
+
if (isInteractive && isBareInvocation(options)) {
|
|
192
|
+
try {
|
|
193
|
+
await runMainMenuLoop(options);
|
|
194
|
+
} catch (err) {
|
|
195
|
+
if (isExitPromptError(err)) {
|
|
196
|
+
printCancelled();
|
|
197
|
+
process.exit(0);
|
|
198
|
+
}
|
|
199
|
+
throw err;
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Chạy trực tiếp push wizard với các options được cung cấp
|
|
205
|
+
try {
|
|
206
|
+
await runPushWizard(options);
|
|
207
|
+
} catch (err) {
|
|
208
|
+
if (isExitPromptError(err)) {
|
|
209
|
+
printCancelled();
|
|
210
|
+
process.exit(0);
|
|
211
|
+
}
|
|
212
|
+
throw err;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* ==========================================================================
|
|
217
|
+
COMMANDER CLI CONFIGURATION
|
|
218
|
+
========================================================================== */
|
|
219
|
+
|
|
220
|
+
const program = new Command();
|
|
221
|
+
styleCliHelp(program);
|
|
222
|
+
|
|
223
|
+
program
|
|
224
|
+
.name('git-push-time')
|
|
225
|
+
.description('Bộ công cụ Git & GitHub CLI: Đẩy code siêu tốc, kết nối GitHub tạo repo, chỉnh thời gian commit và bảo vệ secret')
|
|
226
|
+
.version(VERSION)
|
|
227
|
+
.option('-r, --repo <url>', 'Đường dẫn Git repository (URL hoặc để trống để chọn/tạo mới)')
|
|
228
|
+
.option('-d, --date <datetime>', 'Thời gian commit (VD: "2024-01-15 14:30:00", "-2d", "-5h", "now")')
|
|
229
|
+
.option('-m, --message <msg>', 'Thông điệp commit (Commit message)')
|
|
230
|
+
.option('-b, --branch <branch>', 'Tên branch trên remote (Mặc định: main)')
|
|
231
|
+
.option('-C, --dir <path>', 'Thư mục nguồn cần push (Mặc định: thư mục hiện tại)')
|
|
232
|
+
.option('-f, --force', 'Thực hiện push đè (--force)', false)
|
|
233
|
+
.option('-y, --yes', 'Bỏ qua giao diện hỏi, tự động dùng tham số hoặc giá trị mặc định', false)
|
|
234
|
+
.option('--fix', 'Tự động gỡ file secret khỏi stage & thêm .gitignore (an toàn, không xóa file thật)', false)
|
|
235
|
+
.action(async (opts) => {
|
|
236
|
+
await main(opts);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// LỆNH GITHUB
|
|
240
|
+
const ghCmd = program
|
|
241
|
+
.command('github')
|
|
242
|
+
.description('Quản lý tài khoản GitHub và tạo repository mới trực tiếp')
|
|
243
|
+
.action(async () => {
|
|
244
|
+
printBanner(VERSION);
|
|
245
|
+
await runGitHubMenu();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
ghCmd
|
|
249
|
+
.command('create')
|
|
250
|
+
.description('Tạo repository mới trên GitHub (Public hoặc Private)')
|
|
251
|
+
.option('-C, --dir <path>', 'Thư mục nguồn cần liên kết')
|
|
252
|
+
.action(async (opts) => {
|
|
253
|
+
printBanner(VERSION);
|
|
254
|
+
const res = await promptCreateRepo({ targetDir: opts.dir || process.cwd() });
|
|
255
|
+
if (res.ok && res.repo) {
|
|
256
|
+
console.log(`\n » Repo URL: ${res.repo.cloneUrl}\n`);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
ghCmd
|
|
261
|
+
.command('whoami')
|
|
262
|
+
.description('Xem thông tin tài khoản GitHub đang kết nối')
|
|
263
|
+
.action(async () => {
|
|
264
|
+
printBanner(VERSION);
|
|
265
|
+
await showGitHubStatus();
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
ghCmd
|
|
269
|
+
.command('repos')
|
|
270
|
+
.description('Liệt kê danh sách repository trên GitHub của bạn')
|
|
271
|
+
.action(async () => {
|
|
272
|
+
printBanner(VERSION);
|
|
273
|
+
await showUserRepos();
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
ghCmd
|
|
277
|
+
.command('login')
|
|
278
|
+
.description('Đăng nhập tài khoản GitHub bằng OAuth Device Flow hoặc Token')
|
|
279
|
+
.action(async () => {
|
|
280
|
+
printBanner(VERSION);
|
|
281
|
+
await promptGitHubLogin();
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
ghCmd
|
|
285
|
+
.command('logout')
|
|
286
|
+
.description('Đăng xuất tài khoản GitHub khỏi máy')
|
|
287
|
+
.action(async () => {
|
|
288
|
+
printBanner(VERSION);
|
|
289
|
+
logoutGitHub();
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// LỆNH FIX
|
|
293
|
+
program
|
|
294
|
+
.command('fix')
|
|
295
|
+
.description('Quét & tự động gỡ file secret khỏi stage, cập nhật .gitignore và làm sạch commit unpushed')
|
|
296
|
+
.option('-C, --dir <path>', 'Thư mục cần quét fix (Mặc định: thư mục hiện tại)')
|
|
297
|
+
.action(async (opts) => {
|
|
298
|
+
printBanner(VERSION);
|
|
299
|
+
await runFixCommand(opts);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// LỆNH PULL
|
|
303
|
+
program
|
|
304
|
+
.command('pull [remote] [branch]')
|
|
305
|
+
.description('Cập nhật code từ remote bằng fast-forward --ff-only hoặc --rebase')
|
|
306
|
+
.option('-C, --dir <path>', 'Thư mục repo cần pull (Mặc định: thư mục hiện tại)')
|
|
307
|
+
.action(async (remote, branch, opts) => {
|
|
308
|
+
printBanner(VERSION);
|
|
309
|
+
await runPullCommand(remote || 'origin', branch, opts || {});
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// LỆNH EDIT-TIME
|
|
313
|
+
program
|
|
314
|
+
.command('edit-time')
|
|
315
|
+
.description('Sửa thời gian của commit lịch sử (Backdate commit hash)')
|
|
316
|
+
.option('-C, --dir <path>', 'Thư mục repo (Mặc định: thư mục hiện tại)')
|
|
317
|
+
.action(async (opts) => {
|
|
318
|
+
printBanner(VERSION);
|
|
319
|
+
await runEditCommitTimeCommand(opts);
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
program.parse(process.argv);
|