Skip to content

Commit 14717ff

Browse files
committed
refactor: improve code readability and add Husky v9 peer dependency
- Refactor cli.ts and init.ts from procedural to declarative approach - Add husky@^9.0.0 as peer dependency for clearer version requirements - Simplify Husky validation logic by leveraging npm's peer dependency warnings - Improve error messages with clear installation instructions
1 parent 2f164f1 commit 14717ff

File tree

8 files changed

+347
-93
lines changed

8 files changed

+347
-93
lines changed

dist/chunk-SZTIE65V.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// src/init.ts
2+
import fs from "fs";
3+
import path from "path";
4+
var HUSKY_FILE = "prepare-commit-msg";
5+
var HOOK_LINE = 'cfb "$1" "$2" "$3"';
6+
var createHuskyState = (cwd) => {
7+
const huskyDir = path.join(cwd, ".husky");
8+
const hookPath = path.join(huskyDir, HUSKY_FILE);
9+
const huskyExists = fs.existsSync(huskyDir);
10+
const hookExists = fs.existsSync(hookPath);
11+
let currentContent;
12+
let hookPresent;
13+
if (hookExists) {
14+
currentContent = fs.readFileSync(hookPath, "utf8");
15+
hookPresent = currentContent.includes(HOOK_LINE);
16+
}
17+
return {
18+
huskyDir,
19+
hookPath,
20+
huskyExists,
21+
hookExists,
22+
currentContent,
23+
hookPresent
24+
};
25+
};
26+
var initStrategies = [
27+
(state) => !state.huskyExists ? {
28+
exitCode: 1,
29+
message: [
30+
"[cfb] Husky not found. This package requires Husky v9 as a peer dependency.",
31+
"",
32+
" Install and initialize Husky v9:",
33+
" npm install --save-dev husky@^9.0.0",
34+
" npm exec husky init",
35+
"",
36+
" Then run: cfb init"
37+
].join("\n")
38+
} : null,
39+
(state) => !state.hookExists ? {
40+
exitCode: 0,
41+
message: "[cfb] \u2713 Created .husky/prepare-commit-msg and added cfb hook",
42+
action: () => {
43+
fs.writeFileSync(state.hookPath, HOOK_LINE, "utf8");
44+
fs.chmodSync(state.hookPath, 493);
45+
}
46+
} : null,
47+
(state) => state.hookPresent ? {
48+
exitCode: 0,
49+
message: "[cfb] \u2713 Hook already present"
50+
} : null,
51+
(state) => ({
52+
exitCode: 0,
53+
message: "[cfb] \u2713 Appended cfb hook to existing prepare-commit-msg",
54+
action: () => {
55+
const updated = state.currentContent.trimEnd() + `
56+
57+
${HOOK_LINE}
58+
`;
59+
fs.writeFileSync(state.hookPath, updated, "utf8");
60+
}
61+
})
62+
];
63+
var applyInitStrategy = (state) => {
64+
for (const strategy of initStrategies) {
65+
const result = strategy(state);
66+
if (result) return result;
67+
}
68+
return { exitCode: 1, message: "[cfb] unexpected error" };
69+
};
70+
function initHusky(cwd = process.cwd()) {
71+
const state = createHuskyState(cwd);
72+
const result = applyInitStrategy(state);
73+
result.action?.();
74+
console.log(result.message);
75+
return result.exitCode;
76+
}
77+
78+
export {
79+
initHusky
80+
};

dist/cli.cjs

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ var createLogger = (debug) => (...args) => {
8686
if (debug) console.log("[cfb]", ...args);
8787
};
8888
var createInitialState = (opts = {}) => {
89-
const argv2 = opts.argv ?? process.argv;
89+
const argv = opts.argv ?? process.argv;
9090
const env = opts.env ?? process.env;
9191
const cwd = opts.cwd ?? process.cwd();
92-
const [, , commitMsgPath, source] = argv2;
92+
const [, , commitMsgPath, source] = argv;
9393
if (!commitMsgPath) return null;
9494
const config = loadConfig(cwd);
9595
const branch = getCurrentBranch();
@@ -254,40 +254,90 @@ var import_fs3 = __toESM(require("fs"), 1);
254254
var import_path2 = __toESM(require("path"), 1);
255255
var HUSKY_FILE = "prepare-commit-msg";
256256
var HOOK_LINE = 'cfb "$1" "$2" "$3"';
257-
function initHusky(cwd = process.cwd()) {
257+
var createHuskyState = (cwd) => {
258258
const huskyDir = import_path2.default.join(cwd, ".husky");
259259
const hookPath = import_path2.default.join(huskyDir, HUSKY_FILE);
260-
if (!import_fs3.default.existsSync(huskyDir)) {
261-
console.log("[cfb] .husky not found. Run `npx husky init` first.");
262-
return 0;
263-
}
264-
if (!import_fs3.default.existsSync(hookPath)) {
265-
const commandLine = HOOK_LINE;
266-
import_fs3.default.writeFileSync(hookPath, commandLine, "utf8");
267-
import_fs3.default.chmodSync(hookPath, 493);
268-
console.log("[cfb] created .husky/prepare-commit-msg and added cfb hook");
269-
return 0;
260+
const huskyExists = import_fs3.default.existsSync(huskyDir);
261+
const hookExists = import_fs3.default.existsSync(hookPath);
262+
let currentContent;
263+
let hookPresent;
264+
if (hookExists) {
265+
currentContent = import_fs3.default.readFileSync(hookPath, "utf8");
266+
hookPresent = currentContent.includes(HOOK_LINE);
270267
}
271-
const current = import_fs3.default.readFileSync(hookPath, "utf8");
272-
if (current.includes(HOOK_LINE)) {
273-
console.log("[cfb] hook already present");
274-
return 0;
275-
}
276-
const updated = current.trimEnd() + `
268+
return {
269+
huskyDir,
270+
hookPath,
271+
huskyExists,
272+
hookExists,
273+
currentContent,
274+
hookPresent
275+
};
276+
};
277+
var initStrategies = [
278+
(state) => !state.huskyExists ? {
279+
exitCode: 1,
280+
message: [
281+
"[cfb] Husky not found. This package requires Husky v9 as a peer dependency.",
282+
"",
283+
" Install and initialize Husky v9:",
284+
" npm install --save-dev husky@^9.0.0",
285+
" npm exec husky init",
286+
"",
287+
" Then run: cfb init"
288+
].join("\n")
289+
} : null,
290+
(state) => !state.hookExists ? {
291+
exitCode: 0,
292+
message: "[cfb] \u2713 Created .husky/prepare-commit-msg and added cfb hook",
293+
action: () => {
294+
import_fs3.default.writeFileSync(state.hookPath, HOOK_LINE, "utf8");
295+
import_fs3.default.chmodSync(state.hookPath, 493);
296+
}
297+
} : null,
298+
(state) => state.hookPresent ? {
299+
exitCode: 0,
300+
message: "[cfb] \u2713 Hook already present"
301+
} : null,
302+
(state) => ({
303+
exitCode: 0,
304+
message: "[cfb] \u2713 Appended cfb hook to existing prepare-commit-msg",
305+
action: () => {
306+
const updated = state.currentContent.trimEnd() + `
277307
278308
${HOOK_LINE}
279309
`;
280-
import_fs3.default.writeFileSync(hookPath, updated, "utf8");
281-
console.log("[cfb] appended cfb hook to existing prepare-commit-msg");
282-
return 0;
310+
import_fs3.default.writeFileSync(state.hookPath, updated, "utf8");
311+
}
312+
})
313+
];
314+
var applyInitStrategy = (state) => {
315+
for (const strategy of initStrategies) {
316+
const result = strategy(state);
317+
if (result) return result;
318+
}
319+
return { exitCode: 1, message: "[cfb] unexpected error" };
320+
};
321+
function initHusky(cwd = process.cwd()) {
322+
const state = createHuskyState(cwd);
323+
const result = applyInitStrategy(state);
324+
result.action?.();
325+
console.log(result.message);
326+
return result.exitCode;
283327
}
284328

285329
// src/cli.ts
286-
var argv = process.argv.slice(2);
287-
var cmd = argv[0];
288-
if (cmd === "init") {
289-
process.exit(initHusky(process.cwd()) || 0);
290-
} else {
291-
const passthroughArgv = [process.argv[0], process.argv[1], ...argv];
292-
process.exit(run({ argv: passthroughArgv }) || 0);
293-
}
330+
var createCommandHandlers = (argv) => ({
331+
init: () => initHusky(process.cwd()) || 0,
332+
default: () => {
333+
const passthroughArgv = [process.argv[0], process.argv[1], ...argv];
334+
return run({ argv: passthroughArgv }) || 0;
335+
}
336+
});
337+
var executeCommand = (argv) => {
338+
const [cmd] = argv;
339+
const handlers = createCommandHandlers(argv);
340+
const handler = handlers[cmd] || handlers.default;
341+
return handler();
342+
};
343+
process.exit(executeCommand(process.argv.slice(2)));

dist/cli.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ import {
44
} from "./chunk-EMG7656X.js";
55
import {
66
initHusky
7-
} from "./chunk-4EHHYCRE.js";
7+
} from "./chunk-SZTIE65V.js";
88

99
// src/cli.ts
10-
var argv = process.argv.slice(2);
11-
var cmd = argv[0];
12-
if (cmd === "init") {
13-
process.exit(initHusky(process.cwd()) || 0);
14-
} else {
15-
const passthroughArgv = [process.argv[0], process.argv[1], ...argv];
16-
process.exit(run({ argv: passthroughArgv }) || 0);
17-
}
10+
var createCommandHandlers = (argv) => ({
11+
init: () => initHusky(process.cwd()) || 0,
12+
default: () => {
13+
const passthroughArgv = [process.argv[0], process.argv[1], ...argv];
14+
return run({ argv: passthroughArgv }) || 0;
15+
}
16+
});
17+
var executeCommand = (argv) => {
18+
const [cmd] = argv;
19+
const handlers = createCommandHandlers(argv);
20+
const handler = handlers[cmd] || handlers.default;
21+
return handler();
22+
};
23+
process.exit(executeCommand(process.argv.slice(2)));

dist/init.cjs

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,32 +37,76 @@ var import_fs = __toESM(require("fs"), 1);
3737
var import_path = __toESM(require("path"), 1);
3838
var HUSKY_FILE = "prepare-commit-msg";
3939
var HOOK_LINE = 'cfb "$1" "$2" "$3"';
40-
function initHusky(cwd = process.cwd()) {
40+
var createHuskyState = (cwd) => {
4141
const huskyDir = import_path.default.join(cwd, ".husky");
4242
const hookPath = import_path.default.join(huskyDir, HUSKY_FILE);
43-
if (!import_fs.default.existsSync(huskyDir)) {
44-
console.log("[cfb] .husky not found. Run `npx husky init` first.");
45-
return 0;
46-
}
47-
if (!import_fs.default.existsSync(hookPath)) {
48-
const commandLine = HOOK_LINE;
49-
import_fs.default.writeFileSync(hookPath, commandLine, "utf8");
50-
import_fs.default.chmodSync(hookPath, 493);
51-
console.log("[cfb] created .husky/prepare-commit-msg and added cfb hook");
52-
return 0;
43+
const huskyExists = import_fs.default.existsSync(huskyDir);
44+
const hookExists = import_fs.default.existsSync(hookPath);
45+
let currentContent;
46+
let hookPresent;
47+
if (hookExists) {
48+
currentContent = import_fs.default.readFileSync(hookPath, "utf8");
49+
hookPresent = currentContent.includes(HOOK_LINE);
5350
}
54-
const current = import_fs.default.readFileSync(hookPath, "utf8");
55-
if (current.includes(HOOK_LINE)) {
56-
console.log("[cfb] hook already present");
57-
return 0;
58-
}
59-
const updated = current.trimEnd() + `
51+
return {
52+
huskyDir,
53+
hookPath,
54+
huskyExists,
55+
hookExists,
56+
currentContent,
57+
hookPresent
58+
};
59+
};
60+
var initStrategies = [
61+
(state) => !state.huskyExists ? {
62+
exitCode: 1,
63+
message: [
64+
"[cfb] Husky not found. This package requires Husky v9 as a peer dependency.",
65+
"",
66+
" Install and initialize Husky v9:",
67+
" npm install --save-dev husky@^9.0.0",
68+
" npm exec husky init",
69+
"",
70+
" Then run: cfb init"
71+
].join("\n")
72+
} : null,
73+
(state) => !state.hookExists ? {
74+
exitCode: 0,
75+
message: "[cfb] \u2713 Created .husky/prepare-commit-msg and added cfb hook",
76+
action: () => {
77+
import_fs.default.writeFileSync(state.hookPath, HOOK_LINE, "utf8");
78+
import_fs.default.chmodSync(state.hookPath, 493);
79+
}
80+
} : null,
81+
(state) => state.hookPresent ? {
82+
exitCode: 0,
83+
message: "[cfb] \u2713 Hook already present"
84+
} : null,
85+
(state) => ({
86+
exitCode: 0,
87+
message: "[cfb] \u2713 Appended cfb hook to existing prepare-commit-msg",
88+
action: () => {
89+
const updated = state.currentContent.trimEnd() + `
6090
6191
${HOOK_LINE}
6292
`;
63-
import_fs.default.writeFileSync(hookPath, updated, "utf8");
64-
console.log("[cfb] appended cfb hook to existing prepare-commit-msg");
65-
return 0;
93+
import_fs.default.writeFileSync(state.hookPath, updated, "utf8");
94+
}
95+
})
96+
];
97+
var applyInitStrategy = (state) => {
98+
for (const strategy of initStrategies) {
99+
const result = strategy(state);
100+
if (result) return result;
101+
}
102+
return { exitCode: 1, message: "[cfb] unexpected error" };
103+
};
104+
function initHusky(cwd = process.cwd()) {
105+
const state = createHuskyState(cwd);
106+
const result = applyInitStrategy(state);
107+
result.action?.();
108+
console.log(result.message);
109+
return result.exitCode;
66110
}
67111
// Annotate the CommonJS export names for ESM import in node:
68112
0 && (module.exports = {

dist/init.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
22
initHusky
3-
} from "./chunk-4EHHYCRE.js";
3+
} from "./chunk-SZTIE65V.js";
44
export {
55
initHusky
66
};

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
"release:minor": "npm version minor && npm run release",
4848
"release:major": "npm version major && npm run release"
4949
},
50+
"peerDependencies": {
51+
"husky": "^9.0.0"
52+
},
5053
"devDependencies": {
5154
"@types/node": "^24.3.1",
5255
"tsup": "^8.0.0",

src/cli.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22
import { run } from './core';
33
import { initHusky } from './init';
44

5-
const argv = process.argv.slice(2);
6-
const cmd = argv[0];
7-
8-
if (cmd === 'init') {
9-
process.exit(initHusky(process.cwd()) || 0);
10-
} else {
11-
// passthrough: cfb "$1" "$2" "$3"
12-
// 원래 argv 구조 유지해야 하므로 다시 앞에 dummy 2개 붙여서 run에 전달
13-
const passthroughArgv = [process.argv[0], process.argv[1], ...argv];
14-
process.exit(run({ argv: passthroughArgv }) || 0);
15-
}
5+
type CommandHandler = () => number;
6+
7+
const createCommandHandlers = (argv: string[]): Record<string, CommandHandler> => ({
8+
init: () => initHusky(process.cwd()) || 0,
9+
default: () => {
10+
const passthroughArgv = [process.argv[0], process.argv[1], ...argv];
11+
return run({ argv: passthroughArgv }) || 0;
12+
}
13+
});
14+
15+
const executeCommand = (argv: string[]): number => {
16+
const [cmd] = argv;
17+
const handlers = createCommandHandlers(argv);
18+
const handler = handlers[cmd] || handlers.default;
19+
return handler();
20+
};
21+
22+
process.exit(executeCommand(process.argv.slice(2)));

0 commit comments

Comments
 (0)