@sinemacula/coding-standards 1.17.0 → 1.19.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/README.md +57 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://packagist.org/packages/sinemacula/coding-standards)
|
|
4
4
|
[](https://www.npmjs.com/package/@sinemacula/coding-standards)
|
|
5
|
+
[](https://github.com/sinemacula/coding-standards/actions/workflows/tests.yml)
|
|
6
|
+
[](https://github.com/sinemacula/coding-standards/actions/workflows/quality-gates.yml)
|
|
5
7
|
[](https://qlty.sh/gh/sinemacula/projects/coding-standards)
|
|
6
8
|
[](https://qlty.sh/gh/sinemacula/projects/coding-standards)
|
|
7
9
|
[](https://packagist.org/packages/sinemacula/coding-standards)
|
|
@@ -86,8 +88,8 @@ parameters:
|
|
|
86
88
|
|
|
87
89
|
For Laravel projects, also install
|
|
88
90
|
[`sinemacula/coding-standards-laravel`](https://github.com/sinemacula/coding-standards-laravel) and reference its
|
|
89
|
-
`SineMaculaLaravel` PHPCS standard (which includes this one) in place of `SineMacula`. It adds the
|
|
90
|
-
|
|
91
|
+
`SineMaculaLaravel` PHPCS standard (which includes this one) in place of `SineMacula`. It adds the Laravel-specific
|
|
92
|
+
sniffs and PHPStan rules; see that package's README for setup.
|
|
91
93
|
|
|
92
94
|
### Biome (JavaScript / TypeScript)
|
|
93
95
|
|
|
@@ -112,9 +114,8 @@ After installing the npm package, extend the shared Biome config from your proje
|
|
|
112
114
|
}
|
|
113
115
|
```
|
|
114
116
|
|
|
115
|
-
`extends` paths are resolved through normal Node module lookup, so the package only needs to be installed (no path
|
|
116
|
-
|
|
117
|
-
config.
|
|
117
|
+
`extends` paths are resolved through normal Node module lookup, so the package only needs to be installed (no path math
|
|
118
|
+
against `node_modules/` required). Project-specific `files.includes` and `files.excludes` stay in the consumer config.
|
|
118
119
|
|
|
119
120
|
### ESLint (JavaScript / TypeScript)
|
|
120
121
|
|
|
@@ -134,9 +135,9 @@ The package exposes three flat-config entry points:
|
|
|
134
135
|
- `@sinemacula/coding-standards/js/eslint/type-checked` - the opt-in type-aware layer. It includes the base layer and
|
|
135
136
|
adds the cross-file / type-driven rules, so it needs a consumer `tsconfig`; use it in place of the base layer where
|
|
136
137
|
one exists.
|
|
137
|
-
- `@sinemacula/coding-standards/js/eslint/vue` - the opt-in Vue layer for single-file components. Unlike the
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
- `@sinemacula/coding-standards/js/eslint/vue` - the opt-in Vue layer for single-file components. Unlike the type-aware
|
|
139
|
+
layer it carries no base rules of its own, so spread it *alongside* whichever layer the repository already uses rather
|
|
140
|
+
than in place of one.
|
|
140
141
|
|
|
141
142
|
Create an `eslint.config.js` (or `.qlty/configs/eslint.config.js` when wired through Qlty) that spreads the layer you
|
|
142
143
|
want. Without a `tsconfig`, use the base layer:
|
|
@@ -169,23 +170,23 @@ export default [...typeChecked, ...vue];
|
|
|
169
170
|
```
|
|
170
171
|
|
|
171
172
|
The Vue layer registers the single-file-component parser (without it `.vue` files are not linted at all), resolves
|
|
172
|
-
`<script lang="ts">` blocks through the TypeScript parser, and holds component filenames to kebab-case. It also
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
`<script lang="ts">` blocks through the TypeScript parser, and holds component filenames to kebab-case. It also carries
|
|
174
|
+
the template layout rules, which is the one place ESLint takes on formatting: Biome does not understand single-file
|
|
175
|
+
components, so `.vue` markup would otherwise go unformatted entirely. Those rules are aligned to the shared four-space
|
|
176
|
+
indent.
|
|
176
177
|
|
|
177
178
|
When wiring ESLint through Qlty, the shared eslint plugin sandbox installs only `eslint`, `jest`, and `prettier` by
|
|
178
|
-
default, so the flat config's imports of this package and `typescript-eslint` fail to resolve. Widen the install
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
default, so the flat config's imports of this package and `typescript-eslint` fail to resolve. Widen the install filter
|
|
180
|
+
in your `.qlty/qlty.toml` so the sandbox carries them (this repository's `source.toml` exports the same override, but
|
|
181
|
+
source-exported plugin definitions do not reliably propagate, so mirror it consumer-side):
|
|
181
182
|
|
|
182
183
|
```toml
|
|
183
184
|
[plugins.definitions.eslint]
|
|
184
185
|
package_filters = ["@sinemacula/coding-standards", "typescript-eslint", "@typescript-eslint", "eslint-plugin-jsdoc"]
|
|
185
186
|
```
|
|
186
187
|
|
|
187
|
-
Repositories enabling the Vue layer widen the same filter further, since its plugins have to resolve inside that
|
|
188
|
-
|
|
188
|
+
Repositories enabling the Vue layer widen the same filter further, since its plugins have to resolve inside that sandbox
|
|
189
|
+
too:
|
|
189
190
|
|
|
190
191
|
```toml
|
|
191
192
|
[plugins.definitions.eslint]
|
|
@@ -204,17 +205,25 @@ package (as above) and extend the base from your `tsconfig.json`:
|
|
|
204
205
|
{
|
|
205
206
|
"extends": "@sinemacula/coding-standards/js/tsconfig.base.json",
|
|
206
207
|
"compilerOptions": {
|
|
207
|
-
"lib": [
|
|
208
|
-
|
|
208
|
+
"lib": [
|
|
209
|
+
"ES2023",
|
|
210
|
+
"DOM",
|
|
211
|
+
"DOM.Iterable"
|
|
212
|
+
],
|
|
213
|
+
"types": [
|
|
214
|
+
"node"
|
|
215
|
+
]
|
|
209
216
|
},
|
|
210
|
-
"include": [
|
|
217
|
+
"include": [
|
|
218
|
+
"src"
|
|
219
|
+
]
|
|
211
220
|
}
|
|
212
221
|
```
|
|
213
222
|
|
|
214
|
-
The base carries only the environment-independent options: the full strictness set and the module/resolution
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
223
|
+
The base carries only the environment-independent options: the full strictness set and the module/resolution discipline.
|
|
224
|
+
Everything environment-specific stays in the consuming repo and layers on top - `lib` (DOM for the browser, none for a
|
|
225
|
+
Node service), `types`, Vue's `jsx`/`jsxImportSource`, `paths`, `noEmit`, and the `include`/`exclude` globs. The`target`
|
|
226
|
+
and `module` defaults suit bundler-built apps and libraries; a non-bundler project overrides them.
|
|
218
227
|
|
|
219
228
|
The base sets `noPropertyAccessFromIndexSignature`, so a property that comes from an index signature is accessed with
|
|
220
229
|
brackets (`config['key']`), not a dot. Biome cannot see types and so cannot tell that access apart from a normal one,
|
|
@@ -273,6 +282,7 @@ native directive - `// phpcs:ignore <code>` for a sniff, `@phpstan-ignore <ident
|
|
|
273
282
|
|------------------------------------------------------------|-----------------------------------------------------------------------------|
|
|
274
283
|
| `SineMacula.Attributes.DisallowToolingAttribute` | No IDE/tooling attributes (e.g. `JetBrains\PhpStorm`). |
|
|
275
284
|
| `SineMacula.Classes.RequireFinalClass` | Concrete classes must be `final` or `abstract` (`@inheritable` opts out). |
|
|
285
|
+
| `SineMacula.Classes.RequireReadonlyClass` | A class with only `readonly` properties (no statics) must be `readonly`. |
|
|
276
286
|
| `SineMacula.Classes.RequireReadonlyPublicProperty` | Public properties (declared or promoted) must be `readonly`. |
|
|
277
287
|
| `SineMacula.Commenting.CommentLineLength` | Standalone comment prose wrapped to 80 chars; premature wraps also fixed. |
|
|
278
288
|
| `SineMacula.Commenting.ConsistentEnumCaseComments` | Enum case docs are all-or-nothing within an enum. |
|
|
@@ -294,6 +304,7 @@ native directive - `// phpcs:ignore <code>` for a sniff, `@phpstan-ignore <ident
|
|
|
294
304
|
| `SineMacula.NamingConventions.DisallowInterfacePrefix` | Interface names must not use the Hungarian `I` prefix. |
|
|
295
305
|
| `SineMacula.NamingConventions.ValidEnumCaseName` | Enum cases must be `SCREAMING_SNAKE_CASE`. |
|
|
296
306
|
| `SineMacula.NamingConventions.ValidGlobalFunctionName` | Global functions must be declared in `snake_case`. |
|
|
307
|
+
| `SineMacula.TypeHints.DisallowFullyQualifiedConstantType` | Constant types must be imported, not inline fully-qualified names. |
|
|
297
308
|
| `SineMacula.TypeHints.RequireConstantType` | Class/interface/enum/trait constants must declare a native type. |
|
|
298
309
|
| `SineMacula.WhiteSpace.PromotedConstructorSpacing` | Blank line above each promoted-constructor parameter. |
|
|
299
310
|
|
|
@@ -325,28 +336,28 @@ type-checked layer.
|
|
|
325
336
|
|
|
326
337
|
`boolean-method-name` takes `additionalPrefixes`, `additionalPredicates` and `additionalCommandVerbs` (string arrays)
|
|
327
338
|
to widen the accepted vocabulary from a consumer config. `max-methods-per-class` takes `max`, `no-base-error` takes
|
|
328
|
-
`allow`, and `require-copyright` takes `tags` to adjust their defaults. `align-doc-tags` takes `tags` and `column`,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
339
|
+
`allow`, and `require-copyright` takes `tags` to adjust their defaults. `align-doc-tags` takes `tags` and `column`, the
|
|
340
|
+
column counting from the `@`, so the default of 14 gives `@author` six spaces and `@copyright` three. Together
|
|
341
|
+
`single-line-property-doc` and `multiline-function-doc` set a member's comment shape by its kind: data members
|
|
342
|
+
(interface property signatures, enum members and data class fields) take one line, while methods, interface method
|
|
343
|
+
signatures and class fields holding a function take several. A data comment is never required, only held to one line
|
|
344
|
+
where present; a free function keeps the freedom of either shape.
|
|
334
345
|
|
|
335
346
|
`comment-line-wrap` takes `maxLength` (default 80) and is the syntax-only counterpart of the PHP
|
|
336
347
|
`SineMacula.Commenting.CommentLineLength` sniff. It fills standalone `//` runs and multi-line docblock prose greedily,
|
|
337
348
|
reporting an overflowing line and a prematurely wrapped line on their own footings and autofixing both. Markdown
|
|
338
349
|
headings, docblock tag lines, machine-parsed tool directives (`eslint`, `biome-ignore`, `@ts-`, `Stryker`, `c8`/`v8`/
|
|
339
|
-
`istanbul ignore`, `@vite-ignore` and the like), fenced code, an indented code or command block, a doc-tag whose
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
350
|
+
`istanbul ignore`, `@vite-ignore` and the like), fenced code, an indented code or command block, a doc-tag whose value
|
|
351
|
+
opens a multi-line bracketed type (an `array{...}` shape, a `<...>` generic or a `\Closure(...)` signature), tables,
|
|
352
|
+
separators, a line whose overflow is a single unbreakable token such as a long name or URL, trailing comments after code
|
|
353
|
+
and compact single-line docblocks are left untouched.
|
|
343
354
|
|
|
344
355
|
The base layer also switches on a set of built-in rules: `@typescript-eslint/no-explicit-any`, `curly` (a brace on every
|
|
345
356
|
control statement, as PSR-12 already requires on the PHP side), `max-lines-per-function` (50 lines, test code exempt)
|
|
346
|
-
and `max-depth` (4), plus `eslint-plugin-jsdoc` rules that require a documentation comment
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
357
|
+
and `max-depth` (4), plus `eslint-plugin-jsdoc` rules that require a documentation comment on every declared function,
|
|
358
|
+
method, class, interface member and class field, forbid types in `@param`/`@returns` (the tags themselves are welcome,
|
|
359
|
+
types belong in the signature) and keep a blank line above every documentation block, single-line blocks included. The
|
|
360
|
+
type-checked layer adds `@typescript-eslint/explicit-module-boundary-types` and
|
|
350
361
|
`@typescript-eslint/only-throw-error`.
|
|
351
362
|
|
|
352
363
|
## Requirements
|
|
@@ -357,12 +368,14 @@ single-line blocks included. The type-checked layer adds `@typescript-eslint/exp
|
|
|
357
368
|
## Testing
|
|
358
369
|
|
|
359
370
|
```bash
|
|
360
|
-
composer test
|
|
361
|
-
composer test:coverage
|
|
362
|
-
composer
|
|
363
|
-
composer
|
|
364
|
-
composer
|
|
365
|
-
composer
|
|
371
|
+
composer test # PHPUnit suite for the custom sniffs and PHPStan rule
|
|
372
|
+
composer test:coverage # suite with Clover coverage output
|
|
373
|
+
composer test:mutation # Infection mutation gate (min MSI 90)
|
|
374
|
+
composer test:mutation:full # full mutation suite without thresholds
|
|
375
|
+
composer analyse # PHPStan static analysis
|
|
376
|
+
composer check # static analysis and lint via qlty
|
|
377
|
+
composer format # format via qlty
|
|
378
|
+
composer smells # duplication / complexity smells via qlty
|
|
366
379
|
```
|
|
367
380
|
|
|
368
381
|
## Changelog
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sinemacula/coding-standards",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
4
4
|
"description": "Centralized coding standards, static analysis configurations, and code quality tooling for all Sine Macula repositories.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Ben Carey <bdmc@sinemacula.co.uk>",
|