ghagga 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/hooks/index.d.ts.map +1 -1
- package/dist/commands/hooks/index.js +2 -3
- package/dist/commands/hooks/index.js.map +1 -1
- package/dist/commands/hooks/install.d.ts +1 -1
- package/dist/commands/hooks/install.d.ts.map +1 -1
- package/dist/commands/hooks/install.js +2 -2
- package/dist/commands/hooks/install.js.map +1 -1
- package/dist/commands/hooks/install.test.js +23 -11
- package/dist/commands/hooks/install.test.js.map +1 -1
- package/dist/commands/hooks/status.d.ts +1 -1
- package/dist/commands/hooks/status.d.ts.map +1 -1
- package/dist/commands/hooks/status.js +1 -1
- package/dist/commands/hooks/status.js.map +1 -1
- package/dist/commands/hooks/status.test.js +44 -14
- package/dist/commands/hooks/status.test.js.map +1 -1
- package/dist/commands/hooks/uninstall.d.ts +1 -1
- package/dist/commands/hooks/uninstall.d.ts.map +1 -1
- package/dist/commands/hooks/uninstall.js +1 -1
- package/dist/commands/hooks/uninstall.js.map +1 -1
- package/dist/commands/hooks/uninstall.test.js +34 -12
- package/dist/commands/hooks/uninstall.test.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/login.test.js +5 -3
- package/dist/commands/login.test.js.map +1 -1
- package/dist/commands/logout.test.js +1 -1
- package/dist/commands/logout.test.js.map +1 -1
- package/dist/commands/memory/clear.d.ts +1 -1
- package/dist/commands/memory/clear.d.ts.map +1 -1
- package/dist/commands/memory/clear.js +1 -1
- package/dist/commands/memory/clear.js.map +1 -1
- package/dist/commands/memory/clear.test.js +5 -7
- package/dist/commands/memory/clear.test.js.map +1 -1
- package/dist/commands/memory/delete.d.ts +1 -1
- package/dist/commands/memory/delete.d.ts.map +1 -1
- package/dist/commands/memory/delete.js +2 -2
- package/dist/commands/memory/delete.js.map +1 -1
- package/dist/commands/memory/delete.test.js +5 -7
- package/dist/commands/memory/delete.test.js.map +1 -1
- package/dist/commands/memory/index.d.ts.map +1 -1
- package/dist/commands/memory/index.js +3 -4
- package/dist/commands/memory/index.js.map +1 -1
- package/dist/commands/memory/list.d.ts +1 -1
- package/dist/commands/memory/list.d.ts.map +1 -1
- package/dist/commands/memory/list.js +1 -1
- package/dist/commands/memory/list.js.map +1 -1
- package/dist/commands/memory/list.test.js +17 -5
- package/dist/commands/memory/list.test.js.map +1 -1
- package/dist/commands/memory/search.d.ts +1 -1
- package/dist/commands/memory/search.d.ts.map +1 -1
- package/dist/commands/memory/search.js +1 -1
- package/dist/commands/memory/search.js.map +1 -1
- package/dist/commands/memory/search.test.js +9 -4
- package/dist/commands/memory/search.test.js.map +1 -1
- package/dist/commands/memory/show.d.ts +1 -1
- package/dist/commands/memory/show.d.ts.map +1 -1
- package/dist/commands/memory/show.js +3 -5
- package/dist/commands/memory/show.js.map +1 -1
- package/dist/commands/memory/show.test.js +4 -6
- package/dist/commands/memory/show.test.js.map +1 -1
- package/dist/commands/memory/stats.d.ts +1 -1
- package/dist/commands/memory/stats.d.ts.map +1 -1
- package/dist/commands/memory/stats.js +3 -7
- package/dist/commands/memory/stats.js.map +1 -1
- package/dist/commands/memory/stats.test.js +3 -3
- package/dist/commands/memory/stats.test.js.map +1 -1
- package/dist/commands/memory/utils.d.ts.map +1 -1
- package/dist/commands/memory/utils.js +1 -1
- package/dist/commands/memory/utils.js.map +1 -1
- package/dist/commands/memory/utils.test.js +2 -2
- package/dist/commands/memory/utils.test.js.map +1 -1
- package/dist/commands/review-commit-msg.d.ts.map +1 -1
- package/dist/commands/review-commit-msg.js.map +1 -1
- package/dist/commands/review-commit-msg.test.js +11 -11
- package/dist/commands/review-commit-msg.test.js.map +1 -1
- package/dist/commands/review.d.ts +1 -1
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +14 -18
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/review.test.js +8 -7
- package/dist/commands/review.test.js.map +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/status.test.js +2 -2
- package/dist/commands/status.test.js.map +1 -1
- package/dist/index.js +17 -10
- package/dist/index.js.map +1 -1
- package/dist/lib/config.js +3 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.js +11 -9
- package/dist/lib/config.test.js.map +1 -1
- package/dist/lib/git-hooks.d.ts +1 -1
- package/dist/lib/git-hooks.d.ts.map +1 -1
- package/dist/lib/git-hooks.js +3 -3
- package/dist/lib/git-hooks.js.map +1 -1
- package/dist/lib/git-hooks.test.js +2 -2
- package/dist/lib/git-hooks.test.js.map +1 -1
- package/dist/lib/git.js +1 -1
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/git.test.js +5 -3
- package/dist/lib/git.test.js.map +1 -1
- package/dist/lib/hook-templates.test.js +2 -2
- package/dist/lib/hook-templates.test.js.map +1 -1
- package/dist/lib/oauth.js +1 -1
- package/dist/lib/oauth.js.map +1 -1
- package/dist/lib/oauth.test.js +4 -3
- package/dist/lib/oauth.test.js.map +1 -1
- package/dist/ui/__tests__/format.test.js +36 -7
- package/dist/ui/__tests__/format.test.js.map +1 -1
- package/dist/ui/__tests__/theme.test.js +16 -7
- package/dist/ui/__tests__/theme.test.js.map +1 -1
- package/dist/ui/__tests__/tui.test.js +8 -8
- package/dist/ui/__tests__/tui.test.js.map +1 -1
- package/dist/ui/format.d.ts.map +1 -1
- package/dist/ui/format.js +6 -6
- package/dist/ui/format.js.map +1 -1
- package/dist/ui/theme.d.ts +1 -1
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +1 -1
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/tui.js +1 -1
- package/dist/ui/tui.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,YAAY,SAExB,CAAC"}
|
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
import { registerInstallCommand } from './install.js';
|
|
9
|
-
import { registerUninstallCommand } from './uninstall.js';
|
|
10
9
|
import { registerStatusCommand } from './status.js';
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import { registerUninstallCommand } from './uninstall.js';
|
|
11
|
+
export const hooksCommand = new Command('hooks').description('Manage git hooks for automated code review');
|
|
13
12
|
registerInstallCommand(hooksCommand);
|
|
14
13
|
registerUninstallCommand(hooksCommand);
|
|
15
14
|
registerStatusCommand(hooksCommand);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAC1D,4CAA4C,CAC7C,CAAC;AAEF,sBAAsB,CAAC,YAAY,CAAC,CAAC;AACrC,wBAAwB,CAAC,YAAY,CAAC,CAAC;AACvC,qBAAqB,CAAC,YAAY,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYzC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAwD5D"}
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @see Phase 3, Task 3.2
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { getHooksDir, installHook, isGitRepo } from '../../lib/git-hooks.js';
|
|
12
|
+
import { generateCommitMsgHook, generatePreCommitHook } from '../../lib/hook-templates.js';
|
|
13
13
|
import * as tui from '../../ui/tui.js';
|
|
14
14
|
export function registerInstallCommand(parent) {
|
|
15
15
|
parent
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/commands/hooks/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/commands/hooks/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAE3F,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAQvC,MAAM,UAAU,sBAAsB,CAAC,MAAe;IACpD,MAAM;SACH,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,6CAA6C,CAAC;SAC1D,MAAM,CAAC,SAAS,EAAE,mDAAmD,CAAC;SACtE,MAAM,CAAC,cAAc,EAAE,kCAAkC,CAAC;SAC1D,MAAM,CAAC,cAAc,EAAE,kCAAkC,CAAC;SAC1D,MAAM,CAAC,CAAC,IAAoB,EAAE,EAAE;QAC/B,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACjB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;QAElC,oCAAoC;QACpC,oFAAoF;QACpF,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChF,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEhF,MAAM,KAAK,GAA+C,EAAE,CAAC;QAE7D,IAAI,gBAAgB,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,qBAAqB,EAAE;aACjC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,gBAAgB,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,qBAAqB,EAAE;aACjC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAErE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAChC,SAAS,EAAE,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QAED,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,SAAS,eAAe,QAAQ,EAAE,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @see Phase 4, Test 4
|
|
9
9
|
*/
|
|
10
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
11
10
|
import { Command } from 'commander';
|
|
11
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
12
12
|
// ─── Mocks ──────────────────────────────────────────────────────
|
|
13
13
|
const { mockIsGitRepo, mockGetHooksDir, mockInstallHook, mockGenPreCommit, mockGenCommitMsg } = vi.hoisted(() => ({
|
|
14
14
|
mockIsGitRepo: vi.fn(),
|
|
@@ -34,8 +34,8 @@ vi.mock('../../ui/tui.js', () => ({
|
|
|
34
34
|
warn: vi.fn(),
|
|
35
35
|
},
|
|
36
36
|
}));
|
|
37
|
-
import { registerInstallCommand } from './install.js';
|
|
38
37
|
import * as tui from '../../ui/tui.js';
|
|
38
|
+
import { registerInstallCommand } from './install.js';
|
|
39
39
|
// ─── Helpers ────────────────────────────────────────────────────
|
|
40
40
|
class ProcessExitError extends Error {
|
|
41
41
|
code;
|
|
@@ -56,13 +56,11 @@ async function runInstallCommand(args = []) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
// ─── Setup ──────────────────────────────────────────────────────
|
|
59
|
-
//
|
|
59
|
+
// biome-ignore lint/suspicious/noExplicitAny: mock spy type
|
|
60
60
|
let exitSpy;
|
|
61
61
|
beforeEach(() => {
|
|
62
62
|
vi.clearAllMocks();
|
|
63
|
-
exitSpy = vi
|
|
64
|
-
.spyOn(process, 'exit')
|
|
65
|
-
.mockImplementation(((code) => {
|
|
63
|
+
exitSpy = vi.spyOn(process, 'exit').mockImplementation(((code) => {
|
|
66
64
|
throw new ProcessExitError(code);
|
|
67
65
|
}));
|
|
68
66
|
// Defaults: in a git repo, hooks dir exists
|
|
@@ -83,8 +81,16 @@ afterEach(() => {
|
|
|
83
81
|
describe('ghagga hooks install', () => {
|
|
84
82
|
it('installs both hooks by default', async () => {
|
|
85
83
|
mockInstallHook
|
|
86
|
-
.mockReturnValueOnce({
|
|
87
|
-
|
|
84
|
+
.mockReturnValueOnce({
|
|
85
|
+
type: 'pre-commit',
|
|
86
|
+
success: true,
|
|
87
|
+
message: 'Installed pre-commit hook',
|
|
88
|
+
})
|
|
89
|
+
.mockReturnValueOnce({
|
|
90
|
+
type: 'commit-msg',
|
|
91
|
+
success: true,
|
|
92
|
+
message: 'Installed commit-msg hook',
|
|
93
|
+
});
|
|
88
94
|
await runInstallCommand();
|
|
89
95
|
expect(mockInstallHook).toHaveBeenCalledTimes(2);
|
|
90
96
|
expect(mockInstallHook).toHaveBeenCalledWith('/repo/.git/hooks', 'pre-commit', 'pre-commit-content', false);
|
|
@@ -93,7 +99,9 @@ describe('ghagga hooks install', () => {
|
|
|
93
99
|
});
|
|
94
100
|
it('installs only pre-commit when --pre-commit is passed', async () => {
|
|
95
101
|
mockInstallHook.mockReturnValue({
|
|
96
|
-
type: 'pre-commit',
|
|
102
|
+
type: 'pre-commit',
|
|
103
|
+
success: true,
|
|
104
|
+
message: 'Installed pre-commit hook',
|
|
97
105
|
});
|
|
98
106
|
await runInstallCommand(['--pre-commit']);
|
|
99
107
|
expect(mockInstallHook).toHaveBeenCalledTimes(1);
|
|
@@ -101,7 +109,9 @@ describe('ghagga hooks install', () => {
|
|
|
101
109
|
});
|
|
102
110
|
it('installs only commit-msg when --commit-msg is passed', async () => {
|
|
103
111
|
mockInstallHook.mockReturnValue({
|
|
104
|
-
type: 'commit-msg',
|
|
112
|
+
type: 'commit-msg',
|
|
113
|
+
success: true,
|
|
114
|
+
message: 'Installed commit-msg hook',
|
|
105
115
|
});
|
|
106
116
|
await runInstallCommand(['--commit-msg']);
|
|
107
117
|
expect(mockInstallHook).toHaveBeenCalledTimes(1);
|
|
@@ -109,7 +119,9 @@ describe('ghagga hooks install', () => {
|
|
|
109
119
|
});
|
|
110
120
|
it('passes force flag when --force is used', async () => {
|
|
111
121
|
mockInstallHook.mockReturnValue({
|
|
112
|
-
type: 'pre-commit',
|
|
122
|
+
type: 'pre-commit',
|
|
123
|
+
success: true,
|
|
124
|
+
message: 'Installed',
|
|
113
125
|
});
|
|
114
126
|
await runInstallCommand(['--force', '--pre-commit']);
|
|
115
127
|
expect(mockInstallHook).toHaveBeenCalledWith('/repo/.git/hooks', 'pre-commit', 'pre-commit-content', true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.test.js","sourceRoot":"","sources":["../../../src/commands/hooks/install.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"install.test.js","sourceRoot":"","sources":["../../../src/commands/hooks/install.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA0B3D"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @see Phase 3, Task 3.4
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
10
|
+
import { getHookStatus, getHooksDir, isGitRepo } from '../../lib/git-hooks.js';
|
|
11
11
|
import * as tui from '../../ui/tui.js';
|
|
12
12
|
const HOOK_TYPES = ['pre-commit', 'commit-msg'];
|
|
13
13
|
export function registerStatusCommand(parent) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/hooks/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/commands/hooks/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAE/E,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAEvC,MAAM,UAAU,GAAe,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AAE5D,MAAM,UAAU,qBAAqB,CAAC,MAAe;IACnD,MAAM;SACH,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,0BAA0B,CAAC;SACvC,MAAM,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACjB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAE/B,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,QAAQ,IAAI,CAAC,CAAC;QAE/C,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAEjD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACtB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ,iBAAiB,CAAC,CAAC;YAC/C,CAAC;iBAAM,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;gBAClC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,QAAQ,8BAA8B,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,QAAQ,gDAAgD,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @see Phase 4, Test 6
|
|
9
9
|
*/
|
|
10
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
11
10
|
import { Command } from 'commander';
|
|
11
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
12
12
|
// ─── Mocks ──────────────────────────────────────────────────────
|
|
13
13
|
const { mockIsGitRepo, mockGetHooksDir, mockGetHookStatus } = vi.hoisted(() => ({
|
|
14
14
|
mockIsGitRepo: vi.fn(),
|
|
@@ -28,8 +28,8 @@ vi.mock('../../ui/tui.js', () => ({
|
|
|
28
28
|
warn: vi.fn(),
|
|
29
29
|
},
|
|
30
30
|
}));
|
|
31
|
-
import { registerStatusCommand } from './status.js';
|
|
32
31
|
import * as tui from '../../ui/tui.js';
|
|
32
|
+
import { registerStatusCommand } from './status.js';
|
|
33
33
|
// ─── Helpers ────────────────────────────────────────────────────
|
|
34
34
|
class ProcessExitError extends Error {
|
|
35
35
|
code;
|
|
@@ -50,13 +50,11 @@ async function runStatusCommand(args = []) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
// ─── Setup ──────────────────────────────────────────────────────
|
|
53
|
-
//
|
|
53
|
+
// biome-ignore lint/suspicious/noExplicitAny: mock spy type
|
|
54
54
|
let exitSpy;
|
|
55
55
|
beforeEach(() => {
|
|
56
56
|
vi.clearAllMocks();
|
|
57
|
-
exitSpy = vi
|
|
58
|
-
.spyOn(process, 'exit')
|
|
59
|
-
.mockImplementation(((code) => {
|
|
57
|
+
exitSpy = vi.spyOn(process, 'exit').mockImplementation(((code) => {
|
|
60
58
|
throw new ProcessExitError(code);
|
|
61
59
|
}));
|
|
62
60
|
mockIsGitRepo.mockReturnValue(true);
|
|
@@ -69,8 +67,18 @@ afterEach(() => {
|
|
|
69
67
|
describe('ghagga hooks status', () => {
|
|
70
68
|
it('shows status for both pre-commit and commit-msg hooks', async () => {
|
|
71
69
|
mockGetHookStatus
|
|
72
|
-
.mockReturnValueOnce({
|
|
73
|
-
|
|
70
|
+
.mockReturnValueOnce({
|
|
71
|
+
type: 'pre-commit',
|
|
72
|
+
installed: true,
|
|
73
|
+
managedByGhagga: true,
|
|
74
|
+
path: '/repo/.git/hooks/pre-commit',
|
|
75
|
+
})
|
|
76
|
+
.mockReturnValueOnce({
|
|
77
|
+
type: 'commit-msg',
|
|
78
|
+
installed: false,
|
|
79
|
+
managedByGhagga: false,
|
|
80
|
+
path: '/repo/.git/hooks/commit-msg',
|
|
81
|
+
});
|
|
74
82
|
await runStatusCommand();
|
|
75
83
|
expect(mockGetHookStatus).toHaveBeenCalledTimes(2);
|
|
76
84
|
expect(mockGetHookStatus).toHaveBeenCalledWith('/repo/.git/hooks', 'pre-commit');
|
|
@@ -85,36 +93,58 @@ describe('ghagga hooks status', () => {
|
|
|
85
93
|
});
|
|
86
94
|
it('shows "not installed" for hooks that do not exist', async () => {
|
|
87
95
|
mockGetHookStatus.mockReturnValue({
|
|
88
|
-
type: 'pre-commit',
|
|
96
|
+
type: 'pre-commit',
|
|
97
|
+
installed: false,
|
|
98
|
+
managedByGhagga: false,
|
|
99
|
+
path: '/repo/.git/hooks/pre-commit',
|
|
89
100
|
});
|
|
90
101
|
await runStatusCommand();
|
|
91
102
|
expect(tui.log.info).toHaveBeenCalledWith(expect.stringContaining('not installed'));
|
|
92
103
|
});
|
|
93
104
|
it('shows "GHAGGA-managed" for installed GHAGGA hooks', async () => {
|
|
94
105
|
mockGetHookStatus.mockReturnValue({
|
|
95
|
-
type: 'pre-commit',
|
|
106
|
+
type: 'pre-commit',
|
|
107
|
+
installed: true,
|
|
108
|
+
managedByGhagga: true,
|
|
109
|
+
path: '/repo/.git/hooks/pre-commit',
|
|
96
110
|
});
|
|
97
111
|
await runStatusCommand();
|
|
98
112
|
expect(tui.log.success).toHaveBeenCalledWith(expect.stringContaining('GHAGGA-managed'));
|
|
99
113
|
});
|
|
100
114
|
it('shows "external" for installed non-GHAGGA hooks', async () => {
|
|
101
115
|
mockGetHookStatus.mockReturnValue({
|
|
102
|
-
type: 'pre-commit',
|
|
116
|
+
type: 'pre-commit',
|
|
117
|
+
installed: true,
|
|
118
|
+
managedByGhagga: false,
|
|
119
|
+
path: '/repo/.git/hooks/pre-commit',
|
|
103
120
|
});
|
|
104
121
|
await runStatusCommand();
|
|
105
122
|
expect(tui.log.warn).toHaveBeenCalledWith(expect.stringContaining('external'));
|
|
106
123
|
});
|
|
107
124
|
it('shows hooks directory path', async () => {
|
|
108
125
|
mockGetHookStatus.mockReturnValue({
|
|
109
|
-
type: 'pre-commit',
|
|
126
|
+
type: 'pre-commit',
|
|
127
|
+
installed: false,
|
|
128
|
+
managedByGhagga: false,
|
|
129
|
+
path: '/repo/.git/hooks/pre-commit',
|
|
110
130
|
});
|
|
111
131
|
await runStatusCommand();
|
|
112
132
|
expect(tui.log.info).toHaveBeenCalledWith(expect.stringContaining('/repo/.git/hooks'));
|
|
113
133
|
});
|
|
114
134
|
it('shows mixed status for different hooks', async () => {
|
|
115
135
|
mockGetHookStatus
|
|
116
|
-
.mockReturnValueOnce({
|
|
117
|
-
|
|
136
|
+
.mockReturnValueOnce({
|
|
137
|
+
type: 'pre-commit',
|
|
138
|
+
installed: true,
|
|
139
|
+
managedByGhagga: true,
|
|
140
|
+
path: '/repo/.git/hooks/pre-commit',
|
|
141
|
+
})
|
|
142
|
+
.mockReturnValueOnce({
|
|
143
|
+
type: 'commit-msg',
|
|
144
|
+
installed: true,
|
|
145
|
+
managedByGhagga: false,
|
|
146
|
+
path: '/repo/.git/hooks/commit-msg',
|
|
147
|
+
});
|
|
118
148
|
await runStatusCommand();
|
|
119
149
|
expect(tui.log.success).toHaveBeenCalledWith(expect.stringContaining('pre-commit'));
|
|
120
150
|
expect(tui.log.warn).toHaveBeenCalledWith(expect.stringContaining('commit-msg'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.test.js","sourceRoot":"","sources":["../../../src/commands/hooks/status.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"status.test.js","sourceRoot":"","sources":["../../../src/commands/hooks/status.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/uninstall.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../../src/commands/hooks/uninstall.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAgC9D"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @see Phase 3, Task 3.3
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
10
|
+
import { getHooksDir, isGitRepo, uninstallHook } from '../../lib/git-hooks.js';
|
|
11
11
|
import * as tui from '../../ui/tui.js';
|
|
12
12
|
const HOOK_TYPES = ['pre-commit', 'commit-msg'];
|
|
13
13
|
export function registerUninstallCommand(parent) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../../src/commands/hooks/uninstall.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../../src/commands/hooks/uninstall.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE/E,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAEvC,MAAM,UAAU,GAAe,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AAE5D,MAAM,UAAU,wBAAwB,CAAC,MAAe;IACtD,MAAM;SACH,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,iCAAiC,CAAC;SAC9C,MAAM,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACjB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAEjD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAChC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;oBACvC,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,OAAO,wBAAwB,QAAQ,EAAE,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @see Phase 4, Test 5
|
|
8
8
|
*/
|
|
9
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
10
9
|
import { Command } from 'commander';
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
11
11
|
// ─── Mocks ──────────────────────────────────────────────────────
|
|
12
12
|
const { mockIsGitRepo, mockGetHooksDir, mockUninstallHook } = vi.hoisted(() => ({
|
|
13
13
|
mockIsGitRepo: vi.fn(),
|
|
@@ -27,8 +27,8 @@ vi.mock('../../ui/tui.js', () => ({
|
|
|
27
27
|
warn: vi.fn(),
|
|
28
28
|
},
|
|
29
29
|
}));
|
|
30
|
-
import { registerUninstallCommand } from './uninstall.js';
|
|
31
30
|
import * as tui from '../../ui/tui.js';
|
|
31
|
+
import { registerUninstallCommand } from './uninstall.js';
|
|
32
32
|
// ─── Helpers ────────────────────────────────────────────────────
|
|
33
33
|
class ProcessExitError extends Error {
|
|
34
34
|
code;
|
|
@@ -49,13 +49,11 @@ async function runUninstallCommand(args = []) {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
// ─── Setup ──────────────────────────────────────────────────────
|
|
52
|
-
//
|
|
52
|
+
// biome-ignore lint/suspicious/noExplicitAny: mock spy type
|
|
53
53
|
let exitSpy;
|
|
54
54
|
beforeEach(() => {
|
|
55
55
|
vi.clearAllMocks();
|
|
56
|
-
exitSpy = vi
|
|
57
|
-
.spyOn(process, 'exit')
|
|
58
|
-
.mockImplementation(((code) => {
|
|
56
|
+
exitSpy = vi.spyOn(process, 'exit').mockImplementation(((code) => {
|
|
59
57
|
throw new ProcessExitError(code);
|
|
60
58
|
}));
|
|
61
59
|
mockIsGitRepo.mockReturnValue(true);
|
|
@@ -68,8 +66,16 @@ afterEach(() => {
|
|
|
68
66
|
describe('ghagga hooks uninstall', () => {
|
|
69
67
|
it('calls uninstallHook for both pre-commit and commit-msg', async () => {
|
|
70
68
|
mockUninstallHook
|
|
71
|
-
.mockReturnValueOnce({
|
|
72
|
-
|
|
69
|
+
.mockReturnValueOnce({
|
|
70
|
+
type: 'pre-commit',
|
|
71
|
+
success: true,
|
|
72
|
+
message: 'Removed pre-commit hook',
|
|
73
|
+
})
|
|
74
|
+
.mockReturnValueOnce({
|
|
75
|
+
type: 'commit-msg',
|
|
76
|
+
success: true,
|
|
77
|
+
message: 'Removed commit-msg hook',
|
|
78
|
+
});
|
|
73
79
|
await runUninstallCommand();
|
|
74
80
|
expect(mockUninstallHook).toHaveBeenCalledTimes(2);
|
|
75
81
|
expect(mockUninstallHook).toHaveBeenCalledWith('/repo/.git/hooks', 'pre-commit');
|
|
@@ -84,8 +90,16 @@ describe('ghagga hooks uninstall', () => {
|
|
|
84
90
|
});
|
|
85
91
|
it('shows success messages for removed hooks', async () => {
|
|
86
92
|
mockUninstallHook
|
|
87
|
-
.mockReturnValueOnce({
|
|
88
|
-
|
|
93
|
+
.mockReturnValueOnce({
|
|
94
|
+
type: 'pre-commit',
|
|
95
|
+
success: true,
|
|
96
|
+
message: 'Removed pre-commit hook',
|
|
97
|
+
})
|
|
98
|
+
.mockReturnValueOnce({
|
|
99
|
+
type: 'commit-msg',
|
|
100
|
+
success: true,
|
|
101
|
+
message: 'Removed commit-msg hook',
|
|
102
|
+
});
|
|
89
103
|
await runUninstallCommand();
|
|
90
104
|
expect(tui.log.success).toHaveBeenCalledWith('Removed pre-commit hook');
|
|
91
105
|
expect(tui.log.success).toHaveBeenCalledWith('Removed commit-msg hook');
|
|
@@ -111,8 +125,16 @@ describe('ghagga hooks uninstall', () => {
|
|
|
111
125
|
});
|
|
112
126
|
it('shows correct count when only one hook is actually removed', async () => {
|
|
113
127
|
mockUninstallHook
|
|
114
|
-
.mockReturnValueOnce({
|
|
115
|
-
|
|
128
|
+
.mockReturnValueOnce({
|
|
129
|
+
type: 'pre-commit',
|
|
130
|
+
success: true,
|
|
131
|
+
message: 'Removed pre-commit hook',
|
|
132
|
+
})
|
|
133
|
+
.mockReturnValueOnce({
|
|
134
|
+
type: 'commit-msg',
|
|
135
|
+
success: true,
|
|
136
|
+
message: 'Hook commit-msg not installed, nothing to remove',
|
|
137
|
+
});
|
|
116
138
|
await runUninstallCommand();
|
|
117
139
|
expect(tui.log.info).toHaveBeenCalledWith(expect.stringContaining('Removed 1 GHAGGA hook(s)'));
|
|
118
140
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uninstall.test.js","sourceRoot":"","sources":["../../../src/commands/hooks/uninstall.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"uninstall.test.js","sourceRoot":"","sources":["../../../src/commands/hooks/uninstall.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6BH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CA2DlD"}
|
package/dist/commands/login.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* and polls until the user authorizes. Saves the token to config.
|
|
6
6
|
*/
|
|
7
7
|
import { loadConfig, saveConfig } from '../lib/config.js';
|
|
8
|
-
import {
|
|
8
|
+
import { fetchGitHubUser, pollForAccessToken, requestDeviceCode } from '../lib/oauth.js';
|
|
9
9
|
import * as tui from '../ui/tui.js';
|
|
10
10
|
/**
|
|
11
11
|
* Try to open a URL in the default browser.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* already-logged-in shortcut, happy path, spinner lifecycle,
|
|
6
6
|
* browser auto-open, and error handling.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
9
9
|
// ─── Mocks ─────────────────────────────────────────────────────
|
|
10
10
|
vi.mock('../lib/config.js', () => ({
|
|
11
11
|
loadConfig: vi.fn(),
|
|
@@ -37,7 +37,7 @@ vi.mock('node:os', () => ({
|
|
|
37
37
|
platform: vi.fn().mockReturnValue('linux'),
|
|
38
38
|
}));
|
|
39
39
|
import { loadConfig, saveConfig } from '../lib/config.js';
|
|
40
|
-
import {
|
|
40
|
+
import { fetchGitHubUser, pollForAccessToken, requestDeviceCode } from '../lib/oauth.js';
|
|
41
41
|
import * as tui from '../ui/tui.js';
|
|
42
42
|
import { loginCommand } from './login.js';
|
|
43
43
|
const mockLoadConfig = vi.mocked(loadConfig);
|
|
@@ -46,7 +46,7 @@ const mockRequestDeviceCode = vi.mocked(requestDeviceCode);
|
|
|
46
46
|
const mockPollForAccessToken = vi.mocked(pollForAccessToken);
|
|
47
47
|
const mockFetchGitHubUser = vi.mocked(fetchGitHubUser);
|
|
48
48
|
// ─── Setup ─────────────────────────────────────────────────────
|
|
49
|
-
//
|
|
49
|
+
// biome-ignore lint/suspicious/noExplicitAny: mock spy type
|
|
50
50
|
let mockExit;
|
|
51
51
|
beforeEach(() => {
|
|
52
52
|
vi.clearAllMocks();
|
|
@@ -116,7 +116,9 @@ describe('loginCommand', () => {
|
|
|
116
116
|
expect(mockSpinner.start).toHaveBeenCalledWith('Waiting for authorization...');
|
|
117
117
|
expect(mockSpinner.stop).toHaveBeenCalledWith('Authorization received');
|
|
118
118
|
// start must be called before stop
|
|
119
|
+
// biome-ignore lint/style/noNonNullAssertion: test assertion on known mock data
|
|
119
120
|
const startOrder = mockSpinner.start.mock.invocationCallOrder[0];
|
|
121
|
+
// biome-ignore lint/style/noNonNullAssertion: test assertion on known mock data
|
|
120
122
|
const stopOrder = mockSpinner.stop.mock.invocationCallOrder[0];
|
|
121
123
|
expect(startOrder).toBeLessThan(stopOrder);
|
|
122
124
|
});
|