markuplint 4.0.0-dev.0 → 4.0.0-dev.10
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/lib/cli/index.js +2 -6
- package/lib/cli/init/index.js +13 -15
- package/lib/cli/init/select-modules.d.ts +2 -0
- package/lib/cli/init/select-modules.js +10 -0
- package/lib/reporter/github-reporter.js +1 -1
- package/lib/reporter/simple-reporter.js +8 -8
- package/lib/reporter/standard-reporter.js +33 -18
- package/package.json +14 -22
package/lib/cli/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import getStdin from 'get-stdin';
|
|
|
2
2
|
import { verbosely } from '../debug.js';
|
|
3
3
|
import { cli } from './bootstrap.js';
|
|
4
4
|
import { command } from './command.js';
|
|
5
|
-
import { createRule } from './create-rule/index.js';
|
|
6
5
|
import { initialize } from './init/index.js';
|
|
7
6
|
import { search } from './search/index.js';
|
|
8
7
|
/* eslint-disable unicorn/no-process-exit */
|
|
@@ -23,11 +22,8 @@ if (cli.flags.init) {
|
|
|
23
22
|
process.exit(0);
|
|
24
23
|
}
|
|
25
24
|
if (cli.flags.createRule) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
process.exit(1);
|
|
29
|
-
});
|
|
30
|
-
process.exit(0);
|
|
25
|
+
process.stderr.write("Use to run 'npx @markuplint/create-rule' instead of 'markuplint --create-rule'.\n");
|
|
26
|
+
process.exit(1);
|
|
31
27
|
}
|
|
32
28
|
const files = cli.input;
|
|
33
29
|
if (files.length > 0) {
|
package/lib/cli/init/index.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
2
|
import module from 'node:module';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
5
|
-
import { head, write, error } from '../../util.js';
|
|
6
|
-
import { confirm, confirmSequence, multiSelect } from '../prompt.js';
|
|
4
|
+
import { installModule, multiSelect, confirm, confirmSequence, header } from '@markuplint/cli-utils';
|
|
7
5
|
import { createConfig, langs } from './create-config.js';
|
|
8
6
|
import { getDefaultRules } from './get-default-rules.js';
|
|
9
|
-
import {
|
|
7
|
+
import { selectModules } from './select-modules.js';
|
|
10
8
|
const require = module.createRequire(import.meta.url);
|
|
11
|
-
const writeFile = util.promisify(fs.writeFile);
|
|
12
9
|
const ruleCategories = {
|
|
13
10
|
validation: {
|
|
14
11
|
message: 'Are you going to conformance check according to HTML standard?',
|
|
@@ -27,8 +24,9 @@ const ruleCategories = {
|
|
|
27
24
|
},
|
|
28
25
|
};
|
|
29
26
|
export async function initialize() {
|
|
30
|
-
write(
|
|
31
|
-
write
|
|
27
|
+
process.stdout.write(header('Initialization'));
|
|
28
|
+
process.stdout.write('\n');
|
|
29
|
+
process.stdout.write('\n');
|
|
32
30
|
const selectedLangs = await multiSelect({
|
|
33
31
|
message: 'Which do you use template engines?',
|
|
34
32
|
choices: Object.entries(langs).map(([key, name]) => ({ name, value: key })),
|
|
@@ -59,21 +57,21 @@ export async function initialize() {
|
|
|
59
57
|
}
|
|
60
58
|
const config = createConfig(selectedLangs, ruleSettingMode, defaultRules);
|
|
61
59
|
const filePath = path.resolve(process.cwd(), '.markuplintrc');
|
|
62
|
-
await writeFile(filePath, JSON.stringify(config, null, 2), { encoding: 'utf8' });
|
|
63
|
-
write(`✨Created: ${filePath}`);
|
|
60
|
+
await fs.writeFile(filePath, JSON.stringify(config, null, 2), { encoding: 'utf8' });
|
|
61
|
+
process.stdout.write(`✨Created: ${filePath}\n`);
|
|
64
62
|
if (autoInstall) {
|
|
65
|
-
write('Install automatically');
|
|
63
|
+
process.stdout.write('Install automatically\n');
|
|
66
64
|
const modules = selectModules(selectedLangs);
|
|
67
65
|
const result = await installModule(modules, true).catch(error_ => new Error(error_));
|
|
68
66
|
if (result instanceof Error) {
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
// eslint-disable-next-line unicorn/no-process-exit
|
|
68
|
+
process.exit(1);
|
|
71
69
|
}
|
|
72
70
|
if (result.alreadyExists) {
|
|
73
|
-
write('Modules are installed already
|
|
71
|
+
process.stdout.write('Modules are installed already.\n');
|
|
74
72
|
}
|
|
75
73
|
else {
|
|
76
|
-
write('✨ Success');
|
|
74
|
+
process.stdout.write('✨ Success\n');
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
77
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function selectModules(selectedLangs) {
|
|
2
|
+
const modules = ['markuplint', ...selectedLangs.map(lang => `@markuplint/${lang}-parser`)];
|
|
3
|
+
if (selectedLangs.includes('vue')) {
|
|
4
|
+
modules.push('@markuplint/vue-spec');
|
|
5
|
+
}
|
|
6
|
+
if (selectedLangs.includes('jsx')) {
|
|
7
|
+
modules.push('@markuplint/react-spec');
|
|
8
|
+
}
|
|
9
|
+
return modules;
|
|
10
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
const loggerError =
|
|
4
|
-
const loggerWarning =
|
|
1
|
+
import { name, font, pad, getWidth, messageToString } from '@markuplint/cli-utils';
|
|
2
|
+
const commandName = name.toLowerCase();
|
|
3
|
+
const loggerError = font.red;
|
|
4
|
+
const loggerWarning = font.xterm(208);
|
|
5
5
|
export function simpleReporter(results, options) {
|
|
6
6
|
const sizes = {
|
|
7
7
|
line: 0,
|
|
@@ -12,19 +12,19 @@ export function simpleReporter(results, options) {
|
|
|
12
12
|
sizes.line = Math.max(sizes.line, violation.line.toString(10).length);
|
|
13
13
|
sizes.col = Math.max(sizes.col, violation.col.toString(10).length);
|
|
14
14
|
const meg = messageToString(violation.message, violation.reason);
|
|
15
|
-
sizes.meg = Math.max(sizes.meg,
|
|
15
|
+
sizes.meg = Math.max(sizes.meg, getWidth(meg));
|
|
16
16
|
}
|
|
17
17
|
const out = [];
|
|
18
18
|
if (results.violations.length > 0) {
|
|
19
|
-
out.push(`<${
|
|
19
|
+
out.push(`<${commandName}> ${font.underline(results.filePath)}: ${loggerError('✗')}`);
|
|
20
20
|
for (const violation of results.violations) {
|
|
21
21
|
const s = violation.severity === 'error' ? loggerError('✖') : loggerWarning('⚠️');
|
|
22
22
|
const meg = messageToString(violation.message, violation.reason);
|
|
23
|
-
out.push(` ${
|
|
23
|
+
out.push(` ${font.cyan(`${pad(violation.line, sizes.line, true)}:${pad(violation.col, sizes.col)}`)} ${s} ${pad(meg, sizes.meg)} ${font.xterm(8)(violation.ruleId)} `);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
else if (!options.problemOnly) {
|
|
27
|
-
out.push(`<${
|
|
27
|
+
out.push(`<${commandName}> ${font.underline(results.filePath)}: ${font.green('✓')}`);
|
|
28
28
|
}
|
|
29
29
|
return out;
|
|
30
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
const loggerError =
|
|
4
|
-
const loggerWarning =
|
|
1
|
+
import { messageToString, font, name, invisibleSpace, space, pad, getWidth } from '@markuplint/cli-utils';
|
|
2
|
+
const commandName = name.toLowerCase();
|
|
3
|
+
const loggerError = font.red;
|
|
4
|
+
const loggerWarning = font.xterm(208);
|
|
5
5
|
export function standardReporter(results, options) {
|
|
6
6
|
const sizes = {
|
|
7
7
|
line: 0,
|
|
@@ -12,32 +12,47 @@ export function standardReporter(results, options) {
|
|
|
12
12
|
sizes.line = Math.max(sizes.line, violation.line.toString(10).length);
|
|
13
13
|
sizes.col = Math.max(sizes.col, violation.col.toString(10).length);
|
|
14
14
|
const meg = messageToString(violation.message, violation.reason);
|
|
15
|
-
sizes.meg = Math.max(sizes.meg,
|
|
15
|
+
sizes.meg = Math.max(sizes.meg, getWidth(meg));
|
|
16
16
|
}
|
|
17
17
|
const out = [];
|
|
18
18
|
if (results.violations.length > 0) {
|
|
19
19
|
const lines = results.sourceCode.split(/\r?\n/);
|
|
20
20
|
for (const violation of results.violations) {
|
|
21
|
-
const prev = lines[violation.line - 2] ?? '';
|
|
22
|
-
const line = lines[violation.line - 1] ?? '';
|
|
23
|
-
const next = lines[violation.line - 0] ?? '';
|
|
24
|
-
const before = line.slice(0, Math.max(0, violation.col - 1));
|
|
25
|
-
const after = line.slice(Math.max(0, violation.col - 1 + violation.raw.length));
|
|
26
21
|
const logger = violation.severity === 'error' ? loggerError : loggerWarning;
|
|
27
22
|
const meg = messageToString(violation.message, violation.reason);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
const startLine = violation.line - 1;
|
|
24
|
+
// Main message
|
|
25
|
+
out.push(`<${commandName}> ${logger(`${violation.severity}: ${meg} (${violation.ruleId}) ${font.underline(`${results.filePath}:${violation.line}:${violation.col}`)}`)}`);
|
|
26
|
+
// Previous line
|
|
27
|
+
if (startLine > 0) {
|
|
28
|
+
const prev = lines[startLine - 1] ?? '';
|
|
29
|
+
out.push(` ${font.cyan(pad(startLine, sizes.col, true))}: ${space(prev)}`);
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
// Current line
|
|
32
|
+
const rawLines = violation.raw.split(/\r?\n/);
|
|
33
|
+
const line = lines[startLine] ?? '';
|
|
34
|
+
for (const [i, rawLine] of rawLines.entries()) {
|
|
35
|
+
const currentLine = lines[startLine + i] ?? '';
|
|
36
|
+
const beforeChars = i === 0 ? line.slice(0, Math.max(0, violation.col - 1)) : rawLine.match(/^\s+/)?.[0] ?? '';
|
|
37
|
+
const codeChars = rawLine.trim();
|
|
38
|
+
const afterChars = currentLine.slice(Math.max(0, beforeChars.length + codeChars.length));
|
|
39
|
+
const lineNoChars = pad(violation.line + i, sizes.col, true);
|
|
40
|
+
const lineNo = font.cyan(lineNoChars);
|
|
41
|
+
const before = i === 0 ? space(beforeChars) : font.bgRed(space(beforeChars));
|
|
42
|
+
const code = font.bgRed(codeChars);
|
|
43
|
+
const after = space(afterChars);
|
|
44
|
+
out.push(` ${lineNo}: ${before}${code}${space(after)}`);
|
|
45
|
+
if (!options.color) {
|
|
46
|
+
out.push(` ${invisibleSpace(lineNoChars + ': ' + beforeChars)}${'^'.repeat(codeChars.length)}${invisibleSpace(afterChars)}`);
|
|
47
|
+
}
|
|
35
48
|
}
|
|
36
|
-
|
|
49
|
+
// Next line
|
|
50
|
+
const next = lines[startLine + rawLines.length] ?? '';
|
|
51
|
+
out.push(` ${font.cyan(pad(startLine + rawLines.length + 1, sizes.col, true))}: ${space(next)}`);
|
|
37
52
|
}
|
|
38
53
|
}
|
|
39
54
|
else if (!options.problemOnly) {
|
|
40
|
-
out.push(`<${
|
|
55
|
+
out.push(`<${commandName}> ${font.green('passed')} ${font.underline(results.filePath)}`);
|
|
41
56
|
}
|
|
42
57
|
return out;
|
|
43
58
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markuplint",
|
|
3
|
-
"version": "4.0.0-dev.
|
|
3
|
+
"version": "4.0.0-dev.10+b28398ab",
|
|
4
4
|
"description": "An HTML linter for all markup developers",
|
|
5
5
|
"author": "Yusuke Hirao",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,36 +25,28 @@
|
|
|
25
25
|
"clean": "tsc --build --clean"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@markuplint/
|
|
29
|
-
"@markuplint/file-resolver": "4.0.0-dev.
|
|
30
|
-
"@markuplint/html-parser": "4.0.0-dev.
|
|
31
|
-
"@markuplint/html-spec": "4.0.0-dev.
|
|
32
|
-
"@markuplint/i18n": "4.0.0-dev.
|
|
33
|
-
"@markuplint/ml-ast": "4.0.0-dev.
|
|
34
|
-
"@markuplint/ml-config": "4.0.0-dev.
|
|
35
|
-
"@markuplint/ml-core": "4.0.0-dev.
|
|
36
|
-
"@markuplint/ml-spec": "4.0.0-dev.
|
|
37
|
-
"@markuplint/rules": "4.0.0-dev.
|
|
38
|
-
"@markuplint/shared": "4.0.0-dev.
|
|
39
|
-
"@types/cli-color": "^2.0.6",
|
|
28
|
+
"@markuplint/cli-utils": "4.0.0-dev.3823+b28398ab",
|
|
29
|
+
"@markuplint/file-resolver": "4.0.0-dev.10+b28398ab",
|
|
30
|
+
"@markuplint/html-parser": "4.0.0-dev.10+b28398ab",
|
|
31
|
+
"@markuplint/html-spec": "4.0.0-dev.10+b28398ab",
|
|
32
|
+
"@markuplint/i18n": "4.0.0-dev.10+b28398ab",
|
|
33
|
+
"@markuplint/ml-ast": "4.0.0-dev.10+b28398ab",
|
|
34
|
+
"@markuplint/ml-config": "4.0.0-dev.10+b28398ab",
|
|
35
|
+
"@markuplint/ml-core": "4.0.0-dev.10+b28398ab",
|
|
36
|
+
"@markuplint/ml-spec": "4.0.0-dev.10+b28398ab",
|
|
37
|
+
"@markuplint/rules": "4.0.0-dev.10+b28398ab",
|
|
38
|
+
"@markuplint/shared": "4.0.0-dev.10+b28398ab",
|
|
40
39
|
"@types/debug": "^4.1.12",
|
|
41
|
-
"@types/uuid": "^9.0.7",
|
|
42
40
|
"chokidar": "^3.5.3",
|
|
43
|
-
"cli-color": "^2.0.3",
|
|
44
41
|
"debug": "^4.3.4",
|
|
45
|
-
"detect-installed": "^2.0.4",
|
|
46
|
-
"eastasianwidth": "^0.2.0",
|
|
47
|
-
"enquirer": "^2.4.1",
|
|
48
42
|
"get-stdin": "^9.0.0",
|
|
49
43
|
"gray-matter": "^4.0.3",
|
|
50
|
-
"has-yarn": "^3.0.0",
|
|
51
44
|
"meow": "^12.1.1",
|
|
52
45
|
"node-fetch": "^3.3.2",
|
|
53
46
|
"os-locale": "^6.0.2",
|
|
54
47
|
"strict-event-emitter": "^0.5.1",
|
|
55
48
|
"strip-ansi": "^7.1.0",
|
|
56
|
-
"type-fest": "^4.8.
|
|
57
|
-
"uuid": "^9.0.1"
|
|
49
|
+
"type-fest": "^4.8.3"
|
|
58
50
|
},
|
|
59
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "b28398ab9c8f0ad790f2915ad5da8f3a80e9b8d6"
|
|
60
52
|
}
|