redlint 5.2.1 → 5.2.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/ChangeLog +12 -0
- package/README.md +2 -0
- package/bin/redlint.js +2 -2
- package/lib/choose.js +0 -1
- package/lib/debug.js +0 -1
- package/lib/test/get-fixture-names/get-fixture-names-plugin/index.js +16 -5
- package/lib/test/init-fixture/index.js +2 -2
- package/lib/test/init-fixture/init-fixture-plugin/index.js +11 -6
- package/lib/test/read-fixture/index.js +75 -0
- package/lib/test/read-fixture/read-fixture-plugin/index.js +28 -0
- package/lib/test/run/run.js +43 -0
- package/lib/test/test.js +60 -6
- package/lib/view/view.js +1 -1
- package/package.json +2 -2
package/ChangeLog
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
2026.01.24, v5.2.3
|
|
2
|
+
|
|
3
|
+
feature:
|
|
4
|
+
- 18761b3 test: show correct/incorrect only when different
|
|
5
|
+
|
|
6
|
+
2026.01.24, v5.2.2
|
|
7
|
+
|
|
8
|
+
feature:
|
|
9
|
+
- aeb6b12 redlint: test: run
|
|
10
|
+
- 9db12a6 redlint: @putout/plugin-nodejs v20.0.0
|
|
11
|
+
- 026f9b7 redlint: test: readFixture: add
|
|
12
|
+
|
|
1
13
|
2026.01.24, v5.2.1
|
|
2
14
|
|
|
3
15
|
feature:
|
package/README.md
CHANGED
|
@@ -75,6 +75,8 @@ To add new rule `create-file` located in plugin `custom` for **RedLint** write a
|
|
|
75
75
|
|
|
76
76
|
- ✅ [get fiture names from `index.spec.js`](https://putout.cloudcmd.io/#/gist/558b38ed5e5e662706f1b8a49a0157a1/8e188e99798246263dbf488b86dc250b8dfa1be3).
|
|
77
77
|
- ✅ [init fixture](https://putout.cloudcmd.io/#/gist/e7614e03b3292a210cfc63265718e955/13ccc3a90a8d9ff28f26474b107c5652928e8d0a);
|
|
78
|
+
- ✅ [read fixture](https://putout.cloudcmd.io/#/gist/f8ab318fa1963508322031483d988ad4/b152c5f796bfab9aa74594c847ddbd1f650efb83);
|
|
79
|
+
- ✅ [run plugin](https://putout.cloudcmd.io/#/gist/8e66e45753dbe9e746c797813eb2723a/9855f9aea57f345492c629c65d9972309d250a91);
|
|
78
80
|
|
|
79
81
|
## License
|
|
80
82
|
|
package/bin/redlint.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import {join} from 'node:path';
|
|
4
|
-
import process from 'node:process';
|
|
4
|
+
import process, {stdout} from 'node:process';
|
|
5
5
|
import {readFile, writeFile} from 'node:fs/promises';
|
|
6
6
|
import {lintJSON} from 'putout/lint/json';
|
|
7
7
|
import formatterCodeFrame from '@putout/formatter-codeframe';
|
|
@@ -154,7 +154,7 @@ async function uiLoop(arg) {
|
|
|
154
154
|
if (error)
|
|
155
155
|
return console.error('\n🌴 ' + error.message + '');
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
stdout.write(result);
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
160
|
|
package/lib/choose.js
CHANGED
package/lib/debug.js
CHANGED
|
@@ -2,12 +2,23 @@ import {operator} from 'putout';
|
|
|
2
2
|
|
|
3
3
|
const {getTemplateValues} = operator;
|
|
4
4
|
const TRANSFORM = 't.transform(__a)';
|
|
5
|
+
const TRANSFORM_COUPLE = 't.transform(__a, __b)';
|
|
5
6
|
|
|
6
|
-
export const report = (path) =>
|
|
7
|
-
const {__a} = getTemplateValues(path, TRANSFORM);
|
|
8
|
-
return __a.value;
|
|
9
|
-
};
|
|
7
|
+
export const report = (path) => parseValue(path);
|
|
10
8
|
|
|
11
9
|
export const fix = () => {};
|
|
12
10
|
|
|
13
|
-
export const include = () => [TRANSFORM];
|
|
11
|
+
export const include = () => [TRANSFORM, TRANSFORM_COUPLE];
|
|
12
|
+
|
|
13
|
+
function parseValue(path) {
|
|
14
|
+
const {length} = path.node.arguments;
|
|
15
|
+
|
|
16
|
+
if (length === 1) {
|
|
17
|
+
const {__a} = getTemplateValues(path, TRANSFORM);
|
|
18
|
+
return __a.value;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const {__a} = getTemplateValues(path, TRANSFORM_COUPLE);
|
|
22
|
+
|
|
23
|
+
return __a.value;
|
|
24
|
+
}
|
|
@@ -4,12 +4,12 @@ import * as initFixturePlugin from './init-fixture-plugin/index.js';
|
|
|
4
4
|
export const initFixture = (ast, names) => {
|
|
5
5
|
transform(ast, '', {
|
|
6
6
|
rules: {
|
|
7
|
-
'init-
|
|
7
|
+
'init-fixtures': ['on', {
|
|
8
8
|
names,
|
|
9
9
|
}],
|
|
10
10
|
},
|
|
11
11
|
plugins: [
|
|
12
|
-
['init-
|
|
12
|
+
['init-fixtures', initFixturePlugin],
|
|
13
13
|
],
|
|
14
14
|
});
|
|
15
15
|
|
|
@@ -3,6 +3,7 @@ import {operator} from 'putout';
|
|
|
3
3
|
const {
|
|
4
4
|
createDirectory,
|
|
5
5
|
createFile,
|
|
6
|
+
getFile,
|
|
6
7
|
} = operator;
|
|
7
8
|
|
|
8
9
|
export const report = (dir, {name}) => `Init fixture '${name}'`;
|
|
@@ -19,13 +20,17 @@ export const scan = (root, {options, push}) => {
|
|
|
19
20
|
if (!names.length)
|
|
20
21
|
return;
|
|
21
22
|
|
|
23
|
+
const fixtureDir = getFile(root, 'fixture');
|
|
24
|
+
|
|
22
25
|
for (const [a, b] of names) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
if (!fixtureDir || !getFile(fixtureDir, a))
|
|
27
|
+
push(root, {
|
|
28
|
+
name: a,
|
|
29
|
+
});
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
if (!fixtureDir || !getFile(fixtureDir, b))
|
|
32
|
+
push(root, {
|
|
33
|
+
name: b,
|
|
34
|
+
});
|
|
30
35
|
}
|
|
31
36
|
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {basename} from 'node:path';
|
|
2
|
+
import {transform} from 'putout';
|
|
3
|
+
import * as readFixturesPlugin from './read-fixture-plugin/index.js';
|
|
4
|
+
|
|
5
|
+
const {fromEntries, entries} = Object;
|
|
6
|
+
const getMessage = (a) => a.message;
|
|
7
|
+
const SPLITTER = ' -> ';
|
|
8
|
+
|
|
9
|
+
export const readFixture = (ast, names) => {
|
|
10
|
+
const places = transform(ast, '', {
|
|
11
|
+
rules: {
|
|
12
|
+
'read-fixture': ['on', {
|
|
13
|
+
names,
|
|
14
|
+
}],
|
|
15
|
+
},
|
|
16
|
+
plugins: [
|
|
17
|
+
['read-fixture', readFixturesPlugin],
|
|
18
|
+
],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const parsedFixtures = parseFixtures(places);
|
|
22
|
+
|
|
23
|
+
return mergeFixtures(parsedFixtures);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const split = (a) => {
|
|
27
|
+
const [name] = a.split(SPLITTER, 1);
|
|
28
|
+
const nameLength = name.length;
|
|
29
|
+
const {length} = SPLITTER;
|
|
30
|
+
const content = a.slice(length + nameLength);
|
|
31
|
+
|
|
32
|
+
return [
|
|
33
|
+
basename(name),
|
|
34
|
+
content,
|
|
35
|
+
];
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
function parseFixtures(places) {
|
|
39
|
+
const result = places
|
|
40
|
+
.map(getMessage)
|
|
41
|
+
.map(split);
|
|
42
|
+
|
|
43
|
+
return fromEntries(result);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const isFixFileName = (a) => a.endsWith('-fix.js');
|
|
47
|
+
const getNameFix = (a) => a.replace('.js', '-fix.js');
|
|
48
|
+
const cutExtension = (a) => a.replace('.js', '');
|
|
49
|
+
|
|
50
|
+
function mergeFixtures(fixture) {
|
|
51
|
+
const result = new Map();
|
|
52
|
+
const filesFix = new Map();
|
|
53
|
+
const files = new Map();
|
|
54
|
+
const names = new Map();
|
|
55
|
+
|
|
56
|
+
for (const [name, content] of entries(fixture)) {
|
|
57
|
+
if (isFixFileName(name)) {
|
|
58
|
+
filesFix.set(name, content);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
files.set(name, content);
|
|
63
|
+
names.set(name, getNameFix(name));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
for (const [name, content] of files) {
|
|
67
|
+
const nameFix = names.get(name);
|
|
68
|
+
const contentFix = filesFix.get(nameFix);
|
|
69
|
+
const shortName = cutExtension(name);
|
|
70
|
+
|
|
71
|
+
result.set(shortName, [content, contentFix]);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {operator} from 'putout';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
readDirectory,
|
|
5
|
+
findFile,
|
|
6
|
+
readFileContent,
|
|
7
|
+
getFilename,
|
|
8
|
+
} = operator;
|
|
9
|
+
|
|
10
|
+
export const report = (file) => {
|
|
11
|
+
const name = getFilename(file);
|
|
12
|
+
const content = readFileContent(file);
|
|
13
|
+
|
|
14
|
+
return `${name} -> ${content}`;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const fix = () => {};
|
|
18
|
+
|
|
19
|
+
export const scan = (root, {push}) => {
|
|
20
|
+
const [fixture] = findFile(root, 'fixture');
|
|
21
|
+
|
|
22
|
+
if (!fixture)
|
|
23
|
+
return;
|
|
24
|
+
|
|
25
|
+
for (const file of readDirectory(fixture)) {
|
|
26
|
+
push(file);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {putout} from 'putout';
|
|
2
|
+
|
|
3
|
+
const noop = () => {};
|
|
4
|
+
|
|
5
|
+
export const run = (content, options) => {
|
|
6
|
+
const {require = noop, incorrect} = options;
|
|
7
|
+
|
|
8
|
+
if (!incorrect)
|
|
9
|
+
return;
|
|
10
|
+
|
|
11
|
+
const plugin = createPlugin(content, require);
|
|
12
|
+
|
|
13
|
+
return runPlugin(plugin, incorrect);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function runPlugin(plugin, source) {
|
|
17
|
+
const {code} = putout(source, {
|
|
18
|
+
plugins: [
|
|
19
|
+
['run', plugin],
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return code;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function createPlugin(content, require) {
|
|
27
|
+
const {code} = putout(content, {
|
|
28
|
+
plugins: [
|
|
29
|
+
'nodejs/convert-esm-to-commonjs',
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const fn = Function('module, exports, require', code);
|
|
34
|
+
|
|
35
|
+
const exports = {};
|
|
36
|
+
const module = {
|
|
37
|
+
exports,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
fn(module, exports, require);
|
|
41
|
+
|
|
42
|
+
return exports;
|
|
43
|
+
}
|
package/lib/test/test.js
CHANGED
|
@@ -1,30 +1,84 @@
|
|
|
1
|
+
import {createRequire} from 'node:module';
|
|
1
2
|
import {operator, parse} from 'putout';
|
|
2
3
|
import {branch as _branch} from '@putout/processor-filesystem';
|
|
4
|
+
import {codeFrameColumns} from '@putout/babel';
|
|
3
5
|
import {getFixtureNames} from './get-fixture-names/index.js';
|
|
4
6
|
import {initFixture} from './init-fixture/index.js';
|
|
7
|
+
import {readFixture} from './read-fixture/index.js';
|
|
8
|
+
import {run} from './run/run.js';
|
|
9
|
+
|
|
10
|
+
const createLog = (output) => (a) => {
|
|
11
|
+
output.push(`${a}\n`);
|
|
12
|
+
};
|
|
5
13
|
|
|
6
14
|
const {
|
|
7
15
|
findFile,
|
|
8
16
|
readFileContent,
|
|
17
|
+
getFilename,
|
|
9
18
|
} = operator;
|
|
10
19
|
|
|
20
|
+
const SUCCESS = '🍀';
|
|
21
|
+
const FAIL = '🍄';
|
|
22
|
+
|
|
11
23
|
export const test = (filesystem, overrides = {}) => {
|
|
12
24
|
const {branch = _branch} = overrides;
|
|
13
25
|
|
|
14
26
|
const [{source}] = branch(filesystem);
|
|
15
|
-
const
|
|
27
|
+
const ast = parse(source);
|
|
16
28
|
|
|
17
|
-
const [
|
|
29
|
+
const [spec] = findFile(ast, 'index.spec.js');
|
|
18
30
|
|
|
19
|
-
if (!
|
|
31
|
+
if (!spec)
|
|
20
32
|
return [
|
|
21
33
|
Error(`No 'index.spec.js' found`),
|
|
22
34
|
];
|
|
23
35
|
|
|
24
|
-
const
|
|
36
|
+
const [index] = findFile(ast, 'index.js');
|
|
37
|
+
|
|
38
|
+
if (!index)
|
|
39
|
+
return [
|
|
40
|
+
Error(`No 'index.js' found`),
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
const specContent = readFileContent(spec);
|
|
25
44
|
const names = getFixtureNames(specContent);
|
|
26
45
|
|
|
27
|
-
initFixture(
|
|
46
|
+
initFixture(ast, names);
|
|
47
|
+
const fixture = readFixture(ast, names);
|
|
48
|
+
|
|
49
|
+
const plugin = readFileContent(index);
|
|
50
|
+
const filename = getFilename(index);
|
|
51
|
+
const require = createRequire(filename);
|
|
52
|
+
|
|
53
|
+
const output = ['\n'];
|
|
54
|
+
const log = createLog(output);
|
|
55
|
+
|
|
56
|
+
for (const [name, [incorrect, correct]] of fixture) {
|
|
57
|
+
const output = run(plugin, {
|
|
58
|
+
require,
|
|
59
|
+
incorrect,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const status = correct === output ? SUCCESS : FAIL;
|
|
63
|
+
|
|
64
|
+
log(`# ${status} ${name}`);
|
|
65
|
+
|
|
66
|
+
if (status === SUCCESS)
|
|
67
|
+
continue;
|
|
68
|
+
|
|
69
|
+
log('');
|
|
70
|
+
log(`## ❌ Incorrect code\n`);
|
|
71
|
+
log(codeFrameColumns(incorrect, {}, {
|
|
72
|
+
highlightCode: true,
|
|
73
|
+
}));
|
|
74
|
+
log('');
|
|
75
|
+
log(`## ✅ Correct code\n`);
|
|
76
|
+
|
|
77
|
+
log(codeFrameColumns(correct, {}, {
|
|
78
|
+
highlightCode: true,
|
|
79
|
+
}));
|
|
80
|
+
log('');
|
|
81
|
+
}
|
|
28
82
|
|
|
29
|
-
return [null,
|
|
83
|
+
return [null, output.join('')];
|
|
30
84
|
};
|
package/lib/view/view.js
CHANGED
|
@@ -17,7 +17,7 @@ export const view = (filename, overrides = {}) => {
|
|
|
17
17
|
for (const [line, nameWithContent] of entries(files)) {
|
|
18
18
|
for (const [name, content] of entries(nameWithContent)) {
|
|
19
19
|
lines.push(codeFrameColumns(dedent(content), {}, {
|
|
20
|
-
|
|
20
|
+
highlightCode: true,
|
|
21
21
|
message: `${name}:${line}`,
|
|
22
22
|
}) + '\n');
|
|
23
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "redlint",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
|
|
6
6
|
"description": "Lint Filesystem with 🐊Putout",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@putout/operator-json": "^3.1.0",
|
|
42
42
|
"@putout/plugin-eslint": "^15.0.0",
|
|
43
43
|
"@putout/plugin-filesystem": "^12.0.0",
|
|
44
|
-
"@putout/plugin-nodejs": "^
|
|
44
|
+
"@putout/plugin-nodejs": "^20.0.0",
|
|
45
45
|
"@putout/plugin-react": "^3.0.0",
|
|
46
46
|
"@putout/processor-filesystem": "^7.0.1",
|
|
47
47
|
"chalk": "^5.3.0",
|