@howells/husky 0.1.0 → 0.1.2
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 +5 -3
- package/bin/howells-husky.mjs +51 -17
- package/package.json +13 -5
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ In `package.json`:
|
|
|
18
18
|
"prepare": "howells-husky"
|
|
19
19
|
},
|
|
20
20
|
"lint-staged": {
|
|
21
|
-
"*.{js,ts,jsx,tsx,json,jsonc,css}": "howells-
|
|
21
|
+
"*.{js,ts,jsx,tsx,json,jsonc,css}": "howells-ox-fix"
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
```
|
|
@@ -29,7 +29,9 @@ That's it. On `pnpm install`, the hooks are installed automatically.
|
|
|
29
29
|
|
|
30
30
|
### Pre-commit
|
|
31
31
|
|
|
32
|
-
Runs `pnpm lint-staged` — formats staged files with
|
|
32
|
+
Runs `pnpm lint-staged` — formats staged files with the configured Howells formatter.
|
|
33
|
+
Use `howells-ox-fix` for projects on the Ox lint path. `howells-format` remains supported
|
|
34
|
+
for older projects.
|
|
33
35
|
|
|
34
36
|
### Pre-push
|
|
35
37
|
|
|
@@ -41,7 +43,7 @@ Your `package.json` must have:
|
|
|
41
43
|
|
|
42
44
|
- `"typecheck"` script (e.g. `tsc --noEmit` or `turbo run typecheck`)
|
|
43
45
|
- `"lint"` script (e.g. `howells-lint` or `turbo run lint`)
|
|
44
|
-
- `"lint-staged"` config using `howells-format`
|
|
46
|
+
- `"lint-staged"` config using `howells-ox-fix` or `howells-format`
|
|
45
47
|
|
|
46
48
|
## Why a package?
|
|
47
49
|
|
package/bin/howells-husky.mjs
CHANGED
|
@@ -16,13 +16,46 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { spawnSync } from "node:child_process";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
copyFileSync,
|
|
21
|
+
existsSync,
|
|
22
|
+
mkdirSync,
|
|
23
|
+
readFileSync,
|
|
24
|
+
chmodSync,
|
|
25
|
+
} from "node:fs";
|
|
20
26
|
import { dirname, join, resolve } from "node:path";
|
|
21
27
|
import { fileURLToPath } from "node:url";
|
|
22
28
|
|
|
23
|
-
const __dirname =
|
|
29
|
+
const __dirname = import.meta.dirname;
|
|
24
30
|
const packageRoot = resolve(__dirname, "..");
|
|
25
31
|
const projectRoot = process.cwd();
|
|
32
|
+
// `howells-fix` is the current canonical @howells/lint fixer; `howells-ox-fix`
|
|
33
|
+
// and `howells-format` are earlier names still in use by repos mid-migration.
|
|
34
|
+
// Accept all three so a correct lint-staged config never draws a false warning.
|
|
35
|
+
const lintStagedFormatterCommands = [
|
|
36
|
+
"howells-fix",
|
|
37
|
+
"howells-ox-fix",
|
|
38
|
+
"howells-format",
|
|
39
|
+
];
|
|
40
|
+
const recommendedLintStagedCommand = "howells-fix";
|
|
41
|
+
|
|
42
|
+
function lintStagedCommandValues(config) {
|
|
43
|
+
return Object.values(config).flatMap((value) => {
|
|
44
|
+
if (typeof value === "string") {
|
|
45
|
+
return [value];
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(value)) {
|
|
48
|
+
return value.filter((item) => typeof item === "string");
|
|
49
|
+
}
|
|
50
|
+
return [];
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function usesSupportedFormatter(command) {
|
|
55
|
+
return lintStagedFormatterCommands.some((formatter) =>
|
|
56
|
+
command.includes(formatter)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
26
59
|
|
|
27
60
|
// Skip in CI environments — hooks aren't needed there
|
|
28
61
|
if (process.env.CI === "true" || process.env.VERCEL === "1") {
|
|
@@ -38,19 +71,22 @@ if (!existsSync(join(projectRoot, ".git"))) {
|
|
|
38
71
|
const huskyBin = resolve(packageRoot, "node_modules", ".bin", "husky");
|
|
39
72
|
const huskyResult = spawnSync(huskyBin, [], {
|
|
40
73
|
cwd: projectRoot,
|
|
41
|
-
stdio: "inherit",
|
|
42
74
|
env: process.env,
|
|
75
|
+
stdio: "inherit",
|
|
43
76
|
});
|
|
44
77
|
|
|
45
78
|
if (huskyResult.error) {
|
|
46
79
|
// Fallback: try resolving husky from the project's node_modules
|
|
47
80
|
const fallbackResult = spawnSync("npx", ["husky"], {
|
|
48
81
|
cwd: projectRoot,
|
|
49
|
-
stdio: "inherit",
|
|
50
82
|
env: process.env,
|
|
83
|
+
stdio: "inherit",
|
|
51
84
|
});
|
|
52
85
|
|
|
53
|
-
if (
|
|
86
|
+
if (
|
|
87
|
+
fallbackResult.error ||
|
|
88
|
+
(fallbackResult.status !== null && fallbackResult.status !== 0)
|
|
89
|
+
) {
|
|
54
90
|
console.error("[@howells/husky] Failed to initialise husky");
|
|
55
91
|
process.exit(1);
|
|
56
92
|
}
|
|
@@ -75,30 +111,28 @@ for (const hook of hooks) {
|
|
|
75
111
|
// Step 3: Validate lint-staged config
|
|
76
112
|
const packageJsonPath = join(projectRoot, "package.json");
|
|
77
113
|
if (existsSync(packageJsonPath)) {
|
|
78
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "
|
|
114
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
79
115
|
|
|
80
116
|
if (!packageJson["lint-staged"]) {
|
|
81
117
|
console.warn(
|
|
82
|
-
'[@howells/husky] Warning: no "lint-staged" config found in package.json.'
|
|
118
|
+
'[@howells/husky] Warning: no "lint-staged" config found in package.json.'
|
|
83
119
|
);
|
|
84
120
|
console.warn(
|
|
85
|
-
|
|
121
|
+
` Add: "lint-staged": { "*.{js,ts,jsx,tsx,json,jsonc,css}": "${recommendedLintStagedCommand}" }`
|
|
86
122
|
);
|
|
87
123
|
}
|
|
88
124
|
|
|
89
|
-
// Check that the lint-staged command uses
|
|
125
|
+
// Check that the lint-staged command uses a supported Howells formatter.
|
|
90
126
|
const lsConfig = packageJson["lint-staged"];
|
|
91
127
|
if (lsConfig) {
|
|
92
|
-
const commands =
|
|
93
|
-
const usesHowells = commands.some(
|
|
94
|
-
(cmd) => typeof cmd === "string" && cmd.includes("howells-format"),
|
|
95
|
-
);
|
|
128
|
+
const commands = lintStagedCommandValues(lsConfig);
|
|
129
|
+
const usesHowells = commands.some(usesSupportedFormatter);
|
|
96
130
|
if (!usesHowells) {
|
|
97
131
|
console.warn(
|
|
98
|
-
"[@howells/husky] Warning: lint-staged should use
|
|
132
|
+
"[@howells/husky] Warning: lint-staged should use a supported Howells formatter."
|
|
99
133
|
);
|
|
100
134
|
console.warn(
|
|
101
|
-
|
|
135
|
+
` Expected: "*.{js,ts,jsx,tsx,json,jsonc,css}": "${recommendedLintStagedCommand}"`
|
|
102
136
|
);
|
|
103
137
|
}
|
|
104
138
|
}
|
|
@@ -107,12 +141,12 @@ if (existsSync(packageJsonPath)) {
|
|
|
107
141
|
const scripts = packageJson.scripts || {};
|
|
108
142
|
if (!scripts.typecheck) {
|
|
109
143
|
console.warn(
|
|
110
|
-
'[@howells/husky] Warning: no "typecheck" script found. Pre-push hook requires it.'
|
|
144
|
+
'[@howells/husky] Warning: no "typecheck" script found. Pre-push hook requires it.'
|
|
111
145
|
);
|
|
112
146
|
}
|
|
113
147
|
if (!scripts.lint) {
|
|
114
148
|
console.warn(
|
|
115
|
-
'[@howells/husky] Warning: no "lint" script found. Pre-push hook requires it.'
|
|
149
|
+
'[@howells/husky] Warning: no "lint" script found. Pre-push hook requires it.'
|
|
116
150
|
);
|
|
117
151
|
}
|
|
118
152
|
}
|
package/package.json
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@howells/husky",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Standardised git hooks for Howells projects. Immutable pre-commit and pre-push configuration.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"bin": {
|
|
7
|
+
"howells-husky": "bin/howells-husky.mjs"
|
|
8
|
+
},
|
|
6
9
|
"files": [
|
|
7
10
|
"bin/*.mjs",
|
|
8
11
|
"hooks/*",
|
|
9
12
|
"README.md"
|
|
10
13
|
],
|
|
11
|
-
"
|
|
12
|
-
"
|
|
14
|
+
"exports": {
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"lint": "howells-ox-check --config=oxlint.config.ts package.json bin hooks README.md oxlint.config.ts oxfmt.config.ts",
|
|
19
|
+
"lint:fix": "howells-ox-fix --config=oxlint.config.ts package.json bin hooks README.md oxlint.config.ts oxfmt.config.ts",
|
|
20
|
+
"format": "howells-oxfmt --write package.json bin hooks README.md oxlint.config.ts oxfmt.config.ts README.md"
|
|
13
21
|
},
|
|
14
22
|
"dependencies": {
|
|
15
23
|
"husky": "^9.1.7",
|
|
16
24
|
"lint-staged": "^16.4.0"
|
|
17
25
|
},
|
|
18
|
-
"
|
|
19
|
-
"
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@howells/lint": "^0.2.1"
|
|
20
28
|
}
|
|
21
29
|
}
|