@putout/engine-runner 27.0.5 → 27.2.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 +104 -57
- package/lib/get-position.js +2 -2
- package/lib/scanner/index.js +30 -12
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ They goes from simplest to hardest. Let's start from **Declarator**.
|
|
|
31
31
|
The simplest possible type of plugin, even simpler then [`Replacer`](#replacer):
|
|
32
32
|
|
|
33
33
|
```js
|
|
34
|
-
|
|
34
|
+
export const declare = () => ({
|
|
35
35
|
isString: `const isString = (a) => typeof a === 'string'`,
|
|
36
36
|
});
|
|
37
37
|
```
|
|
@@ -46,26 +46,26 @@ according to [`template variables syntax`](https://github.com/coderaiser/putout/
|
|
|
46
46
|
Simplest replace example:
|
|
47
47
|
|
|
48
48
|
```js
|
|
49
|
-
|
|
49
|
+
export const report = () => 'any message here';
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
export const replace = () => ({
|
|
52
52
|
'const a = 1': 'const b = 1',
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
// optional
|
|
56
|
-
|
|
56
|
+
export const filter = (path) => {
|
|
57
57
|
return true;
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
// optional
|
|
61
|
-
|
|
61
|
+
export const match = () => ({
|
|
62
62
|
'const __a = 1': ({__a}) => {
|
|
63
63
|
return true;
|
|
64
64
|
},
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
// optional
|
|
68
|
-
|
|
68
|
+
export const exclude = () => [
|
|
69
69
|
`const hello = 'world'`,
|
|
70
70
|
'ArrowFunctionExpression',
|
|
71
71
|
];
|
|
@@ -74,37 +74,31 @@ module.exports.exclude = () => [
|
|
|
74
74
|
Simplest remove example:
|
|
75
75
|
|
|
76
76
|
```js
|
|
77
|
-
|
|
77
|
+
export const report = () => 'debugger should not be used';
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
export const replace = () => ({
|
|
80
80
|
debugger: '',
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// debugger; alert(); -> alert();
|
|
81
|
+
}); // debugger; alert(); -> alert();
|
|
84
82
|
```
|
|
85
83
|
|
|
86
84
|
Templates:
|
|
87
85
|
|
|
88
86
|
```js
|
|
89
|
-
|
|
87
|
+
export const report = () => 'any message here';
|
|
90
88
|
|
|
91
|
-
|
|
89
|
+
export const replace = () => ({
|
|
92
90
|
'var __a = 1': 'const __a = 1',
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// var x = 1; -> const x = 1;
|
|
91
|
+
}); // var x = 1; -> const x = 1;
|
|
96
92
|
```
|
|
97
93
|
|
|
98
94
|
A couple variables example:
|
|
99
95
|
|
|
100
96
|
```js
|
|
101
|
-
|
|
97
|
+
export const report = () => 'any message here';
|
|
102
98
|
|
|
103
|
-
|
|
99
|
+
export const replace = () => ({
|
|
104
100
|
'const __a = __b': 'const __b = __a',
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// const hello = world; -> const world = hello;
|
|
101
|
+
}); // const hello = world; -> const world = hello;
|
|
108
102
|
```
|
|
109
103
|
|
|
110
104
|
#### Processing of node using functions
|
|
@@ -114,47 +108,41 @@ You can pass a function as object value for more soficticated processing.
|
|
|
114
108
|
Remove node:
|
|
115
109
|
|
|
116
110
|
```js
|
|
117
|
-
|
|
111
|
+
export const report = () => 'any message here';
|
|
118
112
|
|
|
119
|
-
|
|
113
|
+
export const replace = () => ({
|
|
120
114
|
'for (const __a of __b) __c': ({__a, __b, __c}, path) => {
|
|
121
115
|
// remove node
|
|
122
116
|
return '';
|
|
123
117
|
},
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// for (a of b) {}; alert(); -> alert();
|
|
118
|
+
}); // for (a of b) {}; alert(); -> alert();
|
|
127
119
|
```
|
|
128
120
|
|
|
129
121
|
Update node:
|
|
130
122
|
|
|
131
123
|
```js
|
|
132
|
-
|
|
124
|
+
export const report = () => 'any message here';
|
|
133
125
|
|
|
134
|
-
|
|
126
|
+
export const replace = () => ({
|
|
135
127
|
'for (const __a of __array) __c': ({__a, __array, __c}, path) => {
|
|
136
128
|
// update __array elements
|
|
137
129
|
path.node.right.elements = [];
|
|
138
130
|
return path;
|
|
139
131
|
},
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
// for (const a of [1, 2, 3]) {}; -> for (const a of []) {};
|
|
132
|
+
}); // for (const a of [1, 2, 3]) {}; -> for (const a of []) {};
|
|
143
133
|
```
|
|
144
134
|
|
|
145
135
|
Update node using template variables:
|
|
146
136
|
|
|
147
137
|
```js
|
|
148
|
-
|
|
138
|
+
export const report = () => 'any message here';
|
|
149
139
|
|
|
150
|
-
|
|
140
|
+
export const replace = () => ({
|
|
151
141
|
'for (const __a of __array) __c': ({__a, __array, __c}, path) => {
|
|
152
142
|
// update the whole node using template string
|
|
153
143
|
return 'for (const x of y) z';
|
|
154
144
|
},
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
// for (const item of array) {}; -> for (const x of y) z;
|
|
145
|
+
}); // for (const item of array) {}; -> for (const x of y) z;
|
|
158
146
|
```
|
|
159
147
|
|
|
160
148
|
### Includer
|
|
@@ -162,17 +150,19 @@ module.exports.replace = () => ({
|
|
|
162
150
|
**Includer** is the most preferable format of a plugin, simplest to use (after [`Replacer`](#replacer)):
|
|
163
151
|
|
|
164
152
|
```js
|
|
165
|
-
|
|
153
|
+
export const report = () => 'debugger statement should not be used';
|
|
166
154
|
|
|
167
|
-
|
|
155
|
+
export const fix = (path) => {
|
|
168
156
|
path.remove();
|
|
169
157
|
};
|
|
170
158
|
|
|
171
|
-
|
|
159
|
+
export const include = () => ['debugger'];
|
|
160
|
+
|
|
172
161
|
// optional
|
|
173
|
-
|
|
162
|
+
export const exclude = () => {};
|
|
163
|
+
|
|
174
164
|
// optional
|
|
175
|
-
|
|
165
|
+
export const filter = (path) => {
|
|
176
166
|
return true;
|
|
177
167
|
};
|
|
178
168
|
```
|
|
@@ -190,13 +180,13 @@ Where `__` can be any node. All this possible with help of [@putout/compare](htt
|
|
|
190
180
|
**Traverser** gives you more power to `filter` and `fix` nodes you need.
|
|
191
181
|
|
|
192
182
|
```js
|
|
193
|
-
|
|
183
|
+
export const report = () => 'debugger statement should not be used';
|
|
194
184
|
|
|
195
|
-
|
|
185
|
+
export const fix = (path, {options}) => {
|
|
196
186
|
path.remove();
|
|
197
187
|
};
|
|
198
188
|
|
|
199
|
-
|
|
189
|
+
export const traverse = ({push}) => ({
|
|
200
190
|
'debugger'(path) {
|
|
201
191
|
push(path);
|
|
202
192
|
},
|
|
@@ -231,7 +221,7 @@ const world = '';
|
|
|
231
221
|
Let's process it!
|
|
232
222
|
|
|
233
223
|
```js
|
|
234
|
-
|
|
224
|
+
export const traverse = ({listStore}) => ({
|
|
235
225
|
'debugger'(path) {
|
|
236
226
|
listStore(path);
|
|
237
227
|
},
|
|
@@ -265,7 +255,7 @@ const hello = '';
|
|
|
265
255
|
Let's process it!
|
|
266
256
|
|
|
267
257
|
```js
|
|
268
|
-
|
|
258
|
+
export const traverse = ({pathStore}) => ({
|
|
269
259
|
'debugger'(path) {
|
|
270
260
|
pathStore(path);
|
|
271
261
|
path.remove();
|
|
@@ -286,7 +276,7 @@ module.exports.traverse = ({pathStore}) => ({
|
|
|
286
276
|
When you need `key-value` use `store`:
|
|
287
277
|
|
|
288
278
|
```js
|
|
289
|
-
|
|
279
|
+
export const traverse = ({push, store}) => ({
|
|
290
280
|
'debugger'(path) {
|
|
291
281
|
store('hello', 'world');
|
|
292
282
|
push(path);
|
|
@@ -315,7 +305,7 @@ module.exports.traverse = ({push, store}) => ({
|
|
|
315
305
|
When you need to update already saved values, use `upstore`:
|
|
316
306
|
|
|
317
307
|
```js
|
|
318
|
-
|
|
308
|
+
export const traverse = ({push, upstore}) => ({
|
|
319
309
|
TSTypeAliasDeclaration(path) {
|
|
320
310
|
if (path.parentPath.isExportNamedDeclaration())
|
|
321
311
|
return;
|
|
@@ -352,7 +342,7 @@ module.exports.traverse = ({push, upstore}) => ({
|
|
|
352
342
|
When you need to update named arrays:
|
|
353
343
|
|
|
354
344
|
```js
|
|
355
|
-
|
|
345
|
+
export const traverse = ({uplist, push}) => ({
|
|
356
346
|
'const __object = __a.__b': (fullPath) => {
|
|
357
347
|
const {__a, __b} = getTemplateValues(fullPath, 'const __object = __a.__b');
|
|
358
348
|
const initPath = fullPath.get('declarations.0.init');
|
|
@@ -389,13 +379,13 @@ module.exports.traverse = ({uplist, push}) => ({
|
|
|
389
379
|
**Scanner** gives you all ability to work with files.
|
|
390
380
|
|
|
391
381
|
```js
|
|
392
|
-
|
|
382
|
+
export const report = () => 'Create file hello.txt';
|
|
393
383
|
|
|
394
|
-
|
|
384
|
+
export const fix = (rootPath) => {
|
|
395
385
|
createFile(rootPath, 'hello.txt', 'hello world');
|
|
396
386
|
};
|
|
397
387
|
|
|
398
|
-
|
|
388
|
+
export const scan = (rootPath, {push}) => {
|
|
399
389
|
const [filePath] = findFile(rootPath, 'hello.txt');
|
|
400
390
|
|
|
401
391
|
if (filePath)
|
|
@@ -435,6 +425,8 @@ export const scan = (rootPath, {progress}) => {
|
|
|
435
425
|
};
|
|
436
426
|
```
|
|
437
427
|
|
|
428
|
+
#### `trackFile`
|
|
429
|
+
|
|
438
430
|
Or better `trackFile`, which does the same, but also count `progress`:
|
|
439
431
|
|
|
440
432
|
```js
|
|
@@ -452,19 +444,74 @@ export const scan = (rootPath, {push, trackFile}) => {
|
|
|
452
444
|
|
|
453
445
|
☝️ *When you use `trackFile` use [`progress()`](https://github.com/coderaiser/putout/tree/master/packages/test#progressfilename-expected) for testing*
|
|
454
446
|
|
|
447
|
+
#### `crawlFile`
|
|
448
|
+
|
|
449
|
+
When you need to find files related to other files like in [`esm/apply-name-to-imported-file`](https://github.com/coderaiser/putout/blob/master/packages/plugin-esm/README.md#apply-name-to-imported-file) you can end up with:
|
|
450
|
+
|
|
451
|
+
```js
|
|
452
|
+
export const report = () => 'Add file';
|
|
453
|
+
export const fix = (file) => {
|
|
454
|
+
writeFileContent(file, 'hello');
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
export const scan = (rootPath, {push, trackFile}) => {
|
|
458
|
+
for (const file of trackFile(rootPath, 'hello.txt')) {
|
|
459
|
+
findFile(rootPath, 'again and again');
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
It will be very slow! And you can use [`crawlDirectory()`](https://github.com/coderaiser/putout/blob/master/packages/operator-filesystem/README.md#crawldirectorydirectorypath-directorypath-crawled) instead:
|
|
465
|
+
|
|
466
|
+
```js
|
|
467
|
+
export const report = () => 'Add file';
|
|
468
|
+
export const fix = (file) => {
|
|
469
|
+
writeFileContent(file, 'hello');
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
export const scan = (rootPath, {push, trackFile}) => {
|
|
473
|
+
const crawled = crawlDirectory(rootPath);
|
|
474
|
+
|
|
475
|
+
for (const file of trackFile(rootPath, 'hello.txt')) {
|
|
476
|
+
findFile(rootPath, 'again and again', {
|
|
477
|
+
crawled,
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
But it is easy to forget, or remove during refactoring, since everything will work as before, only twice slower on big amount of files.
|
|
484
|
+
|
|
485
|
+
So you better use **crawlFile**:
|
|
486
|
+
|
|
487
|
+
```js
|
|
488
|
+
export const report = () => 'Add file';
|
|
489
|
+
export const fix = (file) => {
|
|
490
|
+
writeFileContent(file, 'hello');
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
export const scan = (rootPath, {push, trackFile, crawlFile}) => {
|
|
494
|
+
for (const file of trackFile(rootPath, 'hello.txt')) {
|
|
495
|
+
const files = crawlFile(rootPath, 'no matter how many times');
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
It works much faster, use it when you do not mutate filesystem tree: neither remove nor rename files.
|
|
501
|
+
|
|
455
502
|
### Finder
|
|
456
503
|
|
|
457
504
|
**Finder** gives you all the control over traversing, but it's the slowest format.
|
|
458
505
|
Because `traversers` not merged in contrast with other plugin formats.
|
|
459
506
|
|
|
460
507
|
```js
|
|
461
|
-
|
|
508
|
+
export const report = () => 'debugger statement should not be used';
|
|
462
509
|
|
|
463
|
-
|
|
510
|
+
export const fix = (path) => {
|
|
464
511
|
path.remove();
|
|
465
512
|
};
|
|
466
513
|
|
|
467
|
-
|
|
514
|
+
export const find = (ast, {push, traverse}) => {
|
|
468
515
|
traverse(ast, {
|
|
469
516
|
'debugger'(path) {
|
|
470
517
|
push(path);
|
|
@@ -476,8 +523,8 @@ module.exports.find = (ast, {push, traverse}) => {
|
|
|
476
523
|
## Example
|
|
477
524
|
|
|
478
525
|
```js
|
|
479
|
-
|
|
480
|
-
|
|
526
|
+
import {runPlugins} from '@putout/engine-runner';
|
|
527
|
+
import {parse} from '@putout/engine-parser';
|
|
481
528
|
|
|
482
529
|
const plugins = [{
|
|
483
530
|
rule: 'remove-debugger',
|
package/lib/get-position.js
CHANGED
|
@@ -11,14 +11,14 @@ export const getPosition = (path, shebang) => {
|
|
|
11
11
|
if (!loc)
|
|
12
12
|
return {
|
|
13
13
|
line: 0,
|
|
14
|
-
column:
|
|
14
|
+
column: 1,
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
const {line, column} = node.loc.start;
|
|
18
18
|
|
|
19
19
|
return {
|
|
20
20
|
line: shebang ? line + 1 : line,
|
|
21
|
-
column,
|
|
21
|
+
column: column + 1,
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
|
package/lib/scanner/index.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {fullstore} from 'fullstore';
|
|
2
2
|
import {compare} from '@putout/compare';
|
|
3
3
|
import {__filesystem_name} from '@putout/operator-json';
|
|
4
|
+
import * as fromSimple from '@putout/plugin-filesystem/from-simple';
|
|
5
|
+
import * as toSimple from '@putout/plugin-filesystem/to-simple';
|
|
4
6
|
import {
|
|
5
7
|
findFile,
|
|
8
|
+
crawlDirectory,
|
|
6
9
|
pause,
|
|
7
10
|
start,
|
|
8
11
|
} from '@putout/operator-filesystem';
|
|
9
|
-
import * as fromSimple from '@putout/plugin-filesystem/from-simple';
|
|
10
|
-
import * as toSimple from '@putout/plugin-filesystem/to-simple';
|
|
11
12
|
import {createDebug} from '../debug.js';
|
|
12
13
|
|
|
13
14
|
const log = createDebug('putout:runner:scanner');
|
|
@@ -21,7 +22,7 @@ export const scan = ({rule, plugin, msg, options}, {progress}) => {
|
|
|
21
22
|
|
|
22
23
|
progress.inc();
|
|
23
24
|
|
|
24
|
-
const traverse =
|
|
25
|
+
const traverse = createTraverse({
|
|
25
26
|
scan,
|
|
26
27
|
rule,
|
|
27
28
|
progress,
|
|
@@ -56,8 +57,17 @@ const createFileProgress = ({rule, progress}) => ({i, n}) => {
|
|
|
56
57
|
});
|
|
57
58
|
};
|
|
58
59
|
|
|
59
|
-
const
|
|
60
|
-
|
|
60
|
+
const createCrawlFile = (crawled) => (...a) => {
|
|
61
|
+
return findFile(...a, {
|
|
62
|
+
crawled,
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const createTrackFile = ({fileProgress, crawled}) => function*(...a) {
|
|
67
|
+
const files = findFile(...a, {
|
|
68
|
+
crawled,
|
|
69
|
+
});
|
|
70
|
+
|
|
61
71
|
const n = files.length;
|
|
62
72
|
|
|
63
73
|
for (const [i, file] of files.entries()) {
|
|
@@ -69,7 +79,7 @@ const createTrackFile = (fileProgress) => function*(...a) {
|
|
|
69
79
|
}
|
|
70
80
|
};
|
|
71
81
|
|
|
72
|
-
const
|
|
82
|
+
const createTraverse = ({scan, rule, progress}) => ({push, options}) => ({
|
|
73
83
|
[`${__filesystem_name}(__)`](path) {
|
|
74
84
|
log(rule);
|
|
75
85
|
progress.start(rule);
|
|
@@ -77,21 +87,29 @@ const getTraverse = ({scan, rule, progress}) => ({push, options}) => ({
|
|
|
77
87
|
const rootPath = path.get('arguments.0');
|
|
78
88
|
const isSimple = fullstore(false);
|
|
79
89
|
|
|
90
|
+
runSimple(fromSimple, {
|
|
91
|
+
shouldConvert: true,
|
|
92
|
+
path,
|
|
93
|
+
rootPath,
|
|
94
|
+
isSimple,
|
|
95
|
+
});
|
|
96
|
+
|
|
80
97
|
const fileProgress = createFileProgress({
|
|
81
98
|
rule,
|
|
82
99
|
progress,
|
|
83
100
|
});
|
|
84
101
|
|
|
85
|
-
const
|
|
102
|
+
const crawled = crawlDirectory(rootPath);
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
rootPath,
|
|
91
|
-
isSimple,
|
|
104
|
+
const trackFile = createTrackFile({
|
|
105
|
+
fileProgress,
|
|
106
|
+
crawled,
|
|
92
107
|
});
|
|
93
108
|
|
|
109
|
+
const crawlFile = createCrawlFile(crawled);
|
|
110
|
+
|
|
94
111
|
scan(rootPath, {
|
|
112
|
+
crawlFile,
|
|
95
113
|
push: watchPush({
|
|
96
114
|
push,
|
|
97
115
|
rule,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@putout/engine-runner",
|
|
3
|
-
"version": "27.0
|
|
3
|
+
"version": "27.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
6
6
|
"description": "Run 🐊Putout plugins",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"c8": "^10.0.0",
|
|
54
54
|
"eslint": "^10.0.0-alpha.0",
|
|
55
55
|
"eslint-plugin-n": "^17.0.0",
|
|
56
|
-
"eslint-plugin-putout": "^
|
|
56
|
+
"eslint-plugin-putout": "^30.0.0",
|
|
57
57
|
"just-camel-case": "^6.2.0",
|
|
58
58
|
"madrun": "^12.0.0",
|
|
59
59
|
"montag": "^1.0.0",
|