redlint 3.1.2 β†’ 3.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/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ 2023.12.20, v3.2.0
2
+
3
+ feature:
4
+ - 333f321 redlint: debug: back
5
+ - 955f5d3 redlint: pack: add
6
+
1
7
  2023.12.19, v3.1.2
2
8
 
3
9
  feature:
package/README.md CHANGED
@@ -13,13 +13,13 @@
13
13
  >
14
14
  > **(c) The Book of Kon, PoKon and ZaKon**
15
15
 
16
- ![image](https://github.com/putoutjs/redlint/assets/1573141/a34a7e75-b30f-4e79-b132-1d411d96ba15)
16
+ ![image](https://github.com/putoutjs/redlint/assets/1573141/09bed270-cbf5-484f-bdd6-dd031ae38703)
17
17
 
18
18
  What if **Filesystem** was a simple **JSON** file [`.filesystem.json`](https://github.com/putoutjs/redlint/blob/master/.filesystem.json). What if you can transform **JSON** file with 🐊[**Putout**](https://github.com/coderaiser/putout) code transformer and this changes modify **Filesystem**?
19
19
 
20
20
  What if I tell you it is possible? 😱 Checkout in 🐊[**Putout Editor**](https://putout.cloudcmd.io/#/gist/0614c2da35a1864b59ac284f18656328/695a9960c401d4e8f6744f58eac591d8f9185235).
21
21
 
22
- First time ever! Linter for you **Filesystem** πŸ˜πŸ’Ύ.
22
+ First time ever! Linter for your **Filesystem** πŸ˜πŸ’Ύ.
23
23
 
24
24
  ## Install
25
25
 
@@ -31,7 +31,7 @@ npm i redlint -g
31
31
 
32
32
  You can choose interactively when run `redlint`:
33
33
 
34
- ![image](https://github.com/putoutjs/redlint/assets/1573141/1d3c26a6-14f2-43f9-8115-29b28d5d5f26)
34
+ ![image](https://github.com/putoutjs/redlint/assets/1573141/c5d3a231-6caf-4dcb-9410-1d4dda48d9e0)
35
35
 
36
36
  ## Scan
37
37
 
package/bin/redlint.js CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import {lintJSON} from 'putout/lint/json';
3
+ import {join} from 'node:path';
4
4
  import process from 'node:process';
5
5
  import {
6
6
  readFile,
7
7
  writeFile,
8
8
  } from 'node:fs/promises';
9
+ import {lintJSON} from 'putout/lint/json';
9
10
  import stripAnsi from 'strip-ansi';
10
11
  import formatterCodeFrame from '@putout/formatter-codeframe';
11
12
  import formatterDump from '@putout/formatter-dump';
@@ -15,127 +16,144 @@ import {choose} from '../lib/choose.js';
15
16
  import {buildTree} from '../lib/redlint.js';
16
17
  import {convertToSimple} from '../lib/simple.js';
17
18
  import {masterLint} from '../lib/master.js';
19
+ import {masterPack} from '../lib/pack/master.js';
18
20
  import {lint} from '../lib/lint.js';
19
- import {logo} from '../lib/logo.js';
21
+ import {pack} from '../lib/pack/pack.js';
22
+ import {debug} from '../lib/debug.js';
20
23
 
21
24
  const {stringify, parse} = JSON;
22
25
 
23
- let [arg] = process.argv.slice(2);
26
+ const [arg] = process.argv.slice(2);
24
27
  let header = true;
25
28
 
26
- if (!arg) {
27
- const cmd = await choose();
29
+ await uiLoop(arg);
30
+
31
+ async function uiLoop(arg) {
32
+ if (!arg) {
33
+ const cmd = await choose();
34
+
35
+ if (!cmd)
36
+ process.exit(1);
37
+
38
+ [arg] = stripAnsi(cmd).split(' ');
39
+ header = false;
40
+ }
28
41
 
29
- if (!cmd)
30
- process.exit(1);
42
+ if (arg === 'debug') {
43
+ arg = await debug();
44
+
45
+ if (arg === 'back')
46
+ return await uiLoop();
47
+ }
31
48
 
32
- [arg] = stripAnsi(cmd).split(' ');
33
- header = false;
34
- }
35
-
36
- if (arg === 'exit')
37
- process.exit();
38
-
39
- if (arg === 'version') {
40
- const packagePath = new URL('../package.json', import.meta.url);
41
- const packageData = await readFile(packagePath);
42
- const {version} = parse(packageData);
49
+ if (arg === 'exit')
50
+ process.exit();
43
51
 
44
- console.log(`v${version}`);
45
- process.exit();
46
- }
47
-
48
- if (arg === 'help') {
49
- help({
50
- header,
51
- });
52
- process.exit();
53
- }
54
-
55
- console.log('Running:');
56
- const spinner = ora('index filesystem').start();
57
- const result = await buildTree(process.cwd());
58
-
59
- spinner.succeed();
60
-
61
- if (arg === 'generate:simple') {
62
- await writeFile('.filesystem.json', lintJSON(stringify(convertToSimple(result))));
63
- process.exit(0);
64
- }
65
-
66
- const filesystem = lintJSON(stringify(result));
67
-
68
- if (arg === 'scan') {
69
- const places = await masterLint(filesystem, {
70
- fix: false,
71
- });
52
+ if (arg === 'version') {
53
+ const packagePath = new URL('../package.json', import.meta.url);
54
+ const packageData = await readFile(packagePath);
55
+ const {version} = parse(packageData);
56
+
57
+ console.log(`v${version}`);
58
+ process.exit();
59
+ }
72
60
 
73
- if (!places.length)
61
+ if (arg === 'help') {
62
+ help({
63
+ header,
64
+ });
74
65
  process.exit();
66
+ }
75
67
 
76
- console.log('');
77
- const dump = await formatterDump({
78
- name: '.filesystem.json',
79
- source: filesystem,
80
- places,
81
- index: 0,
82
- count: places.length,
83
- filesCount: 1,
84
- errorsCount: places.length,
85
- });
68
+ console.log('Running:');
69
+ const spinner = ora('index filesystem').start();
70
+ const CWD = process.cwd();
71
+ const result = await buildTree(CWD);
86
72
 
87
- process.stderr.write(dump);
73
+ spinner.succeed();
88
74
 
89
- process.exit(1);
90
- }
91
-
92
- if (arg === 'scan:frame') {
93
- const places = await masterLint(filesystem, {
94
- fix: true,
95
- });
75
+ if (arg === 'generate:simple') {
76
+ await writeFile('.filesystem.json', lintJSON(stringify(convertToSimple(result))));
77
+ process.exit(0);
78
+ }
96
79
 
97
- const result = await formatterCodeFrame({
98
- name: '.filesystem.json',
99
- source: filesystem,
100
- places,
101
- index: 0,
102
- count: places.length,
103
- filesCount: 1,
104
- errorsCount: places.length,
105
- });
80
+ const filesystem = lintJSON(stringify(result));
106
81
 
107
- process.stderr.write(result);
108
- process.exit(1);
109
- }
110
-
111
- if (arg === 'lint') {
112
- const places = lint(filesystem, {
113
- fix: true,
114
- });
82
+ if (arg === 'scan') {
83
+ const places = await masterLint(filesystem, {
84
+ fix: false,
85
+ });
86
+
87
+ if (!places.length)
88
+ process.exit();
89
+
90
+ console.log('');
91
+ const dump = await formatterDump({
92
+ name: '.filesystem.json',
93
+ source: filesystem,
94
+ places,
95
+ index: 0,
96
+ count: places.length,
97
+ filesCount: 1,
98
+ errorsCount: places.length,
99
+ });
100
+
101
+ process.stderr.write(dump);
102
+
103
+ process.exit(1);
104
+ }
115
105
 
116
- console.log(logo);
106
+ if (arg === 'pack') {
107
+ const result = await masterPack(CWD, filesystem);
108
+ await writeFile(join(CWD, 'filesystem.red'), result);
109
+ const spinner = ora(`pack 'filesystem.red'`).start();
110
+
111
+ spinner.succeed();
112
+ process.exit();
113
+ }
117
114
 
118
- const result = await formatterCodeFrame({
119
- name: '.filesystem.json',
120
- source: filesystem,
121
- places,
122
- index: 0,
123
- count: places.length,
124
- filesCount: 1,
125
- errorsCount: places.length,
126
- });
115
+ if (arg === 'pack:debug') {
116
+ const result = pack(CWD, filesystem);
117
+ await writeFile(join(CWD, 'filesystem.red'), result);
118
+
119
+ done(`pack 'filesystem.red'`);
120
+ process.exit();
121
+ }
127
122
 
128
- process.stderr.write(result);
129
- process.exit(1);
130
- }
131
-
132
- if (arg === 'fix') {
133
- await masterLint(filesystem, {
134
- fix: true,
135
- });
123
+ if (arg === 'scan:debug') {
124
+ const places = lint(filesystem, {
125
+ fix: true,
126
+ });
127
+
128
+ const result = await formatterCodeFrame({
129
+ name: '.filesystem.json',
130
+ source: filesystem,
131
+ places,
132
+ index: 0,
133
+ count: places.length,
134
+ filesCount: 1,
135
+ errorsCount: places.length,
136
+ });
137
+
138
+ process.stderr.write(result);
139
+ process.exit(1);
140
+ }
136
141
 
137
- process.exit();
142
+ if (arg === 'fix') {
143
+ await masterLint(filesystem, {
144
+ fix: true,
145
+ });
146
+
147
+ process.exit();
148
+ }
149
+
150
+ if (arg === 'generate')
151
+ await writeFile('.filesystem.json', filesystem);
152
+
153
+ done(`generate '.filesystem.json'`);
138
154
  }
139
155
 
140
- if (arg === 'generate')
141
- await writeFile('.filesystem.json', filesystem);
156
+ function done(message) {
157
+ const spinner = ora(message).start();
158
+ spinner.succeed();
159
+ }
package/lib/choose.js CHANGED
@@ -9,12 +9,13 @@ export const choose = async () => {
9
9
 
10
10
  const command = await chooseDialog('Command:', [
11
11
  'scan',
12
- 'scan:frame',
13
12
  'fix',
13
+ 'pack',
14
14
  'generate',
15
15
  'generate:simple',
16
16
  'help',
17
17
  'version',
18
+ 'debug',
18
19
  'exit',
19
20
  ]);
20
21
 
package/lib/debug.js ADDED
@@ -0,0 +1,14 @@
1
+ import {choose as chooseDialog} from '@putout/cli-choose';
2
+
3
+ export const debug = async () => {
4
+ const command = await chooseDialog('Debug:', [
5
+ 'scan:debug',
6
+ 'pack:debug',
7
+ 'back',
8
+ 'exit',
9
+ ]);
10
+
11
+ console.log('');
12
+
13
+ return command;
14
+ };
package/lib/help.js CHANGED
@@ -12,10 +12,12 @@ export const help = ({header = true}) => {
12
12
 
13
13
  console.log(`Commands:
14
14
  scan - scan files according to 🐊Putout rules
15
- scan:frame - scan files, show results in code frame
16
15
  fix - fix files according to 🐊Putout rules
16
+ pack - pack 'filesystem.red' with directory contents
17
17
  help - show help screen and exit
18
18
  generate - generate .filesystem.json file and exit
19
19
  generate:simple - generate simple .filesystem.json file and exit
20
+ version - show version and exit
21
+ debug = run commands without workers
20
22
  `);
21
23
  };
@@ -0,0 +1,136 @@
1
+ import {Worker} from 'node:worker_threads';
2
+ import ora from 'ora';
3
+ import chalk from 'chalk';
4
+ import fullstore from 'fullstore';
5
+
6
+ export function masterPack(cwd, filesystem, {
7
+ start = setStart,
8
+ end = setEnd,
9
+ push = setPush,
10
+ fail = setFail,
11
+ success = setSuccess,
12
+ } = {}) {
13
+ return run(cwd, filesystem, {
14
+ start,
15
+ end,
16
+ push,
17
+ fail,
18
+ success,
19
+ });
20
+ }
21
+
22
+ function setStart(rule, store) {
23
+ const spinner = ora(rule).start();
24
+
25
+ spinner.suffixText = '';
26
+
27
+ store({
28
+ rule,
29
+ count: 0,
30
+ spinner,
31
+ });
32
+ }
33
+
34
+ function setPush(store) {
35
+ const {
36
+ rule,
37
+ count,
38
+ spinner,
39
+ } = store();
40
+
41
+ store({
42
+ rule,
43
+ count: count + 1,
44
+ spinner,
45
+ });
46
+ }
47
+
48
+ function setFail(store) {
49
+ const {
50
+ rule,
51
+ count,
52
+ spinner,
53
+ } = store();
54
+
55
+ spinner.suffixText = chalk.red(count);
56
+ spinner.fail();
57
+
58
+ store({
59
+ rule,
60
+ count,
61
+ spinner,
62
+ });
63
+ }
64
+
65
+ function setSuccess(store) {
66
+ const {spinner} = store();
67
+
68
+ spinner.succeed();
69
+ spinner.suffixText = '';
70
+
71
+ store({
72
+ ...store(),
73
+ spinner: null,
74
+ });
75
+ }
76
+
77
+ function setEnd(data, resolve) {
78
+ resolve(data);
79
+ }
80
+
81
+ function run(cwd, filesystem, {start, end, fail, success}) {
82
+ return new Promise((resolve, reject) => {
83
+ const worker = new Worker(new URL('./slave.js', import.meta.url), {
84
+ workerData: {
85
+ cwd,
86
+ filesystem,
87
+ },
88
+ });
89
+
90
+ const store = fullstore({});
91
+
92
+ worker.on('message', ([event, data]) => {
93
+ if (event === 'end') {
94
+ end(data, resolve);
95
+ return;
96
+ }
97
+
98
+ if (event === 'rule:start') {
99
+ start(data, store);
100
+ return;
101
+ }
102
+
103
+ const {
104
+ rule,
105
+ count,
106
+ spinner,
107
+ } = store();
108
+
109
+ if (!spinner)
110
+ return;
111
+
112
+ store({
113
+ rule,
114
+ count,
115
+ spinner,
116
+ });
117
+
118
+ const endFail = count && event === 'rule:end';
119
+ const endSuccess = !count && event === 'rule:end';
120
+
121
+ if (endFail) {
122
+ fail(store);
123
+ return;
124
+ }
125
+
126
+ if (endSuccess) {
127
+ success(store);
128
+ return;
129
+ }
130
+ });
131
+ worker.on('error', reject);
132
+ worker.on('exit', (code) => {
133
+ reject(Error(`Worker stopped with exit code ${code}`));
134
+ });
135
+ });
136
+ }
@@ -0,0 +1,39 @@
1
+ import {
2
+ parse,
3
+ transform,
4
+ print,
5
+ } from 'putout';
6
+ import {createProgress} from '@putout/engine-runner/progress';
7
+ import * as pluginFilesystem from '@putout/plugin-filesystem';
8
+ import {
9
+ branch,
10
+ merge,
11
+ } from '@putout/processor-filesystem';
12
+
13
+ const [, readAllFiles] = pluginFilesystem.rules['read-all-files'];
14
+ const [, replaceCwd] = pluginFilesystem.rules['replace-cwd'];
15
+
16
+ export const pack = (from, filesystem, {progress = createProgress()} = {}) => {
17
+ const [{source}] = branch(filesystem);
18
+ const ast = parse(source);
19
+
20
+ transform(ast, filesystem, {
21
+ fix: true,
22
+ fixCount: 1,
23
+ progress,
24
+ rules: {
25
+ 'replace-cwd': ['on', {
26
+ from,
27
+ to: '/',
28
+ }],
29
+ },
30
+ plugins: [
31
+ ['read-all-files', readAllFiles],
32
+ ['replace-cwd', replaceCwd],
33
+ ],
34
+ });
35
+
36
+ const code = print(ast);
37
+
38
+ return merge(filesystem, [code]);
39
+ };
@@ -0,0 +1,25 @@
1
+ import {
2
+ parentPort,
3
+ workerData,
4
+ } from 'node:worker_threads';
5
+ import {pack} from './pack.js';
6
+ import {createProgress} from '@putout/engine-runner/progress';
7
+
8
+ const {filesystem, cwd} = workerData;
9
+ const progress = createProgress();
10
+
11
+ progress.on('start', ({rule}) => {
12
+ parentPort.postMessage(['rule:start', rule]);
13
+ });
14
+
15
+ progress.on('push', ({rule}) => {
16
+ parentPort.postMessage(['rule:push', rule]);
17
+ });
18
+
19
+ progress.on('end', ({rule}) => {
20
+ parentPort.postMessage(['rule:end', rule]);
21
+ });
22
+
23
+ parentPort.postMessage(['end', pack(cwd, filesystem, {
24
+ progress,
25
+ })]);
package/lib/slave.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  import {lint} from './lint.js';
6
6
  import {createProgress} from '@putout/engine-runner/progress';
7
7
 
8
- const {filesystem, fix} = workerData;
8
+ const {fix, filesystem} = workerData;
9
9
 
10
10
  const progress = createProgress();
11
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "redlint",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "Lint Filesystem with 🐊Putout",
@@ -34,6 +34,7 @@
34
34
  "@putout/engine-runner": "^20.1.0",
35
35
  "@putout/formatter-codeframe": "^6.0.0",
36
36
  "@putout/formatter-dump": "^4.0.1",
37
+ "@putout/plugin-filesystem": "^3.6.0",
37
38
  "@putout/processor-filesystem": "^3.0.0",
38
39
  "chalk": "^5.3.0",
39
40
  "fullstore": "^3.0.0",