Skip to content

Commit f0b11ac

Browse files
committed
v1.0.0
0 parents  commit f0b11ac

File tree

12 files changed

+3349
-0
lines changed

12 files changed

+3349
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
node_modules

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# eslint-plugin-todo-plz
2+
3+
Enforce consistent and maintainable TODO comments.
4+
5+
## Installation
6+
7+
You'll first need to install [ESLint](http://eslint.org):
8+
9+
```
10+
$ npm i eslint --save-dev
11+
```
12+
13+
Next, install `eslint-plugin-todo-plz`:
14+
15+
```
16+
$ npm install eslint-plugin-todo-plz --save-dev
17+
```
18+
19+
## Usage
20+
21+
Add `todo-plz` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
22+
23+
```json
24+
{
25+
"plugins": ["todo-plz"]
26+
}
27+
```
28+
29+
Then configure the rules you want to use under the rules section.
30+
31+
```json
32+
{
33+
"rules": {
34+
"todo-plz/ticket-ref": ["error", { "pattern": "ABC-[0-9]+" }]
35+
}
36+
}
37+
```
38+
39+
## Supported Rules
40+
41+
- [`ticket-ref`](docs/rules/ticket-ref.md)
42+
43+
## Inspiration
44+
45+
- Shoutout [`expiring-todo-comments`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/expiring-todo-comments.md) for showing me how to build my first ESLint rule.

docs/rules/ticket-ref.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Require a ticket reference in the TODO comment (ticket-ref)
2+
3+
Adding a `TODO` comment that will be addressed in the future should have a corresponding ticket (AKA issue) in the project backlog so the team doesn't lose track of the pending work.
4+
5+
## Fail
6+
7+
Examples of **incorrect** code for this rule:
8+
9+
```js
10+
// TODO: Unmock this API request
11+
```
12+
13+
## Pass
14+
15+
Examples of **correct** code for this rule:
16+
17+
```js
18+
// TODO (ABC-123): Unmock this API request
19+
```
20+
21+
## Options
22+
23+
### pattern
24+
25+
This option controls what the ticket pattern is to match against. Expects a regex string.
26+
27+
For example, let's say you're using Jira and your ticket IDs are prefixed with `ABC` followed by a number (e.g `ABC-123`), you would configure this rule like:
28+
29+
```json
30+
{
31+
"rules": {
32+
"todo-plz/ticket-ref": ["error", { "pattern": "ABC-[0-9]+" }]
33+
}
34+
}
35+
```

lib/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use strict";
2+
3+
module.exports.rules = {
4+
"ticket-ref": require("./rules/ticket-ref"),
5+
};

lib/rules/ticket-ref.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* @fileoverview Require a ticket reference in the TODO comment
3+
* @author Sawyer
4+
*/
5+
"use strict";
6+
7+
const messages = {
8+
missingTicket:
9+
"TODO comment is missing a ticket reference matching pattern: {{ pattern }}",
10+
};
11+
12+
const schema = [
13+
{
14+
type: "object",
15+
properties: {
16+
pattern: {
17+
type: "string",
18+
},
19+
terms: {
20+
type: "array",
21+
items: {
22+
type: "string",
23+
},
24+
},
25+
},
26+
},
27+
];
28+
29+
function create(context) {
30+
const { pattern, terms } = {
31+
terms: ["TODO"],
32+
...context.options[0],
33+
};
34+
const sourceCode = context.getSourceCode();
35+
const comments = sourceCode.getAllComments();
36+
37+
function validate(comment) {
38+
const value = comment.value;
39+
const hasTerm = terms.some((term) => value.includes(term));
40+
if (!hasTerm) {
41+
return;
42+
}
43+
44+
terms.forEach((term) => {
45+
const searchPattern = new RegExp(`${term}\\s?\\(${pattern}\\)`, "i");
46+
if (searchPattern.test(value)) return;
47+
48+
context.report({
49+
loc: comment.loc,
50+
messageId: "missingTicket",
51+
data: { pattern },
52+
});
53+
});
54+
}
55+
56+
comments.forEach(validate);
57+
58+
return {};
59+
}
60+
61+
module.exports = {
62+
meta: {
63+
docs: {
64+
description: "Require a ticket reference in the TODO comment",
65+
category: "Fill me in",
66+
recommended: false,
67+
},
68+
fixable: null, // or "code" or "whitespace"
69+
messages,
70+
schema,
71+
type: "suggestion",
72+
},
73+
create,
74+
};

0 commit comments

Comments
 (0)