@archpublicwebsite/eslint-config 1.0.10 → 1.0.13
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 +101 -79
- package/eslint.config.mjs +110 -32
- package/package.json +6 -4
- package/tools/git-hooks/verify-commit-message.mjs +14 -8
- package/tools/setup/vscode.mjs +8 -8
package/README.md
CHANGED
|
@@ -1,53 +1,79 @@
|
|
|
1
|
-
# eslint-config
|
|
1
|
+
# @archpublicwebsite/eslint-config
|
|
2
2
|
|
|
3
|
-
Reusable ESLint
|
|
3
|
+
Reusable ESLint flat config and git-hook toolkit for Archipelago projects.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## What this package includes
|
|
6
|
+
|
|
7
|
+
This package ships a ready-to-use flat config plus setup scripts for local project automation:
|
|
8
|
+
|
|
9
|
+
- `createArchipelagoConfig()` for building an ESLint flat config
|
|
10
|
+
- Git hook scripts for pre-commit and commit-message enforcement
|
|
11
|
+
- Setup automation that bootstraps the consumer project
|
|
12
|
+
- VS Code settings updates for the recommended linting workflow
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- Flat config based on `@antfu/eslint-config`
|
|
17
|
+
- Vue, TypeScript, Tailwind, and Nuxt-friendly defaults
|
|
18
|
+
- Git hooks for consistent formatting and commit validation
|
|
19
|
+
- Automatic project setup on install
|
|
20
|
+
- Works with the Archipelago repo style rules
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
Consumer projects should have these tools available when using the full setup:
|
|
6
25
|
|
|
7
26
|
```bash
|
|
8
|
-
|
|
9
|
-
pnpm version patch
|
|
10
|
-
npm publish --access public
|
|
27
|
+
pnpm add -D eslint prettier lint-staged turbo
|
|
11
28
|
```
|
|
12
29
|
|
|
13
|
-
|
|
30
|
+
## Installation
|
|
14
31
|
|
|
15
|
-
|
|
16
|
-
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add -D @archpublicwebsite/eslint-config
|
|
34
|
+
```
|
|
17
35
|
|
|
18
|
-
##
|
|
36
|
+
## Usage
|
|
19
37
|
|
|
20
|
-
|
|
21
|
-
|
|
38
|
+
Create or update the root `eslint.config.mjs`:
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
import { createArchipelagoConfig } from '@archpublicwebsite/eslint-config'
|
|
42
|
+
|
|
43
|
+
export default createArchipelagoConfig()
|
|
22
44
|
```
|
|
23
45
|
|
|
24
|
-
|
|
46
|
+
Override rules when your project needs to diverge from the shared defaults:
|
|
25
47
|
|
|
26
|
-
|
|
48
|
+
```js
|
|
49
|
+
import { createArchipelagoConfig } from '@archpublicwebsite/eslint-config'
|
|
27
50
|
|
|
28
|
-
|
|
29
|
-
|
|
51
|
+
export default createArchipelagoConfig({
|
|
52
|
+
name: 'project/overrides',
|
|
53
|
+
rules: {
|
|
54
|
+
'no-console': 'off',
|
|
55
|
+
'vue/max-attributes-per-line': 'off',
|
|
56
|
+
},
|
|
57
|
+
})
|
|
30
58
|
```
|
|
31
59
|
|
|
32
|
-
|
|
33
|
-
- `prettier` is used by the `lint:fix` flow.
|
|
34
|
-
- `turbo` is used by the required `lint:check` / `lint:fix` scripts.
|
|
60
|
+
## What the setup does
|
|
35
61
|
|
|
36
|
-
On install,
|
|
62
|
+
On install or when you run the setup script manually, the package prepares the consumer project with:
|
|
37
63
|
|
|
38
64
|
- `.hooks/pre-commit`
|
|
39
65
|
- `.hooks/prepare-commit-msg`
|
|
40
66
|
- `.hooks/commit-msg`
|
|
41
67
|
- `.hooks/post-commit`
|
|
42
|
-
- `eslint.config.mjs`
|
|
68
|
+
- `eslint.config.mjs` when one does not already exist
|
|
43
69
|
- `.prettierrc` plugin entry for `prettier-plugin-tailwindcss`
|
|
44
|
-
- `.vscode/settings.json`
|
|
45
|
-
- `.vscode/extensions.json`
|
|
46
|
-
- `git config core.hooksPath .hooks`
|
|
70
|
+
- `.vscode/settings.json` with ESLint flat-config settings
|
|
71
|
+
- `.vscode/extensions.json` with recommended extensions
|
|
72
|
+
- `git config core.hooksPath .hooks` when the project is a Git repository
|
|
47
73
|
|
|
48
|
-
|
|
74
|
+
## VS Code integration
|
|
49
75
|
|
|
50
|
-
|
|
76
|
+
The setup merges ESLint-related settings into `.vscode/settings.json`:
|
|
51
77
|
|
|
52
78
|
```json
|
|
53
79
|
{
|
|
@@ -65,100 +91,88 @@ On install, `.vscode/settings.json` is created or merged with these settings:
|
|
|
65
91
|
}
|
|
66
92
|
```
|
|
67
93
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
You can also re-run it manually:
|
|
94
|
+
Existing settings are preserved. Only the ESLint-related keys are added or updated.
|
|
71
95
|
|
|
72
|
-
|
|
73
|
-
node node_modules/@archpublicwebsite/eslint-config/tools/setup/install.mjs
|
|
74
|
-
```
|
|
96
|
+
## Public API
|
|
75
97
|
|
|
76
|
-
|
|
98
|
+
The package exports:
|
|
77
99
|
|
|
78
|
-
- `
|
|
79
|
-
-
|
|
80
|
-
- `pre-commit.mjs`
|
|
81
|
-
- `prepare-commit-msg.mjs`
|
|
82
|
-
- `commit-msg.mjs`
|
|
83
|
-
- `post-commit.mjs`
|
|
84
|
-
- `generate-commit-message.mjs`
|
|
85
|
-
- `verify-commit-message.mjs`
|
|
86
|
-
- `tools/setup/install.mjs` automatic project bootstrap
|
|
100
|
+
- `createArchipelagoConfig`
|
|
101
|
+
- setup scripts under `tools/`
|
|
87
102
|
|
|
88
|
-
##
|
|
103
|
+
## AI Implementation Guide
|
|
89
104
|
|
|
90
|
-
|
|
105
|
+
If you are extending or regenerating this package, keep the workflow explicit:
|
|
91
106
|
|
|
92
|
-
|
|
93
|
-
|
|
107
|
+
1. Update `eslint.config.mjs` when shared lint rules change.
|
|
108
|
+
2. Update `tools/setup/install.mjs` when install-time bootstrap behavior changes.
|
|
109
|
+
3. Update `tools/git-hooks/` when hook behavior changes.
|
|
110
|
+
4. Keep the package export map aligned with the public API.
|
|
111
|
+
5. Document any new consumer dependency that the setup expects.
|
|
94
112
|
|
|
95
|
-
|
|
96
|
-
```
|
|
113
|
+
### AI-friendly implementation notes
|
|
97
114
|
|
|
98
|
-
|
|
115
|
+
- Use `createArchipelagoConfig()` in the consumer project, not the internal setup scripts.
|
|
116
|
+
- Keep root scripts in sync with the hook and lint expectations.
|
|
117
|
+
- Re-run the package setup flow when changing VS Code or hook behavior.
|
|
118
|
+
- Prefer explicit examples that show what the consumer project should add.
|
|
99
119
|
|
|
100
|
-
|
|
120
|
+
## Manual setup
|
|
101
121
|
|
|
102
|
-
|
|
103
|
-
import { createArchipelagoConfig } from 'eslint-config'
|
|
104
|
-
|
|
105
|
-
export default createArchipelagoConfig({
|
|
106
|
-
name: 'project/overrides',
|
|
107
|
-
rules: {
|
|
108
|
-
'no-console': 'off',
|
|
109
|
-
'vue/max-attributes-per-line': 'off',
|
|
110
|
-
},
|
|
111
|
-
})
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## Manual setup (optional)
|
|
115
|
-
|
|
116
|
-
Automatic setup is the default. If needed, you can still run setup manually:
|
|
122
|
+
If you need to rerun the bootstrap manually:
|
|
117
123
|
|
|
118
124
|
```bash
|
|
119
|
-
node node_modules/eslint-config/tools/setup/install.mjs
|
|
125
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/setup/install.mjs
|
|
120
126
|
```
|
|
121
127
|
|
|
122
128
|
## Hook wrappers reference
|
|
123
129
|
|
|
124
|
-
Root `.hooks` scripts should delegate to installed package path:
|
|
125
|
-
|
|
126
|
-
- `.hooks/pre-commit`
|
|
130
|
+
Root `.hooks` scripts should delegate to the installed package path:
|
|
127
131
|
|
|
128
132
|
```bash
|
|
129
133
|
#!/usr/bin/env bash
|
|
130
134
|
set -euo pipefail
|
|
131
135
|
cd "$(git rev-parse --show-toplevel)"
|
|
132
|
-
node node_modules/eslint-config/tools/git-hooks/pre-commit.mjs
|
|
136
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/pre-commit.mjs
|
|
133
137
|
```
|
|
134
138
|
|
|
135
|
-
- `.hooks/prepare-commit-msg`
|
|
136
|
-
|
|
137
139
|
```bash
|
|
138
140
|
#!/usr/bin/env bash
|
|
139
141
|
set -euo pipefail
|
|
140
142
|
cd "$(git rev-parse --show-toplevel)"
|
|
141
|
-
node node_modules/eslint-config/tools/git-hooks/prepare-commit-msg.mjs "$@"
|
|
143
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/prepare-commit-msg.mjs "$@"
|
|
142
144
|
```
|
|
143
145
|
|
|
144
|
-
- `.hooks/commit-msg`
|
|
145
|
-
|
|
146
146
|
```bash
|
|
147
147
|
#!/usr/bin/env bash
|
|
148
148
|
set -euo pipefail
|
|
149
149
|
cd "$(git rev-parse --show-toplevel)"
|
|
150
|
-
node node_modules/eslint-config/tools/git-hooks/commit-msg.mjs "$1"
|
|
150
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/commit-msg.mjs "$1"
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
- `.hooks/post-commit`
|
|
154
|
-
|
|
155
153
|
```bash
|
|
156
154
|
#!/usr/bin/env bash
|
|
157
155
|
set -euo pipefail
|
|
158
156
|
cd "$(git rev-parse --show-toplevel)"
|
|
159
|
-
node node_modules/eslint-config/tools/git-hooks/post-commit.mjs
|
|
157
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/post-commit.mjs
|
|
160
158
|
```
|
|
161
159
|
|
|
160
|
+
## Publish
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cd packages/eslint-config
|
|
164
|
+
pnpm version patch
|
|
165
|
+
npm publish --access public
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Before publish, run:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
npm pack --dry-run
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Make sure the tarball contains only the intended public files: `eslint.config.mjs`, `tools/`, and `README.md`.
|
|
175
|
+
|
|
162
176
|
## Required root scripts
|
|
163
177
|
|
|
164
178
|
```json
|
|
@@ -173,3 +187,11 @@ node node_modules/eslint-config/tools/git-hooks/post-commit.mjs
|
|
|
173
187
|
}
|
|
174
188
|
}
|
|
175
189
|
```
|
|
190
|
+
|
|
191
|
+
## Verification
|
|
192
|
+
|
|
193
|
+
After making config changes, validate the package by checking the installed consumer workflow or by running the setup script in a test project.
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
package/eslint.config.mjs
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import antfu from '@antfu/eslint-config'
|
|
2
|
-
import perfectionistNatural from 'eslint-plugin-perfectionist'
|
|
3
2
|
import tailwind from 'eslint-plugin-tailwindcss'
|
|
4
3
|
|
|
5
4
|
export function createArchipelagoConfig(...overrides) {
|
|
6
5
|
return antfu(
|
|
7
6
|
{
|
|
8
|
-
formatters
|
|
9
|
-
|
|
7
|
+
// Disable CSS/HTML/Markdown formatters — we only use @stylistic rules
|
|
8
|
+
formatters: false,
|
|
9
|
+
// Canonical style: no semicolons, single quotes, 2-space indent
|
|
10
|
+
// antfu propagates these to ALL related rules (semi, member-delimiter, etc.)
|
|
11
|
+
stylistic: {
|
|
12
|
+
semi: false,
|
|
13
|
+
quotes: 'single',
|
|
14
|
+
indent: 2,
|
|
15
|
+
},
|
|
10
16
|
vue: true,
|
|
11
17
|
typescript: true,
|
|
12
18
|
},
|
|
19
|
+
|
|
20
|
+
// ── Global ignores ────────────────────────────────────────────────────────
|
|
13
21
|
{
|
|
14
22
|
name: 'archipelago/ignores',
|
|
15
23
|
ignores: [
|
|
@@ -21,43 +29,54 @@ export function createArchipelagoConfig(...overrides) {
|
|
|
21
29
|
'**/coverage/**',
|
|
22
30
|
'**/.next/**',
|
|
23
31
|
'**/public/**',
|
|
32
|
+
'**/*.d.ts',
|
|
24
33
|
],
|
|
25
34
|
},
|
|
35
|
+
|
|
36
|
+
// ── Tailwind ──────────────────────────────────────────────────────────────
|
|
26
37
|
...tailwind.configs['flat/recommended'],
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
plugins: {
|
|
30
|
-
perfectionistNatural,
|
|
31
|
-
},
|
|
32
|
-
rules: {
|
|
33
|
-
'import/order': 'off',
|
|
34
|
-
'sort-imports': 'off',
|
|
35
|
-
'perfectionist/sort-imports': ['warn', {
|
|
36
|
-
type: 'alphabetical',
|
|
37
|
-
}],
|
|
38
|
-
'perfectionist/sort-exports': ['warn', {
|
|
39
|
-
type: 'alphabetical',
|
|
40
|
-
}],
|
|
41
|
-
'perfectionist/sort-named-imports': ['warn', {
|
|
42
|
-
type: 'alphabetical',
|
|
43
|
-
}],
|
|
44
|
-
'perfectionist/sort-named-exports': ['warn', {
|
|
45
|
-
type: 'alphabetical',
|
|
46
|
-
}],
|
|
47
|
-
},
|
|
48
|
-
},
|
|
38
|
+
|
|
39
|
+
// ── Canonical rules ───────────────────────────────────────────────────────
|
|
49
40
|
{
|
|
50
41
|
name: 'archipelago/rules',
|
|
51
42
|
rules: {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
'
|
|
43
|
+
// format/prettier is loaded by antfu internals even with formatters:false.
|
|
44
|
+
// Configure it to AGREE with our style so it never conflicts with
|
|
45
|
+
// style/quotes and style/semi → eliminates circular fix warnings.
|
|
46
|
+
'format/prettier': ['warn', {
|
|
47
|
+
singleQuote: true,
|
|
48
|
+
semi: false,
|
|
49
|
+
printWidth: 120,
|
|
50
|
+
trailingComma: 'all',
|
|
51
|
+
arrowParens: 'avoid',
|
|
52
|
+
}],
|
|
53
|
+
|
|
54
|
+
// ── Anti-loop: disable rules that fight @stylistic equivalents ─────────
|
|
55
|
+
'object-curly-newline': 'off',
|
|
56
|
+
'style/object-curly-newline': 'off',
|
|
57
|
+
'style/operator-linebreak': 'off',
|
|
58
|
+
'style/indent': 'off',
|
|
59
|
+
'style/indent-binary-ops': 'off',
|
|
60
|
+
'max-statements-per-line': 'off',
|
|
61
|
+
'antfu/consistent-list-newline': 'off',
|
|
62
|
+
'antfu/consistent-chaining': 'off',
|
|
63
|
+
'antfu/if-newline': 'off',
|
|
64
|
+
'antfu/no-import-dist': 'off',
|
|
65
|
+
|
|
66
|
+
// ── Vue ──────────────────────────────────────────────────────────────
|
|
56
67
|
'vue/multi-word-component-names': 'off',
|
|
57
68
|
'vue/no-required-prop-with-default': 'off',
|
|
58
69
|
'vue/html-self-closing': 'off',
|
|
59
70
|
'vue/html-closing-bracket-spacing': 'off',
|
|
60
71
|
'vue/no-multiple-template-root': 'off',
|
|
72
|
+
'vue/attributes-order': 'off',
|
|
73
|
+
'vue/singleline-html-element-content-newline': 'off',
|
|
74
|
+
'vue/html-closing-bracket-newline': 'off',
|
|
75
|
+
'vue/html-indent': 'off',
|
|
76
|
+
'vue/no-useless-v-bind': 'off',
|
|
77
|
+
'vue/prefer-separate-static-class': 'off',
|
|
78
|
+
'vue/attribute-hyphenation': 'off',
|
|
79
|
+
'vue/define-macros-order': 'off',
|
|
61
80
|
'vue/max-attributes-per-line': ['error', {
|
|
62
81
|
singleline: 3,
|
|
63
82
|
multiline: 1,
|
|
@@ -72,12 +91,71 @@ export function createArchipelagoConfig(...overrides) {
|
|
|
72
91
|
ignoreHTMLAttributeValues: true,
|
|
73
92
|
ignoreHTMLTextContents: true,
|
|
74
93
|
}],
|
|
75
|
-
|
|
76
|
-
|
|
94
|
+
|
|
95
|
+
// ── TypeScript ───────────────────────────────────────────────────────
|
|
96
|
+
'ts/no-use-before-define': 'off',
|
|
97
|
+
'ts/no-empty-object-type': 'off',
|
|
98
|
+
'ts/no-explicit-any': 'warn',
|
|
99
|
+
'ts/no-var-requires': 'warn',
|
|
100
|
+
'ts/consistent-type-imports': ['error', {
|
|
101
|
+
prefer: 'type-imports',
|
|
102
|
+
fixStyle: 'inline-type-imports',
|
|
77
103
|
}],
|
|
78
|
-
|
|
104
|
+
|
|
105
|
+
// ── Import ordering ──────────────────────────────────────────────────
|
|
106
|
+
'import/order': 'off',
|
|
107
|
+
'import/newline-after-import': 'off',
|
|
108
|
+
'import/consistent-type-specifier-style': 'off',
|
|
109
|
+
'perfectionist/sort-imports': 'off',
|
|
110
|
+
'perfectionist/sort-exports': 'off',
|
|
111
|
+
'perfectionist/sort-named-imports': 'off',
|
|
112
|
+
'perfectionist/sort-named-exports': 'off',
|
|
113
|
+
|
|
114
|
+
// ── Tailwind ─────────────────────────────────────────────────────────
|
|
115
|
+
'tailwindcss/no-custom-classname': 'off',
|
|
116
|
+
'tailwindcss/migration-from-tailwind-2': 'off',
|
|
117
|
+
'tailwindcss/enforces-shorthand': 'off',
|
|
118
|
+
|
|
119
|
+
// ── Misc ─────────────────────────────────────────────────────────────
|
|
120
|
+
'no-console': 'warn',
|
|
121
|
+
'no-alert': 'off',
|
|
122
|
+
'jsonc/sort-keys': 'off',
|
|
123
|
+
'jsonc/sort-array-values': 'off',
|
|
124
|
+
'regexp/no-unused-capturing-group': 'off',
|
|
125
|
+
'regexp/optimal-quantifier-concatenation': 'off',
|
|
126
|
+
'regexp/no-super-linear-backtracking': 'off',
|
|
127
|
+
'regexp/negation': 'off',
|
|
128
|
+
'node/prefer-global/process': 'off',
|
|
129
|
+
'unicorn/prefer-number-properties': 'off',
|
|
130
|
+
'unicorn/new-for-builtins': 'off',
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
// ── Package-level overrides (matches user's packages/** pattern) ──────────
|
|
135
|
+
{
|
|
136
|
+
name: 'archipelago/packages',
|
|
137
|
+
files: ['packages/**/*.{js,ts,vue}'],
|
|
138
|
+
rules: {
|
|
139
|
+
'vue/multi-word-component-names': 'off',
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
// ── Nuxt app overrides ────────────────────────────────────────────────────
|
|
144
|
+
{
|
|
145
|
+
name: 'archipelago/nuxt',
|
|
146
|
+
files: [
|
|
147
|
+
'apps/nuxt-web/components/**/*.{js,ts,vue}',
|
|
148
|
+
'apps/nuxt-web/pages/**/*.{js,ts,vue}',
|
|
149
|
+
'apps/nuxt-web/layouts/**/*.{js,ts,vue}',
|
|
150
|
+
'apps/nuxt-web/composables/**/*.{js,ts}',
|
|
151
|
+
'apps/nuxt-web/constants/**/*.{js,ts}',
|
|
152
|
+
],
|
|
153
|
+
rules: {
|
|
154
|
+
'vue/multi-word-component-names': 'off',
|
|
155
|
+
'ts/no-explicit-any': 'warn',
|
|
79
156
|
},
|
|
80
157
|
},
|
|
158
|
+
|
|
81
159
|
...overrides,
|
|
82
160
|
)
|
|
83
161
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archpublicwebsite/eslint-config",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"author": "Archipelago
|
|
3
|
+
"version": "1.0.13",
|
|
4
|
+
"author": "Archipelago Hotels",
|
|
5
5
|
"description": "Reusable ESLint flat config and git-hook toolkit for Archipelago projects",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./eslint.config.mjs",
|
|
@@ -47,13 +47,15 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@antfu/eslint-config": "^4.12.0",
|
|
49
49
|
"@unocss/eslint-config": "^66.5.3",
|
|
50
|
-
"eslint": "^9.
|
|
50
|
+
"eslint": "^9.39.4",
|
|
51
|
+
"prettier": "^3.8.3",
|
|
51
52
|
"eslint-plugin-format": "^1.0.1",
|
|
52
53
|
"eslint-plugin-perfectionist": "^4.10.1",
|
|
53
54
|
"eslint-plugin-tailwindcss": "^3.17.3",
|
|
54
55
|
"prettier-plugin-tailwindcss": "^0.6.14"
|
|
55
56
|
},
|
|
56
57
|
"publishConfig": {
|
|
57
|
-
"access": "public"
|
|
58
|
+
"access": "public",
|
|
59
|
+
"provenance": false
|
|
58
60
|
}
|
|
59
61
|
}
|
|
@@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs'
|
|
|
2
2
|
|
|
3
3
|
export function isValidCommitMessage(message) {
|
|
4
4
|
const releaseRE = /^v\d/
|
|
5
|
-
const commitRE = /^(revert: )?(feat|fix|docs|refactor|perf|test|build|ci|chore|style|types|workflow|release|deps)(\([a-z0-9-]+\))?: \S
|
|
5
|
+
const commitRE = /^(revert: )?(feat|fix|docs|refactor|perf|test|build|ci|chore|style|types|workflow|release|deps)(\([a-z0-9-]+\))?: \S.*$/
|
|
6
6
|
return releaseRE.test(message) || commitRE.test(message)
|
|
7
7
|
}
|
|
8
8
|
|
|
@@ -13,10 +13,17 @@ function getCommitSubject(rawMessage) {
|
|
|
13
13
|
.find(line => line && !line.startsWith('#')) || ''
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
function isSkippableCommitSubject(subject) {
|
|
17
|
+
return !subject || subject.startsWith('Merge ') || subject.startsWith('fixup! ') || subject.startsWith('squash! ')
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
export function verifyCommitMessageFile(messageFilePath) {
|
|
17
21
|
const rawMessage = readFileSync(messageFilePath, 'utf-8')
|
|
18
22
|
const subject = getCommitSubject(rawMessage)
|
|
19
23
|
|
|
24
|
+
if (isSkippableCommitSubject(subject))
|
|
25
|
+
return
|
|
26
|
+
|
|
20
27
|
if (isValidCommitMessage(subject))
|
|
21
28
|
return
|
|
22
29
|
|
|
@@ -25,13 +32,12 @@ export function verifyCommitMessageFile(messageFilePath) {
|
|
|
25
32
|
'fix: handle events on blur (close #28)',
|
|
26
33
|
]
|
|
27
34
|
|
|
28
|
-
console.
|
|
29
|
-
console.
|
|
30
|
-
console.
|
|
31
|
-
console.
|
|
32
|
-
examples.forEach(example => console.
|
|
33
|
-
console.
|
|
34
|
-
process.exit(1)
|
|
35
|
+
console.warn('\nSUGGESTION: conventional commit format is recommended.\n')
|
|
36
|
+
console.warn('Required format: <type>(optional-scope): <description>')
|
|
37
|
+
console.warn('Suggested subject length: around 100 characters\n')
|
|
38
|
+
console.warn('Examples:')
|
|
39
|
+
examples.forEach(example => console.warn(` - ${example}`))
|
|
40
|
+
console.warn('\nSee README.md (Auto commit message flow) for details.\n')
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
package/tools/setup/vscode.mjs
CHANGED
|
@@ -41,23 +41,23 @@ const VSCODE_ESLINT_SETTINGS = {
|
|
|
41
41
|
'editor.defaultFormatter': 'dbaeumer.vscode-eslint',
|
|
42
42
|
},
|
|
43
43
|
|
|
44
|
-
//
|
|
45
|
-
'git.inputValidation':
|
|
46
|
-
'git.inputValidationSubjectLength':
|
|
47
|
-
'git.inputValidationLength':
|
|
44
|
+
// Keep commit message rules as guidance only, not strict blocking.
|
|
45
|
+
'git.inputValidation': false,
|
|
46
|
+
'git.inputValidationSubjectLength': 100,
|
|
47
|
+
'git.inputValidationLength': 120,
|
|
48
48
|
|
|
49
49
|
// Editor rules for git commit editor
|
|
50
50
|
'[git-commit]': {
|
|
51
|
-
'editor.rulers': [
|
|
51
|
+
'editor.rulers': [100, 120],
|
|
52
52
|
'editor.wordWrap': 'wordWrapColumn',
|
|
53
|
-
'editor.wordWrapColumn':
|
|
53
|
+
'editor.wordWrapColumn': 120,
|
|
54
54
|
},
|
|
55
55
|
|
|
56
56
|
// Editor rules for SCM input box (VS Code 1.86+)
|
|
57
57
|
'[scminput]': {
|
|
58
|
-
'editor.rulers': [
|
|
58
|
+
'editor.rulers': [100, 120],
|
|
59
59
|
'editor.wordWrap': 'wordWrapColumn',
|
|
60
|
-
'editor.wordWrapColumn':
|
|
60
|
+
'editor.wordWrapColumn': 120,
|
|
61
61
|
},
|
|
62
62
|
}
|
|
63
63
|
|