eslint-plugin-traceability 1.1.1 → 1.1.3
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/package.json +6 -1
- package/.env.example +0 -6
- package/.github/workflows/ci-cd.yml +0 -110
- package/.husky/pre-commit +0 -1
- package/.husky/pre-push +0 -1
- package/.prettierignore +0 -27
- package/.prettierrc +0 -4
- package/.releaserc.json +0 -20
- package/.voder/history.md +0 -162
- package/.voder/implementation-progress.md +0 -144
- package/.voder/last-action.md +0 -83
- package/.voder/plan.md +0 -12
- package/.voder/progress-chart.png +0 -0
- package/.voder/progress-log-areas.csv +0 -39
- package/.voder/progress-log.csv +0 -38
- package/.voder/traceability/docs-stories-001.0-DEV-PLUGIN-SETUP.story.xml +0 -17
- package/.voder/traceability/docs-stories-002.0-DEV-ESLINT-CONFIG.story.xml +0 -13
- package/.voder/traceability/docs-stories-003.0-DEV-FUNCTION-ANNOTATIONS.story.xml +0 -9
- package/.voder/traceability/docs-stories-004.0-DEV-BRANCH-ANNOTATIONS.story.xml +0 -9
- package/.voder/traceability/docs-stories-005.0-DEV-ANNOTATION-VALIDATION.story.xml +0 -9
- package/.voder/traceability/docs-stories-006.0-DEV-FILE-VALIDATION.story.xml +0 -9
- package/.voder/traceability/docs-stories-007.0-DEV-ERROR-REPORTING.story.xml +0 -9
- package/.voder/traceability/docs-stories-008.0-DEV-AUTO-FIX.story.xml +0 -9
- package/.voder/traceability/docs-stories-009.0-DEV-MAINTENANCE-TOOLS.story.xml +0 -16
- package/.voder/traceability/docs-stories-010.0-DEV-DEEP-VALIDATION.story.xml +0 -11
- package/CHANGELOG.md +0 -58
- package/CONTRIBUTING.md +0 -99
- package/cli-integration.js +0 -103
- package/docs/cli-integration.md +0 -105
- package/docs/config-presets.md +0 -38
- package/docs/conventional-commits-guide.md +0 -185
- package/docs/decisions/001-typescript-for-eslint-plugin.accepted.md +0 -111
- package/docs/decisions/002-jest-for-eslint-testing.accepted.md +0 -137
- package/docs/decisions/003-code-quality-ratcheting-plan.md +0 -48
- package/docs/decisions/004-automated-version-bumping-for-ci-cd.md +0 -196
- package/docs/decisions/005-github-actions-validation-tooling.accepted.md +0 -144
- package/docs/decisions/006-semantic-release-for-automated-publishing.accepted.md +0 -227
- package/docs/eslint-9-setup-guide.md +0 -517
- package/docs/eslint-plugin-development-guide.md +0 -483
- package/docs/jest-testing-guide.md +0 -100
- package/docs/rules/require-branch-annotation.md +0 -34
- package/docs/rules/require-req-annotation.md +0 -39
- package/docs/rules/require-story-annotation.md +0 -36
- package/docs/rules/valid-annotation-format.md +0 -52
- package/docs/rules/valid-req-reference.md +0 -58
- package/docs/rules/valid-story-reference.md +0 -47
- package/docs/security-incidents/unresolved-vulnerabilities.md +0 -11
- package/docs/stories/001.0-DEV-PLUGIN-SETUP.story.md +0 -82
- package/docs/stories/002.0-DEV-ESLINT-CONFIG.story.md +0 -82
- package/docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md +0 -85
- package/docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md +0 -107
- package/docs/stories/005.0-DEV-ANNOTATION-VALIDATION.story.md +0 -119
- package/docs/stories/006.0-DEV-FILE-VALIDATION.story.md +0 -127
- package/docs/stories/007.0-DEV-ERROR-REPORTING.story.md +0 -89
- package/docs/stories/008.0-DEV-AUTO-FIX.story.md +0 -104
- package/docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md +0 -104
- package/docs/stories/010.0-DEV-DEEP-VALIDATION.story.md +0 -110
- package/docs/stories/developer-story.map.md +0 -118
- package/eslint.config.js +0 -146
- package/jest.config.js +0 -21
- package/scripts/smoke-test.sh +0 -51
- package/src/index.ts +0 -56
- package/src/maintenance/batch.ts +0 -29
- package/src/maintenance/detect.ts +0 -42
- package/src/maintenance/index.ts +0 -14
- package/src/maintenance/report.ts +0 -15
- package/src/maintenance/update.ts +0 -40
- package/src/maintenance/utils.ts +0 -28
- package/src/rules/require-branch-annotation.ts +0 -114
- package/src/rules/require-req-annotation.ts +0 -36
- package/src/rules/require-story-annotation.ts +0 -52
- package/src/rules/valid-annotation-format.ts +0 -62
- package/src/rules/valid-req-reference.ts +0 -114
- package/src/rules/valid-story-reference.ts +0 -213
- package/tests/fixtures/stale/example.ts +0 -2
- package/tests/fixtures/story_bullet.md +0 -6
- package/tests/fixtures/update/example.ts +0 -2
- package/tests/fixtures/valid-annotations/example.ts +0 -2
- package/tests/maintenance/batch.test.ts +0 -55
- package/tests/maintenance/detect-isolated.test.ts +0 -65
- package/tests/maintenance/detect.test.ts +0 -19
- package/tests/maintenance/report.test.ts +0 -37
- package/tests/maintenance/update-isolated.test.ts +0 -39
- package/tests/maintenance/update.test.ts +0 -21
- package/tests/plugin-default-export-and-configs.test.ts +0 -50
- package/tests/plugin-setup.test.ts +0 -17
- package/tests/rules/require-branch-annotation.test.ts +0 -250
- package/tests/rules/require-req-annotation.test.ts +0 -38
- package/tests/rules/require-story-annotation.test.ts +0 -33
- package/tests/rules/valid-annotation-format.test.ts +0 -55
- package/tests/rules/valid-req-reference.test.ts +0 -85
- package/tests/rules/valid-story-reference.test.ts +0 -66
- package/tsconfig.json +0 -15
- package/user-docs/api-reference.md +0 -135
- package/user-docs/examples.md +0 -73
- package/user-docs/migration-guide.md +0 -71
|
@@ -1,483 +0,0 @@
|
|
|
1
|
-
# ESLint Plugin Development Guidance
|
|
2
|
-
|
|
3
|
-
This document provides comprehensive guidance for developing ESLint plugins, specifically tailored for the eslint-plugin-traceability project. It's based on the official [ESLint plugin documentation](https://eslint.org/docs/latest/extend/plugins) and includes project-specific considerations.
|
|
4
|
-
|
|
5
|
-
## Plugin Structure Overview
|
|
6
|
-
|
|
7
|
-
An ESLint plugin is a JavaScript object that exposes specific properties to ESLint:
|
|
8
|
-
|
|
9
|
-
- `meta` - information about the plugin
|
|
10
|
-
- `configs` - an object containing named configurations
|
|
11
|
-
- `rules` - an object containing custom rule definitions
|
|
12
|
-
- `processors` - an object containing named processors
|
|
13
|
-
|
|
14
|
-
## Basic Plugin Template
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
// src/index.ts
|
|
18
|
-
const plugin = {
|
|
19
|
-
meta: {
|
|
20
|
-
name: "eslint-plugin-traceability",
|
|
21
|
-
version: "1.0.0",
|
|
22
|
-
namespace: "traceability",
|
|
23
|
-
},
|
|
24
|
-
configs: {},
|
|
25
|
-
rules: {},
|
|
26
|
-
processors: {},
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// for ESM source (compiled to CommonJS)
|
|
30
|
-
export default plugin;
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Meta Data Requirements
|
|
34
|
-
|
|
35
|
-
### Essential Meta Properties
|
|
36
|
-
|
|
37
|
-
Every plugin should include meta information for debugging and caching:
|
|
38
|
-
|
|
39
|
-
```typescript
|
|
40
|
-
const plugin = {
|
|
41
|
-
meta: {
|
|
42
|
-
name: "eslint-plugin-traceability", // npm package name
|
|
43
|
-
version: "1.0.0", // npm package version
|
|
44
|
-
namespace: "traceability", // prefix for rules/configs
|
|
45
|
-
},
|
|
46
|
-
// ... other properties
|
|
47
|
-
};
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Reading from package.json
|
|
51
|
-
|
|
52
|
-
For maintainability, read name and version from package.json:
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
import fs from "fs";
|
|
56
|
-
import { fileURLToPath } from "url";
|
|
57
|
-
import { dirname, join } from "path";
|
|
58
|
-
|
|
59
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
60
|
-
const __dirname = dirname(__filename);
|
|
61
|
-
|
|
62
|
-
const pkg = JSON.parse(
|
|
63
|
-
fs.readFileSync(join(__dirname, "../package.json"), "utf8"),
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
const plugin = {
|
|
67
|
-
meta: {
|
|
68
|
-
name: pkg.name,
|
|
69
|
-
version: pkg.version,
|
|
70
|
-
namespace: "traceability",
|
|
71
|
-
},
|
|
72
|
-
// ... other properties
|
|
73
|
-
};
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Rule Development
|
|
77
|
-
|
|
78
|
-
### Rule Structure
|
|
79
|
-
|
|
80
|
-
Rules are the core functionality of an ESLint plugin:
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
const plugin = {
|
|
84
|
-
meta: {
|
|
85
|
-
name: "eslint-plugin-traceability",
|
|
86
|
-
version: "1.0.0",
|
|
87
|
-
namespace: "traceability",
|
|
88
|
-
},
|
|
89
|
-
rules: {
|
|
90
|
-
"require-story-annotation": {
|
|
91
|
-
meta: {
|
|
92
|
-
type: "problem",
|
|
93
|
-
docs: {
|
|
94
|
-
description: "require @story annotations on functions",
|
|
95
|
-
category: "Traceability",
|
|
96
|
-
recommended: true,
|
|
97
|
-
},
|
|
98
|
-
schema: [
|
|
99
|
-
{
|
|
100
|
-
type: "object",
|
|
101
|
-
properties: {
|
|
102
|
-
// rule options
|
|
103
|
-
},
|
|
104
|
-
additionalProperties: false,
|
|
105
|
-
},
|
|
106
|
-
],
|
|
107
|
-
messages: {
|
|
108
|
-
missingStory: "Function '{{name}}' is missing @story annotation",
|
|
109
|
-
invalidStoryFormat: "@story annotation format is invalid: {{format}}",
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
create(context) {
|
|
113
|
-
return {
|
|
114
|
-
FunctionDeclaration(node) {
|
|
115
|
-
// rule implementation
|
|
116
|
-
},
|
|
117
|
-
};
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Rule Implementation Guidelines
|
|
125
|
-
|
|
126
|
-
1. **Use TypeScript for type safety**: Leverage @typescript-eslint/utils for AST manipulation
|
|
127
|
-
2. **Clear error messages**: Provide helpful, actionable error messages
|
|
128
|
-
3. **Configurable options**: Allow users to customize rule behavior
|
|
129
|
-
4. **Performance**: Avoid expensive operations in visitors
|
|
130
|
-
5. **Testing**: Use ESLint's RuleTester for comprehensive testing
|
|
131
|
-
|
|
132
|
-
### AST Node Handling
|
|
133
|
-
|
|
134
|
-
When working with AST nodes, use TypeScript for safety:
|
|
135
|
-
|
|
136
|
-
```typescript
|
|
137
|
-
import { TSESTree } from "@typescript-eslint/utils";
|
|
138
|
-
|
|
139
|
-
function checkFunctionAnnotation(node: TSESTree.FunctionDeclaration) {
|
|
140
|
-
// Type-safe AST manipulation
|
|
141
|
-
if (node.id?.name) {
|
|
142
|
-
// Check for @story annotation in comments
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Configuration Presets
|
|
148
|
-
|
|
149
|
-
### Recommended Configuration
|
|
150
|
-
|
|
151
|
-
Provide a recommended configuration for common use cases:
|
|
152
|
-
|
|
153
|
-
```typescript
|
|
154
|
-
const plugin = {
|
|
155
|
-
// ... meta and rules
|
|
156
|
-
configs: {},
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
// Assign configs after plugin definition to reference plugin
|
|
160
|
-
Object.assign(plugin.configs, {
|
|
161
|
-
recommended: [
|
|
162
|
-
{
|
|
163
|
-
plugins: {
|
|
164
|
-
traceability: plugin,
|
|
165
|
-
},
|
|
166
|
-
rules: {
|
|
167
|
-
"traceability/require-story-annotation": "error",
|
|
168
|
-
"traceability/require-req-annotation": "error",
|
|
169
|
-
"traceability/valid-story-reference": "error",
|
|
170
|
-
"traceability/valid-req-reference": "error",
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
strict: [
|
|
175
|
-
{
|
|
176
|
-
plugins: {
|
|
177
|
-
traceability: plugin,
|
|
178
|
-
},
|
|
179
|
-
rules: {
|
|
180
|
-
"traceability/require-story-annotation": "error",
|
|
181
|
-
"traceability/require-req-annotation": "error",
|
|
182
|
-
"traceability/valid-story-reference": "error",
|
|
183
|
-
"traceability/valid-req-reference": "error",
|
|
184
|
-
"traceability/require-branch-annotation": "error",
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
],
|
|
188
|
-
});
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### Configuration Usage
|
|
192
|
-
|
|
193
|
-
Users can extend configurations in their eslint.config.js:
|
|
194
|
-
|
|
195
|
-
```javascript
|
|
196
|
-
// eslint.config.js
|
|
197
|
-
import { defineConfig } from "eslint/config";
|
|
198
|
-
import traceability from "eslint-plugin-traceability";
|
|
199
|
-
|
|
200
|
-
export default defineConfig([
|
|
201
|
-
{
|
|
202
|
-
files: ["src/**/*.{js,ts}"],
|
|
203
|
-
plugins: {
|
|
204
|
-
traceability,
|
|
205
|
-
},
|
|
206
|
-
extends: ["traceability/recommended"],
|
|
207
|
-
},
|
|
208
|
-
]);
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## Testing Strategy
|
|
212
|
-
|
|
213
|
-
### Using ESLint's RuleTester
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
// tests/rules/require-story-annotation.test.ts
|
|
217
|
-
import { RuleTester } from "eslint";
|
|
218
|
-
import rule from "../../src/rules/require-story-annotation";
|
|
219
|
-
|
|
220
|
-
const ruleTester = new RuleTester({
|
|
221
|
-
parser: require.resolve("@typescript-eslint/parser"),
|
|
222
|
-
parserOptions: {
|
|
223
|
-
ecmaVersion: 2020,
|
|
224
|
-
sourceType: "module",
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
ruleTester.run("require-story-annotation", rule, {
|
|
229
|
-
valid: [
|
|
230
|
-
{
|
|
231
|
-
code: `
|
|
232
|
-
/**
|
|
233
|
-
* @story docs/stories/001.0-DEV-EXAMPLE.story.md
|
|
234
|
-
* @req REQ-EXAMPLE
|
|
235
|
-
*/
|
|
236
|
-
function validFunction() {}
|
|
237
|
-
`,
|
|
238
|
-
},
|
|
239
|
-
],
|
|
240
|
-
invalid: [
|
|
241
|
-
{
|
|
242
|
-
code: `function invalidFunction() {}`,
|
|
243
|
-
errors: [
|
|
244
|
-
{
|
|
245
|
-
messageId: "missingStory",
|
|
246
|
-
data: { name: "invalidFunction" },
|
|
247
|
-
},
|
|
248
|
-
],
|
|
249
|
-
},
|
|
250
|
-
],
|
|
251
|
-
});
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
### Test Organization
|
|
255
|
-
|
|
256
|
-
- **Unit tests**: Test individual rules in isolation
|
|
257
|
-
- **Integration tests**: Test plugin loading and configuration
|
|
258
|
-
- **File system tests**: Test file reference validation (use temporary directories)
|
|
259
|
-
|
|
260
|
-
## Project-Specific Considerations
|
|
261
|
-
|
|
262
|
-
### File System Integration
|
|
263
|
-
|
|
264
|
-
For validating @story references to actual files:
|
|
265
|
-
|
|
266
|
-
```typescript
|
|
267
|
-
import fs from "fs/promises";
|
|
268
|
-
import path from "path";
|
|
269
|
-
|
|
270
|
-
async function validateStoryFile(
|
|
271
|
-
storyPath: string,
|
|
272
|
-
context: any,
|
|
273
|
-
): Promise<boolean> {
|
|
274
|
-
try {
|
|
275
|
-
const fullPath = path.resolve(context.getCwd(), storyPath);
|
|
276
|
-
|
|
277
|
-
// Check file exists
|
|
278
|
-
await fs.access(fullPath);
|
|
279
|
-
|
|
280
|
-
// Check file extension
|
|
281
|
-
if (!fullPath.endsWith(".story.md")) {
|
|
282
|
-
return false;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
return true;
|
|
286
|
-
} catch {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### Requirement Reference Validation
|
|
293
|
-
|
|
294
|
-
For validating @req references within story files:
|
|
295
|
-
|
|
296
|
-
```typescript
|
|
297
|
-
async function validateRequirement(
|
|
298
|
-
storyPath: string,
|
|
299
|
-
reqId: string,
|
|
300
|
-
): Promise<boolean> {
|
|
301
|
-
try {
|
|
302
|
-
const content = await fs.readFile(storyPath, "utf8");
|
|
303
|
-
|
|
304
|
-
// Look for requirement ID in story content
|
|
305
|
-
const reqPattern = new RegExp(`\\*\\*${reqId}\\*\\*:`, "g");
|
|
306
|
-
return reqPattern.test(content);
|
|
307
|
-
} catch {
|
|
308
|
-
return false;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
### Configuration Options
|
|
314
|
-
|
|
315
|
-
Allow users to customize behavior:
|
|
316
|
-
|
|
317
|
-
```typescript
|
|
318
|
-
interface RuleOptions {
|
|
319
|
-
storyFilePattern?: string; // Default: "**/*.story.md"
|
|
320
|
-
requirementPattern?: string; // Default: "REQ-*"
|
|
321
|
-
excludePatterns?: string[]; // Files to exclude
|
|
322
|
-
includePrivateFunctions?: boolean; // Default: false
|
|
323
|
-
}
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
## Build and Distribution
|
|
327
|
-
|
|
328
|
-
### TypeScript Configuration
|
|
329
|
-
|
|
330
|
-
Configure TypeScript to output CommonJS for ESLint compatibility:
|
|
331
|
-
|
|
332
|
-
```json
|
|
333
|
-
// tsconfig.json
|
|
334
|
-
{
|
|
335
|
-
"compilerOptions": {
|
|
336
|
-
"target": "ES2020",
|
|
337
|
-
"module": "commonjs",
|
|
338
|
-
"moduleResolution": "node",
|
|
339
|
-
"declaration": true,
|
|
340
|
-
"outDir": "./lib",
|
|
341
|
-
"strict": true
|
|
342
|
-
},
|
|
343
|
-
"include": ["src/**/*"],
|
|
344
|
-
"exclude": ["node_modules", "lib", "tests"]
|
|
345
|
-
}
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### Package.json Configuration
|
|
349
|
-
|
|
350
|
-
Essential package.json settings for ESLint plugins:
|
|
351
|
-
|
|
352
|
-
```json
|
|
353
|
-
{
|
|
354
|
-
"name": "eslint-plugin-traceability",
|
|
355
|
-
"version": "1.0.0",
|
|
356
|
-
"description": "ESLint plugin for enforcing code traceability annotations",
|
|
357
|
-
"main": "lib/index.js",
|
|
358
|
-
"types": "lib/index.d.ts",
|
|
359
|
-
"keywords": ["eslint", "eslintplugin", "eslint-plugin", "traceability"],
|
|
360
|
-
"peerDependencies": {
|
|
361
|
-
"eslint": ">=9.0.0"
|
|
362
|
-
},
|
|
363
|
-
"engines": {
|
|
364
|
-
"node": ">=18.0.0"
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## Development Workflow
|
|
370
|
-
|
|
371
|
-
### Local Testing
|
|
372
|
-
|
|
373
|
-
1. **Link locally**: Use `npm link` for local development
|
|
374
|
-
2. **Test project**: Create a test project to verify plugin behavior
|
|
375
|
-
3. **Rule tester**: Use ESLint's RuleTester for individual rule testing
|
|
376
|
-
4. **Integration testing**: Test complete plugin configuration
|
|
377
|
-
|
|
378
|
-
### Quality Checks
|
|
379
|
-
|
|
380
|
-
Recommended linting for the plugin itself:
|
|
381
|
-
|
|
382
|
-
```javascript
|
|
383
|
-
// eslint.config.js (for the plugin project)
|
|
384
|
-
import js from "@eslint/js";
|
|
385
|
-
import typescript from "@typescript-eslint/eslint-plugin";
|
|
386
|
-
import eslintPlugin from "eslint-plugin-eslint-plugin";
|
|
387
|
-
|
|
388
|
-
export default [
|
|
389
|
-
js.configs.recommended,
|
|
390
|
-
{
|
|
391
|
-
plugins: {
|
|
392
|
-
"@typescript-eslint": typescript,
|
|
393
|
-
"eslint-plugin": eslintPlugin,
|
|
394
|
-
},
|
|
395
|
-
rules: {
|
|
396
|
-
// Plugin-specific linting rules
|
|
397
|
-
},
|
|
398
|
-
},
|
|
399
|
-
];
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
## Performance Considerations
|
|
403
|
-
|
|
404
|
-
### Efficient AST Traversal
|
|
405
|
-
|
|
406
|
-
- **Minimal visitors**: Only register for needed node types
|
|
407
|
-
- **Early returns**: Exit early when conditions aren't met
|
|
408
|
-
- **Caching**: Cache expensive operations (file reads, regex compilation)
|
|
409
|
-
- **Async handling**: Use proper async patterns for file operations
|
|
410
|
-
|
|
411
|
-
### Memory Management
|
|
412
|
-
|
|
413
|
-
- **Avoid global state**: Keep rule instances isolated
|
|
414
|
-
- **Clean up resources**: Properly handle file handles and timers
|
|
415
|
-
- **Limit recursion**: Avoid deep recursive operations
|
|
416
|
-
|
|
417
|
-
## Documentation Requirements
|
|
418
|
-
|
|
419
|
-
### Rule Documentation
|
|
420
|
-
|
|
421
|
-
Each rule should have comprehensive documentation:
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
const rule = {
|
|
425
|
-
meta: {
|
|
426
|
-
docs: {
|
|
427
|
-
description: "require @story annotations on functions",
|
|
428
|
-
category: "Traceability",
|
|
429
|
-
recommended: true,
|
|
430
|
-
url: "https://github.com/voder-ai/eslint-plugin-traceability#require-story-annotation",
|
|
431
|
-
},
|
|
432
|
-
// ... other meta properties
|
|
433
|
-
},
|
|
434
|
-
// ... rule implementation
|
|
435
|
-
};
|
|
436
|
-
```
|
|
437
|
-
|
|
438
|
-
### README Structure
|
|
439
|
-
|
|
440
|
-
Include in the plugin README:
|
|
441
|
-
|
|
442
|
-
1. **Installation instructions**
|
|
443
|
-
2. **Configuration examples**
|
|
444
|
-
3. **Rule documentation**
|
|
445
|
-
4. **Usage examples**
|
|
446
|
-
5. **Troubleshooting guide**
|
|
447
|
-
|
|
448
|
-
## Security Considerations
|
|
449
|
-
|
|
450
|
-
### File System Access
|
|
451
|
-
|
|
452
|
-
- **Validate paths**: Prevent directory traversal attacks
|
|
453
|
-
- **Sanitize input**: Validate user-provided file patterns
|
|
454
|
-
- **Limit scope**: Restrict file access to project directory
|
|
455
|
-
|
|
456
|
-
### Input Validation
|
|
457
|
-
|
|
458
|
-
- **Schema validation**: Use JSON Schema for rule options
|
|
459
|
-
- **Type checking**: Leverage TypeScript for compile-time safety
|
|
460
|
-
- **Runtime checks**: Validate configuration at runtime
|
|
461
|
-
|
|
462
|
-
## Maintenance Guidelines
|
|
463
|
-
|
|
464
|
-
### Version Management
|
|
465
|
-
|
|
466
|
-
- **Semantic versioning**: Follow semver for releases
|
|
467
|
-
- **Breaking changes**: Document breaking changes clearly
|
|
468
|
-
- **Migration guides**: Provide upgrade instructions
|
|
469
|
-
|
|
470
|
-
### Community Support
|
|
471
|
-
|
|
472
|
-
- **Issue templates**: Provide clear bug report templates
|
|
473
|
-
- **Contributing guide**: Document contribution process
|
|
474
|
-
- **Code of conduct**: Establish community guidelines
|
|
475
|
-
|
|
476
|
-
---
|
|
477
|
-
|
|
478
|
-
## Related Resources
|
|
479
|
-
|
|
480
|
-
- [ESLint Plugin Development Guide](https://eslint.org/docs/latest/extend/plugins)
|
|
481
|
-
- [ESLint Custom Rules](https://eslint.org/docs/latest/extend/custom-rules)
|
|
482
|
-
- [@typescript-eslint/utils](https://typescript-eslint.io/packages/utils/)
|
|
483
|
-
- [ESLint RuleTester](https://eslint.org/docs/latest/integrate/nodejs-api#ruletester)
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# Jest Testing Guide
|
|
2
|
-
|
|
3
|
-
This guide covers testing practices and configuration for the eslint-plugin-traceability project.
|
|
4
|
-
|
|
5
|
-
## Traceability in Test Output
|
|
6
|
-
|
|
7
|
-
### Viewing Story and Requirement References
|
|
8
|
-
|
|
9
|
-
By default, Jest's standard output only shows file-level test results without displaying individual test descriptions or traceability annotations. To see the full traceability information including story references and requirement IDs, you must use the `--verbose` option.
|
|
10
|
-
|
|
11
|
-
**Standard output (limited visibility):**
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm test
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Shows only:
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
PASS tests/maintenance/batch.test.ts
|
|
21
|
-
PASS tests/rules/require-branch-annotation.test.ts
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**Verbose output (full traceability):**
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npm test -- --verbose
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Shows detailed test descriptions with traceability annotations:
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
PASS tests/maintenance/batch.test.ts
|
|
34
|
-
batchUpdateAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)
|
|
35
|
-
✓ [REQ-MAINT-BATCH] should return 0 when no mappings applied (6 ms)
|
|
36
|
-
verifyAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)
|
|
37
|
-
✓ [REQ-MAINT-VERIFY] should return true when annotations are valid
|
|
38
|
-
|
|
39
|
-
PASS tests/rules/require-branch-annotation.test.ts
|
|
40
|
-
Require Branch Annotation Rule (Story 004.0-DEV-BRANCH-ANNOTATIONS)
|
|
41
|
-
require-branch-annotation
|
|
42
|
-
valid
|
|
43
|
-
✓ [REQ-BRANCH-DETECTION] valid if-statement with annotations (4 ms)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Test Structure Requirements
|
|
47
|
-
|
|
48
|
-
All tests in this project follow a specific structure to support traceability:
|
|
49
|
-
|
|
50
|
-
1. **File-level annotations** at the top of each test file:
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
/**
|
|
54
|
-
* Tests for: docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
55
|
-
* @story docs/stories/009.0-DEV-MAINTENANCE-TOOLS.story.md
|
|
56
|
-
* @req REQ-MAINT-BATCH - Perform batch updates
|
|
57
|
-
* @req REQ-MAINT-VERIFY - Verify annotation references
|
|
58
|
-
*/
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
2. **Describe blocks** that reference the story:
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
describe('batchUpdateAnnotations (Story 009.0-DEV-MAINTENANCE-TOOLS)', () => {
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
3. **Test cases** that reference specific requirements:
|
|
68
|
-
```typescript
|
|
69
|
-
it('[REQ-MAINT-BATCH] should return 0 when no mappings applied', () => {
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Running Tests for Traceability Review
|
|
73
|
-
|
|
74
|
-
When reviewing test coverage for specific stories or requirements:
|
|
75
|
-
|
|
76
|
-
- **For development/debugging**: Use `npm test -- --verbose` to see all traceability information
|
|
77
|
-
- **For CI/CD pipelines**: Standard `npm test` provides sufficient pass/fail information
|
|
78
|
-
- **For coverage analysis**: Both modes provide the same coverage statistics
|
|
79
|
-
|
|
80
|
-
### Best Practices
|
|
81
|
-
|
|
82
|
-
1. **Always include story references** in describe blocks to make them visible in verbose output
|
|
83
|
-
2. **Prefix test descriptions with requirement IDs** in square brackets (e.g., `[REQ-MAINT-BATCH]`)
|
|
84
|
-
3. **Use meaningful test descriptions** that clearly indicate what requirement is being tested
|
|
85
|
-
4. **Run with --verbose during development** to verify traceability annotations are properly displayed
|
|
86
|
-
|
|
87
|
-
## Configuration
|
|
88
|
-
|
|
89
|
-
The project's Jest configuration is defined in `jest.config.js` and includes:
|
|
90
|
-
|
|
91
|
-
- Coverage reporting
|
|
92
|
-
- TypeScript support via ts-jest
|
|
93
|
-
- Test file patterns
|
|
94
|
-
- CI-friendly options (--ci --bail --coverage)
|
|
95
|
-
|
|
96
|
-
## Related Documentation
|
|
97
|
-
|
|
98
|
-
- [Story Files](stories/) - User story definitions
|
|
99
|
-
- [ESLint Plugin Development Guide](eslint-plugin-development-guide.md) - General development practices
|
|
100
|
-
- [Decision Records](decisions/) - Architectural decisions including Jest adoption
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# require-branch-annotation
|
|
2
|
-
|
|
3
|
-
Ensures that significant code branches (if/else, switch cases, loops, try/catch) have `@story` and `@req` annotations for traceability.
|
|
4
|
-
|
|
5
|
-
@story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
6
|
-
@req REQ-BRANCH-DETECTION - Detect significant code branches for traceability annotations
|
|
7
|
-
|
|
8
|
-
## Rule Details
|
|
9
|
-
|
|
10
|
-
This rule checks for JSDoc or inline comments immediately preceding significant code branches and ensures both `@story` and `@req` annotations are present.
|
|
11
|
-
|
|
12
|
-
### Options Schema
|
|
13
|
-
|
|
14
|
-
This rule does not accept any options (schema is `[]`).
|
|
15
|
-
|
|
16
|
-
### Examples
|
|
17
|
-
|
|
18
|
-
#### Correct
|
|
19
|
-
|
|
20
|
-
```js
|
|
21
|
-
// @story docs/stories/004.0-DEV-BRANCH-ANNOTATIONS.story.md
|
|
22
|
-
// @req REQ-BRANCH-DETECTION
|
|
23
|
-
if (error) {
|
|
24
|
-
handleError();
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
#### Incorrect
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
if (error) {
|
|
32
|
-
handleError();
|
|
33
|
-
}
|
|
34
|
-
```
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# require-req-annotation
|
|
2
|
-
|
|
3
|
-
Enforces the presence of `@req` annotations on function declarations to ensure each function maps to a specific requirement ID.
|
|
4
|
-
|
|
5
|
-
@story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
6
|
-
@req REQ-ANNOTATION-REQUIRED - Require `@req` annotation on functions
|
|
7
|
-
|
|
8
|
-
## Rule Details
|
|
9
|
-
|
|
10
|
-
This rule validates that every function declaration has a JSDoc comment containing an `@req` annotation.
|
|
11
|
-
|
|
12
|
-
### Options Schema
|
|
13
|
-
|
|
14
|
-
This rule does not accept any options (schema is `[]`).
|
|
15
|
-
|
|
16
|
-
### Examples
|
|
17
|
-
|
|
18
|
-
#### Correct
|
|
19
|
-
|
|
20
|
-
```js
|
|
21
|
-
/**
|
|
22
|
-
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
23
|
-
* @req REQ-ANNOTATION-REQUIRED
|
|
24
|
-
*/
|
|
25
|
-
function initAuth() {
|
|
26
|
-
// authentication logic
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
#### Incorrect
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
/**
|
|
34
|
-
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
35
|
-
*/
|
|
36
|
-
function initAuth() {
|
|
37
|
-
// authentication logic
|
|
38
|
-
}
|
|
39
|
-
```
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# require-story-annotation
|
|
2
|
-
|
|
3
|
-
Enforces the presence of `@story` annotations on function declarations to ensure traceability from code to user stories.
|
|
4
|
-
|
|
5
|
-
@story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
6
|
-
@req REQ-ANNOTATION-REQUIRED - Require `@story` annotation on functions
|
|
7
|
-
|
|
8
|
-
## Rule Details
|
|
9
|
-
|
|
10
|
-
This rule validates that every function declaration has a JSDoc comment containing an `@story` annotation pointing to the relevant story file.
|
|
11
|
-
|
|
12
|
-
### Options Schema
|
|
13
|
-
|
|
14
|
-
This rule does not accept any options (schema is `[]`).
|
|
15
|
-
|
|
16
|
-
### Examples
|
|
17
|
-
|
|
18
|
-
#### Correct
|
|
19
|
-
|
|
20
|
-
```js
|
|
21
|
-
/**
|
|
22
|
-
* @story docs/stories/003.0-DEV-FUNCTION-ANNOTATIONS.story.md
|
|
23
|
-
* @req REQ-ANNOTATION-REQUIRED
|
|
24
|
-
*/
|
|
25
|
-
function initAuth() {
|
|
26
|
-
// authentication logic
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
#### Incorrect
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
function initAuth() {
|
|
34
|
-
// authentication logic
|
|
35
|
-
}
|
|
36
|
-
```
|