@archpublicwebsite/eslint-config 1.0.10 → 1.0.15
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 +102 -79
- package/eslint.config.mjs +103 -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,80 @@
|
|
|
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
|
+
- Prettier remains available for editor guidance, but the global `format/prettier` bridge is disabled to avoid flat-config parser conflicts
|
|
20
|
+
- Automatic project setup on install
|
|
21
|
+
- Works with the Archipelago repo style rules
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
Consumer projects should have these tools available when using the full setup:
|
|
6
26
|
|
|
7
27
|
```bash
|
|
8
|
-
|
|
9
|
-
pnpm version patch
|
|
10
|
-
npm publish --access public
|
|
28
|
+
pnpm add -D eslint prettier lint-staged turbo
|
|
11
29
|
```
|
|
12
30
|
|
|
13
|
-
|
|
31
|
+
## Installation
|
|
14
32
|
|
|
15
|
-
|
|
16
|
-
|
|
33
|
+
```bash
|
|
34
|
+
pnpm add -D @archpublicwebsite/eslint-config
|
|
35
|
+
```
|
|
17
36
|
|
|
18
|
-
##
|
|
37
|
+
## Usage
|
|
19
38
|
|
|
20
|
-
|
|
21
|
-
|
|
39
|
+
Create or update the root `eslint.config.mjs`:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { createArchipelagoConfig } from '@archpublicwebsite/eslint-config'
|
|
43
|
+
|
|
44
|
+
export default createArchipelagoConfig()
|
|
22
45
|
```
|
|
23
46
|
|
|
24
|
-
|
|
47
|
+
Override rules when your project needs to diverge from the shared defaults:
|
|
25
48
|
|
|
26
|
-
|
|
49
|
+
```js
|
|
50
|
+
import { createArchipelagoConfig } from '@archpublicwebsite/eslint-config'
|
|
27
51
|
|
|
28
|
-
|
|
29
|
-
|
|
52
|
+
export default createArchipelagoConfig({
|
|
53
|
+
name: 'project/overrides',
|
|
54
|
+
rules: {
|
|
55
|
+
'no-console': 'off',
|
|
56
|
+
'vue/max-attributes-per-line': 'off',
|
|
57
|
+
},
|
|
58
|
+
})
|
|
30
59
|
```
|
|
31
60
|
|
|
32
|
-
|
|
33
|
-
- `prettier` is used by the `lint:fix` flow.
|
|
34
|
-
- `turbo` is used by the required `lint:check` / `lint:fix` scripts.
|
|
61
|
+
## What the setup does
|
|
35
62
|
|
|
36
|
-
On install,
|
|
63
|
+
On install or when you run the setup script manually, the package prepares the consumer project with:
|
|
37
64
|
|
|
38
65
|
- `.hooks/pre-commit`
|
|
39
66
|
- `.hooks/prepare-commit-msg`
|
|
40
67
|
- `.hooks/commit-msg`
|
|
41
68
|
- `.hooks/post-commit`
|
|
42
|
-
- `eslint.config.mjs`
|
|
69
|
+
- `eslint.config.mjs` when one does not already exist
|
|
43
70
|
- `.prettierrc` plugin entry for `prettier-plugin-tailwindcss`
|
|
44
|
-
- `.vscode/settings.json`
|
|
45
|
-
- `.vscode/extensions.json`
|
|
46
|
-
- `git config core.hooksPath .hooks`
|
|
71
|
+
- `.vscode/settings.json` with ESLint flat-config settings
|
|
72
|
+
- `.vscode/extensions.json` with recommended extensions
|
|
73
|
+
- `git config core.hooksPath .hooks` when the project is a Git repository
|
|
47
74
|
|
|
48
|
-
|
|
75
|
+
## VS Code integration
|
|
49
76
|
|
|
50
|
-
|
|
77
|
+
The setup merges ESLint-related settings into `.vscode/settings.json`:
|
|
51
78
|
|
|
52
79
|
```json
|
|
53
80
|
{
|
|
@@ -65,100 +92,88 @@ On install, `.vscode/settings.json` is created or merged with these settings:
|
|
|
65
92
|
}
|
|
66
93
|
```
|
|
67
94
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
You can also re-run it manually:
|
|
95
|
+
Existing settings are preserved. Only the ESLint-related keys are added or updated.
|
|
71
96
|
|
|
72
|
-
|
|
73
|
-
node node_modules/@archpublicwebsite/eslint-config/tools/setup/install.mjs
|
|
74
|
-
```
|
|
97
|
+
## Public API
|
|
75
98
|
|
|
76
|
-
|
|
99
|
+
The package exports:
|
|
77
100
|
|
|
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
|
|
101
|
+
- `createArchipelagoConfig`
|
|
102
|
+
- setup scripts under `tools/`
|
|
87
103
|
|
|
88
|
-
##
|
|
104
|
+
## AI Implementation Guide
|
|
89
105
|
|
|
90
|
-
|
|
106
|
+
If you are extending or regenerating this package, keep the workflow explicit:
|
|
91
107
|
|
|
92
|
-
|
|
93
|
-
|
|
108
|
+
1. Update `eslint.config.mjs` when shared lint rules change.
|
|
109
|
+
2. Update `tools/setup/install.mjs` when install-time bootstrap behavior changes.
|
|
110
|
+
3. Update `tools/git-hooks/` when hook behavior changes.
|
|
111
|
+
4. Keep the package export map aligned with the public API.
|
|
112
|
+
5. Document any new consumer dependency that the setup expects.
|
|
94
113
|
|
|
95
|
-
|
|
96
|
-
```
|
|
114
|
+
### AI-friendly implementation notes
|
|
97
115
|
|
|
98
|
-
|
|
116
|
+
- Use `createArchipelagoConfig()` in the consumer project, not the internal setup scripts.
|
|
117
|
+
- Keep root scripts in sync with the hook and lint expectations.
|
|
118
|
+
- Re-run the package setup flow when changing VS Code or hook behavior.
|
|
119
|
+
- Prefer explicit examples that show what the consumer project should add.
|
|
99
120
|
|
|
100
|
-
|
|
121
|
+
## Manual setup
|
|
101
122
|
|
|
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:
|
|
123
|
+
If you need to rerun the bootstrap manually:
|
|
117
124
|
|
|
118
125
|
```bash
|
|
119
|
-
node node_modules/eslint-config/tools/setup/install.mjs
|
|
126
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/setup/install.mjs
|
|
120
127
|
```
|
|
121
128
|
|
|
122
129
|
## Hook wrappers reference
|
|
123
130
|
|
|
124
|
-
Root `.hooks` scripts should delegate to installed package path:
|
|
125
|
-
|
|
126
|
-
- `.hooks/pre-commit`
|
|
131
|
+
Root `.hooks` scripts should delegate to the installed package path:
|
|
127
132
|
|
|
128
133
|
```bash
|
|
129
134
|
#!/usr/bin/env bash
|
|
130
135
|
set -euo pipefail
|
|
131
136
|
cd "$(git rev-parse --show-toplevel)"
|
|
132
|
-
node node_modules/eslint-config/tools/git-hooks/pre-commit.mjs
|
|
137
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/pre-commit.mjs
|
|
133
138
|
```
|
|
134
139
|
|
|
135
|
-
- `.hooks/prepare-commit-msg`
|
|
136
|
-
|
|
137
140
|
```bash
|
|
138
141
|
#!/usr/bin/env bash
|
|
139
142
|
set -euo pipefail
|
|
140
143
|
cd "$(git rev-parse --show-toplevel)"
|
|
141
|
-
node node_modules/eslint-config/tools/git-hooks/prepare-commit-msg.mjs "$@"
|
|
144
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/prepare-commit-msg.mjs "$@"
|
|
142
145
|
```
|
|
143
146
|
|
|
144
|
-
- `.hooks/commit-msg`
|
|
145
|
-
|
|
146
147
|
```bash
|
|
147
148
|
#!/usr/bin/env bash
|
|
148
149
|
set -euo pipefail
|
|
149
150
|
cd "$(git rev-parse --show-toplevel)"
|
|
150
|
-
node node_modules/eslint-config/tools/git-hooks/commit-msg.mjs "$1"
|
|
151
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/commit-msg.mjs "$1"
|
|
151
152
|
```
|
|
152
153
|
|
|
153
|
-
- `.hooks/post-commit`
|
|
154
|
-
|
|
155
154
|
```bash
|
|
156
155
|
#!/usr/bin/env bash
|
|
157
156
|
set -euo pipefail
|
|
158
157
|
cd "$(git rev-parse --show-toplevel)"
|
|
159
|
-
node node_modules/eslint-config/tools/git-hooks/post-commit.mjs
|
|
158
|
+
node node_modules/@archpublicwebsite/eslint-config/tools/git-hooks/post-commit.mjs
|
|
160
159
|
```
|
|
161
160
|
|
|
161
|
+
## Publish
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
cd packages/eslint-config
|
|
165
|
+
pnpm version patch
|
|
166
|
+
npm publish --access public
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Before publish, run:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npm pack --dry-run
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Make sure the tarball contains only the intended public files: `eslint.config.mjs`, `tools/`, and `README.md`.
|
|
176
|
+
|
|
162
177
|
## Required root scripts
|
|
163
178
|
|
|
164
179
|
```json
|
|
@@ -173,3 +188,11 @@ node node_modules/eslint-config/tools/git-hooks/post-commit.mjs
|
|
|
173
188
|
}
|
|
174
189
|
}
|
|
175
190
|
```
|
|
191
|
+
|
|
192
|
+
## Verification
|
|
193
|
+
|
|
194
|
+
After making config changes, validate the package by checking the installed consumer workflow or by running the setup script in a test project.
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
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,47 @@ 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
|
+
// Disable the global Prettier bridge rule here because it requires a
|
|
44
|
+
// parser per file type and creates validation conflicts in flat config.
|
|
45
|
+
'format/prettier': 'off',
|
|
46
|
+
|
|
47
|
+
// ── Anti-loop: disable rules that fight @stylistic equivalents ─────────
|
|
48
|
+
'object-curly-newline': 'off',
|
|
49
|
+
'style/object-curly-newline': 'off',
|
|
50
|
+
'style/operator-linebreak': 'off',
|
|
51
|
+
'style/indent': 'off',
|
|
52
|
+
'style/indent-binary-ops': 'off',
|
|
53
|
+
'max-statements-per-line': 'off',
|
|
54
|
+
'antfu/consistent-list-newline': 'off',
|
|
55
|
+
'antfu/consistent-chaining': 'off',
|
|
56
|
+
'antfu/if-newline': 'off',
|
|
57
|
+
'antfu/no-import-dist': 'off',
|
|
58
|
+
|
|
59
|
+
// ── Vue ──────────────────────────────────────────────────────────────
|
|
56
60
|
'vue/multi-word-component-names': 'off',
|
|
57
61
|
'vue/no-required-prop-with-default': 'off',
|
|
58
62
|
'vue/html-self-closing': 'off',
|
|
59
63
|
'vue/html-closing-bracket-spacing': 'off',
|
|
60
64
|
'vue/no-multiple-template-root': 'off',
|
|
65
|
+
'vue/attributes-order': 'off',
|
|
66
|
+
'vue/singleline-html-element-content-newline': 'off',
|
|
67
|
+
'vue/html-closing-bracket-newline': 'off',
|
|
68
|
+
'vue/html-indent': 'off',
|
|
69
|
+
'vue/no-useless-v-bind': 'off',
|
|
70
|
+
'vue/prefer-separate-static-class': 'off',
|
|
71
|
+
'vue/attribute-hyphenation': 'off',
|
|
72
|
+
'vue/define-macros-order': 'off',
|
|
61
73
|
'vue/max-attributes-per-line': ['error', {
|
|
62
74
|
singleline: 3,
|
|
63
75
|
multiline: 1,
|
|
@@ -72,12 +84,71 @@ export function createArchipelagoConfig(...overrides) {
|
|
|
72
84
|
ignoreHTMLAttributeValues: true,
|
|
73
85
|
ignoreHTMLTextContents: true,
|
|
74
86
|
}],
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
|
|
88
|
+
// ── TypeScript ───────────────────────────────────────────────────────
|
|
89
|
+
'ts/no-use-before-define': 'off',
|
|
90
|
+
'ts/no-empty-object-type': 'off',
|
|
91
|
+
'ts/no-explicit-any': 'warn',
|
|
92
|
+
'ts/no-var-requires': 'warn',
|
|
93
|
+
'ts/consistent-type-imports': ['error', {
|
|
94
|
+
prefer: 'type-imports',
|
|
95
|
+
fixStyle: 'inline-type-imports',
|
|
77
96
|
}],
|
|
78
|
-
|
|
97
|
+
|
|
98
|
+
// ── Import ordering ──────────────────────────────────────────────────
|
|
99
|
+
'import/order': 'off',
|
|
100
|
+
'import/newline-after-import': 'off',
|
|
101
|
+
'import/consistent-type-specifier-style': 'off',
|
|
102
|
+
'perfectionist/sort-imports': 'off',
|
|
103
|
+
'perfectionist/sort-exports': 'off',
|
|
104
|
+
'perfectionist/sort-named-imports': 'off',
|
|
105
|
+
'perfectionist/sort-named-exports': 'off',
|
|
106
|
+
|
|
107
|
+
// ── Tailwind ─────────────────────────────────────────────────────────
|
|
108
|
+
'tailwindcss/no-custom-classname': 'off',
|
|
109
|
+
'tailwindcss/migration-from-tailwind-2': 'off',
|
|
110
|
+
'tailwindcss/enforces-shorthand': 'off',
|
|
111
|
+
|
|
112
|
+
// ── Misc ─────────────────────────────────────────────────────────────
|
|
113
|
+
'no-console': 'warn',
|
|
114
|
+
'no-alert': 'off',
|
|
115
|
+
'jsonc/sort-keys': 'off',
|
|
116
|
+
'jsonc/sort-array-values': 'off',
|
|
117
|
+
'regexp/no-unused-capturing-group': 'off',
|
|
118
|
+
'regexp/optimal-quantifier-concatenation': 'off',
|
|
119
|
+
'regexp/no-super-linear-backtracking': 'off',
|
|
120
|
+
'regexp/negation': 'off',
|
|
121
|
+
'node/prefer-global/process': 'off',
|
|
122
|
+
'unicorn/prefer-number-properties': 'off',
|
|
123
|
+
'unicorn/new-for-builtins': 'off',
|
|
79
124
|
},
|
|
80
125
|
},
|
|
126
|
+
|
|
127
|
+
// ── Package-level overrides (matches user's packages/** pattern) ──────────
|
|
128
|
+
{
|
|
129
|
+
name: 'archipelago/packages',
|
|
130
|
+
files: ['packages/**/*.{js,ts,vue}'],
|
|
131
|
+
rules: {
|
|
132
|
+
'vue/multi-word-component-names': 'off',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
// ── Nuxt app overrides ────────────────────────────────────────────────────
|
|
137
|
+
{
|
|
138
|
+
name: 'archipelago/nuxt',
|
|
139
|
+
files: [
|
|
140
|
+
'apps/nuxt-web/components/**/*.{js,ts,vue}',
|
|
141
|
+
'apps/nuxt-web/pages/**/*.{js,ts,vue}',
|
|
142
|
+
'apps/nuxt-web/layouts/**/*.{js,ts,vue}',
|
|
143
|
+
'apps/nuxt-web/composables/**/*.{js,ts}',
|
|
144
|
+
'apps/nuxt-web/constants/**/*.{js,ts}',
|
|
145
|
+
],
|
|
146
|
+
rules: {
|
|
147
|
+
'vue/multi-word-component-names': 'off',
|
|
148
|
+
'ts/no-explicit-any': 'warn',
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
|
|
81
152
|
...overrides,
|
|
82
153
|
)
|
|
83
154
|
}
|
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.15",
|
|
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
|
|