preguito 0.2.1 → 0.2.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/README.md +55 -3
- package/dist/cli-sea.cjs +194 -349
- package/dist/cli.mjs +185 -339
- package/package.json +1 -1
package/dist/cli-sea.cjs
CHANGED
|
@@ -36,7 +36,7 @@ let node_os = require("node:os");
|
|
|
36
36
|
let node_util = require("node:util");
|
|
37
37
|
let node_readline_promises = require("node:readline/promises");
|
|
38
38
|
|
|
39
|
-
//#region node_modules/commander/lib/error.js
|
|
39
|
+
//#region ../../node_modules/commander/lib/error.js
|
|
40
40
|
var require_error = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
41
41
|
/**
|
|
42
42
|
* CommanderError class
|
|
@@ -76,7 +76,7 @@ var require_error = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
76
76
|
}));
|
|
77
77
|
|
|
78
78
|
//#endregion
|
|
79
|
-
//#region node_modules/commander/lib/argument.js
|
|
79
|
+
//#region ../../node_modules/commander/lib/argument.js
|
|
80
80
|
var require_argument = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
81
81
|
const { InvalidArgumentError } = require_error();
|
|
82
82
|
var Argument = class {
|
|
@@ -201,7 +201,7 @@ var require_argument = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
201
201
|
}));
|
|
202
202
|
|
|
203
203
|
//#endregion
|
|
204
|
-
//#region node_modules/commander/lib/help.js
|
|
204
|
+
//#region ../../node_modules/commander/lib/help.js
|
|
205
205
|
var require_help = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
206
206
|
const { humanReadableArgName } = require_argument();
|
|
207
207
|
/**
|
|
@@ -663,7 +663,7 @@ var require_help = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
663
663
|
}));
|
|
664
664
|
|
|
665
665
|
//#endregion
|
|
666
|
-
//#region node_modules/commander/lib/option.js
|
|
666
|
+
//#region ../../node_modules/commander/lib/option.js
|
|
667
667
|
var require_option = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
668
668
|
const { InvalidArgumentError } = require_error();
|
|
669
669
|
var Option = class {
|
|
@@ -955,7 +955,7 @@ var require_option = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
955
955
|
}));
|
|
956
956
|
|
|
957
957
|
//#endregion
|
|
958
|
-
//#region node_modules/commander/lib/suggestSimilar.js
|
|
958
|
+
//#region ../../node_modules/commander/lib/suggestSimilar.js
|
|
959
959
|
var require_suggestSimilar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
960
960
|
const maxDistance = 3;
|
|
961
961
|
function editDistance(a, b) {
|
|
@@ -1011,7 +1011,7 @@ var require_suggestSimilar = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
1011
1011
|
}));
|
|
1012
1012
|
|
|
1013
1013
|
//#endregion
|
|
1014
|
-
//#region node_modules/commander/lib/command.js
|
|
1014
|
+
//#region ../../node_modules/commander/lib/command.js
|
|
1015
1015
|
var require_command = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
1016
1016
|
const EventEmitter = require("node:events").EventEmitter;
|
|
1017
1017
|
const childProcess = require("node:child_process");
|
|
@@ -2912,7 +2912,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2912
2912
|
}));
|
|
2913
2913
|
|
|
2914
2914
|
//#endregion
|
|
2915
|
-
//#region node_modules/commander/index.js
|
|
2915
|
+
//#region ../../node_modules/commander/index.js
|
|
2916
2916
|
var require_commander = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
2917
2917
|
const { Argument } = require_argument();
|
|
2918
2918
|
const { Command } = require_command();
|
|
@@ -2936,7 +2936,7 @@ var require_commander = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
2936
2936
|
}));
|
|
2937
2937
|
|
|
2938
2938
|
//#endregion
|
|
2939
|
-
//#region node_modules/commander/esm.mjs
|
|
2939
|
+
//#region ../../node_modules/commander/esm.mjs
|
|
2940
2940
|
var import_commander = /* @__PURE__ */ __toESM(require_commander(), 1);
|
|
2941
2941
|
const { program: program$1, createCommand, createArgument, createOption, CommanderError, InvalidArgumentError, InvalidOptionArgumentError, Command, Argument, Option, Help } = import_commander.default;
|
|
2942
2942
|
|
|
@@ -3259,6 +3259,29 @@ function resolveShortcodes(shortcodesStr, config) {
|
|
|
3259
3259
|
return result;
|
|
3260
3260
|
}
|
|
3261
3261
|
|
|
3262
|
+
//#endregion
|
|
3263
|
+
//#region src/utils/validation.ts
|
|
3264
|
+
const GIT_HASH_PATTERN = /^[a-f0-9]{4,40}$/i;
|
|
3265
|
+
const GIT_REF_FORBIDDEN_CHARS = /[\x00-\x1f\x7f ~^:?*[\\]/;
|
|
3266
|
+
const GIT_REF_FORBIDDEN_SEQUENCES = /\.\.|\.lock(\/|$)|@\{|\/\//;
|
|
3267
|
+
function validateHash(hash) {
|
|
3268
|
+
if (!GIT_HASH_PATTERN.test(hash)) throw new PrequitoError(`Invalid git hash: "${hash}". Expected 4-40 hexadecimal characters.`);
|
|
3269
|
+
}
|
|
3270
|
+
function validateRefName(name, type) {
|
|
3271
|
+
if (!name || name.trim() === "") throw new PrequitoError(`${type} name cannot be empty.`);
|
|
3272
|
+
if (name.startsWith("-")) throw new PrequitoError(`Invalid ${type} name: "${name}". Cannot start with '-'.`);
|
|
3273
|
+
if (name.endsWith(".")) throw new PrequitoError(`Invalid ${type} name: "${name}". Cannot end with '.'.`);
|
|
3274
|
+
if (name.endsWith("/")) throw new PrequitoError(`Invalid ${type} name: "${name}". Cannot end with '/'.`);
|
|
3275
|
+
if (GIT_REF_FORBIDDEN_CHARS.test(name)) throw new PrequitoError(`Invalid ${type} name: "${name}". Contains forbidden characters.`);
|
|
3276
|
+
if (GIT_REF_FORBIDDEN_SEQUENCES.test(name)) throw new PrequitoError(`Invalid ${type} name: "${name}". Contains forbidden pattern.`);
|
|
3277
|
+
}
|
|
3278
|
+
function validateBranchName(branch) {
|
|
3279
|
+
validateRefName(branch, "Branch");
|
|
3280
|
+
}
|
|
3281
|
+
function validateTagName(tag) {
|
|
3282
|
+
validateRefName(tag, "Tag");
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3262
3285
|
//#endregion
|
|
3263
3286
|
//#region src/git/operations.ts
|
|
3264
3287
|
const execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
|
|
@@ -3338,6 +3361,7 @@ async function forcePushLease() {
|
|
|
3338
3361
|
return result.stdout + result.stderr;
|
|
3339
3362
|
}
|
|
3340
3363
|
async function checkout(branch) {
|
|
3364
|
+
validateBranchName(branch);
|
|
3341
3365
|
await git(["checkout", branch]);
|
|
3342
3366
|
}
|
|
3343
3367
|
async function pull() {
|
|
@@ -3345,10 +3369,12 @@ async function pull() {
|
|
|
3345
3369
|
return result.stdout + result.stderr;
|
|
3346
3370
|
}
|
|
3347
3371
|
async function rebase(branch) {
|
|
3372
|
+
validateBranchName(branch);
|
|
3348
3373
|
const result = await git(["rebase", branch]);
|
|
3349
3374
|
return result.stdout + result.stderr;
|
|
3350
3375
|
}
|
|
3351
3376
|
async function rebaseInteractiveEdit(hash) {
|
|
3377
|
+
validateHash(hash);
|
|
3352
3378
|
const sedCmd = `sed -i 's/^pick ${hash.slice(0, 7)}/edit ${hash.slice(0, 7)}/'`;
|
|
3353
3379
|
const result = await git([
|
|
3354
3380
|
"rebase",
|
|
@@ -3375,7 +3401,8 @@ async function rebaseInteractive(count) {
|
|
|
3375
3401
|
`HEAD~${count}`
|
|
3376
3402
|
]);
|
|
3377
3403
|
}
|
|
3378
|
-
async function pushUpstream
|
|
3404
|
+
async function pushUpstream(branch) {
|
|
3405
|
+
if (branch !== void 0) validateBranchName(branch);
|
|
3379
3406
|
const result = await git([
|
|
3380
3407
|
"push",
|
|
3381
3408
|
"--set-upstream",
|
|
@@ -3385,6 +3412,7 @@ async function pushUpstream$1(branch) {
|
|
|
3385
3412
|
return result.stdout + result.stderr;
|
|
3386
3413
|
}
|
|
3387
3414
|
async function commitFixup(hash) {
|
|
3415
|
+
validateHash(hash);
|
|
3388
3416
|
return (await git([
|
|
3389
3417
|
"commit",
|
|
3390
3418
|
"--fixup",
|
|
@@ -3399,14 +3427,17 @@ async function resetSoft(count = 1) {
|
|
|
3399
3427
|
])).stdout;
|
|
3400
3428
|
}
|
|
3401
3429
|
async function createBranch(branch) {
|
|
3430
|
+
validateBranchName(branch);
|
|
3402
3431
|
await git([
|
|
3403
3432
|
"checkout",
|
|
3404
3433
|
"-b",
|
|
3405
3434
|
branch
|
|
3406
3435
|
]);
|
|
3407
3436
|
}
|
|
3408
|
-
async function stash() {
|
|
3409
|
-
|
|
3437
|
+
async function stash(message) {
|
|
3438
|
+
const args = ["stash"];
|
|
3439
|
+
if (message) args.push("-m", message);
|
|
3440
|
+
return (await git(args)).stdout;
|
|
3410
3441
|
}
|
|
3411
3442
|
async function stashPop() {
|
|
3412
3443
|
return (await git(["stash", "pop"])).stdout;
|
|
@@ -3430,6 +3461,7 @@ async function logGrep(keyword, count) {
|
|
|
3430
3461
|
return (await git(args)).stdout;
|
|
3431
3462
|
}
|
|
3432
3463
|
async function logTag(tag) {
|
|
3464
|
+
validateTagName(tag);
|
|
3433
3465
|
return (await git([
|
|
3434
3466
|
"log",
|
|
3435
3467
|
"--oneline",
|
|
@@ -3437,12 +3469,44 @@ async function logTag(tag) {
|
|
|
3437
3469
|
])).stdout;
|
|
3438
3470
|
}
|
|
3439
3471
|
async function logTagAll(tag) {
|
|
3472
|
+
validateTagName(tag);
|
|
3440
3473
|
return (await git([
|
|
3441
3474
|
"log",
|
|
3442
3475
|
"--oneline",
|
|
3443
3476
|
tag
|
|
3444
3477
|
])).stdout;
|
|
3445
3478
|
}
|
|
3479
|
+
async function diff(options = []) {
|
|
3480
|
+
return (await git(["diff", ...options])).stdout;
|
|
3481
|
+
}
|
|
3482
|
+
async function stashList() {
|
|
3483
|
+
return (await git(["stash", "list"])).stdout;
|
|
3484
|
+
}
|
|
3485
|
+
|
|
3486
|
+
//#endregion
|
|
3487
|
+
//#region src/utils/command.ts
|
|
3488
|
+
async function requireGitRepo() {
|
|
3489
|
+
if (!await isGitRepo()) throw new PrequitoError("Not inside a git repository.");
|
|
3490
|
+
}
|
|
3491
|
+
function withErrorHandling(fn) {
|
|
3492
|
+
return async (...args) => {
|
|
3493
|
+
try {
|
|
3494
|
+
await fn(...args);
|
|
3495
|
+
} catch (error) {
|
|
3496
|
+
if (error instanceof PrequitoError) {
|
|
3497
|
+
console.error(`✖ ${error.message}`);
|
|
3498
|
+
process.exit(1);
|
|
3499
|
+
}
|
|
3500
|
+
throw error;
|
|
3501
|
+
}
|
|
3502
|
+
};
|
|
3503
|
+
}
|
|
3504
|
+
function parseCount(value, defaultValue = 1) {
|
|
3505
|
+
if (value === void 0) return defaultValue;
|
|
3506
|
+
const num = parseInt(value, 10);
|
|
3507
|
+
if (isNaN(num) || num <= 0) throw new PrequitoError("Count must be a positive integer.");
|
|
3508
|
+
return num;
|
|
3509
|
+
}
|
|
3446
3510
|
|
|
3447
3511
|
//#endregion
|
|
3448
3512
|
//#region src/utils/spinner.ts
|
|
@@ -3489,23 +3553,12 @@ function spinner(message, options) {
|
|
|
3489
3553
|
//#endregion
|
|
3490
3554
|
//#region src/commands/commit.ts
|
|
3491
3555
|
function registerCommitCommand(program) {
|
|
3492
|
-
program.command("c").alias("commit").description("Templated commit (e.g. guito c 42 f \"msg\" -p)").argument("[args...]", "Card ID, shortcodes, and message").option("-p, --push", "Push after committing").option("-f, --force", "Push with --force-with-lease after committing").option("-d, --dry-run", "Show the generated message without executing").option("-S, --no-stage", "Skip auto-staging (git add -A)").
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
} catch (error) {
|
|
3496
|
-
if (error instanceof PrequitoError) {
|
|
3497
|
-
console.error(`\u2716 ${error.message}`);
|
|
3498
|
-
process.exit(1);
|
|
3499
|
-
}
|
|
3500
|
-
throw error;
|
|
3501
|
-
}
|
|
3502
|
-
});
|
|
3556
|
+
program.command("c").alias("commit").description("Templated commit (e.g. guito c 42 f \"msg\" -p)").argument("[args...]", "Card ID, shortcodes, and message").option("-p, --push", "Push after committing").option("-f, --force", "Push with --force-with-lease after committing").option("-d, --dry-run", "Show the generated message without executing").option("-S, --no-stage", "Skip auto-staging (git add -A)").action(withErrorHandling(async (args, opts) => {
|
|
3557
|
+
await executeCommit(args, opts);
|
|
3558
|
+
}));
|
|
3503
3559
|
}
|
|
3504
3560
|
async function executeCommit(args, opts) {
|
|
3505
|
-
|
|
3506
|
-
console.error("✖ Not inside a git repository.");
|
|
3507
|
-
process.exit(1);
|
|
3508
|
-
}
|
|
3561
|
+
await requireGitRepo();
|
|
3509
3562
|
const config = await loadConfigOrDefault();
|
|
3510
3563
|
const { context, message, body } = parsePositionalArgs(args, config, typeof opts.body === "string" ? opts.body : void 0);
|
|
3511
3564
|
const commitTitle = renderTemplate(config.template, context, message);
|
|
@@ -3515,10 +3568,7 @@ async function executeCommit(args, opts) {
|
|
|
3515
3568
|
return;
|
|
3516
3569
|
}
|
|
3517
3570
|
if (opts.stage !== false) await stageAll();
|
|
3518
|
-
if (!await hasStagedChanges())
|
|
3519
|
-
console.error("✖ No staged changes to commit.");
|
|
3520
|
-
process.exit(1);
|
|
3521
|
-
}
|
|
3571
|
+
if (!await hasStagedChanges()) throw new PrequitoError("No staged changes to commit.");
|
|
3522
3572
|
const stopCommit = spinner(`Committing: ${commitTitle}`);
|
|
3523
3573
|
await commit(commitMessage);
|
|
3524
3574
|
stopCommit("✔ Committed.");
|
|
@@ -3536,34 +3586,11 @@ async function executeCommit(args, opts) {
|
|
|
3536
3586
|
//#endregion
|
|
3537
3587
|
//#region src/commands/amend-push.ts
|
|
3538
3588
|
function registerAmendPushCommands(program) {
|
|
3539
|
-
program.command("ap").description("Amend last commit + force push (git push --force)").action(
|
|
3540
|
-
|
|
3541
|
-
await amendAndPush(false);
|
|
3542
|
-
} catch (error) {
|
|
3543
|
-
if (error instanceof PrequitoError) {
|
|
3544
|
-
console.error(`✖ ${error.message}`);
|
|
3545
|
-
process.exit(1);
|
|
3546
|
-
}
|
|
3547
|
-
throw error;
|
|
3548
|
-
}
|
|
3549
|
-
});
|
|
3550
|
-
program.command("apl").description("Amend last commit + safe force push (--force-with-lease)").action(async () => {
|
|
3551
|
-
try {
|
|
3552
|
-
await amendAndPush(true);
|
|
3553
|
-
} catch (error) {
|
|
3554
|
-
if (error instanceof PrequitoError) {
|
|
3555
|
-
console.error(`✖ ${error.message}`);
|
|
3556
|
-
process.exit(1);
|
|
3557
|
-
}
|
|
3558
|
-
throw error;
|
|
3559
|
-
}
|
|
3560
|
-
});
|
|
3589
|
+
program.command("ap").description("Amend last commit + force push (git push --force)").action(withErrorHandling(() => amendAndPush(false)));
|
|
3590
|
+
program.command("apl").description("Amend last commit + safe force push (--force-with-lease)").action(withErrorHandling(() => amendAndPush(true)));
|
|
3561
3591
|
}
|
|
3562
3592
|
async function amendAndPush(useLease) {
|
|
3563
|
-
|
|
3564
|
-
console.error("✖ Not inside a git repository.");
|
|
3565
|
-
process.exit(1);
|
|
3566
|
-
}
|
|
3593
|
+
await requireGitRepo();
|
|
3567
3594
|
const stopStage = spinner("Staging all changes...");
|
|
3568
3595
|
await stageAll();
|
|
3569
3596
|
stopStage("✔ Staged.");
|
|
@@ -3584,45 +3611,12 @@ async function amendAndPush(useLease) {
|
|
|
3584
3611
|
//#endregion
|
|
3585
3612
|
//#region src/commands/rebase.ts
|
|
3586
3613
|
function registerRebaseCommands(program) {
|
|
3587
|
-
program.command("r <branch>").alias("rebase").description("Rebase on <branch> (checkout, pull, rebase) (e.g. guito r main)").action(
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
} catch (error) {
|
|
3591
|
-
if (error instanceof PrequitoError) {
|
|
3592
|
-
console.error(`✖ ${error.message}`);
|
|
3593
|
-
process.exit(1);
|
|
3594
|
-
}
|
|
3595
|
-
throw error;
|
|
3596
|
-
}
|
|
3597
|
-
});
|
|
3598
|
-
program.command("ri <count>").description("Interactive rebase last <count> commits (e.g. guito ri 3)").action(async (count) => {
|
|
3599
|
-
try {
|
|
3600
|
-
await interactiveRebase(count);
|
|
3601
|
-
} catch (error) {
|
|
3602
|
-
if (error instanceof PrequitoError) {
|
|
3603
|
-
console.error(`✖ ${error.message}`);
|
|
3604
|
-
process.exit(1);
|
|
3605
|
-
}
|
|
3606
|
-
throw error;
|
|
3607
|
-
}
|
|
3608
|
-
});
|
|
3609
|
-
program.command("re <hash>").description("Edit rebase at <hash> (e.g. guito re abc123)").action(async (hash) => {
|
|
3610
|
-
try {
|
|
3611
|
-
await editRebase(hash);
|
|
3612
|
-
} catch (error) {
|
|
3613
|
-
if (error instanceof PrequitoError) {
|
|
3614
|
-
console.error(`✖ ${error.message}`);
|
|
3615
|
-
process.exit(1);
|
|
3616
|
-
}
|
|
3617
|
-
throw error;
|
|
3618
|
-
}
|
|
3619
|
-
});
|
|
3614
|
+
program.command("r <branch>").alias("rebase").description("Rebase on <branch> (checkout, pull, rebase) (e.g. guito r main)").action(withErrorHandling(quickRebase));
|
|
3615
|
+
program.command("ri <count>").description("Interactive rebase last <count> commits (e.g. guito ri 3)").action(withErrorHandling(interactiveRebase));
|
|
3616
|
+
program.command("re <hash>").description("Edit rebase at <hash> (e.g. guito re abc123)").action(withErrorHandling(editRebase));
|
|
3620
3617
|
}
|
|
3621
3618
|
async function quickRebase(branch) {
|
|
3622
|
-
|
|
3623
|
-
console.error("✖ Not inside a git repository.");
|
|
3624
|
-
process.exit(1);
|
|
3625
|
-
}
|
|
3619
|
+
await requireGitRepo();
|
|
3626
3620
|
const currentBranch = await getCurrentBranch();
|
|
3627
3621
|
console.log(`→ Current branch: ${currentBranch}`);
|
|
3628
3622
|
let stop = spinner(`Checking out ${branch}...`);
|
|
@@ -3639,23 +3633,13 @@ async function quickRebase(branch) {
|
|
|
3639
3633
|
stop("✔ Rebase complete.");
|
|
3640
3634
|
}
|
|
3641
3635
|
async function interactiveRebase(count) {
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
process.exit(1);
|
|
3645
|
-
}
|
|
3646
|
-
const num = parseInt(count, 10);
|
|
3647
|
-
if (isNaN(num) || num <= 0) {
|
|
3648
|
-
console.error("✖ Count must be a positive integer.");
|
|
3649
|
-
process.exit(1);
|
|
3650
|
-
}
|
|
3636
|
+
await requireGitRepo();
|
|
3637
|
+
const num = parseCount(count);
|
|
3651
3638
|
console.log(`→ Starting interactive rebase for the last ${num} commit(s)...`);
|
|
3652
3639
|
await rebaseInteractive(num);
|
|
3653
3640
|
}
|
|
3654
3641
|
async function editRebase(hash) {
|
|
3655
|
-
|
|
3656
|
-
console.error("✖ Not inside a git repository.");
|
|
3657
|
-
process.exit(1);
|
|
3658
|
-
}
|
|
3642
|
+
await requireGitRepo();
|
|
3659
3643
|
console.log(`→ Starting edit rebase on commit ${hash}...`);
|
|
3660
3644
|
await rebaseInteractiveEdit(hash);
|
|
3661
3645
|
console.log("✔ Rebase paused at the target commit. Make your changes, then run:");
|
|
@@ -3976,76 +3960,32 @@ function registerConfigCommand(program) {
|
|
|
3976
3960
|
//#endregion
|
|
3977
3961
|
//#region src/commands/push.ts
|
|
3978
3962
|
function registerPushCommands(program) {
|
|
3979
|
-
program.command("p").alias("push").description("Push current branch (git push)").action(async () => {
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
}
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
await pushUpstream();
|
|
3993
|
-
} catch (error) {
|
|
3994
|
-
if (error instanceof PrequitoError) {
|
|
3995
|
-
console.error(`✖ ${error.message}`);
|
|
3996
|
-
process.exit(1);
|
|
3997
|
-
}
|
|
3998
|
-
throw error;
|
|
3999
|
-
}
|
|
4000
|
-
});
|
|
4001
|
-
}
|
|
4002
|
-
async function executePush() {
|
|
4003
|
-
if (!await isGitRepo()) {
|
|
4004
|
-
console.error("✖ Not inside a git repository.");
|
|
4005
|
-
process.exit(1);
|
|
4006
|
-
}
|
|
4007
|
-
const stop = spinner("Pushing...");
|
|
4008
|
-
await push();
|
|
4009
|
-
stop("✔ Pushed.");
|
|
4010
|
-
}
|
|
4011
|
-
async function pushUpstream() {
|
|
4012
|
-
if (!await isGitRepo()) {
|
|
4013
|
-
console.error("✖ Not inside a git repository.");
|
|
4014
|
-
process.exit(1);
|
|
4015
|
-
}
|
|
4016
|
-
const branch = await getCurrentBranch();
|
|
4017
|
-
const stop = spinner(`Pushing with --set-upstream origin ${branch}...`);
|
|
4018
|
-
await pushUpstream$1(branch);
|
|
4019
|
-
stop("✔ Pushed.");
|
|
3963
|
+
program.command("p").alias("push").description("Push current branch (git push)").action(withErrorHandling(async () => {
|
|
3964
|
+
await requireGitRepo();
|
|
3965
|
+
const stop = spinner("Pushing...");
|
|
3966
|
+
await push();
|
|
3967
|
+
stop("✔ Pushed.");
|
|
3968
|
+
}));
|
|
3969
|
+
program.command("pu").description("Push + set upstream (git push --set-upstream origin <branch>)").action(withErrorHandling(async () => {
|
|
3970
|
+
await requireGitRepo();
|
|
3971
|
+
const branch = await getCurrentBranch();
|
|
3972
|
+
const stop = spinner(`Pushing with --set-upstream origin ${branch}...`);
|
|
3973
|
+
await pushUpstream(branch);
|
|
3974
|
+
stop("✔ Pushed.");
|
|
3975
|
+
}));
|
|
4020
3976
|
}
|
|
4021
3977
|
|
|
4022
3978
|
//#endregion
|
|
4023
3979
|
//#region src/commands/fixup.ts
|
|
4024
3980
|
function registerFixupCommand(program) {
|
|
4025
|
-
program.command("cf <hash>").description("Fixup commit for <hash> (e.g. guito cf abc123 -f)").option("-p, --push", "Push after creating the fixup commit").option("-f, --force", "Push with --force-with-lease after creating").action(
|
|
4026
|
-
try {
|
|
4027
|
-
await executeFixup(hash, opts);
|
|
4028
|
-
} catch (error) {
|
|
4029
|
-
if (error instanceof PrequitoError) {
|
|
4030
|
-
console.error(`✖ ${error.message}`);
|
|
4031
|
-
process.exit(1);
|
|
4032
|
-
}
|
|
4033
|
-
throw error;
|
|
4034
|
-
}
|
|
4035
|
-
});
|
|
3981
|
+
program.command("cf <hash>").description("Fixup commit for <hash> (e.g. guito cf abc123 -f)").option("-p, --push", "Push after creating the fixup commit").option("-f, --force", "Push with --force-with-lease after creating").action(withErrorHandling(executeFixup));
|
|
4036
3982
|
}
|
|
4037
3983
|
async function executeFixup(hash, opts) {
|
|
4038
|
-
|
|
4039
|
-
console.error("✖ Not inside a git repository.");
|
|
4040
|
-
process.exit(1);
|
|
4041
|
-
}
|
|
3984
|
+
await requireGitRepo();
|
|
4042
3985
|
const stopStage = spinner("Staging all changes...");
|
|
4043
3986
|
await stageAll();
|
|
4044
3987
|
stopStage("✔ Staged.");
|
|
4045
|
-
if (!await hasStagedChanges())
|
|
4046
|
-
console.error("✖ No staged changes to commit.");
|
|
4047
|
-
process.exit(1);
|
|
4048
|
-
}
|
|
3988
|
+
if (!await hasStagedChanges()) throw new PrequitoError("No staged changes to commit.");
|
|
4049
3989
|
const stopCommit = spinner(`Creating fixup commit for ${hash}...`);
|
|
4050
3990
|
await commitFixup(hash);
|
|
4051
3991
|
stopCommit("✔ Fixup commit created.");
|
|
@@ -4063,221 +4003,125 @@ async function executeFixup(hash, opts) {
|
|
|
4063
4003
|
//#endregion
|
|
4064
4004
|
//#region src/commands/undo.ts
|
|
4065
4005
|
function registerUndoCommand(program) {
|
|
4066
|
-
program.command("u [count]").alias("undo").description("Undo last N commits, keep changes staged (e.g. guito u 3)").action(async (count) => {
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
}
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
}
|
|
4076
|
-
});
|
|
4077
|
-
}
|
|
4078
|
-
async function executeUndo(count) {
|
|
4079
|
-
if (!await isGitRepo()) {
|
|
4080
|
-
console.error("✖ Not inside a git repository.");
|
|
4081
|
-
process.exit(1);
|
|
4082
|
-
}
|
|
4083
|
-
const num = count ? parseInt(count, 10) : 1;
|
|
4084
|
-
if (isNaN(num) || num <= 0) {
|
|
4085
|
-
console.error("✖ Count must be a positive integer.");
|
|
4086
|
-
process.exit(1);
|
|
4087
|
-
}
|
|
4088
|
-
const stop = spinner(`Undoing last ${num} commit(s)...`);
|
|
4089
|
-
await resetSoft(num);
|
|
4090
|
-
stop(`✔ Undid last ${num} commit(s). Changes are staged.`);
|
|
4091
|
-
const st = await status();
|
|
4092
|
-
if (st) console.log(st);
|
|
4006
|
+
program.command("u [count]").alias("undo").description("Undo last N commits, keep changes staged (e.g. guito u 3)").action(withErrorHandling(async (count) => {
|
|
4007
|
+
await requireGitRepo();
|
|
4008
|
+
const num = parseCount(count);
|
|
4009
|
+
console.log(`→ Undoing last ${num} commit(s)...`);
|
|
4010
|
+
await resetSoft(num);
|
|
4011
|
+
console.log(`✔ Undid last ${num} commit(s). Changes are staged.`);
|
|
4012
|
+
const st = await status();
|
|
4013
|
+
if (st) console.log(st);
|
|
4014
|
+
}));
|
|
4093
4015
|
}
|
|
4094
4016
|
|
|
4095
4017
|
//#endregion
|
|
4096
4018
|
//#region src/commands/status.ts
|
|
4097
4019
|
function registerStatusCommand(program) {
|
|
4098
|
-
program.command("s").alias("status").description("Short status (git status --short)").action(async () => {
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
process.exit(1);
|
|
4105
|
-
}
|
|
4106
|
-
throw error;
|
|
4107
|
-
}
|
|
4108
|
-
});
|
|
4109
|
-
}
|
|
4110
|
-
async function executeStatus() {
|
|
4111
|
-
if (!await isGitRepo()) {
|
|
4112
|
-
console.error("✖ Not inside a git repository.");
|
|
4113
|
-
process.exit(1);
|
|
4114
|
-
}
|
|
4115
|
-
const output = await status();
|
|
4116
|
-
if (output) console.log(output.trimEnd());
|
|
4117
|
-
else console.log("✨ Nothing to commit, working tree clean.");
|
|
4020
|
+
program.command("s").alias("status").description("Short status (git status --short)").action(withErrorHandling(async () => {
|
|
4021
|
+
await requireGitRepo();
|
|
4022
|
+
const output = await status();
|
|
4023
|
+
if (output) console.log(output.trimEnd());
|
|
4024
|
+
else console.log("✨ Nothing to commit, working tree clean.");
|
|
4025
|
+
}));
|
|
4118
4026
|
}
|
|
4119
4027
|
|
|
4120
4028
|
//#endregion
|
|
4121
4029
|
//#region src/commands/switch.ts
|
|
4122
4030
|
function registerSwitchCommand(program) {
|
|
4123
|
-
program.command("sw <branch>").alias("switch").description("Switch branch, -n to create (e.g. guito sw -n feature/x)").option("-n, --new", "Create a new branch").action(async (branch, opts) => {
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
}
|
|
4133
|
-
});
|
|
4134
|
-
}
|
|
4135
|
-
async function executeSwitch(branch, opts) {
|
|
4136
|
-
if (!await isGitRepo()) {
|
|
4137
|
-
console.error("✖ Not inside a git repository.");
|
|
4138
|
-
process.exit(1);
|
|
4139
|
-
}
|
|
4140
|
-
const stop = spinner(opts.new ? `Creating and switching to ${branch}...` : `Switching to ${branch}...`);
|
|
4141
|
-
if (opts.new) await createBranch(branch);
|
|
4142
|
-
else await checkout(branch);
|
|
4143
|
-
stop(`✔ On branch ${branch}.`);
|
|
4031
|
+
program.command("sw <branch>").alias("switch").description("Switch branch, -n to create (e.g. guito sw -n feature/x)").option("-n, --new", "Create a new branch").action(withErrorHandling(async (branch, opts) => {
|
|
4032
|
+
await requireGitRepo();
|
|
4033
|
+
if (opts.new) {
|
|
4034
|
+
console.log(`→ Creating and switching to ${branch}...`);
|
|
4035
|
+
await createBranch(branch);
|
|
4036
|
+
} else {
|
|
4037
|
+
console.log(`→ Switching to ${branch}...`);
|
|
4038
|
+
await checkout(branch);
|
|
4039
|
+
}
|
|
4040
|
+
console.log(`✔ On branch ${branch}.`);
|
|
4041
|
+
}));
|
|
4144
4042
|
}
|
|
4145
4043
|
|
|
4146
4044
|
//#endregion
|
|
4147
4045
|
//#region src/commands/stash.ts
|
|
4148
4046
|
function registerStashCommands(program) {
|
|
4149
|
-
program.command("st").description("Stash all changes (git stash)").action(async () => {
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
throw error;
|
|
4169
|
-
}
|
|
4170
|
-
});
|
|
4171
|
-
}
|
|
4172
|
-
async function executeStash() {
|
|
4173
|
-
if (!await isGitRepo()) {
|
|
4174
|
-
console.error("✖ Not inside a git repository.");
|
|
4175
|
-
process.exit(1);
|
|
4176
|
-
}
|
|
4177
|
-
const stop = spinner("Stashing changes...");
|
|
4178
|
-
await stash();
|
|
4179
|
-
stop("✔ Stashed.");
|
|
4180
|
-
}
|
|
4181
|
-
async function executeStashPop() {
|
|
4182
|
-
if (!await isGitRepo()) {
|
|
4183
|
-
console.error("✖ Not inside a git repository.");
|
|
4184
|
-
process.exit(1);
|
|
4185
|
-
}
|
|
4186
|
-
const stop = spinner("Restoring stashed changes...");
|
|
4187
|
-
await stashPop();
|
|
4188
|
-
stop("✔ Restored.");
|
|
4047
|
+
program.command("st").description("Stash all changes (git stash)").option("-m, --message <message>", "Stash with a descriptive message").action(withErrorHandling(async (opts) => {
|
|
4048
|
+
await requireGitRepo();
|
|
4049
|
+
if (opts.message) console.log(`→ Stashing changes: ${opts.message}...`);
|
|
4050
|
+
else console.log("→ Stashing changes...");
|
|
4051
|
+
await stash(opts.message);
|
|
4052
|
+
console.log("✔ Stashed.");
|
|
4053
|
+
}));
|
|
4054
|
+
program.command("stp").description("Pop the latest stash (git stash pop)").action(withErrorHandling(async () => {
|
|
4055
|
+
await requireGitRepo();
|
|
4056
|
+
console.log("→ Restoring stashed changes...");
|
|
4057
|
+
await stashPop();
|
|
4058
|
+
console.log("✔ Restored.");
|
|
4059
|
+
}));
|
|
4060
|
+
program.command("stl").description("List all stashes (git stash list)").action(withErrorHandling(async () => {
|
|
4061
|
+
await requireGitRepo();
|
|
4062
|
+
const output = await stashList();
|
|
4063
|
+
if (output) console.log(output.trimEnd());
|
|
4064
|
+
else console.log("✨ No stashes found.");
|
|
4065
|
+
}));
|
|
4189
4066
|
}
|
|
4190
4067
|
|
|
4191
4068
|
//#endregion
|
|
4192
4069
|
//#region src/commands/log.ts
|
|
4193
4070
|
function registerLogCommand(program) {
|
|
4194
|
-
program.command("l [count]").alias("log").description("Compact log, default last 10 (e.g. guito l 20)").action(async (count) => {
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
}
|
|
4202
|
-
throw error;
|
|
4203
|
-
}
|
|
4204
|
-
});
|
|
4205
|
-
}
|
|
4206
|
-
async function executeLog(count) {
|
|
4207
|
-
if (!await isGitRepo()) {
|
|
4208
|
-
console.error("✖ Not inside a git repository.");
|
|
4209
|
-
process.exit(1);
|
|
4210
|
-
}
|
|
4211
|
-
const num = count ? parseInt(count, 10) : 10;
|
|
4212
|
-
if (isNaN(num) || num <= 0) {
|
|
4213
|
-
console.error("✖ Count must be a positive integer.");
|
|
4214
|
-
process.exit(1);
|
|
4215
|
-
}
|
|
4216
|
-
const output = await logOneline(num);
|
|
4217
|
-
if (output) console.log(output.trimEnd());
|
|
4218
|
-
else console.log("✨ No commits found.");
|
|
4071
|
+
program.command("l [count]").alias("log").description("Compact log, default last 10 (e.g. guito l 20)").action(withErrorHandling(async (count) => {
|
|
4072
|
+
await requireGitRepo();
|
|
4073
|
+
const num = parseCount(count, 10);
|
|
4074
|
+
const output = await logOneline(num);
|
|
4075
|
+
if (output) console.log(output.trimEnd());
|
|
4076
|
+
else console.log("✨ No commits found.");
|
|
4077
|
+
}));
|
|
4219
4078
|
}
|
|
4220
4079
|
|
|
4221
4080
|
//#endregion
|
|
4222
4081
|
//#region src/commands/find.ts
|
|
4223
4082
|
function registerFindCommands(program) {
|
|
4224
|
-
program.command("f <keyword>").alias("find").description("Search commits by message (e.g. guito f \"login\")").option("-n, --number <count>", "Limit number of results").action(async (keyword, opts) => {
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
if (error instanceof PrequitoError) {
|
|
4229
|
-
console.error(`✖ ${error.message}`);
|
|
4230
|
-
process.exit(1);
|
|
4231
|
-
}
|
|
4232
|
-
throw error;
|
|
4233
|
-
}
|
|
4234
|
-
});
|
|
4235
|
-
program.command("t <tag>").alias("tag").description("Commits since <tag> (e.g. guito t v1.0.0)").option("-a, --all", "Show all commits reachable from the tag").action(async (tag, opts) => {
|
|
4236
|
-
try {
|
|
4237
|
-
await executeTag(tag, opts);
|
|
4238
|
-
} catch (error) {
|
|
4239
|
-
if (error instanceof PrequitoError) {
|
|
4240
|
-
console.error(`✖ ${error.message}`);
|
|
4241
|
-
process.exit(1);
|
|
4242
|
-
}
|
|
4243
|
-
throw error;
|
|
4244
|
-
}
|
|
4245
|
-
});
|
|
4246
|
-
}
|
|
4247
|
-
async function executeFind(keyword, opts) {
|
|
4248
|
-
if (!await isGitRepo()) {
|
|
4249
|
-
console.error("✖ Not inside a git repository.");
|
|
4250
|
-
process.exit(1);
|
|
4251
|
-
}
|
|
4252
|
-
const count = opts.number ? parseInt(opts.number, 10) : void 0;
|
|
4253
|
-
const stop = spinner(`Searching for "${keyword}"...`);
|
|
4254
|
-
const output = await logGrep(keyword, count);
|
|
4255
|
-
stop("");
|
|
4256
|
-
if (output) console.log(output.trimEnd());
|
|
4257
|
-
else console.log(`✨ No commits found matching "${keyword}".`);
|
|
4258
|
-
}
|
|
4259
|
-
async function executeTag(tag, opts) {
|
|
4260
|
-
if (!await isGitRepo()) {
|
|
4261
|
-
console.error("✖ Not inside a git repository.");
|
|
4262
|
-
process.exit(1);
|
|
4263
|
-
}
|
|
4264
|
-
if (opts.all) {
|
|
4265
|
-
console.log(`🏷️ Commits reachable from ${tag}:`);
|
|
4266
|
-
const output = await logTagAll(tag);
|
|
4083
|
+
program.command("f <keyword>").alias("find").description("Search commits by message (e.g. guito f \"login\")").option("-n, --number <count>", "Limit number of results").action(withErrorHandling(async (keyword, opts) => {
|
|
4084
|
+
await requireGitRepo();
|
|
4085
|
+
const count = opts.number ? parseInt(opts.number, 10) : void 0;
|
|
4086
|
+
const output = await logGrep(keyword, count);
|
|
4267
4087
|
if (output) console.log(output.trimEnd());
|
|
4268
|
-
else console.log(
|
|
4269
|
-
}
|
|
4270
|
-
|
|
4271
|
-
|
|
4088
|
+
else console.log(`✨ No commits found matching "${keyword}".`);
|
|
4089
|
+
}));
|
|
4090
|
+
program.command("t <tag>").alias("tag").description("Commits since <tag> (e.g. guito t v1.0.0)").option("-a, --all", "Show all commits reachable from the tag").action(withErrorHandling(async (tag, opts) => {
|
|
4091
|
+
await requireGitRepo();
|
|
4092
|
+
if (opts.all) {
|
|
4093
|
+
console.log(`🏷️ Commits reachable from ${tag}:`);
|
|
4094
|
+
const output = await logTagAll(tag);
|
|
4095
|
+
if (output) console.log(output.trimEnd());
|
|
4096
|
+
else console.log("✨ No commits found.");
|
|
4097
|
+
} else {
|
|
4098
|
+
console.log(`🏷️ Commits since ${tag}:`);
|
|
4099
|
+
const output = await logTag(tag);
|
|
4100
|
+
if (output) console.log(output.trimEnd());
|
|
4101
|
+
else console.log("✨ No commits since this tag.");
|
|
4102
|
+
}
|
|
4103
|
+
}));
|
|
4104
|
+
}
|
|
4105
|
+
|
|
4106
|
+
//#endregion
|
|
4107
|
+
//#region src/commands/diff.ts
|
|
4108
|
+
function registerDiffCommand(program) {
|
|
4109
|
+
program.command("d").alias("diff").description("Show changes (git diff)").option("-s, --staged", "Show staged changes only").option("--stat", "Show diffstat summary").option("-n, --name-only", "Show only names of changed files").action(withErrorHandling(async (opts) => {
|
|
4110
|
+
await requireGitRepo();
|
|
4111
|
+
const options = [];
|
|
4112
|
+
if (opts.staged) options.push("--staged");
|
|
4113
|
+
if (opts.stat) options.push("--stat");
|
|
4114
|
+
if (opts.nameOnly) options.push("--name-only");
|
|
4115
|
+
const output = await diff(options);
|
|
4272
4116
|
if (output) console.log(output.trimEnd());
|
|
4273
|
-
else console.log("✨ No
|
|
4274
|
-
}
|
|
4117
|
+
else console.log("✨ No changes.");
|
|
4118
|
+
}));
|
|
4275
4119
|
}
|
|
4276
4120
|
|
|
4277
4121
|
//#endregion
|
|
4278
4122
|
//#region src/cli.ts
|
|
4279
4123
|
const program = new Command();
|
|
4280
|
-
program.name("guito").description("preguito - a lazy git CLI with commit templates and shortcuts").version("0.
|
|
4124
|
+
program.name("guito").description("preguito - a lazy git CLI with commit templates and shortcuts").version("0.2.3").addHelpText("before", "\n🦥 preguito v0.1.0\n A lazy git CLI with commit templates and shortcuts.\n");
|
|
4281
4125
|
registerCommitCommand(program);
|
|
4282
4126
|
registerAmendPushCommands(program);
|
|
4283
4127
|
registerRebaseCommands(program);
|
|
@@ -4291,6 +4135,7 @@ registerSwitchCommand(program);
|
|
|
4291
4135
|
registerStashCommands(program);
|
|
4292
4136
|
registerLogCommand(program);
|
|
4293
4137
|
registerFindCommands(program);
|
|
4138
|
+
registerDiffCommand(program);
|
|
4294
4139
|
program.parse();
|
|
4295
4140
|
|
|
4296
4141
|
//#endregion
|