markdownlint-cli2 0.4.0 → 0.5.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 +54 -30
- package/markdownlint-cli2.js +145 -64
- package/package.json +25 -25
package/README.md
CHANGED
|
@@ -20,8 +20,11 @@ As a development dependency of the current package:
|
|
|
20
20
|
npm install markdownlint-cli2 --save-dev
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
Or
|
|
24
|
-
|
|
23
|
+
Or as a Docker container image:
|
|
24
|
+
|
|
25
|
+
```shell
|
|
26
|
+
docker pull davidanson/markdownlint-cli2
|
|
27
|
+
```
|
|
25
28
|
|
|
26
29
|
## Overview
|
|
27
30
|
|
|
@@ -70,10 +73,10 @@ Dot-only glob:
|
|
|
70
73
|
Configuration via:
|
|
71
74
|
- .markdownlint-cli2.jsonc
|
|
72
75
|
- .markdownlint-cli2.yaml
|
|
73
|
-
- .markdownlint-cli2.cjs
|
|
76
|
+
- .markdownlint-cli2.cjs or .markdownlint-cli2.mjs
|
|
74
77
|
- .markdownlint.jsonc or .markdownlint.json
|
|
75
78
|
- .markdownlint.yaml or .markdownlint.yml
|
|
76
|
-
- .markdownlint.cjs
|
|
79
|
+
- .markdownlint.cjs or .markdownlint.mjs
|
|
77
80
|
|
|
78
81
|
Cross-platform compatibility:
|
|
79
82
|
- UNIX and Windows shells expand globs according to different rules; quoting arguments is recommended
|
|
@@ -87,9 +90,9 @@ $ markdownlint-cli2 "**/*.md" "#node_modules"
|
|
|
87
90
|
```
|
|
88
91
|
|
|
89
92
|
For scenarios where it is preferable to specify glob expressions in a
|
|
90
|
-
configuration file, the `globs` property of `.markdownlint-cli2.jsonc
|
|
91
|
-
`.
|
|
92
|
-
|
|
93
|
+
configuration file, the `globs` property of `.markdownlint-cli2.jsonc`, `.yaml`,
|
|
94
|
+
`.cjs`, or `.mjs` may be used instead of (or in addition to) passing
|
|
95
|
+
`glob0 ... globN` on the command-line.
|
|
93
96
|
|
|
94
97
|
As shown above, a typical command-line for `markdownlint-cli2` looks something
|
|
95
98
|
like:
|
|
@@ -116,6 +119,10 @@ accepts a path to any supported configuration file as its first argument:
|
|
|
116
119
|
markdownlint-cli2-config "config/.markdownlint-cli2.jsonc" "**/*.md" "#node_modules"
|
|
117
120
|
```
|
|
118
121
|
|
|
122
|
+
The configuration file name must be (or end with) one of the supported types
|
|
123
|
+
above. For example, `.markdownlint.json` or `example.markdownlint-cli2.jsonc`.
|
|
124
|
+
The specified configuration file will be loaded, parsed, and applied as a base
|
|
125
|
+
configuration for the current directory - which will then be handled normally.
|
|
119
126
|
Otherwise, this command behaves identically to `markdownlint-cli2`.
|
|
120
127
|
|
|
121
128
|
### Container Image
|
|
@@ -124,7 +131,7 @@ A container image [`davidanson/markdownlint-cli2`][docker-hub-markdownlint-cli2]
|
|
|
124
131
|
can also be used (e.g., as part of a CI pipeline):
|
|
125
132
|
|
|
126
133
|
```bash
|
|
127
|
-
docker run -v $PWD:/workdir davidanson/markdownlint-cli2:0.
|
|
134
|
+
docker run -v $PWD:/workdir davidanson/markdownlint-cli2:0.5.0 "**/*.md" "#node_modules"
|
|
128
135
|
```
|
|
129
136
|
|
|
130
137
|
Notes:
|
|
@@ -141,14 +148,14 @@ Notes:
|
|
|
141
148
|
- A custom working directory can be specified with Docker's `-w` flag:
|
|
142
149
|
|
|
143
150
|
```bash
|
|
144
|
-
docker run -w /myfolder -v $PWD:/myfolder davidanson/markdownlint-cli2:0.
|
|
151
|
+
docker run -w /myfolder -v $PWD:/myfolder davidanson/markdownlint-cli2:0.5.0 "**/*.md" "#node_modules"
|
|
145
152
|
```
|
|
146
153
|
|
|
147
154
|
To invoke the `markdownlint-cli2-config` or `markdownlint-cli2-fix` commands
|
|
148
155
|
instead, use Docker's `--entrypoint` flag:
|
|
149
156
|
|
|
150
157
|
```bash
|
|
151
|
-
docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/markdownlint-cli2:0.
|
|
158
|
+
docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/markdownlint-cli2:0.5.0 "**/*.md" "#node_modules"
|
|
152
159
|
```
|
|
153
160
|
|
|
154
161
|
### Exit Codes
|
|
@@ -172,11 +179,11 @@ docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/mark
|
|
|
172
179
|
- See the [Configuration][markdownlint-configuration] section of the
|
|
173
180
|
`markdownlint` documentation for information about the inline comment syntax
|
|
174
181
|
for enabling and disabling rules with HTML comments.
|
|
175
|
-
- In general, glob expressions match files under the current directory and
|
|
176
|
-
configuration for that
|
|
182
|
+
- In general, glob expressions match files under the current directory and the
|
|
183
|
+
configuration for that directory applies to the entire tree.
|
|
177
184
|
- When glob expressions match files *not* under the current directory,
|
|
178
|
-
configuration for the current
|
|
179
|
-
|
|
185
|
+
configuration for the current directory is applied to the closest common
|
|
186
|
+
parent directory.
|
|
180
187
|
|
|
181
188
|
### `.markdownlint-cli2.jsonc`
|
|
182
189
|
|
|
@@ -190,8 +197,6 @@ docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/mark
|
|
|
190
197
|
- `customRules`: `Array` of `String`s (or `Array`s of `String`s) of module
|
|
191
198
|
names/paths of [custom rules][markdownlint-custom-rules] to load and use
|
|
192
199
|
when linting
|
|
193
|
-
- Each `String` is passed as the `id` parameter to Node's
|
|
194
|
-
[require function][nodejs-require]
|
|
195
200
|
- Relative paths are resolved based on the location of the `JSONC` file
|
|
196
201
|
- Search [`markdownlint-rule` on npm][markdownlint-rule]
|
|
197
202
|
- `fix`: `Boolean` value to enable fixing of linting errors reported by rules
|
|
@@ -242,9 +247,16 @@ docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/mark
|
|
|
242
247
|
- This top-level setting is valid **only** in the directory from which
|
|
243
248
|
`markdownlint-cli2` is run
|
|
244
249
|
- Search [`markdownlint-cli2-formatter` on npm][markdownlint-cli2-formatter]
|
|
250
|
+
- When referencing a module via the `customRules`, `markdownItPlugins`, or
|
|
251
|
+
`outputFormatters` properties, each `String` identifier is passed to Node's
|
|
252
|
+
[`require` function][nodejs-require] then (if that failed) its
|
|
253
|
+
[`import` expression][nodejs-import-expression]
|
|
254
|
+
- Importing a locally-installed module using a bare specifier (ex:
|
|
255
|
+
`package-name`) or using a directory name (ex: `./package-dir`) will not
|
|
256
|
+
work until [`import.meta.resolve`][nodejs-import-meta-resolve] is available
|
|
245
257
|
- Settings in this file apply to the directory it is in and all subdirectories.
|
|
246
258
|
- Settings **merge with** those applied by any versions of this file in a parent
|
|
247
|
-
directory.
|
|
259
|
+
directory (up to the current directory).
|
|
248
260
|
- For example: [`.markdownlint-cli2.jsonc`][markdownlint-cli2-jsonc] with all
|
|
249
261
|
properties set
|
|
250
262
|
|
|
@@ -258,17 +270,20 @@ docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/mark
|
|
|
258
270
|
- For example: [`.markdownlint-cli2.yaml`][markdownlint-cli2-yaml] with all
|
|
259
271
|
properties set
|
|
260
272
|
|
|
261
|
-
### `.markdownlint-cli2.cjs`
|
|
273
|
+
### `.markdownlint-cli2.cjs` or `.markdownlint-cli2.mjs`
|
|
262
274
|
|
|
263
|
-
- The format of this file is a [CommonJS module][commonjs-module]
|
|
264
|
-
|
|
275
|
+
- The format of this file is a [CommonJS module][commonjs-module] (`.cjs`) or
|
|
276
|
+
[ECMAScript module][ecmascript-module] (`.mjs`) that exports the object
|
|
277
|
+
described above for `.markdownlint-cli2.jsonc`.
|
|
265
278
|
- Instead of passing a `String` to identify the module name/path to load for
|
|
266
279
|
`customRules`, `markdownItPlugins`, and `outputFormatters`, the corresponding
|
|
267
280
|
`Object` or `Function` can be provided directly.
|
|
268
281
|
- Other details are the same as for `.markdownlint-cli2.jsonc` described above.
|
|
269
282
|
- If a `.markdownlint-cli2.jsonc` or `.markdownlint-cli2.yaml` file is present
|
|
270
|
-
in the same directory, it takes precedence.
|
|
271
|
-
|
|
283
|
+
in the same directory, it takes precedence; `.markdownlint-cli2.cjs` takes
|
|
284
|
+
precedence over `.markdownlint-cli2.mjs`.
|
|
285
|
+
- For example: [`.markdownlint-cli2.cjs`][markdownlint-cli2-cjs] or
|
|
286
|
+
[`.markdownlint-cli2.mjs`][markdownlint-cli2-mjs]
|
|
272
287
|
|
|
273
288
|
### `.markdownlint.jsonc` or `.markdownlint.json`
|
|
274
289
|
|
|
@@ -276,7 +291,7 @@ docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/mark
|
|
|
276
291
|
the [`markdownlint` `config` object][markdownlint-config].
|
|
277
292
|
- Settings in this file apply to the directory it is in and all subdirectories
|
|
278
293
|
- Settings **override** those applied by any versions of this file in a parent
|
|
279
|
-
directory.
|
|
294
|
+
directory (up to the current directory).
|
|
280
295
|
- If `jsonc` and `json` files are present in the same directory, the `jsonc`
|
|
281
296
|
version takes precedence.
|
|
282
297
|
- To merge the settings of these files or share configuration, use the `extends`
|
|
@@ -295,14 +310,17 @@ docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/mark
|
|
|
295
310
|
precedence.
|
|
296
311
|
- For example: [`.markdownlint.yaml`][markdownlint-yaml]
|
|
297
312
|
|
|
298
|
-
### `.markdownlint.cjs`
|
|
313
|
+
### `.markdownlint.cjs` or `.markdownlint.mjs`
|
|
299
314
|
|
|
300
|
-
- The format of this file is a [CommonJS module][commonjs-module]
|
|
301
|
-
|
|
315
|
+
- The format of this file is a [CommonJS module][commonjs-module] (`.cjs`) or
|
|
316
|
+
[ECMAScript module][ecmascript-module] (`.mjs`) that exports the
|
|
317
|
+
[`markdownlint` `config` object][markdownlint-config].
|
|
302
318
|
- Other details are the same as for `jsonc`/`json` files described above.
|
|
303
|
-
- If a
|
|
304
|
-
it takes precedence.
|
|
305
|
-
|
|
319
|
+
- If a `.markdownlint.jsonc`, `.json`, `.yaml`, or `.yml` file is present in the
|
|
320
|
+
same directory, it takes precedence; `.markdownlint.cjs` takes precedence over
|
|
321
|
+
`.markdownlint.mjs`.
|
|
322
|
+
- For example: [`.markdownlint.cjs`][markdownlint-cjs] or
|
|
323
|
+
[`.markdownlint.mjs`][markdownlint-mjs]
|
|
306
324
|
|
|
307
325
|
## Compatibility
|
|
308
326
|
|
|
@@ -326,7 +344,7 @@ reference to the `repos` list in that project's `.pre-commit-config.yaml` like:
|
|
|
326
344
|
|
|
327
345
|
```yaml
|
|
328
346
|
- repo: https://github.com/DavidAnson/markdownlint-cli2
|
|
329
|
-
rev: v0.
|
|
347
|
+
rev: v0.5.0
|
|
330
348
|
hooks:
|
|
331
349
|
- id: markdownlint-cli2
|
|
332
350
|
```
|
|
@@ -359,11 +377,13 @@ reference to the `repos` list in that project's `.pre-commit-config.yaml` like:
|
|
|
359
377
|
- 0.3.1 - Extensibility tweaks
|
|
360
378
|
- 0.3.2 - Extensibility/Windows/consistency improvements
|
|
361
379
|
- 0.4.0 - New rules, async custom rules, explicit config, CJS (breaking)
|
|
380
|
+
- 0.5.0 - New rules, support modules (MJS) everywhere, include dotfiles
|
|
362
381
|
|
|
363
382
|
<!-- markdownlint-disable line-length -->
|
|
364
383
|
|
|
365
384
|
[commonmark]: https://commonmark.org/
|
|
366
385
|
[commonjs-module]: https://nodejs.org/api/modules.html#modules_modules_commonjs_modules
|
|
386
|
+
[ecmascript-module]: https://nodejs.org/api/esm.html#modules-ecmascript-modules
|
|
367
387
|
[docker-bind-mounts]: https://docs.docker.com/storage/bind-mounts/
|
|
368
388
|
[docker-hub-markdownlint-cli2]: https://hub.docker.com/r/davidanson/markdownlint-cli2
|
|
369
389
|
[front-matter]: https://jekyllrb.com/docs/frontmatter/
|
|
@@ -390,14 +410,18 @@ reference to the `repos` list in that project's `.pre-commit-config.yaml` like:
|
|
|
390
410
|
[markdownlint-cli2-formatter]: https://www.npmjs.com/search?q=keywords:markdownlint-cli2-formatter
|
|
391
411
|
[markdownlint-cli2-cjs]: test/markdownlint-cli2-cjs/.markdownlint-cli2.cjs
|
|
392
412
|
[markdownlint-cli2-jsonc]: test/markdownlint-cli2-jsonc-example/.markdownlint-cli2.jsonc
|
|
413
|
+
[markdownlint-cli2-mjs]: test/markdownlint-cli2-mjs/.markdownlint-cli2.mjs
|
|
393
414
|
[markdownlint-cli2-yaml]: test/markdownlint-cli2-yaml-example/.markdownlint-cli2.yaml
|
|
394
415
|
[markdownlint-cjs]: test/markdownlint-cjs/.markdownlint.cjs
|
|
395
416
|
[markdownlint-jsonc]: https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.jsonc
|
|
417
|
+
[markdownlint-mjs]: test/markdownlint-mjs/.markdownlint.mjs
|
|
396
418
|
[markdownlint-rule]: https://www.npmjs.com/search?q=keywords:markdownlint-rule
|
|
397
419
|
[markdownlint-yaml]: https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.yaml
|
|
398
420
|
[nodejs]: https://nodejs.org/
|
|
399
421
|
[nodejs-docker]: https://github.com/nodejs/docker-node
|
|
400
422
|
[nodejs-docker-non-root]: https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#non-root-user
|
|
423
|
+
[nodejs-import-expression]: https://nodejs.org/api/esm.html#import-expressions
|
|
424
|
+
[nodejs-import-meta-resolve]: https://nodejs.org/api/esm.html#importmetaresolvespecifier-parent
|
|
401
425
|
[nodejs-require]: https://nodejs.org/api/modules.html#modules_require_id
|
|
402
426
|
[npm-image]: https://img.shields.io/npm/v/markdownlint-cli2.svg
|
|
403
427
|
[npm-url]: https://www.npmjs.com/package/markdownlint-cli2
|
package/markdownlint-cli2.js
CHANGED
|
@@ -10,18 +10,19 @@ const dynamicRequire = (typeof __non_webpack_require__ === "undefined") ? requir
|
|
|
10
10
|
// Capture native require implementation for dynamic loading of modules
|
|
11
11
|
|
|
12
12
|
// Requires
|
|
13
|
-
const path = require("path");
|
|
13
|
+
const path = require("node:path");
|
|
14
|
+
const { pathToFileURL } = require("node:url");
|
|
14
15
|
const markdownlintLibrary = require("markdownlint");
|
|
15
16
|
const { markdownlint, "readConfig": markdownlintReadConfig } =
|
|
16
17
|
markdownlintLibrary.promises;
|
|
17
|
-
const markdownlintRuleHelpers = require("markdownlint
|
|
18
|
+
const markdownlintRuleHelpers = require("markdownlint/helpers");
|
|
18
19
|
const appendToArray = require("./append-to-array");
|
|
19
20
|
const mergeOptions = require("./merge-options");
|
|
20
21
|
const resolveAndRequire = require("./resolve-and-require");
|
|
21
22
|
|
|
22
23
|
// Variables
|
|
23
24
|
const packageName = "markdownlint-cli2";
|
|
24
|
-
const packageVersion = "0.
|
|
25
|
+
const packageVersion = "0.5.0";
|
|
25
26
|
const libraryName = "markdownlint";
|
|
26
27
|
const libraryVersion = markdownlintLibrary.getVersion();
|
|
27
28
|
const dotOnlySubstitute = "*.{md,markdown}";
|
|
@@ -64,41 +65,59 @@ const readConfig = (fs, dir, name, otherwise) => {
|
|
|
64
65
|
);
|
|
65
66
|
};
|
|
66
67
|
|
|
67
|
-
//
|
|
68
|
-
const
|
|
68
|
+
// Import or resolve/require a module ID with a custom directory in the path
|
|
69
|
+
const importOrRequireResolve = async (dir, id) => {
|
|
69
70
|
if (typeof id === "string") {
|
|
70
|
-
|
|
71
|
+
const expandId =
|
|
72
|
+
markdownlintRuleHelpers.expandTildePath(id, require("node:os"));
|
|
73
|
+
const errors = [];
|
|
74
|
+
try {
|
|
75
|
+
return resolveAndRequire(dynamicRequire, expandId, dir);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
errors.push(error);
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const fileUrlString =
|
|
81
|
+
pathToFileURL(path.resolve(dir, expandId)).toString();
|
|
82
|
+
// eslint-disable-next-line node/no-unsupported-features/es-syntax
|
|
83
|
+
const module = await import(fileUrlString);
|
|
84
|
+
return module.default;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
errors.push(error);
|
|
87
|
+
}
|
|
88
|
+
// Use AggregateError once available in Node 15+
|
|
89
|
+
throw new Error(errors.map((error) => error.message).join(" / "));
|
|
71
90
|
}
|
|
72
91
|
return id;
|
|
73
92
|
};
|
|
74
93
|
|
|
75
|
-
//
|
|
76
|
-
const
|
|
77
|
-
noRequire ? [] : ids.map((id) =>
|
|
94
|
+
// Import or require an array of modules by ID
|
|
95
|
+
const importOrRequireIds = (dir, ids, noRequire) => (
|
|
96
|
+
Promise.all(noRequire ? [] : ids.map((id) => importOrRequireResolve(dir, id)))
|
|
78
97
|
);
|
|
79
98
|
|
|
80
|
-
//
|
|
81
|
-
const
|
|
99
|
+
// Import or require an array of modules by ID (preserving parameters)
|
|
100
|
+
const importOrRequireIdsAndParams = async (dir, idsAndParams, noRequire) => {
|
|
82
101
|
if (noRequire) {
|
|
83
102
|
return [];
|
|
84
103
|
}
|
|
85
104
|
const ids = idsAndParams.map((entry) => entry[0]);
|
|
86
|
-
const modules =
|
|
105
|
+
const modules = await importOrRequireIds(dir, ids);
|
|
87
106
|
const modulesAndParams = idsAndParams.
|
|
88
107
|
map((entry, i) => [ modules[i], ...entry.slice(1) ]);
|
|
89
108
|
return modulesAndParams;
|
|
90
109
|
};
|
|
91
110
|
|
|
92
|
-
//
|
|
93
|
-
const
|
|
111
|
+
// Import or require a JavaScript file and return the exported object
|
|
112
|
+
const importOrRequireConfig = (fs, dir, name, noRequire, otherwise) => (
|
|
94
113
|
() => (noRequire
|
|
95
114
|
// eslint-disable-next-line prefer-promise-reject-errors
|
|
96
115
|
? Promise.reject()
|
|
97
116
|
: fs.promises.access(path.posix.join(dir, name))
|
|
98
117
|
).
|
|
99
118
|
then(
|
|
100
|
-
() =>
|
|
101
|
-
|
|
119
|
+
() => importOrRequireResolve(dir, `./${name}`),
|
|
120
|
+
otherwise
|
|
102
121
|
)
|
|
103
122
|
);
|
|
104
123
|
|
|
@@ -113,8 +132,13 @@ const readOptionsOrConfig = async (configPath, fs, noRequire) => {
|
|
|
113
132
|
options = jsoncParse(await fs.promises.readFile(configPath, utf8));
|
|
114
133
|
} else if (basename.endsWith(".markdownlint-cli2.yaml")) {
|
|
115
134
|
options = yamlParse(await fs.promises.readFile(configPath, utf8));
|
|
116
|
-
} else if (
|
|
117
|
-
|
|
135
|
+
} else if (
|
|
136
|
+
basename.endsWith(".markdownlint-cli2.cjs") ||
|
|
137
|
+
basename.endsWith(".markdownlint-cli2.mjs")
|
|
138
|
+
) {
|
|
139
|
+
options = await (
|
|
140
|
+
importOrRequireConfig(fs, dirname, basename, noRequire, noop)()
|
|
141
|
+
);
|
|
118
142
|
} else if (
|
|
119
143
|
basename.endsWith(".markdownlint.jsonc") ||
|
|
120
144
|
basename.endsWith(".markdownlint.json") ||
|
|
@@ -124,8 +148,19 @@ const readOptionsOrConfig = async (configPath, fs, noRequire) => {
|
|
|
124
148
|
const jsoncParse = await getJsoncParse();
|
|
125
149
|
config =
|
|
126
150
|
await markdownlintReadConfig(configPath, [ jsoncParse, yamlParse ], fs);
|
|
127
|
-
} else if (
|
|
128
|
-
|
|
151
|
+
} else if (
|
|
152
|
+
basename.endsWith(".markdownlint.cjs") ||
|
|
153
|
+
basename.endsWith(".markdownlint.mjs")
|
|
154
|
+
) {
|
|
155
|
+
config = await (
|
|
156
|
+
importOrRequireConfig(fs, dirname, basename, noRequire, noop)()
|
|
157
|
+
);
|
|
158
|
+
} else {
|
|
159
|
+
throw new Error(
|
|
160
|
+
`Configuration file "${configPath}" is unrecognized; ` +
|
|
161
|
+
"its name should be (or end with) one of the supported types " +
|
|
162
|
+
"(e.g., \".markdownlint.json\" or \"example.markdownlint-cli2.jsonc\")."
|
|
163
|
+
);
|
|
129
164
|
}
|
|
130
165
|
return options || { config };
|
|
131
166
|
};
|
|
@@ -188,10 +223,10 @@ Dot-only glob:
|
|
|
188
223
|
Configuration via:
|
|
189
224
|
- .markdownlint-cli2.jsonc
|
|
190
225
|
- .markdownlint-cli2.yaml
|
|
191
|
-
- .markdownlint-cli2.cjs
|
|
226
|
+
- .markdownlint-cli2.cjs or .markdownlint-cli2.mjs
|
|
192
227
|
- .markdownlint.jsonc or .markdownlint.json
|
|
193
228
|
- .markdownlint.yaml or .markdownlint.yml
|
|
194
|
-
- .markdownlint.cjs
|
|
229
|
+
- .markdownlint.cjs or .markdownlint.mjs
|
|
195
230
|
|
|
196
231
|
Cross-platform compatibility:
|
|
197
232
|
- UNIX and Windows shells expand globs according to different rules; quoting arguments is recommended
|
|
@@ -208,11 +243,12 @@ $ markdownlint-cli2 "**/*.md" "#node_modules"`
|
|
|
208
243
|
|
|
209
244
|
// Get (creating if necessary) and process a directory's info object
|
|
210
245
|
const getAndProcessDirInfo =
|
|
211
|
-
(fs, tasks, dirToDirInfo, dir, noRequire, func) => {
|
|
246
|
+
(fs, tasks, dirToDirInfo, dir, relativeDir, noRequire, func) => {
|
|
212
247
|
let dirInfo = dirToDirInfo[dir];
|
|
213
248
|
if (!dirInfo) {
|
|
214
249
|
dirInfo = {
|
|
215
250
|
dir,
|
|
251
|
+
relativeDir,
|
|
216
252
|
"parent": null,
|
|
217
253
|
"files": [],
|
|
218
254
|
"markdownlintConfig": null,
|
|
@@ -239,11 +275,18 @@ const getAndProcessDirInfo =
|
|
|
239
275
|
() => fs.promises.
|
|
240
276
|
readFile(markdownlintCli2Yaml, utf8).
|
|
241
277
|
then(yamlParse),
|
|
242
|
-
|
|
278
|
+
importOrRequireConfig(
|
|
243
279
|
fs,
|
|
244
280
|
dir,
|
|
245
281
|
".markdownlint-cli2.cjs",
|
|
246
|
-
noRequire
|
|
282
|
+
noRequire,
|
|
283
|
+
importOrRequireConfig(
|
|
284
|
+
fs,
|
|
285
|
+
dir,
|
|
286
|
+
".markdownlint-cli2.mjs",
|
|
287
|
+
noRequire,
|
|
288
|
+
noop
|
|
289
|
+
)
|
|
247
290
|
)
|
|
248
291
|
)
|
|
249
292
|
).
|
|
@@ -270,11 +313,18 @@ const getAndProcessDirInfo =
|
|
|
270
313
|
fs,
|
|
271
314
|
dir,
|
|
272
315
|
".markdownlint.yml",
|
|
273
|
-
|
|
316
|
+
importOrRequireConfig(
|
|
274
317
|
fs,
|
|
275
318
|
dir,
|
|
276
319
|
".markdownlint.cjs",
|
|
277
|
-
noRequire
|
|
320
|
+
noRequire,
|
|
321
|
+
importOrRequireConfig(
|
|
322
|
+
fs,
|
|
323
|
+
dir,
|
|
324
|
+
".markdownlint.mjs",
|
|
325
|
+
noRequire,
|
|
326
|
+
noop
|
|
327
|
+
)
|
|
278
328
|
)
|
|
279
329
|
)
|
|
280
330
|
)
|
|
@@ -297,20 +347,28 @@ const getAndProcessDirInfo =
|
|
|
297
347
|
const getBaseOptions = async (
|
|
298
348
|
fs,
|
|
299
349
|
baseDir,
|
|
350
|
+
relativeDir,
|
|
300
351
|
globPatterns,
|
|
301
|
-
|
|
352
|
+
options,
|
|
302
353
|
fixDefault,
|
|
303
354
|
noGlobs,
|
|
304
355
|
noRequire
|
|
305
356
|
) => {
|
|
306
357
|
const tasks = [];
|
|
307
358
|
const dirToDirInfo = {};
|
|
308
|
-
getAndProcessDirInfo(
|
|
359
|
+
getAndProcessDirInfo(
|
|
360
|
+
fs,
|
|
361
|
+
tasks,
|
|
362
|
+
dirToDirInfo,
|
|
363
|
+
baseDir,
|
|
364
|
+
relativeDir,
|
|
365
|
+
noRequire
|
|
366
|
+
);
|
|
309
367
|
await Promise.all(tasks);
|
|
310
368
|
// eslint-disable-next-line no-multi-assign
|
|
311
369
|
const baseMarkdownlintOptions = dirToDirInfo[baseDir].markdownlintOptions =
|
|
312
370
|
mergeOptions(
|
|
313
|
-
mergeOptions(
|
|
371
|
+
mergeOptions(options, { "fix": fixDefault }),
|
|
314
372
|
dirToDirInfo[baseDir].markdownlintOptions
|
|
315
373
|
);
|
|
316
374
|
|
|
@@ -340,6 +398,7 @@ async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, noErrors, noRequi
|
|
|
340
398
|
const globbyOptions = {
|
|
341
399
|
"absolute": true,
|
|
342
400
|
"cwd": baseDir,
|
|
401
|
+
"dot": true,
|
|
343
402
|
"expandDirectories": false,
|
|
344
403
|
fs
|
|
345
404
|
};
|
|
@@ -400,6 +459,7 @@ async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, noErrors, noRequi
|
|
|
400
459
|
tasks,
|
|
401
460
|
dirToDirInfo,
|
|
402
461
|
dir,
|
|
462
|
+
null,
|
|
403
463
|
noRequire,
|
|
404
464
|
(dirInfo) => {
|
|
405
465
|
dirInfo.files.push(file);
|
|
@@ -437,6 +497,7 @@ const enumerateParents = async (fs, baseDir, dirToDirInfo, noRequire) => {
|
|
|
437
497
|
tasks,
|
|
438
498
|
dirToDirInfo,
|
|
439
499
|
dir,
|
|
500
|
+
null,
|
|
440
501
|
noRequire,
|
|
441
502
|
// eslint-disable-next-line no-loop-func
|
|
442
503
|
(dirInfo) => {
|
|
@@ -478,11 +539,13 @@ async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, optionsOverride,
|
|
|
478
539
|
dirs.sort((a, b) => b.length - a.length);
|
|
479
540
|
const dirInfos = [];
|
|
480
541
|
const noConfigDirInfo =
|
|
542
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
481
543
|
(dirInfo) => (
|
|
482
544
|
dirInfo.parent &&
|
|
483
545
|
!dirInfo.markdownlintConfig &&
|
|
484
546
|
!dirInfo.markdownlintOptions
|
|
485
547
|
);
|
|
548
|
+
const tasks = [];
|
|
486
549
|
for (const dir of dirs) {
|
|
487
550
|
const dirInfo = dirToDirInfo[dir];
|
|
488
551
|
if (noConfigDirInfo(dirInfo)) {
|
|
@@ -491,28 +554,34 @@ async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, optionsOverride,
|
|
|
491
554
|
}
|
|
492
555
|
dirToDirInfo[dir] = null;
|
|
493
556
|
} else {
|
|
494
|
-
const { markdownlintOptions } = dirInfo;
|
|
557
|
+
const { markdownlintOptions, relativeDir } = dirInfo;
|
|
495
558
|
if (markdownlintOptions && markdownlintOptions.customRules) {
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
dir,
|
|
559
|
+
tasks.push(
|
|
560
|
+
importOrRequireIds(
|
|
561
|
+
relativeDir || dir,
|
|
499
562
|
markdownlintOptions.customRules,
|
|
500
563
|
noRequire
|
|
501
|
-
)
|
|
502
|
-
|
|
503
|
-
|
|
564
|
+
).then((customRules) => {
|
|
565
|
+
// Expand nested arrays (for packages that export multiple rules)
|
|
566
|
+
markdownlintOptions.customRules = customRules.flat();
|
|
567
|
+
})
|
|
568
|
+
);
|
|
504
569
|
}
|
|
505
570
|
if (markdownlintOptions && markdownlintOptions.markdownItPlugins) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
dir,
|
|
571
|
+
tasks.push(
|
|
572
|
+
importOrRequireIdsAndParams(
|
|
573
|
+
relativeDir || dir,
|
|
509
574
|
markdownlintOptions.markdownItPlugins,
|
|
510
575
|
noRequire
|
|
511
|
-
)
|
|
576
|
+
).then((markdownItPlugins) => {
|
|
577
|
+
markdownlintOptions.markdownItPlugins = markdownItPlugins;
|
|
578
|
+
})
|
|
579
|
+
);
|
|
512
580
|
}
|
|
513
581
|
dirInfos.push(dirInfo);
|
|
514
582
|
}
|
|
515
583
|
}
|
|
584
|
+
await Promise.all(tasks);
|
|
516
585
|
for (const dirInfo of dirInfos) {
|
|
517
586
|
while (dirInfo.parent && !dirToDirInfo[dirInfo.parent.dir]) {
|
|
518
587
|
dirInfo.parent = dirInfo.parent.parent;
|
|
@@ -578,7 +647,8 @@ async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, optionsOverride,
|
|
|
578
647
|
};
|
|
579
648
|
|
|
580
649
|
// Lint files in groups by shared configuration
|
|
581
|
-
const lintFiles = (fs, dirInfos, fileContents) => {
|
|
650
|
+
const lintFiles = async (fs, dirInfos, fileContents) => {
|
|
651
|
+
const jsoncParse = await getJsoncParse();
|
|
582
652
|
const tasks = [];
|
|
583
653
|
// For each dirInfo
|
|
584
654
|
for (const dirInfo of dirInfos) {
|
|
@@ -607,6 +677,7 @@ const lintFiles = (fs, dirInfos, fileContents) => {
|
|
|
607
677
|
"files": filteredFiles,
|
|
608
678
|
"strings": filteredStrings,
|
|
609
679
|
"config": markdownlintConfig || markdownlintOptions.config,
|
|
680
|
+
"configParsers": [ jsoncParse ],
|
|
610
681
|
"customRules": markdownlintOptions.customRules,
|
|
611
682
|
"frontMatter": markdownlintOptions.frontMatter
|
|
612
683
|
? new RegExp(markdownlintOptions.frontMatter, "u")
|
|
@@ -688,26 +759,33 @@ const createSummary = (baseDir, taskResults) => {
|
|
|
688
759
|
};
|
|
689
760
|
|
|
690
761
|
// Output summary via formatters
|
|
691
|
-
const outputSummary =
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
762
|
+
const outputSummary = async (
|
|
763
|
+
baseDir,
|
|
764
|
+
relativeDir,
|
|
765
|
+
summary,
|
|
766
|
+
outputFormatters,
|
|
767
|
+
logMessage,
|
|
768
|
+
logError
|
|
769
|
+
) => {
|
|
770
|
+
const errorsPresent = (summary.length > 0);
|
|
771
|
+
if (errorsPresent || outputFormatters) {
|
|
772
|
+
const formatterOptions = {
|
|
773
|
+
"directory": baseDir,
|
|
774
|
+
"results": summary,
|
|
775
|
+
logMessage,
|
|
776
|
+
logError
|
|
777
|
+
};
|
|
778
|
+
const dir = relativeDir || baseDir;
|
|
779
|
+
const formattersAndParams = outputFormatters
|
|
780
|
+
? await importOrRequireIdsAndParams(dir, outputFormatters)
|
|
781
|
+
: [ [ require("markdownlint-cli2-formatter-default") ] ];
|
|
782
|
+
await Promise.all(formattersAndParams.map((formatterAndParams) => {
|
|
783
|
+
const [ formatter, ...formatterParams ] = formatterAndParams;
|
|
784
|
+
return formatter(formatterOptions, ...formatterParams);
|
|
785
|
+
}));
|
|
786
|
+
}
|
|
787
|
+
return errorsPresent;
|
|
788
|
+
};
|
|
711
789
|
|
|
712
790
|
// Main function
|
|
713
791
|
const main = async (params) => {
|
|
@@ -727,7 +805,7 @@ const main = async (params) => {
|
|
|
727
805
|
} = params;
|
|
728
806
|
const logMessage = params.logMessage || noop;
|
|
729
807
|
const logError = params.logError || noop;
|
|
730
|
-
const fs = params.fs || require("fs");
|
|
808
|
+
const fs = params.fs || require("node:fs");
|
|
731
809
|
const baseDirSystem =
|
|
732
810
|
(directory && path.resolve(directory)) ||
|
|
733
811
|
process.cwd();
|
|
@@ -739,10 +817,12 @@ const main = async (params) => {
|
|
|
739
817
|
);
|
|
740
818
|
// Read argv configuration file (if relevant and present)
|
|
741
819
|
let optionsArgv = null;
|
|
820
|
+
let relativeDir = null;
|
|
742
821
|
const [ configPath ] = (argv || []);
|
|
743
822
|
if ((name === "markdownlint-cli2-config") && configPath) {
|
|
744
823
|
optionsArgv =
|
|
745
824
|
await readOptionsOrConfig(configPath, fs, noRequire);
|
|
825
|
+
relativeDir = path.dirname(configPath);
|
|
746
826
|
}
|
|
747
827
|
// Process arguments and get base options
|
|
748
828
|
const globPatterns = processArgv(optionsArgv ? argv.slice(1) : argv);
|
|
@@ -750,6 +830,7 @@ const main = async (params) => {
|
|
|
750
830
|
await getBaseOptions(
|
|
751
831
|
fs,
|
|
752
832
|
baseDir,
|
|
833
|
+
relativeDir,
|
|
753
834
|
globPatterns,
|
|
754
835
|
optionsArgv || optionsDefault,
|
|
755
836
|
fixDefault,
|
|
@@ -810,7 +891,7 @@ const main = async (params) => {
|
|
|
810
891
|
(optionsOverride && optionsOverride.outputFormatters) ||
|
|
811
892
|
baseMarkdownlintOptions.outputFormatters;
|
|
812
893
|
const errorsPresent = await outputSummary(
|
|
813
|
-
baseDir, summary, outputFormatters, logMessage, logError
|
|
894
|
+
baseDir, relativeDir, summary, outputFormatters, logMessage, logError
|
|
814
895
|
);
|
|
815
896
|
// Return result
|
|
816
897
|
return errorsPresent ? 1 : 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "markdownlint-cli2",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A fast, flexible, configuration-based command-line interface for linting Markdown/CommonMark files with the `markdownlint` library",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "David Anson",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"type": "commonjs",
|
|
11
|
-
"
|
|
11
|
+
"exports": "./markdownlint-cli2.js",
|
|
12
12
|
"bin": {
|
|
13
13
|
"markdownlint-cli2": "markdownlint-cli2.js",
|
|
14
14
|
"markdownlint-cli2-config": "markdownlint-cli2-config.js",
|
|
@@ -21,24 +21,26 @@
|
|
|
21
21
|
},
|
|
22
22
|
"bugs": "https://github.com/DavidAnson/markdownlint-cli2/issues",
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build-docker-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker build -t davidanson/markdownlint-cli2
|
|
24
|
+
"build-docker-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker build -t davidanson/markdownlint-cli2:v$VERSION -f docker/Dockerfile --label org.opencontainers.image.version=v$VERSION .",
|
|
25
25
|
"ci": "npm-run-all --continue-on-error --parallel test-cover lint",
|
|
26
26
|
"docker-npm-install": "docker run --rm --tty --name npm-install --volume $PWD:/home/workdir --workdir /home/workdir --user node node:16 npm install",
|
|
27
27
|
"docker-npm-run-upgrade": "docker run --rm --tty --name npm-run-upgrade --volume $PWD:/home/workdir --workdir /home/workdir --user node node:16 npm run upgrade",
|
|
28
28
|
"lint": "eslint --max-warnings 0 .",
|
|
29
29
|
"lint-dockerfile": "docker run --rm -i hadolint/hadolint:latest-alpine < docker/Dockerfile",
|
|
30
30
|
"lint-watch": "git ls-files | entr npm run lint",
|
|
31
|
-
"publish-docker-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker buildx build --platform linux/arm64,linux/amd64 -t davidanson/markdownlint-cli2
|
|
31
|
+
"publish-docker-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker buildx build --platform linux/arm64,linux/amd64 -t davidanson/markdownlint-cli2:v$VERSION -t davidanson/markdownlint-cli2:latest -f docker/Dockerfile --push .",
|
|
32
32
|
"test": "ava --timeout=1m test/append-to-array-test.js test/fs-mock-test.js test/markdownlint-cli2-test.js test/markdownlint-cli2-test-exec.js test/markdownlint-cli2-test-fs.js test/markdownlint-cli2-test-main.js test/merge-options-test.js test/resolve-and-require-test.js",
|
|
33
|
-
"test-docker-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2
|
|
34
|
-
"test-docker-hub-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker image rm davidanson/markdownlint-cli2
|
|
33
|
+
"test-docker-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2:v$VERSION \"*.md\"",
|
|
34
|
+
"test-docker-hub-image": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker image rm davidanson/markdownlint-cli2:v$VERSION davidanson/markdownlint-cli2:latest || true && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2:v$VERSION \"*.md\" && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2:latest \"*.md\"",
|
|
35
35
|
"test-cover": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 npm test",
|
|
36
36
|
"test-watch": "git ls-files | entr npm run test",
|
|
37
37
|
"update-snapshots": "ava --update-snapshots test/markdownlint-cli2-test-exec.js test/markdownlint-cli2-test-fs.js test/markdownlint-cli2-test-main.js",
|
|
38
|
-
"upgrade": "npx --yes npm-check-updates --upgrade"
|
|
38
|
+
"upgrade": "npx --yes npm-check-updates --upgrade",
|
|
39
|
+
"webworker": "cd webworker && webpack --mode none",
|
|
40
|
+
"webworker-install": "npm run docker-npm-install -- --no-save path-browserify process setimmediate stream-browserify url util webpack-cli"
|
|
39
41
|
},
|
|
40
42
|
"engines": {
|
|
41
|
-
"node": ">=
|
|
43
|
+
"node": ">=14"
|
|
42
44
|
},
|
|
43
45
|
"files": [
|
|
44
46
|
"append-to-array.js",
|
|
@@ -49,31 +51,29 @@
|
|
|
49
51
|
"resolve-and-require.js"
|
|
50
52
|
],
|
|
51
53
|
"dependencies": {
|
|
52
|
-
"globby": "
|
|
53
|
-
"markdownlint": "0.
|
|
54
|
+
"globby": "13.1.2",
|
|
55
|
+
"markdownlint": "0.26.1",
|
|
54
56
|
"markdownlint-cli2-formatter-default": "0.0.3",
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"yaml": "1.10.2"
|
|
57
|
+
"micromatch": "4.0.5",
|
|
58
|
+
"strip-json-comments": "5.0.0",
|
|
59
|
+
"yaml": "2.1.1"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
62
|
"@iktakahiro/markdown-it-katex": "4.0.1",
|
|
62
|
-
"ava": "4.
|
|
63
|
-
"c8": "7.
|
|
64
|
-
"cpy": "
|
|
65
|
-
"del": "
|
|
66
|
-
"eslint": "8.
|
|
63
|
+
"ava": "4.3.1",
|
|
64
|
+
"c8": "7.12.0",
|
|
65
|
+
"cpy": "9.0.1",
|
|
66
|
+
"del": "7.0.0",
|
|
67
|
+
"eslint": "8.20.0",
|
|
67
68
|
"eslint-plugin-node": "11.1.0",
|
|
68
|
-
"eslint-plugin-unicorn": "
|
|
69
|
-
"execa": "6.
|
|
70
|
-
"markdown-it-emoji": "2.0.
|
|
69
|
+
"eslint-plugin-unicorn": "43.0.2",
|
|
70
|
+
"execa": "6.1.0",
|
|
71
|
+
"markdown-it-emoji": "2.0.2",
|
|
71
72
|
"markdown-it-for-inline": "0.1.1",
|
|
72
|
-
"markdownlint-cli2-formatter-json": "0.0.
|
|
73
|
-
"markdownlint-cli2-formatter-junit": "0.0.
|
|
73
|
+
"markdownlint-cli2-formatter-json": "0.0.6",
|
|
74
|
+
"markdownlint-cli2-formatter-junit": "0.0.5",
|
|
74
75
|
"markdownlint-cli2-formatter-pretty": "0.0.3",
|
|
75
76
|
"markdownlint-cli2-formatter-summarize": "0.0.5",
|
|
76
|
-
"markdownlint-rule-github-internal-links": "0.1.0",
|
|
77
77
|
"markdownlint-rule-titlecase": "0.1.0",
|
|
78
78
|
"npm-run-all": "4.1.5"
|
|
79
79
|
},
|