@itcase/config 1.6.67 → 1.6.68

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 CHANGED
@@ -87,13 +87,33 @@ npm install --save-dev commitizen @commitlint/cz-commitlint
87
87
 
88
88
  В репозитории остаются файлы, на которые опираются git и husky. Логика лежит в `@itcase/config/husky-hooks`. При установке пакета npm кладёт бинарь `itcase-config-husky-hooks` в `node_modules/.bin` — husky уже добавляет этот путь в `PATH`.
89
89
 
90
- При `npm i` пакет копирует `.husky/_run.sh` и создаёт недостающие обёртки хуков. Свои полные хуки не перезаписывает. Добавьте в `.gitignore`:
90
+ При каждом `npm i` в проекте нужен `prepare` (скрипт корня репозитория, не `postinstall` зависимости):
91
+
92
+ ```json
93
+ {
94
+ "scripts": {
95
+ "prepare": "husky && itcase-config-husky-install"
96
+ }
97
+ }
98
+ ```
99
+
100
+ Пока бинарь ещё не в установленной версии пакета, можно так:
101
+
102
+ ```json
103
+ {
104
+ "scripts": {
105
+ "prepare": "husky && node node_modules/@itcase/config/husky-hooks/install-launcher.js"
106
+ }
107
+ }
108
+ ```
109
+
110
+ `itcase-config-husky-install` копирует `.husky/_run.sh`, создаёт недостающие обёртки и при пустом `.husky` восстанавливает `config` из `config.example`. Свои полные хуки не перезаписывает. Добавьте в `.gitignore`:
91
111
 
92
112
  ```gitignore
93
113
  .husky/_run.sh
94
114
  ```
95
115
 
96
- Репы без обёрток и без одного только `.husky/config` скрипт не трогает. `npm i --ignore-scripts` файлы не создаст.
116
+ `npm i --ignore-scripts` файлы не создаст.
97
117
 
98
118
  В каждом git-hook оставьте обёртку:
99
119
 
@@ -111,4 +131,4 @@ PROTECTED_BRANCHES="master"
111
131
  RELEASE_BRANCHES="master"
112
132
  ```
113
133
 
114
- `prepare` в `package.json` как обычно: `"prepare": "husky"`.
134
+ `prepare` в `package.json`: `"prepare": "husky && itcase-config-husky-install"`.
@@ -56,6 +56,13 @@ function isOldItcaseHook(text) {
56
56
  return text.includes('GIT_WORKFLOW') && text.includes('/config')
57
57
  }
58
58
 
59
+ function isEmptyHuskyDir(huskyDir) {
60
+ const names = fs
61
+ .readdirSync(huskyDir)
62
+ .filter((name) => name !== '_' && name !== '.DS_Store')
63
+ return names.length === 0
64
+ }
65
+
59
66
  function isItcaseHuskyDir(huskyDir) {
60
67
  if (fs.existsSync(path.join(huskyDir, 'config'))) {
61
68
  return true
@@ -65,6 +72,10 @@ function isItcaseHuskyDir(huskyDir) {
65
72
  return true
66
73
  }
67
74
 
75
+ if (isEmptyHuskyDir(huskyDir)) {
76
+ return true
77
+ }
78
+
68
79
  const hookContents = GIT_HOOKS.map((name) => readHook(huskyDir, name))
69
80
  return hookContents.some(
70
81
  (text) => text?.includes('_run.sh') || isOldItcaseHook(text),
@@ -75,9 +86,23 @@ function shouldWriteWrapper(text) {
75
86
  return text === null || text.includes('_run.sh') || isOldItcaseHook(text)
76
87
  }
77
88
 
78
- function writeWrapper(huskyDir, name) {
79
- const dest = path.join(huskyDir, name)
80
- fs.writeFileSync(dest, WRAPPER)
89
+ function writeExecutable(dest, contents) {
90
+ fs.writeFileSync(dest, contents)
91
+ try {
92
+ fs.chmodSync(dest, 0o755)
93
+ } catch {
94
+ // Windows may not support chmod; Git Bash still runs the file via sh.
95
+ }
96
+ }
97
+
98
+ function ensureConfig(huskyDir) {
99
+ const dest = path.join(huskyDir, 'config')
100
+ if (fs.existsSync(dest)) {
101
+ return
102
+ }
103
+
104
+ const example = path.join(import.meta.dirname, 'config.example')
105
+ fs.copyFileSync(example, dest)
81
106
  try {
82
107
  fs.chmodSync(dest, 0o755)
83
108
  } catch {
@@ -91,16 +116,14 @@ if (!fs.existsSync(huskyDir) || !isItcaseHuskyDir(huskyDir)) {
91
116
  process.exit(0)
92
117
  }
93
118
 
94
- const src = path.join(import.meta.dirname, '_run.sh')
95
- fs.copyFileSync(src, path.join(huskyDir, '_run.sh'))
96
- try {
97
- fs.chmodSync(path.join(huskyDir, '_run.sh'), 0o755)
98
- } catch {
99
- // Windows may not support chmod; Git Bash still runs the file via sh.
100
- }
119
+ writeExecutable(
120
+ path.join(huskyDir, '_run.sh'),
121
+ fs.readFileSync(path.join(import.meta.dirname, '_run.sh')),
122
+ )
123
+ ensureConfig(huskyDir)
101
124
 
102
125
  for (const name of GIT_HOOKS) {
103
126
  if (shouldWriteWrapper(readHook(huskyDir, name))) {
104
- writeWrapper(huskyDir, name)
127
+ writeExecutable(path.join(huskyDir, name), WRAPPER)
105
128
  }
106
129
  }
package/package.json CHANGED
@@ -1,16 +1,17 @@
1
1
  {
2
2
  "name": "@itcase/config",
3
- "version": "1.6.67",
3
+ "version": "1.6.68",
4
4
  "author": "ITCase",
5
5
  "description": "ITCase Config",
6
6
  "engines": {
7
7
  "node": ">=22.0.0"
8
8
  },
9
9
  "bin": {
10
- "itcase-config-husky-hooks": "./husky-hooks/run.js"
10
+ "itcase-config-husky-hooks": "./husky-hooks/run.js",
11
+ "itcase-config-husky-install": "./husky-hooks/install-launcher.js"
11
12
  },
12
13
  "scripts": {
13
- "prepare": "husky",
14
+ "prepare": "husky && node ./husky-hooks/install-launcher.js",
14
15
  "postinstall": "node ./husky-hooks/install-launcher.js",
15
16
  "semantic-release": "semantic-release"
16
17
  },