1import fs from 'fs';
2
3import { unified } from 'unified';
4import remarkParse from 'remark-parse';
5import remarkStringify from 'remark-stringify';
6import presetLintNode from 'remark-preset-lint-node';
7import { read } from 'to-vfile';
8import { reporter } from 'vfile-reporter';
9
10const paths = process.argv.slice(2);
11
12if (!paths.length) {
13  console.error('Usage: lint-md.mjs <path> [<path> ...]');
14  process.exit(1);
15}
16
17let format = false;
18
19if (paths[0] === '--format') {
20  paths.shift();
21  format = true;
22}
23
24const linter = unified()
25  .use(remarkParse)
26  .use(presetLintNode)
27  .use(remarkStringify);
28
29paths.forEach(async (path) => {
30  const file = await read(path);
31  // We need to calculate `fileContents` before running `linter.process(files)`
32  // because `linter.process(files)` mutates `file` and returns it as `result`.
33  // So we won't be able to use `file` after that to see if its contents have
34  // changed as they will have been altered to the changed version.
35  const fileContents = file.toString();
36  const result = await linter.process(file);
37  const isDifferent = fileContents !== result.toString();
38  if (format) {
39    if (isDifferent) {
40      fs.writeFileSync(path, result.toString());
41    }
42  } else {
43    if (isDifferent) {
44      process.exitCode = 1;
45      const cmd = process.platform === 'win32' ? 'vcbuild' : 'make';
46      console.error(`${path} is not formatted. Please run '${cmd} format-md'.`);
47    }
48    if (result.messages.length) {
49      process.exitCode = 1;
50      console.error(reporter(result));
51    }
52  }
53});
54