lechnerio-git-hooks 1.1.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/config/commitlint.config.js +29 -0
- package/config/lintstagedrc.js +4 -0
- package/hooks/commit-msg +1 -0
- package/hooks/post-commit +292 -0
- package/hooks/pre-commit +4 -0
- package/package.json +21 -0
- package/scripts/generate-changelog.mjs +77 -0
- package/setup.mjs +70 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
extends: ["@commitlint/config-conventional"],
|
|
3
|
+
rules: {
|
|
4
|
+
"type-enum": [
|
|
5
|
+
2,
|
|
6
|
+
"always",
|
|
7
|
+
[
|
|
8
|
+
"feat",
|
|
9
|
+
"fix",
|
|
10
|
+
"docs",
|
|
11
|
+
"style",
|
|
12
|
+
"refactor",
|
|
13
|
+
"test",
|
|
14
|
+
"chore",
|
|
15
|
+
"perf",
|
|
16
|
+
"revert",
|
|
17
|
+
"ci",
|
|
18
|
+
"typo",
|
|
19
|
+
"fun",
|
|
20
|
+
"update",
|
|
21
|
+
],
|
|
22
|
+
],
|
|
23
|
+
"type-case": [2, "always", "lower-case"],
|
|
24
|
+
"type-empty": [2, "never"],
|
|
25
|
+
"subject-empty": [2, "never"],
|
|
26
|
+
"subject-full-stop": [2, "never", "."],
|
|
27
|
+
"subject-case": [2, "always", "lower-case"],
|
|
28
|
+
},
|
|
29
|
+
}
|
package/hooks/commit-msg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
npx --no-install commitlint --edit
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
RED='\033[0;31m'
|
|
4
|
+
GREEN='\033[0;32m'
|
|
5
|
+
YELLOW='\033[1;33m'
|
|
6
|
+
BLUE='\033[0;34m'
|
|
7
|
+
CYAN='\033[0;36m'
|
|
8
|
+
GRAY='\033[0;90m'
|
|
9
|
+
NC='\033[0m'
|
|
10
|
+
|
|
11
|
+
if [ "$_SKIP_POST_COMMIT" = "1" ]; then
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
14
|
+
export _SKIP_POST_COMMIT=1
|
|
15
|
+
|
|
16
|
+
DRY_RUN=${1:-false}
|
|
17
|
+
|
|
18
|
+
get_version() {
|
|
19
|
+
node -p "require('./package.json').version"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get_subpatch() {
|
|
23
|
+
local ver=$(get_version)
|
|
24
|
+
if [[ "$ver" =~ ^[0-9]+\.[0-9]+\.[0-9]+([a-z])$ ]]; then
|
|
25
|
+
echo "${BASH_REMATCH[1]}"
|
|
26
|
+
else
|
|
27
|
+
echo ""
|
|
28
|
+
fi
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get_base_version() {
|
|
32
|
+
local ver=$(get_version)
|
|
33
|
+
echo "$ver" | sed 's/[a-z]$//'
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
next_subpatch() {
|
|
37
|
+
local current_sub=$(get_subpatch)
|
|
38
|
+
if [ -z "$current_sub" ]; then
|
|
39
|
+
echo "a"
|
|
40
|
+
else
|
|
41
|
+
echo "$current_sub" | tr 'a-y' 'b-z'
|
|
42
|
+
fi
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
set_version() {
|
|
46
|
+
local new_ver="$1"
|
|
47
|
+
node -e "
|
|
48
|
+
const fs = require('fs');
|
|
49
|
+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
50
|
+
pkg.version = '$new_ver';
|
|
51
|
+
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
|
|
52
|
+
"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
bump_and_amend() {
|
|
56
|
+
local new_ver="$1"
|
|
57
|
+
local label="$2"
|
|
58
|
+
set_version "$new_ver"
|
|
59
|
+
git add package.json
|
|
60
|
+
git commit --amend --no-edit
|
|
61
|
+
git tag -f -a "v${new_ver}" -m "v${new_ver}"
|
|
62
|
+
node scripts/generate-changelog.mjs 2>/dev/null
|
|
63
|
+
git add data/changelog.json
|
|
64
|
+
git commit --amend --no-edit --no-verify
|
|
65
|
+
git tag -f -a "v${new_ver}" -m "v${new_ver}"
|
|
66
|
+
echo -e "${GREEN}✅ $label version bumped to ${new_ver}${NC}"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
commit_message=$(git log -1 --pretty=%B)
|
|
70
|
+
if [[ "$commit_message" == *"Bump version"* ]] || [[ "$commit_message" == *"bump version"* ]]; then
|
|
71
|
+
echo -e "${YELLOW}⏭️ Skipping post-commit actions for version bump commit${NC}"
|
|
72
|
+
exit 0
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
echo
|
|
76
|
+
echo -e "${GREEN}🎉 Commit completed successfully!${NC}"
|
|
77
|
+
echo
|
|
78
|
+
|
|
79
|
+
node scripts/generate-changelog.mjs 2>/dev/null
|
|
80
|
+
if ! git diff --quiet data/changelog.json 2>/dev/null; then
|
|
81
|
+
git add data/changelog.json
|
|
82
|
+
git commit --amend --no-edit --no-verify
|
|
83
|
+
echo -e "${CYAN}📋 Changelog updated${NC}"
|
|
84
|
+
echo
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
files_changed=$(git diff --name-only HEAD~1 HEAD 2>/dev/null | wc -l)
|
|
88
|
+
lines_changed=$(git diff --shortstat HEAD~1 HEAD 2>/dev/null)
|
|
89
|
+
|
|
90
|
+
if [ "$files_changed" -eq 0 ] || [ -z "$lines_changed" ]; then
|
|
91
|
+
echo -e "${YELLOW}⚠️ No file changes detected in this commit.${NC}"
|
|
92
|
+
echo -e "${YELLOW}⏭️ Skipping version bump.${NC}"
|
|
93
|
+
echo
|
|
94
|
+
|
|
95
|
+
if [ -n "$POST_ACTION" ]; then
|
|
96
|
+
choice="$POST_ACTION"
|
|
97
|
+
elif exec < /dev/tty 2>/dev/null; then
|
|
98
|
+
echo -e "${CYAN}What would you like to do next?${NC}"
|
|
99
|
+
echo
|
|
100
|
+
echo "1) Push to GitHub"
|
|
101
|
+
echo "2) Merge to Main"
|
|
102
|
+
echo -e "${GRAY}0) None${NC}"
|
|
103
|
+
echo
|
|
104
|
+
echo -n "Select option (1-2, Enter for Default or 0 to skip): "
|
|
105
|
+
read -r choice
|
|
106
|
+
choice=${choice:-1}
|
|
107
|
+
else
|
|
108
|
+
choice=0
|
|
109
|
+
fi
|
|
110
|
+
echo
|
|
111
|
+
|
|
112
|
+
case $choice in
|
|
113
|
+
1)
|
|
114
|
+
echo -e "${YELLOW}✈️ Pushing to GitHub...${NC}"
|
|
115
|
+
if [ "$DRY_RUN" = "true" ]; then
|
|
116
|
+
echo -e "${YELLOW}[DRY RUN] Would execute: git push${NC}"
|
|
117
|
+
else
|
|
118
|
+
git push --follow-tags && git push --tags
|
|
119
|
+
if [ $? -eq 0 ]; then
|
|
120
|
+
echo -e "${GREEN}✅ Successfully pushed to GitHub${NC}"
|
|
121
|
+
else
|
|
122
|
+
echo -e "${RED}❌ Failed to push to GitHub${NC}"
|
|
123
|
+
fi
|
|
124
|
+
fi
|
|
125
|
+
;;
|
|
126
|
+
2)
|
|
127
|
+
echo -e "${YELLOW}🔄 Merging to main...${NC}"
|
|
128
|
+
if [ "$DRY_RUN" = "true" ]; then
|
|
129
|
+
echo -e "${YELLOW}[DRY RUN] Would execute: git checkout main && git merge $(git branch --show-current)${NC}"
|
|
130
|
+
else
|
|
131
|
+
current_branch=$(git branch --show-current)
|
|
132
|
+
git checkout main
|
|
133
|
+
git merge "$current_branch"
|
|
134
|
+
if [ $? -eq 0 ]; then
|
|
135
|
+
echo -e "${GREEN}✅ Successfully merged to main${NC}"
|
|
136
|
+
git checkout "$current_branch"
|
|
137
|
+
else
|
|
138
|
+
echo -e "${RED}❌ Failed to merge to main${NC}"
|
|
139
|
+
git checkout "$current_branch"
|
|
140
|
+
fi
|
|
141
|
+
fi
|
|
142
|
+
;;
|
|
143
|
+
0)
|
|
144
|
+
echo -e "${YELLOW}⏭️ Skipping additional actions${NC}"
|
|
145
|
+
;;
|
|
146
|
+
esac
|
|
147
|
+
echo
|
|
148
|
+
exit 0
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
echo -e "${BLUE}📝 Changes in this commit:${NC}"
|
|
152
|
+
echo -e "${YELLOW}$lines_changed${NC}"
|
|
153
|
+
echo
|
|
154
|
+
|
|
155
|
+
current_ver=$(get_version)
|
|
156
|
+
base_ver=$(get_base_version)
|
|
157
|
+
sub=$(get_subpatch)
|
|
158
|
+
next_sub=$(next_subpatch)
|
|
159
|
+
|
|
160
|
+
IFS='.' read -r major minor patch_raw <<< "$base_ver"
|
|
161
|
+
patch=$((patch_raw))
|
|
162
|
+
next_patch=$((patch + 1))
|
|
163
|
+
next_minor=$((minor + 1))
|
|
164
|
+
next_major=$((major + 1))
|
|
165
|
+
|
|
166
|
+
subtle_ver="${base_ver}${next_sub}"
|
|
167
|
+
patch_ver="${major}.${minor}.${next_patch}"
|
|
168
|
+
minor_ver="${major}.${next_minor}.0"
|
|
169
|
+
major_ver="${next_major}.0.0"
|
|
170
|
+
|
|
171
|
+
if [ -n "$VERSION_BUMP" ]; then
|
|
172
|
+
version_choice="$VERSION_BUMP"
|
|
173
|
+
elif exec < /dev/tty 2>/dev/null; then
|
|
174
|
+
echo -e "${CYAN}What version bump would you like to apply?${NC}"
|
|
175
|
+
echo
|
|
176
|
+
echo -e "1) Subtle Bump ${YELLOW}(default)${NC} ${GRAY}${current_ver} -> ${subtle_ver}${NC} - typos, formatting, comments, etc."
|
|
177
|
+
echo -e "2) Bump Patch ${GRAY}${current_ver} -> ${patch_ver}${NC} - bug fixes, small changes"
|
|
178
|
+
echo -e "3) Bump Minor ${GRAY}${current_ver} -> ${minor_ver}${NC} - new features, backwards compatible"
|
|
179
|
+
echo -e "4) Bump Major ${GRAY}${current_ver} -> ${major_ver}${NC} - breaking changes"
|
|
180
|
+
echo -e "${GRAY}0) Nothing - skip version bump${NC}"
|
|
181
|
+
echo
|
|
182
|
+
echo -n "Select option (1-4, Enter for Default or 0 to skip): "
|
|
183
|
+
read -r version_choice
|
|
184
|
+
version_choice=${version_choice:-1}
|
|
185
|
+
else
|
|
186
|
+
echo -e "${YELLOW}⏭️ No TTY available and VERSION_BUMP not set, skipping version bump${NC}"
|
|
187
|
+
version_choice=0
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
echo
|
|
191
|
+
|
|
192
|
+
case $version_choice in
|
|
193
|
+
1)
|
|
194
|
+
echo -e "${YELLOW}📦 Subtle bump...${NC}"
|
|
195
|
+
if [ "$DRY_RUN" = "true" ]; then
|
|
196
|
+
echo -e "${YELLOW}[DRY RUN] Would bump to ${subtle_ver}${NC}"
|
|
197
|
+
else
|
|
198
|
+
bump_and_amend "$subtle_ver" "Subtle"
|
|
199
|
+
fi
|
|
200
|
+
;;
|
|
201
|
+
2)
|
|
202
|
+
echo -e "${YELLOW}📦 Bumping patch version...${NC}"
|
|
203
|
+
if [ "$DRY_RUN" = "true" ]; then
|
|
204
|
+
echo -e "${YELLOW}[DRY RUN] Would bump to ${patch_ver}${NC}"
|
|
205
|
+
else
|
|
206
|
+
bump_and_amend "$patch_ver" "Patch"
|
|
207
|
+
fi
|
|
208
|
+
;;
|
|
209
|
+
3)
|
|
210
|
+
echo -e "${YELLOW}📦 Bumping minor version...${NC}"
|
|
211
|
+
if [ "$DRY_RUN" = "true" ]; then
|
|
212
|
+
echo -e "${YELLOW}[DRY RUN] Would bump to ${minor_ver}${NC}"
|
|
213
|
+
else
|
|
214
|
+
bump_and_amend "$minor_ver" "Minor"
|
|
215
|
+
fi
|
|
216
|
+
;;
|
|
217
|
+
4)
|
|
218
|
+
echo -e "${YELLOW}📦 Bumping major version...${NC}"
|
|
219
|
+
if [ "$DRY_RUN" = "true" ]; then
|
|
220
|
+
echo -e "${YELLOW}[DRY RUN] Would bump to ${major_ver}${NC}"
|
|
221
|
+
else
|
|
222
|
+
bump_and_amend "$major_ver" "Major"
|
|
223
|
+
fi
|
|
224
|
+
;;
|
|
225
|
+
0)
|
|
226
|
+
echo -e "${YELLOW}⏭️ Skipping version bump${NC}"
|
|
227
|
+
;;
|
|
228
|
+
*)
|
|
229
|
+
echo -e "${RED}❌ Invalid option. Skipping version bump${NC}"
|
|
230
|
+
;;
|
|
231
|
+
esac
|
|
232
|
+
|
|
233
|
+
echo
|
|
234
|
+
|
|
235
|
+
if [ -n "$POST_ACTION" ]; then
|
|
236
|
+
choice="$POST_ACTION"
|
|
237
|
+
elif exec < /dev/tty 2>/dev/null; then
|
|
238
|
+
echo -e "${CYAN}What would you like to do next?${NC}"
|
|
239
|
+
echo
|
|
240
|
+
echo -e "1) Push to GitHub ${YELLOW}(default)${NC}"
|
|
241
|
+
echo "2) Merge to Main"
|
|
242
|
+
echo -e "${GRAY}0) None${NC}"
|
|
243
|
+
echo
|
|
244
|
+
echo -n "Select option (1-2, Enter for Default or 0 to skip): "
|
|
245
|
+
read -r choice
|
|
246
|
+
choice=${choice:-1}
|
|
247
|
+
else
|
|
248
|
+
choice=0
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
echo
|
|
252
|
+
|
|
253
|
+
case $choice in
|
|
254
|
+
1)
|
|
255
|
+
echo -e "${YELLOW}✈️ Pushing to GitHub...${NC}"
|
|
256
|
+
if [ "$DRY_RUN" = "true" ]; then
|
|
257
|
+
echo -e "${YELLOW}[DRY RUN] Would execute: git push --follow-tags && git push --tags${NC}"
|
|
258
|
+
else
|
|
259
|
+
git push --follow-tags && git push --tags
|
|
260
|
+
if [ $? -eq 0 ]; then
|
|
261
|
+
echo -e "${GREEN}✅ Successfully pushed to GitHub${NC}"
|
|
262
|
+
else
|
|
263
|
+
echo -e "${RED}❌ Failed to push to GitHub${NC}"
|
|
264
|
+
fi
|
|
265
|
+
fi
|
|
266
|
+
;;
|
|
267
|
+
2)
|
|
268
|
+
echo -e "${YELLOW}🔄 Merging to main...${NC}"
|
|
269
|
+
if [ "$DRY_RUN" = "true" ]; then
|
|
270
|
+
echo -e "${YELLOW}[DRY RUN] Would execute: git checkout main && git merge $(git branch --show-current)${NC}"
|
|
271
|
+
else
|
|
272
|
+
current_branch=$(git branch --show-current)
|
|
273
|
+
git checkout main
|
|
274
|
+
git merge "$current_branch"
|
|
275
|
+
if [ $? -eq 0 ]; then
|
|
276
|
+
echo -e "${GREEN}✅ Successfully merged to main${NC}"
|
|
277
|
+
git checkout "$current_branch"
|
|
278
|
+
else
|
|
279
|
+
echo -e "${RED}❌ Failed to merge to main${NC}"
|
|
280
|
+
git checkout "$current_branch"
|
|
281
|
+
fi
|
|
282
|
+
fi
|
|
283
|
+
;;
|
|
284
|
+
0)
|
|
285
|
+
echo -e "${YELLOW}⏭️ Skipping additional actions${NC}"
|
|
286
|
+
;;
|
|
287
|
+
*)
|
|
288
|
+
echo -e "${RED}❌ Invalid option. Skipping additional actions${NC}"
|
|
289
|
+
;;
|
|
290
|
+
esac
|
|
291
|
+
|
|
292
|
+
echo
|
package/hooks/pre-commit
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lechnerio-git-hooks",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Shared git hooks for lechnerio projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"postinstall": "node setup.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"hooks",
|
|
11
|
+
"scripts",
|
|
12
|
+
"config",
|
|
13
|
+
"setup.mjs"
|
|
14
|
+
],
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@commitlint/cli": "^20.4.1",
|
|
17
|
+
"@commitlint/config-conventional": "^20.4.1",
|
|
18
|
+
"husky": "^9.1.7",
|
|
19
|
+
"lint-staged": "^16.2.7"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { execSync } from "child_process"
|
|
2
|
+
import { writeFileSync, mkdirSync } from "fs"
|
|
3
|
+
|
|
4
|
+
const run = (cmd) => execSync(cmd, { encoding: "utf-8", shell: "bash" }).trim()
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
run("git --version")
|
|
8
|
+
run("git rev-parse --git-dir")
|
|
9
|
+
} catch {
|
|
10
|
+
console.warn("git not available, skipping changelog generation")
|
|
11
|
+
process.exit(0)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const tags = run("git tag -l --sort=-version:refname").split("\n").filter(Boolean)
|
|
15
|
+
if (tags.length === 0) {
|
|
16
|
+
console.warn("no git tags found, keeping existing changelog")
|
|
17
|
+
process.exit(0)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const changelog = []
|
|
21
|
+
|
|
22
|
+
const currentVersion = tags[0].replace(/^v/, "")
|
|
23
|
+
const unreleasedRaw = run(`git log --format="%s" ${tags[0]}..HEAD`)
|
|
24
|
+
if (unreleasedRaw) {
|
|
25
|
+
const commits = [...new Set(unreleasedRaw.split("\n").filter(Boolean))].map((message) => ({ message }))
|
|
26
|
+
if (commits.length > 0) {
|
|
27
|
+
const date = run(`git log --format=%ai HEAD -1`).split(" ")[0]
|
|
28
|
+
changelog.push({ version: currentVersion, tag: null, date, commits })
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < tags.length; i++) {
|
|
33
|
+
const tag = tags[i]
|
|
34
|
+
const date = run(`git log --format=%ai ${tag} -1`).split(" ")[0]
|
|
35
|
+
const prevTag = tags[i + 1]
|
|
36
|
+
|
|
37
|
+
const range = prevTag ? `${prevTag}..${tag}` : tag
|
|
38
|
+
const raw = run(`git log --format="%s" ${range}`)
|
|
39
|
+
|
|
40
|
+
const commits = raw
|
|
41
|
+
? [...new Set(raw.split("\n").filter(Boolean))].map((message) => ({ message }))
|
|
42
|
+
: []
|
|
43
|
+
|
|
44
|
+
changelog.push({
|
|
45
|
+
version: tag.replace(/^v/, ""),
|
|
46
|
+
tag,
|
|
47
|
+
date,
|
|
48
|
+
commits,
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const baseVersion = (v) => v.replace(/[a-z]+$/i, "")
|
|
53
|
+
|
|
54
|
+
const grouped = []
|
|
55
|
+
for (const entry of changelog) {
|
|
56
|
+
const base = baseVersion(entry.version)
|
|
57
|
+
const existing = grouped.find((g) => g.version === base && g.tag !== null)
|
|
58
|
+
if (existing) {
|
|
59
|
+
existing.commits.push(...entry.commits)
|
|
60
|
+
if (entry.date < existing.date) existing.date = entry.date
|
|
61
|
+
} else {
|
|
62
|
+
grouped.push({ ...entry, version: base })
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const entry of grouped) {
|
|
67
|
+
const seen = new Set()
|
|
68
|
+
entry.commits = entry.commits.filter((c) => {
|
|
69
|
+
if (seen.has(c.message)) return false
|
|
70
|
+
seen.add(c.message)
|
|
71
|
+
return true
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
mkdirSync("data", { recursive: true })
|
|
76
|
+
writeFileSync("data/changelog.json", JSON.stringify(grouped, null, 2))
|
|
77
|
+
console.log(`changelog generated: ${grouped.length} versions`)
|
package/setup.mjs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { cpSync, mkdirSync, existsSync, readFileSync, writeFileSync } from "fs"
|
|
2
|
+
import { resolve, dirname } from "path"
|
|
3
|
+
import { fileURLToPath } from "url"
|
|
4
|
+
import { execSync } from "child_process"
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
7
|
+
|
|
8
|
+
function findProjectRoot(startDir) {
|
|
9
|
+
let dir = startDir
|
|
10
|
+
while (true) {
|
|
11
|
+
if (!dir.includes("node_modules") && existsSync(resolve(dir, "package.json"))) {
|
|
12
|
+
return dir
|
|
13
|
+
}
|
|
14
|
+
const parent = dirname(dir)
|
|
15
|
+
if (parent === dir) return null
|
|
16
|
+
dir = parent
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const projectRoot = findProjectRoot(__dirname)
|
|
21
|
+
|
|
22
|
+
if (!projectRoot) {
|
|
23
|
+
process.exit(0)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const pkgPath = resolve(projectRoot, "package.json")
|
|
27
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"))
|
|
28
|
+
|
|
29
|
+
const hooksSource = resolve(__dirname, "hooks")
|
|
30
|
+
const scriptsSource = resolve(__dirname, "scripts")
|
|
31
|
+
const configSource = resolve(__dirname, "config")
|
|
32
|
+
|
|
33
|
+
const huskyDest = resolve(projectRoot, ".husky")
|
|
34
|
+
const scriptsDest = resolve(projectRoot, "scripts")
|
|
35
|
+
|
|
36
|
+
mkdirSync(huskyDest, { recursive: true })
|
|
37
|
+
mkdirSync(scriptsDest, { recursive: true })
|
|
38
|
+
|
|
39
|
+
cpSync(resolve(hooksSource, "post-commit"), resolve(huskyDest, "post-commit"))
|
|
40
|
+
cpSync(resolve(hooksSource, "pre-commit"), resolve(huskyDest, "pre-commit"))
|
|
41
|
+
cpSync(resolve(hooksSource, "commit-msg"), resolve(huskyDest, "commit-msg"))
|
|
42
|
+
cpSync(resolve(scriptsSource, "generate-changelog.mjs"), resolve(scriptsDest, "generate-changelog.mjs"))
|
|
43
|
+
cpSync(resolve(configSource, "commitlint.config.js"), resolve(projectRoot, "commitlint.config.js"))
|
|
44
|
+
cpSync(resolve(configSource, "lintstagedrc.js"), resolve(projectRoot, ".lintstagedrc.js"))
|
|
45
|
+
|
|
46
|
+
let modified = false
|
|
47
|
+
|
|
48
|
+
if (!pkg.scripts) pkg.scripts = {}
|
|
49
|
+
|
|
50
|
+
if (!pkg.scripts.prepare || !pkg.scripts.prepare.includes("husky")) {
|
|
51
|
+
pkg.scripts.prepare = "husky"
|
|
52
|
+
modified = true
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!pkg.scripts["lint-staged"]) {
|
|
56
|
+
pkg.scripts["lint-staged"] = "lint-staged"
|
|
57
|
+
modified = true
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (modified) {
|
|
61
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n")
|
|
62
|
+
console.log("lechnerio-git-hooks: updated package.json scripts")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
try {
|
|
66
|
+
execSync("git config core.hooksPath .husky", { cwd: projectRoot, stdio: "ignore" })
|
|
67
|
+
console.log("lechnerio-git-hooks: git hooks path configured")
|
|
68
|
+
} catch {}
|
|
69
|
+
|
|
70
|
+
console.log("lechnerio-git-hooks: setup complete")
|