@archpublicwebsite/eslint-config 1.0.7 → 1.0.9
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
package/package.json
CHANGED
|
@@ -7,7 +7,8 @@ const source = process.argv[3] || ''
|
|
|
7
7
|
if (!messageFile)
|
|
8
8
|
process.exit(0)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// Skip auto-generation only for flows where Git already supplies a meaningful message.
|
|
11
|
+
if (['merge', 'squash', 'commit'].includes(source))
|
|
11
12
|
process.exit(0)
|
|
12
13
|
|
|
13
14
|
const currentMessage = readFileSync(messageFile, 'utf-8')
|
|
@@ -6,9 +6,18 @@ export function isValidCommitMessage(message) {
|
|
|
6
6
|
return releaseRE.test(message) || commitRE.test(message)
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
function getCommitSubject(rawMessage) {
|
|
10
|
+
return rawMessage
|
|
11
|
+
.split('\n')
|
|
12
|
+
.map(line => line.trim())
|
|
13
|
+
.find(line => line && !line.startsWith('#')) || ''
|
|
14
|
+
}
|
|
15
|
+
|
|
9
16
|
export function verifyCommitMessageFile(messageFilePath) {
|
|
10
|
-
const
|
|
11
|
-
|
|
17
|
+
const rawMessage = readFileSync(messageFilePath, 'utf-8')
|
|
18
|
+
const subject = getCommitSubject(rawMessage)
|
|
19
|
+
|
|
20
|
+
if (isValidCommitMessage(subject))
|
|
12
21
|
return
|
|
13
22
|
|
|
14
23
|
const examples = [
|
|
@@ -21,7 +30,7 @@ export function verifyCommitMessageFile(messageFilePath) {
|
|
|
21
30
|
console.error('Description max length: 50 characters\n')
|
|
22
31
|
console.error('Examples:')
|
|
23
32
|
examples.forEach(example => console.error(` - ${example}`))
|
|
24
|
-
console.error('\nSee .
|
|
33
|
+
console.error('\nSee README.md (Auto commit message flow) for details.\n')
|
|
25
34
|
process.exit(1)
|
|
26
35
|
}
|
|
27
36
|
|
package/tools/setup/install.mjs
CHANGED
|
@@ -3,6 +3,12 @@ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'n
|
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
import { ensureVscodeSettings } from './vscode.mjs'
|
|
5
5
|
|
|
6
|
+
const TAG = '[@archpublicwebsite/eslint-config]'
|
|
7
|
+
|
|
8
|
+
function log(msg) {
|
|
9
|
+
console.log(`${TAG} ${msg}`)
|
|
10
|
+
}
|
|
11
|
+
|
|
6
12
|
function getProjectRoot() {
|
|
7
13
|
const root = process.env.INIT_CWD || process.cwd()
|
|
8
14
|
if (!existsSync(join(root, 'package.json')))
|
|
@@ -10,18 +16,91 @@ function getProjectRoot() {
|
|
|
10
16
|
return root
|
|
11
17
|
}
|
|
12
18
|
|
|
13
|
-
function ensureDir(
|
|
14
|
-
if (!existsSync(
|
|
15
|
-
mkdirSync(
|
|
19
|
+
function ensureDir(dirPath) {
|
|
20
|
+
if (!existsSync(dirPath))
|
|
21
|
+
mkdirSync(dirPath, { recursive: true })
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
function writeIfMissing(
|
|
19
|
-
if (existsSync(
|
|
24
|
+
function writeIfMissing(filePath, content) {
|
|
25
|
+
if (existsSync(filePath))
|
|
20
26
|
return false
|
|
21
|
-
writeFileSync(
|
|
27
|
+
writeFileSync(filePath, content, 'utf8')
|
|
22
28
|
return true
|
|
23
29
|
}
|
|
24
30
|
|
|
31
|
+
// ─── .editorconfig ──────────────────────────────────────────────────────────
|
|
32
|
+
|
|
33
|
+
function ensureEditorConfig(projectRoot) {
|
|
34
|
+
const editorConfigPath = join(projectRoot, '.editorconfig')
|
|
35
|
+
const content = `# EditorConfig — consistent coding style across editors
|
|
36
|
+
# https://editorconfig.org
|
|
37
|
+
|
|
38
|
+
root = true
|
|
39
|
+
|
|
40
|
+
[*]
|
|
41
|
+
charset = utf-8
|
|
42
|
+
end_of_line = lf
|
|
43
|
+
indent_style = space
|
|
44
|
+
indent_size = 2
|
|
45
|
+
insert_final_newline = true
|
|
46
|
+
trim_trailing_whitespace = true
|
|
47
|
+
|
|
48
|
+
[*.md]
|
|
49
|
+
trim_trailing_whitespace = false
|
|
50
|
+
|
|
51
|
+
[*.{yml,yaml}]
|
|
52
|
+
indent_size = 2
|
|
53
|
+
|
|
54
|
+
[Makefile]
|
|
55
|
+
indent_style = tab
|
|
56
|
+
`
|
|
57
|
+
if (writeIfMissing(editorConfigPath, content))
|
|
58
|
+
log('Created .editorconfig')
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ─── .eslint-user-ignore ────────────────────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
function ensureEslintUserIgnore(projectRoot) {
|
|
64
|
+
const ignorePath = join(projectRoot, '.eslint-user-ignore')
|
|
65
|
+
const content = `# User-overridable ESLint ignore rules
|
|
66
|
+
#
|
|
67
|
+
# Remove a line to include it again, or add your own patterns.
|
|
68
|
+
# Uses standard glob/gitignore-style patterns.
|
|
69
|
+
|
|
70
|
+
# Ignore document formats
|
|
71
|
+
*.doc
|
|
72
|
+
*.docx
|
|
73
|
+
|
|
74
|
+
# Ignore markdown files
|
|
75
|
+
*.md
|
|
76
|
+
|
|
77
|
+
# Optional examples:
|
|
78
|
+
# docs/**
|
|
79
|
+
# *.pdf
|
|
80
|
+
`
|
|
81
|
+
if (writeIfMissing(ignorePath, content))
|
|
82
|
+
log('Created .eslint-user-ignore')
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ─── eslint.config.mjs ─────────────────────────────────────────────────────
|
|
86
|
+
|
|
87
|
+
function ensureEslintConfig(projectRoot) {
|
|
88
|
+
const eslintConfigPath = join(projectRoot, 'eslint.config.mjs')
|
|
89
|
+
const content = `import { createArchipelagoConfig } from '@archpublicwebsite/eslint-config'
|
|
90
|
+
|
|
91
|
+
export default createArchipelagoConfig({
|
|
92
|
+
name: 'project/overrides',
|
|
93
|
+
rules: {
|
|
94
|
+
// Add your project overrides here
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
`
|
|
98
|
+
if (writeIfMissing(eslintConfigPath, content))
|
|
99
|
+
log('Created eslint.config.mjs')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ─── .prettierrc ────────────────────────────────────────────────────────────
|
|
103
|
+
|
|
25
104
|
function ensurePrettierConfig(projectRoot) {
|
|
26
105
|
const prettierPath = join(projectRoot, '.prettierrc')
|
|
27
106
|
const defaults = {
|
|
@@ -36,6 +115,7 @@ function ensurePrettierConfig(projectRoot) {
|
|
|
36
115
|
|
|
37
116
|
if (!existsSync(prettierPath)) {
|
|
38
117
|
writeFileSync(prettierPath, `${JSON.stringify(defaults, null, 2)}\n`, 'utf8')
|
|
118
|
+
log('Created .prettierrc')
|
|
39
119
|
return
|
|
40
120
|
}
|
|
41
121
|
|
|
@@ -49,17 +129,14 @@ function ensurePrettierConfig(projectRoot) {
|
|
|
49
129
|
if (typeof current.semi !== 'boolean')
|
|
50
130
|
current.semi = false
|
|
51
131
|
writeFileSync(prettierPath, `${JSON.stringify(current, null, 2)}\n`, 'utf8')
|
|
132
|
+
log('Updated .prettierrc')
|
|
52
133
|
}
|
|
53
134
|
catch {
|
|
54
135
|
// Keep existing file untouched if it is not JSON.
|
|
55
136
|
}
|
|
56
137
|
}
|
|
57
138
|
|
|
58
|
-
|
|
59
|
-
const eslintConfigPath = join(projectRoot, 'eslint.config.mjs')
|
|
60
|
-
const content = `import { createArchipelagoConfig } from 'eslint-config'\n\nexport default createArchipelagoConfig({\n name: 'project/overrides',\n rules: {\n // Add your project overrides here\n },\n})\n`
|
|
61
|
-
writeIfMissing(eslintConfigPath, content)
|
|
62
|
-
}
|
|
139
|
+
// ─── .hooks ─────────────────────────────────────────────────────────────────
|
|
63
140
|
|
|
64
141
|
function ensureHooks(projectRoot) {
|
|
65
142
|
const hooksDir = join(projectRoot, '.hooks')
|
|
@@ -70,33 +147,38 @@ function ensureHooks(projectRoot) {
|
|
|
70
147
|
set -euo pipefail
|
|
71
148
|
|
|
72
149
|
cd "$(git rev-parse --show-toplevel)"
|
|
73
|
-
node node_modules/eslint-config/tools/git-hooks/pre-commit.mjs
|
|
150
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/pre-commit.mjs
|
|
74
151
|
`,
|
|
75
152
|
'prepare-commit-msg': `#!/usr/bin/env bash
|
|
76
153
|
set -euo pipefail
|
|
77
154
|
|
|
78
155
|
cd "$(git rev-parse --show-toplevel)"
|
|
79
|
-
node node_modules/eslint-config/tools/git-hooks/prepare-commit-msg.mjs "$@"
|
|
156
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/prepare-commit-msg.mjs "$@"
|
|
80
157
|
`,
|
|
81
158
|
'commit-msg': `#!/usr/bin/env bash
|
|
82
159
|
set -euo pipefail
|
|
83
160
|
|
|
84
161
|
cd "$(git rev-parse --show-toplevel)"
|
|
85
|
-
node node_modules/eslint-config/tools/git-hooks/commit-msg.mjs "$1"
|
|
162
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/commit-msg.mjs "$1"
|
|
86
163
|
`,
|
|
87
164
|
'post-commit': `#!/usr/bin/env bash
|
|
88
165
|
set -euo pipefail
|
|
89
166
|
|
|
90
167
|
cd "$(git rev-parse --show-toplevel)"
|
|
91
|
-
node node_modules/eslint-config/tools/git-hooks/post-commit.mjs
|
|
168
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/post-commit.mjs
|
|
92
169
|
`,
|
|
93
170
|
}
|
|
94
171
|
|
|
172
|
+
let created = false
|
|
95
173
|
Object.entries(hooks).forEach(([name, content]) => {
|
|
96
|
-
const
|
|
97
|
-
if (writeIfMissing(
|
|
98
|
-
chmodSync(
|
|
174
|
+
const hookPath = join(hooksDir, name)
|
|
175
|
+
if (writeIfMissing(hookPath, content)) {
|
|
176
|
+
chmodSync(hookPath, 0o755)
|
|
177
|
+
created = true
|
|
178
|
+
}
|
|
99
179
|
})
|
|
180
|
+
if (created)
|
|
181
|
+
log('Created .hooks/ (pre-commit, prepare-commit-msg, commit-msg, post-commit)')
|
|
100
182
|
}
|
|
101
183
|
|
|
102
184
|
function ensureHooksPath(projectRoot) {
|
|
@@ -104,18 +186,20 @@ function ensureHooksPath(projectRoot) {
|
|
|
104
186
|
return
|
|
105
187
|
try {
|
|
106
188
|
execSync('git config core.hooksPath .hooks', { cwd: projectRoot, stdio: 'ignore' })
|
|
189
|
+
log('Set git core.hooksPath → .hooks')
|
|
107
190
|
}
|
|
108
191
|
catch {
|
|
109
192
|
// Ignore setup failures in non-git contexts.
|
|
110
193
|
}
|
|
111
194
|
}
|
|
112
195
|
|
|
196
|
+
// ─── .vscode/extensions.json ────────────────────────────────────────────────
|
|
197
|
+
|
|
113
198
|
function ensureVscodeExtensions(projectRoot) {
|
|
114
199
|
const vscodeDir = join(projectRoot, '.vscode')
|
|
115
200
|
const extPath = join(vscodeDir, 'extensions.json')
|
|
116
201
|
|
|
117
|
-
|
|
118
|
-
mkdirSync(vscodeDir, { recursive: true })
|
|
202
|
+
ensureDir(vscodeDir)
|
|
119
203
|
|
|
120
204
|
const recommended = [
|
|
121
205
|
'dbaeumer.vscode-eslint',
|
|
@@ -138,19 +222,28 @@ function ensureVscodeExtensions(projectRoot) {
|
|
|
138
222
|
const merged = [...new Set([...current.recommendations, ...recommended])]
|
|
139
223
|
current.recommendations = merged
|
|
140
224
|
writeFileSync(extPath, `${JSON.stringify(current, null, 2)}\n`, 'utf8')
|
|
225
|
+
log('Created/updated .vscode/extensions.json')
|
|
141
226
|
}
|
|
142
227
|
|
|
228
|
+
// ─── main ───────────────────────────────────────────────────────────────────
|
|
229
|
+
|
|
143
230
|
function main() {
|
|
144
231
|
const projectRoot = getProjectRoot()
|
|
145
232
|
if (!projectRoot)
|
|
146
233
|
return
|
|
147
234
|
|
|
148
|
-
|
|
149
|
-
|
|
235
|
+
log('Setting up project...')
|
|
236
|
+
|
|
237
|
+
ensureEditorConfig(projectRoot)
|
|
238
|
+
ensureEslintUserIgnore(projectRoot)
|
|
150
239
|
ensureEslintConfig(projectRoot)
|
|
151
240
|
ensurePrettierConfig(projectRoot)
|
|
241
|
+
ensureHooks(projectRoot)
|
|
242
|
+
ensureHooksPath(projectRoot)
|
|
152
243
|
ensureVscodeSettings(projectRoot)
|
|
153
244
|
ensureVscodeExtensions(projectRoot)
|
|
245
|
+
|
|
246
|
+
log('Setup complete ✓')
|
|
154
247
|
}
|
|
155
248
|
|
|
156
249
|
main()
|
package/tools/setup/vscode.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
|
|
4
|
+
const TAG = '[@archpublicwebsite/eslint-config]'
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* VS Code settings required for ESLint flat config to work properly.
|
|
6
8
|
* These tell the ESLint extension to use flat config mode and validate
|
|
@@ -29,7 +31,7 @@ const VSCODE_ESLINT_SETTINGS = {
|
|
|
29
31
|
},
|
|
30
32
|
|
|
31
33
|
// Let ESLint handle formatting instead of the built-in formatter
|
|
32
|
-
'editor.formatOnSave':
|
|
34
|
+
'editor.formatOnSave': true,
|
|
33
35
|
|
|
34
36
|
// Disable the default VS Code JSON formatter for files ESLint handles
|
|
35
37
|
'[json]': {
|
|
@@ -116,4 +118,5 @@ export function ensureVscodeSettings(projectRoot) {
|
|
|
116
118
|
|
|
117
119
|
const merged = deepMerge(current, VSCODE_ESLINT_SETTINGS)
|
|
118
120
|
writeFileSync(settingsPath, `${JSON.stringify(merged, null, 2)}\n`, 'utf8')
|
|
121
|
+
console.log(`${TAG} Created/updated .vscode/settings.json`)
|
|
119
122
|
}
|