diff --git a/.github/dictionary.txt b/.github/dictionary.txt
index bb41cdce..777dfd4a 100644
--- a/.github/dictionary.txt
+++ b/.github/dictionary.txt
@@ -1,6 +1,8 @@
-async
+Async
CJS
+Changelog
CLI
+CodeClimate
CommonJS
CommonMark
config
@@ -8,6 +10,7 @@ dotfiles
formatter
formatters
Formatters
+GitLab
Globbing
globby
Homebrew
@@ -15,6 +18,7 @@ JSON
JSONC
JUnit
markdownlint-cli2
+markdownlint-cli2-formatter-codequality
markdownlint-cli2-formatter-default
markdownlint-cli2-formatter-json
markdownlint-cli2-formatter-junit
diff --git a/.github/workflows/checkers.yml b/.github/workflows/checkers.yml
index 5a33d7ba..783dfd22 100644
--- a/.github/workflows/checkers.yml
+++ b/.github/workflows/checkers.yml
@@ -3,6 +3,8 @@ name: Checkers
on:
pull_request:
push:
+ branches-ignore:
+ - 'dependabot/**'
schedule:
- cron: '30 12 * * *'
workflow_dispatch:
@@ -16,7 +18,7 @@ jobs:
- uses: JustinBeckwith/linkinator-action@v1.10.4
with:
linksToSkip: '^https://github.com/.*/search\?q= ^https://opensource.org/'
- paths: '*.md formatter-default/*.md formatter-json/*.md formatter-junit/*.md formatter-pretty/*.md formatter-summarize/*.md'
+ paths: '*.md doc/*.md formatter-*/*.md'
spellcheck:
runs-on: ubuntu-latest
@@ -25,4 +27,4 @@ jobs:
- uses: tbroadley/spellchecker-cli-action@v1
with:
dictionaries: '.github/dictionary.txt'
- files: '*.md formatter-default/*.md formatter-json/*.md formatter-junit/*.md formatter-pretty/*.md formatter-summarize/*.md'
+ files: '*.md doc/*.md formatter-*/*.md'
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0f4ad306..7f6ad1b8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -3,6 +3,8 @@ name: CI
on:
pull_request:
push:
+ branches-ignore:
+ - 'dependabot/**'
schedule:
- cron: '30 12 * * *'
workflow_dispatch:
@@ -14,11 +16,14 @@ jobs:
strategy:
fail-fast: false
matrix:
- os: [macos-latest, ubuntu-latest, windows-latest]
- node-version: [14.x, 16.x, 18.x]
+ os: [ macos-latest, ubuntu-latest, windows-latest ]
+ node-version: [ 14, 16, 18, 20 ]
steps:
- uses: actions/checkout@v3
+ - name: Edit .npmrc to avoid setup-node issue with Node 14
+ if: ${{ matrix.node-version == '14' }}
+ run: perl -i -p -e 's/(ignore-scripts=true)/# $1/' .npmrc && git add .npmrc
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 842c4f59..d3691d40 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -3,6 +3,8 @@ name: CodeQL
on:
pull_request:
push:
+ branches-ignore:
+ - 'dependabot/**'
schedule:
- cron: '30 12 * * *'
workflow_dispatch:
diff --git a/.github/workflows/publish-container-image.yml b/.github/workflows/publish-container-image.yml
index 0da6c9ea..f01b45c4 100644
--- a/.github/workflows/publish-container-image.yml
+++ b/.github/workflows/publish-container-image.yml
@@ -36,7 +36,7 @@ jobs:
images: ${{ github.repository }}
- name: Build container image
- uses: docker/build-push-action@v3
+ uses: docker/build-push-action@v4
with:
context: .
file: docker/Dockerfile
@@ -48,7 +48,7 @@ jobs:
run: docker run --rm -v $PWD:/workdir local:test "*.md"
- name: Push container image
- uses: docker/build-push-action@v3
+ uses: docker/build-push-action@v4
with:
context: .
file: docker/Dockerfile
@@ -56,3 +56,21 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
push: true
+
+ - name: Extract tags and labels for -rules
+ id: meta-rules
+ uses: docker/metadata-action@v4
+ with:
+ images: ${{ github.repository }}-rules
+
+ - name: Build and push container image for -rules
+ uses: docker/build-push-action@v4
+ with:
+ context: .
+ file: docker/Dockerfile-rules
+ platforms: linux/arm64,linux/amd64
+ tags: ${{ steps.meta-rules.outputs.tags }}
+ labels: ${{ steps.meta-rules.outputs.labels }}
+ build-args: |
+ VERSION=${{ steps.meta.outputs.version }}
+ push: true
diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml
index 1ef6ff45..f82842c4 100644
--- a/.pre-commit-hooks.yaml
+++ b/.pre-commit-hooks.yaml
@@ -40,3 +40,24 @@
language: docker_image
types: [markdown]
minimum_pre_commit_version: 0.15.0
+- id: markdownlint-cli2-rules-docker
+ name: markdownlint-cli2-rules-docker
+ description: "Checks the style of Markdown/CommonMark files."
+ entry: davidanson/markdownlint-cli2-rules
+ language: docker_image
+ types: [markdown]
+ minimum_pre_commit_version: 0.15.0
+- id: markdownlint-cli2-config-rules-docker
+ name: markdownlint-cli2-config-rules-docker
+ description: "Checks the style of Markdown/CommonMark files with a non-root configuration."
+ entry: davidanson/markdownlint-cli2-rules markdownlint-cli2-config
+ language: docker_image
+ types: [markdown]
+ minimum_pre_commit_version: 0.15.0
+- id: markdownlint-cli2-fix-rules-docker
+ name: markdownlint-cli2-fix-rules-docker
+ description: "Checks and fixes the style of Markdown/CommonMark files."
+ entry: davidanson/markdownlint-cli2-rules markdownlint-cli2-fix
+ language: docker_image
+ types: [markdown]
+ minimum_pre_commit_version: 0.15.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..85849239
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,120 @@
+# Changelog
+
+## 0.7.0
+
+- Add support for `extends` in `config` property of `.markdownlint-cli2.*` files
+- Build and publish `davidanson/markdownlint-cli2-rules` Docker container image
+- Update dependencies (including `markdownlint`)
+
+## 0.6.0
+
+- Update dependencies (including `markdownlint`)
+
+## 0.5.1
+
+- Update dependencies
+
+## 0.5.0
+
+- New rules
+- Support modules (MJS) everywhere
+- Include dotfiles
+
+## 0.4.0
+
+- New rules
+- Async custom rules
+- Explicit config
+- CJS (breaking)
+
+## 0.3.2
+
+- Extensibility/Windows/consistency improvements
+
+## 0.3.1
+
+- Extensibility tweaks
+
+## 0.3.0
+
+- Add Docker container
+- Update dependencies
+
+## 0.2.0
+
+- Improve handling of Windows paths using backslash
+
+## 0.1.3
+
+- Support rule collections
+
+## 0.1.2
+
+- Update use of `require` to be more flexible
+
+## 0.1.1
+
+- Restore previous use of `require`
+
+## 0.1.0
+
+- Simplify use of `require`
+- Increment minor version
+
+## 0.0.15
+
+- Improve extensibility
+
+## 0.0.14
+
+- Update dependencies (including `markdownlint`)
+
+## 0.0.13
+
+- Add `markdownlint-cli2-fix` command
+
+## 0.0.12
+
+- Update dependencies (including `markdownlint`)
+
+## 0.0.11
+
+- Improve performance of `fix`
+- Update banner
+
+## 0.0.10
+
+- Improve performance and configuration
+
+## 0.0.9
+
+- Improve configuration file handling
+
+## 0.0.8
+
+- Support `.markdownlint-cli2.yaml`
+- Add progress
+
+## 0.0.7
+
+- Support `.markdownlint-cli2.js` and `.markdownlint.js`
+
+## 0.0.6
+
+- Improve handling of very large directory trees
+
+## 0.0.5
+
+- Improve support for ignoring files
+
+## 0.0.4
+
+- Support output formatters and `markdown-it` plugins
+
+## 0.0.3
+
+- Feature parity with `markdownlint-cli`
+
+## 0.0.2
+
+- Initial release
diff --git a/LICENSE b/LICENSE
index 18caa9a6..75c778e5 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 David Anson
+Copyright (c) David Anson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 311de50a..0f25920e 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ As a [GitHub Action][github-action] via
```yaml
- name: markdownlint-cli2-action
- uses: DavidAnson/markdownlint-cli2-action
+ uses: DavidAnson/markdownlint-cli2-action@v9
```
## Overview
@@ -145,7 +145,7 @@ A container image [`davidanson/markdownlint-cli2`][docker-hub-markdownlint-cli2]
can also be used (e.g., as part of a CI pipeline):
```bash
-docker run -v $PWD:/workdir davidanson/markdownlint-cli2:v0.6.0 "**/*.md" "#node_modules"
+docker run -v $PWD:/workdir davidanson/markdownlint-cli2:v0.7.0 "**/*.md" "#node_modules"
```
Notes:
@@ -162,16 +162,25 @@ Notes:
- A custom working directory can be specified with Docker's `-w` flag:
```bash
- docker run -w /myfolder -v $PWD:/myfolder davidanson/markdownlint-cli2:v0.6.0 "**/*.md" "#node_modules"
+ docker run -w /myfolder -v $PWD:/myfolder davidanson/markdownlint-cli2:v0.7.0 "**/*.md" "#node_modules"
```
To invoke the `markdownlint-cli2-config` or `markdownlint-cli2-fix` commands
instead, use Docker's `--entrypoint` flag:
```bash
-docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/markdownlint-cli2:v0.6.0 "**/*.md" "#node_modules"
+docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/markdownlint-cli2:v0.7.0 "**/*.md" "#node_modules"
```
+For convenience, the container image
+[`davidanson/markdownlint-cli2-rules`][docker-hub-markdownlint-cli2-rules]
+includes the latest versions of custom rules published to npm with the tag
+[`markdownlint-rule`][markdownlint-rule]. These rules are installed globally
+onto the base image `davidanson/markdownlint-cli2`.
+
+**Note**: This container image exists for convenience and is not an endorsement
+of the rules within.
+
### Exit Codes
- `0`: Linting was successful and there were no errors
@@ -193,11 +202,20 @@ docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/mark
- See the [Configuration][markdownlint-configuration] section of the
`markdownlint` documentation for information about the inline comment syntax
for enabling and disabling rules with HTML comments.
-- In general, glob expressions match files under the current directory and the
- configuration for that directory applies to the entire tree.
+- In general, glob expressions should match files under the current directory;
+ the configuration for that directory will apply to the entire tree.
- When glob expressions match files *not* under the current directory,
configuration for the current directory is applied to the closest common
parent directory.
+- There are two kinds of configuration file (both detailed below):
+ - Configuration files like `.markdownlint-cli2.*` allow complete control of
+ `markdownlint-cli2` behavior and are also used by `vscode-markdownlint`.
+ - Configuration files like `.markdownlint.*` allow control over only the
+ `markdownlint` `config` object and tend to be supported more broadly (such
+ as by `markdownlint-cli`).
+- The VS Code extension `vscode-markdownlint` includes a schema definition for
+ the `JSON(C)` configuration files described below. This adds auto-complete and
+ can make it easier to define proper structure.
### `.markdownlint-cli2.jsonc`
@@ -208,6 +226,8 @@ docker run -v $PWD:/workdir --entrypoint="markdownlint-cli2-fix" davidanson/mark
rules for this part of the directory tree
- If a `.markdownlint.{jsonc,json,yaml,yml,js}` file (see below) is present
in the same directory, it overrides the value of this property
+ - If the `config` object contains an `extends` property, it will be resolved
+ the same as `.markdownlint.{jsonc,json,yaml,yml,js}` (see below)
- `customRules`: `Array` of `String`s (or `Array`s of `String`s) of module
names/paths of [custom rules][markdownlint-custom-rules] to load and use
when linting
@@ -358,7 +378,7 @@ reference to the `repos` list in that project's `.pre-commit-config.yaml` like:
```yaml
- repo: https://github.com/DavidAnson/markdownlint-cli2
- rev: v0.6.0
+ rev: v0.7.0
hooks:
- id: markdownlint-cli2
```
@@ -368,32 +388,7 @@ reference to the `repos` list in that project's `.pre-commit-config.yaml` like:
## History
-- 0.0.2 - Initial release
-- 0.0.3 - Feature parity with `markdownlint-cli`
-- 0.0.4 - Support output formatters and `markdown-it` plugins
-- 0.0.5 - Improve support for ignoring files
-- 0.0.6 - Improve handling of very large directory trees
-- 0.0.7 - Support `.markdownlint-cli2.js` and `.markdownlint.js`
-- 0.0.8 - Support `.markdownlint-cli2.yaml`, add progress
-- 0.0.9 - Improve configuration file handling
-- 0.0.10 - Improve performance and configuration
-- 0.0.11 - Improve performance of `fix`, update banner
-- 0.0.12 - Update dependencies (including `markdownlint`)
-- 0.0.13 - Add `markdownlint-cli2-fix` command
-- 0.0.14 - Update dependencies (including `markdownlint`)
-- 0.0.15 - Improve extensibility
-- 0.1.0 - Simplify use of `require`, increment minor version
- - 0.1.1 - Restore previous use of `require`
- - 0.1.2 - Update use of `require` to be more flexible
- - 0.1.3 - Support rule collections
-- 0.2.0 - Improve handling of Windows paths using backslash
-- 0.3.0 - Add Docker container, update dependencies
- - 0.3.1 - Extensibility tweaks
- - 0.3.2 - Extensibility/Windows/consistency improvements
-- 0.4.0 - New rules, async custom rules, explicit config, CJS (breaking)
-- 0.5.0 - New rules, support modules (MJS) everywhere, include dotfiles
- - 0.5.1 - Update dependencies
-- 0.6.0 - Update dependencies (including `markdownlint`)
+See [CHANGELOG.md](CHANGELOG.md).
@@ -403,6 +398,7 @@ reference to the `repos` list in that project's `.pre-commit-config.yaml` like:
[docker]: https://www.docker.com
[docker-bind-mounts]: https://docs.docker.com/storage/bind-mounts/
[docker-hub-markdownlint-cli2]: https://hub.docker.com/r/davidanson/markdownlint-cli2
+[docker-hub-markdownlint-cli2-rules]: https://hub.docker.com/r/davidanson/markdownlint-cli2-rules
[front-matter]: https://jekyllrb.com/docs/frontmatter/
[github-action]: https://docs.github.com/actions
[globby]: https://www.npmjs.com/package/globby
diff --git a/doc/OutputFormatters.md b/doc/OutputFormatters.md
index d63537ce..2acd8f97 100644
--- a/doc/OutputFormatters.md
+++ b/doc/OutputFormatters.md
@@ -20,8 +20,8 @@ module.exports = (options, params) => { ... }
Where `options` is an object that looks like:
-- `results`: `Array` of [`markdownlint` `LintError` objects][markdownlint-d-ts]
- - [Example `results` object][output-formatters-json]
+- `results`: `Array` of [`markdownlint` `LintError` objects][markdownlint-d-ts],
+ each with an added `String` property `fileName` containing a relative path
- `logMessage`: `Function` that takes a single `String` argument and logs it to
standard output
- `logError`: `Function` that takes a single `String` argument and logs it to
@@ -62,4 +62,3 @@ For a `.markdownlint-cli2.jsonc` like:
[formatter-junit]: ../formatter-junit/markdownlint-cli2-formatter-junit.js
[markdownlint-cli2-formatter]: https://www.npmjs.com/search?q=keywords:markdownlint-cli2-formatter
[markdownlint-d-ts]: https://github.com/DavidAnson/markdownlint/blob/main/lib/markdownlint.d.ts
-[output-formatters-json]: ../test/outputFormatters.formatter.json
diff --git a/docker/Dockerfile-rules b/docker/Dockerfile-rules
new file mode 100644
index 00000000..e8a33bad
--- /dev/null
+++ b/docker/Dockerfile-rules
@@ -0,0 +1,23 @@
+ARG VERSION
+FROM davidanson/markdownlint-cli2:${VERSION}
+
+USER root
+
+RUN npm install --global --no-package-lock --production \
+ @github/markdownlint-github \
+ markdownlint-rule-enhanced-proper-names \
+ markdownlint-rule-github-admonition \
+ markdownlint-rule-github-internal-links \
+ markdownlint-rule-header-id \
+ markdownlint-rule-list-duplicates \
+ markdownlint-rule-max-one-sentence-per-line \
+ markdownlint-rule-no-trailing-slash-in-links \
+ markdownlint-rule-olstart \
+ markdownlint-rule-relative-links \
+ markdownlint-rule-search-replace \
+ markdownlint-rule-titlecase \
+ markdownlint-rule-trace-template-headers \
+ markdownlint-rules-foliant \
+ markdownlint-rules-grav-pages
+
+USER node
diff --git a/export-markdownlint-helpers.js b/export-markdownlint-helpers.js
new file mode 100644
index 00000000..44cfe31a
--- /dev/null
+++ b/export-markdownlint-helpers.js
@@ -0,0 +1,5 @@
+// @ts-check
+
+"use strict";
+
+module.exports = require("markdownlint/helpers");
diff --git a/export-markdownlint.js b/export-markdownlint.js
new file mode 100644
index 00000000..b3f98eb0
--- /dev/null
+++ b/export-markdownlint.js
@@ -0,0 +1,5 @@
+// @ts-check
+
+"use strict";
+
+module.exports = require("markdownlint");
diff --git a/formatter-codequality/LICENSE b/formatter-codequality/LICENSE
index 18caa9a6..75c778e5 100644
--- a/formatter-codequality/LICENSE
+++ b/formatter-codequality/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 David Anson
+Copyright (c) David Anson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/formatter-codequality/README.md b/formatter-codequality/README.md
index b54947bc..5588f353 100644
--- a/formatter-codequality/README.md
+++ b/formatter-codequality/README.md
@@ -15,7 +15,8 @@ npm install markdownlint-cli2-formatter-codequality --save-dev
## Use
-Use the following `.markdownlint-cli2.jsonc`:
+For the default output file name of `"markdownlint-cli2-codequality.json"`, use
+the following `.markdownlint-cli2.jsonc`:
```json
{
@@ -25,6 +26,16 @@ Use the following `.markdownlint-cli2.jsonc`:
}
```
+To customize the output file name, use the following `.markdownlint-cli2.jsonc`:
+
+```json
+{
+ "outputFormatters": [
+ [ "markdownlint-cli2-formatter-codequality", { "name": "custom-name.json" } ]
+ ]
+}
+```
+
## Use in GitLab CI
```yaml
diff --git a/formatter-codequality/markdownlint-cli2-formatter-codequality.js b/formatter-codequality/markdownlint-cli2-formatter-codequality.js
index 3ac3b7dc..32c1a2f2 100644
--- a/formatter-codequality/markdownlint-cli2-formatter-codequality.js
+++ b/formatter-codequality/markdownlint-cli2-formatter-codequality.js
@@ -19,8 +19,9 @@ const createFingerprint = function createFingerprint (violation) {
// Writes markdownlint-cli2 results to a GitLab Code Quality report JSON file.
// eslint-disable-next-line max-len
// See: https://docs.gitlab.com/ee/ci/testing/code_quality.html#implementing-a-custom-tool
-const outputFormatter = (options) => {
+const outputFormatter = (options, params) => {
const { directory, results } = options;
+ const { name } = (params || {});
const issues = [];
for (const errorInfo of results) {
@@ -62,7 +63,7 @@ const outputFormatter = (options) => {
path.resolve(
// eslint-disable-next-line no-inline-comments
directory /* c8 ignore next */ || "",
- "markdownlint-cli2-codequality.json"
+ name || "markdownlint-cli2-codequality.json"
),
content,
"utf8"
diff --git a/formatter-codequality/package.json b/formatter-codequality/package.json
index ca594164..c4540575 100644
--- a/formatter-codequality/package.json
+++ b/formatter-codequality/package.json
@@ -1,6 +1,6 @@
{
"name": "markdownlint-cli2-formatter-codequality",
- "version": "0.0.2",
+ "version": "0.0.4",
"description": "An output formatter for markdownlint-cli2 that writes results to a GitLab Code Quality report artifact JSON file",
"author": {
"name": "Matthias Schoettle",
diff --git a/formatter-default/LICENSE b/formatter-default/LICENSE
index 18caa9a6..75c778e5 100644
--- a/formatter-default/LICENSE
+++ b/formatter-default/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 David Anson
+Copyright (c) David Anson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/formatter-default/package.json b/formatter-default/package.json
index 33c9dadf..df692c58 100644
--- a/formatter-default/package.json
+++ b/formatter-default/package.json
@@ -1,6 +1,6 @@
{
"name": "markdownlint-cli2-formatter-default",
- "version": "0.0.3",
+ "version": "0.0.4",
"description": "An output formatter for markdownlint-cli2 that produces the same output as markdownlint-cli",
"author": {
"name": "David Anson",
diff --git a/formatter-json/LICENSE b/formatter-json/LICENSE
index 18caa9a6..75c778e5 100644
--- a/formatter-json/LICENSE
+++ b/formatter-json/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 David Anson
+Copyright (c) David Anson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/formatter-json/package.json b/formatter-json/package.json
index f93db4be..c9da723f 100644
--- a/formatter-json/package.json
+++ b/formatter-json/package.json
@@ -1,6 +1,6 @@
{
"name": "markdownlint-cli2-formatter-json",
- "version": "0.0.6",
+ "version": "0.0.7",
"description": "An output formatter for markdownlint-cli2 that writes results to a file in JSON format",
"author": {
"name": "David Anson",
diff --git a/formatter-junit/LICENSE b/formatter-junit/LICENSE
index 18caa9a6..75c778e5 100644
--- a/formatter-junit/LICENSE
+++ b/formatter-junit/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 David Anson
+Copyright (c) David Anson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/formatter-junit/markdownlint-cli2-formatter-junit.js b/formatter-junit/markdownlint-cli2-formatter-junit.js
index 9beb651c..98700b46 100644
--- a/formatter-junit/markdownlint-cli2-formatter-junit.js
+++ b/formatter-junit/markdownlint-cli2-formatter-junit.js
@@ -12,10 +12,11 @@ const outputFormatter = (options, params) => {
const { name } = (params || {});
// Get a new builder instance because the default builder is shared
const builder = junitReportBuilder.newBuilder();
+ const outputFormatterName = path.basename(__filename).replace(/\.js$/u, "");
const suite =
builder.
testSuite().
- name(path.basename(__filename).replace(/\.js$/u, "")).
+ name(outputFormatterName).
time(0);
for (const errorInfo of results) {
const { fileName, lineNumber, ruleNames, ruleDescription, errorDetail,
@@ -38,6 +39,7 @@ const outputFormatter = (options, params) => {
if (results.length === 0) {
suite.
testCase().
+ name(outputFormatterName).
time(0);
}
const content = builder.build();
diff --git a/formatter-junit/package.json b/formatter-junit/package.json
index a40590ad..8f04e27d 100644
--- a/formatter-junit/package.json
+++ b/formatter-junit/package.json
@@ -1,6 +1,6 @@
{
"name": "markdownlint-cli2-formatter-junit",
- "version": "0.0.5",
+ "version": "0.0.6",
"description": "An output formatter for markdownlint-cli2 that writes results to a file in JUnit XML format",
"author": {
"name": "David Anson",
diff --git a/formatter-pretty/LICENSE b/formatter-pretty/LICENSE
index 18caa9a6..75c778e5 100644
--- a/formatter-pretty/LICENSE
+++ b/formatter-pretty/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 David Anson
+Copyright (c) David Anson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/formatter-pretty/package.json b/formatter-pretty/package.json
index 225ef186..f3f88e24 100644
--- a/formatter-pretty/package.json
+++ b/formatter-pretty/package.json
@@ -1,6 +1,6 @@
{
"name": "markdownlint-cli2-formatter-pretty",
- "version": "0.0.3",
+ "version": "0.0.4",
"description": "An output formatter for markdownlint-cli2 that looks like markdownlint-cli2-formatter-default with color and clickable links",
"author": {
"name": "David Anson",
diff --git a/formatter-summarize/LICENSE b/formatter-summarize/LICENSE
index 18caa9a6..75c778e5 100644
--- a/formatter-summarize/LICENSE
+++ b/formatter-summarize/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 David Anson
+Copyright (c) David Anson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/formatter-summarize/package.json b/formatter-summarize/package.json
index 91ada788..0a30537b 100644
--- a/formatter-summarize/package.json
+++ b/formatter-summarize/package.json
@@ -1,6 +1,6 @@
{
"name": "markdownlint-cli2-formatter-summarize",
- "version": "0.0.5",
+ "version": "0.0.6",
"description": "An output formatter for markdownlint-cli2 that summarizes the results",
"author": {
"name": "David Anson",
diff --git a/markdownlint-cli2.js b/markdownlint-cli2.js
index ee2dc807..d82426e7 100755
--- a/markdownlint-cli2.js
+++ b/markdownlint-cli2.js
@@ -13,8 +13,11 @@ const dynamicRequire = (typeof __non_webpack_require__ === "undefined") ? requir
const path = require("node:path");
const { pathToFileURL } = require("node:url");
const markdownlintLibrary = require("markdownlint");
-const { markdownlint, "readConfig": markdownlintReadConfig } =
- markdownlintLibrary.promises;
+const {
+ markdownlint,
+ "extendConfig": markdownlintExtendConfig,
+ "readConfig": markdownlintReadConfig
+} = markdownlintLibrary.promises;
const markdownlintRuleHelpers = require("markdownlint/helpers");
const appendToArray = require("./append-to-array");
const mergeOptions = require("./merge-options");
@@ -22,7 +25,7 @@ const resolveAndRequire = require("./resolve-and-require");
// Variables
const packageName = "markdownlint-cli2";
-const packageVersion = "0.6.0";
+const packageVersion = "0.7.0";
const libraryName = "markdownlint";
const libraryVersion = markdownlintLibrary.getVersion();
const dotOnlySubstitute = "*.{md,markdown}";
@@ -242,105 +245,121 @@ $ markdownlint-cli2 "**/*.md" "#node_modules"`
// Get (creating if necessary) and process a directory's info object
const getAndProcessDirInfo =
-(fs, tasks, dirToDirInfo, dir, relativeDir, noRequire, func) => {
- let dirInfo = dirToDirInfo[dir];
- if (!dirInfo) {
- dirInfo = {
- dir,
- relativeDir,
- "parent": null,
- "files": [],
- "markdownlintConfig": null,
- "markdownlintOptions": null
- };
- dirToDirInfo[dir] = dirInfo;
-
- // Load markdownlint-cli2 object(s)
- const markdownlintCli2Jsonc =
- path.posix.join(dir, ".markdownlint-cli2.jsonc");
- const markdownlintCli2Yaml =
- path.posix.join(dir, ".markdownlint-cli2.yaml");
- tasks.push(
- fs.promises.access(markdownlintCli2Jsonc).
- then(
- () => fs.promises.
- readFile(markdownlintCli2Jsonc, utf8).
- then(
- (content) => getJsoncParse().
- then((jsoncParse) => jsoncParse(content))
- ),
- () => fs.promises.access(markdownlintCli2Yaml).
- then(
- () => fs.promises.
- readFile(markdownlintCli2Yaml, utf8).
- then(yamlParse),
- importOrRequireConfig(
- fs,
- dir,
- ".markdownlint-cli2.cjs",
- noRequire,
+ (fs, tasks, dirToDirInfo, dir, relativeDir, noRequire, func) => {
+ let dirInfo = dirToDirInfo[dir];
+ if (!dirInfo) {
+ dirInfo = {
+ dir,
+ relativeDir,
+ "parent": null,
+ "files": [],
+ "markdownlintConfig": null,
+ "markdownlintOptions": null
+ };
+ dirToDirInfo[dir] = dirInfo;
+
+ // Load markdownlint-cli2 object(s)
+ const markdownlintCli2Jsonc =
+ path.posix.join(dir, ".markdownlint-cli2.jsonc");
+ const markdownlintCli2Yaml =
+ path.posix.join(dir, ".markdownlint-cli2.yaml");
+ tasks.push(
+ fs.promises.access(markdownlintCli2Jsonc).
+ then(
+ () => fs.promises.
+ readFile(markdownlintCli2Jsonc, utf8).
+ then(
+ (content) => getJsoncParse().
+ then((jsoncParse) => jsoncParse(content))
+ ),
+ () => fs.promises.access(markdownlintCli2Yaml).
+ then(
+ () => fs.promises.
+ readFile(markdownlintCli2Yaml, utf8).
+ then(yamlParse),
importOrRequireConfig(
fs,
dir,
- ".markdownlint-cli2.mjs",
+ ".markdownlint-cli2.cjs",
noRequire,
- noop
+ importOrRequireConfig(
+ fs,
+ dir,
+ ".markdownlint-cli2.mjs",
+ noRequire,
+ noop
+ )
)
)
- )
- ).
- then((options) => {
- dirInfo.markdownlintOptions = options;
- })
- );
+ ).
+ then((options) => {
+ dirInfo.markdownlintOptions = options;
+ return options &&
+ options.config &&
+ options.config.extends &&
+ getJsoncParse().
+ then(
+ (jsoncParse) => markdownlintExtendConfig(
+ options.config,
+ // Just needs to identify a file in the right directory
+ markdownlintCli2Jsonc,
+ [ jsoncParse, yamlParse ],
+ fs
+ )
+ ).
+ then((config) => {
+ options.config = config;
+ });
+ })
+ );
- // Load markdownlint object(s)
- const readConfigs =
- readConfig(
- fs,
- dir,
- ".markdownlint.jsonc",
+ // Load markdownlint object(s)
+ const readConfigs =
readConfig(
fs,
dir,
- ".markdownlint.json",
+ ".markdownlint.jsonc",
readConfig(
fs,
dir,
- ".markdownlint.yaml",
+ ".markdownlint.json",
readConfig(
fs,
dir,
- ".markdownlint.yml",
- importOrRequireConfig(
+ ".markdownlint.yaml",
+ readConfig(
fs,
dir,
- ".markdownlint.cjs",
- noRequire,
+ ".markdownlint.yml",
importOrRequireConfig(
fs,
dir,
- ".markdownlint.mjs",
+ ".markdownlint.cjs",
noRequire,
- noop
+ importOrRequireConfig(
+ fs,
+ dir,
+ ".markdownlint.mjs",
+ noRequire,
+ noop
+ )
)
)
)
)
- )
+ );
+ tasks.push(
+ readConfigs().
+ then((config) => {
+ dirInfo.markdownlintConfig = config;
+ })
);
- tasks.push(
- readConfigs().
- then((config) => {
- dirInfo.markdownlintConfig = config;
- })
- );
- }
- if (func) {
- func(dirInfo);
- }
- return dirInfo;
-};
+ }
+ if (func) {
+ func(dirInfo);
+ }
+ return dirInfo;
+ };
// Get base markdownlint-cli2 options object
const getBaseOptions = async (
@@ -367,7 +386,10 @@ const getBaseOptions = async (
// eslint-disable-next-line no-multi-assign
const baseMarkdownlintOptions = dirToDirInfo[baseDir].markdownlintOptions =
mergeOptions(
- mergeOptions(options, { "fix": fixDefault }),
+ mergeOptions(
+ { "fix": fixDefault },
+ options
+ ),
dirToDirInfo[baseDir].markdownlintOptions
);
@@ -391,81 +413,81 @@ const getBaseOptions = async (
// Enumerate files from globs and build directory infos
const enumerateFiles =
-// eslint-disable-next-line max-len
-async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, noErrors, noRequire) => {
- const tasks = [];
- const globbyOptions = {
- "absolute": true,
- "cwd": baseDir,
- "dot": true,
- "expandDirectories": false,
- fs
- };
- if (noErrors) {
- globbyOptions.suppressErrors = true;
- }
- // Special-case literal files
- const literalFiles = [];
- const filteredGlobPatterns = globPatterns.filter(
- (globPattern) => {
- if (globPattern.startsWith(":")) {
- literalFiles.push(
- posixPath(path.resolve(baseDirSystem, globPattern.slice(1)))
- );
- return false;
- }
- return true;
+ // eslint-disable-next-line max-len
+ async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, noErrors, noRequire) => {
+ const tasks = [];
+ const globbyOptions = {
+ "absolute": true,
+ "cwd": baseDir,
+ "dot": true,
+ "expandDirectories": false,
+ fs
+ };
+ if (noErrors) {
+ globbyOptions.suppressErrors = true;
}
- ).map((globPattern) => globPattern.replace(/^\\:/u, ":"));
- const baseMarkdownlintOptions = dirToDirInfo[baseDir].markdownlintOptions;
- const globsForIgnore =
- (baseMarkdownlintOptions.globs || []).
- filter((glob) => glob.startsWith("!"));
- const filteredLiteralFiles =
- ((literalFiles.length > 0) && (globsForIgnore.length > 0))
- ? removeIgnoredFiles(baseDir, literalFiles, globsForIgnore)
- : literalFiles;
- // Manually expand directories to avoid globby call to dir-glob.sync
- const expandedDirectories = await Promise.all(
- filteredGlobPatterns.map((globPattern) => {
- const barePattern =
- globPattern.startsWith("!")
- ? globPattern.slice(1)
- : globPattern;
- const globPath =
- (path.posix.isAbsolute(barePattern) || path.isAbsolute(barePattern))
- ? barePattern
- : path.posix.join(baseDir, barePattern);
- return fs.promises.stat(globPath).
- then((stats) => (stats.isDirectory()
- ? path.posix.join(globPattern, "**")
- : globPattern)).
- catch(() => globPattern);
- })
- );
- // Process glob patterns
- // eslint-disable-next-line no-inline-comments
- const { globby } = await import(/* webpackMode: "eager" */ "globby");
- const files = [
- ...await globby(expandedDirectories, globbyOptions),
- ...filteredLiteralFiles
- ];
- for (const file of files) {
- const dir = path.posix.dirname(file);
- getAndProcessDirInfo(
- fs,
- tasks,
- dirToDirInfo,
- dir,
- null,
- noRequire,
- (dirInfo) => {
- dirInfo.files.push(file);
+ // Special-case literal files
+ const literalFiles = [];
+ const filteredGlobPatterns = globPatterns.filter(
+ (globPattern) => {
+ if (globPattern.startsWith(":")) {
+ literalFiles.push(
+ posixPath(path.resolve(baseDirSystem, globPattern.slice(1)))
+ );
+ return false;
+ }
+ return true;
}
+ ).map((globPattern) => globPattern.replace(/^\\:/u, ":"));
+ const baseMarkdownlintOptions = dirToDirInfo[baseDir].markdownlintOptions;
+ const globsForIgnore =
+ (baseMarkdownlintOptions.globs || []).
+ filter((glob) => glob.startsWith("!"));
+ const filteredLiteralFiles =
+ ((literalFiles.length > 0) && (globsForIgnore.length > 0))
+ ? removeIgnoredFiles(baseDir, literalFiles, globsForIgnore)
+ : literalFiles;
+ // Manually expand directories to avoid globby call to dir-glob.sync
+ const expandedDirectories = await Promise.all(
+ filteredGlobPatterns.map((globPattern) => {
+ const barePattern =
+ globPattern.startsWith("!")
+ ? globPattern.slice(1)
+ : globPattern;
+ const globPath =
+ (path.posix.isAbsolute(barePattern) || path.isAbsolute(barePattern))
+ ? barePattern
+ : path.posix.join(baseDir, barePattern);
+ return fs.promises.stat(globPath).
+ then((stats) => (stats.isDirectory()
+ ? path.posix.join(globPattern, "**")
+ : globPattern)).
+ catch(() => globPattern);
+ })
);
- }
- await Promise.all(tasks);
-};
+ // Process glob patterns
+ // eslint-disable-next-line no-inline-comments
+ const { globby } = await import(/* webpackMode: "eager" */ "globby");
+ const files = [
+ ...await globby(expandedDirectories, globbyOptions),
+ ...filteredLiteralFiles
+ ];
+ for (const file of files) {
+ const dir = path.posix.dirname(file);
+ getAndProcessDirInfo(
+ fs,
+ tasks,
+ dirToDirInfo,
+ dir,
+ null,
+ noRequire,
+ (dirInfo) => {
+ dirInfo.files.push(file);
+ }
+ );
+ }
+ await Promise.all(tasks);
+ };
// Enumerate (possibly missing) parent directories and update directory infos
const enumerateParents = async (fs, baseDir, dirToDirInfo, noRequire) => {
@@ -514,135 +536,135 @@ const enumerateParents = async (fs, baseDir, dirToDirInfo, noRequire) => {
// Create directory info objects by enumerating file globs
const createDirInfos =
-// eslint-disable-next-line max-len
-async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, optionsOverride, noErrors, noRequire) => {
- await enumerateFiles(
- fs,
- baseDirSystem,
- baseDir,
- globPatterns,
- dirToDirInfo,
- noErrors,
- noRequire
- );
- await enumerateParents(
- fs,
- baseDir,
- dirToDirInfo,
- noRequire
- );
-
- // Merge file lists with identical configuration
- const dirs = Object.keys(dirToDirInfo);
- dirs.sort((a, b) => b.length - a.length);
- const dirInfos = [];
- const noConfigDirInfo =
- // eslint-disable-next-line unicorn/consistent-function-scoping
- (dirInfo) => (
- dirInfo.parent &&
- !dirInfo.markdownlintConfig &&
- !dirInfo.markdownlintOptions
+ // eslint-disable-next-line max-len
+ async (fs, baseDirSystem, baseDir, globPatterns, dirToDirInfo, optionsOverride, noErrors, noRequire) => {
+ await enumerateFiles(
+ fs,
+ baseDirSystem,
+ baseDir,
+ globPatterns,
+ dirToDirInfo,
+ noErrors,
+ noRequire
);
- const tasks = [];
- for (const dir of dirs) {
- const dirInfo = dirToDirInfo[dir];
- if (noConfigDirInfo(dirInfo)) {
- if (dirInfo.parent) {
- appendToArray(dirInfo.parent.files, dirInfo.files);
- }
- dirToDirInfo[dir] = null;
- } else {
- const { markdownlintOptions, relativeDir } = dirInfo;
- if (markdownlintOptions && markdownlintOptions.customRules) {
- tasks.push(
- importOrRequireIds(
- relativeDir || dir,
- markdownlintOptions.customRules,
- noRequire
- ).then((customRules) => {
- // Expand nested arrays (for packages that export multiple rules)
- markdownlintOptions.customRules = customRules.flat();
- })
- );
- }
- if (markdownlintOptions && markdownlintOptions.markdownItPlugins) {
- tasks.push(
- importOrRequireIdsAndParams(
- relativeDir || dir,
- markdownlintOptions.markdownItPlugins,
- noRequire
- ).then((markdownItPlugins) => {
- markdownlintOptions.markdownItPlugins = markdownItPlugins;
- })
- );
+ await enumerateParents(
+ fs,
+ baseDir,
+ dirToDirInfo,
+ noRequire
+ );
+
+ // Merge file lists with identical configuration
+ const dirs = Object.keys(dirToDirInfo);
+ dirs.sort((a, b) => b.length - a.length);
+ const dirInfos = [];
+ const noConfigDirInfo =
+ // eslint-disable-next-line unicorn/consistent-function-scoping
+ (dirInfo) => (
+ dirInfo.parent &&
+ !dirInfo.markdownlintConfig &&
+ !dirInfo.markdownlintOptions
+ );
+ const tasks = [];
+ for (const dir of dirs) {
+ const dirInfo = dirToDirInfo[dir];
+ if (noConfigDirInfo(dirInfo)) {
+ if (dirInfo.parent) {
+ appendToArray(dirInfo.parent.files, dirInfo.files);
+ }
+ dirToDirInfo[dir] = null;
+ } else {
+ const { markdownlintOptions, relativeDir } = dirInfo;
+ if (markdownlintOptions && markdownlintOptions.customRules) {
+ tasks.push(
+ importOrRequireIds(
+ relativeDir || dir,
+ markdownlintOptions.customRules,
+ noRequire
+ ).then((customRules) => {
+ // Expand nested arrays (for packages that export multiple rules)
+ markdownlintOptions.customRules = customRules.flat();
+ })
+ );
+ }
+ if (markdownlintOptions && markdownlintOptions.markdownItPlugins) {
+ tasks.push(
+ importOrRequireIdsAndParams(
+ relativeDir || dir,
+ markdownlintOptions.markdownItPlugins,
+ noRequire
+ ).then((markdownItPlugins) => {
+ markdownlintOptions.markdownItPlugins = markdownItPlugins;
+ })
+ );
+ }
+ dirInfos.push(dirInfo);
}
- dirInfos.push(dirInfo);
}
- }
- await Promise.all(tasks);
- for (const dirInfo of dirInfos) {
- while (dirInfo.parent && !dirToDirInfo[dirInfo.parent.dir]) {
- dirInfo.parent = dirInfo.parent.parent;
+ await Promise.all(tasks);
+ for (const dirInfo of dirInfos) {
+ while (dirInfo.parent && !dirToDirInfo[dirInfo.parent.dir]) {
+ dirInfo.parent = dirInfo.parent.parent;
+ }
}
- }
- // Verify dirInfos is simplified
- // if (
- // dirInfos.filter(
- // (di) => di.parent && !dirInfos.includes(di.parent)
- // ).length > 0
- // ) {
- // throw new Error("Extra parent");
- // }
- // if (
- // dirInfos.filter(
- // (di) => !di.parent && (di.dir !== baseDir)
- // ).length > 0
- // ) {
- // throw new Error("Missing parent");
- // }
- // if (
- // dirInfos.filter(
- // (di) => di.parent &&
- // !((di.markdownlintConfig ? 1 : 0) ^ (di.markdownlintOptions ? 1 : 0))
- // ).length > 0
- // ) {
- // throw new Error("Missing object");
- // }
- // if (dirInfos.filter((di) => di.dir === "/").length > 0) {
- // throw new Error("Includes root");
- // }
-
- // Merge configuration by inheritance
- for (const dirInfo of dirInfos) {
- let markdownlintOptions = dirInfo.markdownlintOptions || {};
- let { markdownlintConfig } = dirInfo;
- let parent = dirInfo;
- // eslint-disable-next-line prefer-destructuring
- while ((parent = parent.parent)) {
- if (parent.markdownlintOptions) {
- markdownlintOptions = mergeOptions(
- parent.markdownlintOptions,
- markdownlintOptions
- );
- }
- if (
- !markdownlintConfig &&
- parent.markdownlintConfig &&
- !markdownlintOptions.config
- ) {
- // eslint-disable-next-line prefer-destructuring
- markdownlintConfig = parent.markdownlintConfig;
+ // Verify dirInfos is simplified
+ // if (
+ // dirInfos.filter(
+ // (di) => di.parent && !dirInfos.includes(di.parent)
+ // ).length > 0
+ // ) {
+ // throw new Error("Extra parent");
+ // }
+ // if (
+ // dirInfos.filter(
+ // (di) => !di.parent && (di.dir !== baseDir)
+ // ).length > 0
+ // ) {
+ // throw new Error("Missing parent");
+ // }
+ // if (
+ // dirInfos.filter(
+ // (di) => di.parent &&
+ // !((di.markdownlintConfig ? 1 : 0) ^ (di.markdownlintOptions ? 1 : 0))
+ // ).length > 0
+ // ) {
+ // throw new Error("Missing object");
+ // }
+ // if (dirInfos.filter((di) => di.dir === "/").length > 0) {
+ // throw new Error("Includes root");
+ // }
+
+ // Merge configuration by inheritance
+ for (const dirInfo of dirInfos) {
+ let markdownlintOptions = dirInfo.markdownlintOptions || {};
+ let { markdownlintConfig } = dirInfo;
+ let parent = dirInfo;
+ // eslint-disable-next-line prefer-destructuring
+ while ((parent = parent.parent)) {
+ if (parent.markdownlintOptions) {
+ markdownlintOptions = mergeOptions(
+ parent.markdownlintOptions,
+ markdownlintOptions
+ );
+ }
+ if (
+ !markdownlintConfig &&
+ parent.markdownlintConfig &&
+ !markdownlintOptions.config
+ ) {
+ // eslint-disable-next-line prefer-destructuring
+ markdownlintConfig = parent.markdownlintConfig;
+ }
}
+ dirInfo.markdownlintOptions = mergeOptions(
+ markdownlintOptions,
+ optionsOverride
+ );
+ dirInfo.markdownlintConfig = markdownlintConfig;
}
- dirInfo.markdownlintOptions = mergeOptions(
- markdownlintOptions,
- optionsOverride
- );
- dirInfo.markdownlintConfig = markdownlintConfig;
- }
- return dirInfos;
-};
+ return dirInfos;
+ };
// Lint files in groups by shared configuration
const lintFiles = async (fs, dirInfos, fileContents) => {
diff --git a/package.json b/package.json
index d8b155bc..ee1bd3e2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "markdownlint-cli2",
- "version": "0.6.0",
+ "version": "0.7.0",
"description": "A fast, flexible, configuration-based command-line interface for linting Markdown/CommonMark files with the `markdownlint` library",
"author": {
"name": "David Anson",
@@ -9,7 +9,11 @@
"license": "MIT",
"type": "commonjs",
"main": "./markdownlint-cli2.js",
- "exports": "./markdownlint-cli2.js",
+ "exports": {
+ ".": "./markdownlint-cli2.js",
+ "./markdownlint": "./export-markdownlint.js",
+ "./markdownlint/helpers": "./export-markdownlint-helpers.js"
+ },
"bin": {
"markdownlint-cli2": "markdownlint-cli2.js",
"markdownlint-cli2-config": "markdownlint-cli2-config.js",
@@ -23,6 +27,7 @@
"bugs": "https://github.com/DavidAnson/markdownlint-cli2/issues",
"scripts": {
"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 .",
+ "build-docker-image-rules": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker build -t davidanson/markdownlint-cli2-rules:v$VERSION -f docker/Dockerfile-rules --build-arg VERSION=v$VERSION --label org.opencontainers.image.version=v$VERSION .",
"ci": "npm-run-all --continue-on-error --parallel test-cover lint",
"docker-npm-install": "docker run --rm --tty --name npm-install --volume $PWD:/home/workdir --workdir /home/workdir --user node node:16 npm install",
"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",
@@ -32,10 +37,12 @@
"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 .",
"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",
"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\"",
+ "test-docker-image-rules": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2-rules:v$VERSION \"*.md\"",
"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\"",
+ "test-docker-hub-image-rules": "VERSION=$(node -e \"process.stdout.write(require('./package.json').version)\") && docker image rm davidanson/markdownlint-cli2-rules:v$VERSION davidanson/markdownlint-cli2-rules:latest || true && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2-rules:v$VERSION \"*.md\" && docker run --rm -v $PWD:/workdir davidanson/markdownlint-cli2-rules:latest \"*.md\"",
"test-cover": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 npm test",
"test-watch": "git ls-files | entr npm run test",
- "update-snapshots": "ava --update-snapshots test/markdownlint-cli2-test-exec.js test/markdownlint-cli2-test-fs.js test/markdownlint-cli2-test-main.js",
+ "update-snapshots": "ava --timeout=1m --update-snapshots test/markdownlint-cli2-test-exec.js test/markdownlint-cli2-test-fs.js test/markdownlint-cli2-test-main.js",
"upgrade": "npx --yes npm-check-updates --upgrade",
"webworker": "cd webworker && webpack --mode none",
"webworker-install": "npm run docker-npm-install -- --no-save path-browserify process setimmediate stream-browserify url util webpack-cli"
@@ -45,6 +52,8 @@
},
"files": [
"append-to-array.js",
+ "export-markdownlint.js",
+ "export-markdownlint-helpers.js",
"markdownlint-cli2.js",
"markdownlint-cli2-config.js",
"markdownlint-cli2-fix.js",
@@ -52,30 +61,30 @@
"resolve-and-require.js"
],
"dependencies": {
- "globby": "13.1.3",
- "markdownlint": "0.27.0",
- "markdownlint-cli2-formatter-default": "0.0.3",
+ "globby": "13.1.4",
+ "markdownlint": "0.28.1",
+ "markdownlint-cli2-formatter-default": "0.0.4",
"micromatch": "4.0.5",
"strip-json-comments": "5.0.0",
"yaml": "2.2.1"
},
"devDependencies": {
"@iktakahiro/markdown-it-katex": "4.0.1",
- "ava": "5.1.0",
- "c8": "7.12.0",
+ "ava": "5.2.0",
+ "c8": "7.13.0",
"cpy": "9.0.1",
"del": "7.0.0",
- "eslint": "8.30.0",
- "eslint-plugin-n": "15.6.0",
- "eslint-plugin-unicorn": "45.0.2",
- "execa": "6.1.0",
+ "eslint": "8.38.0",
+ "eslint-plugin-n": "15.7.0",
+ "eslint-plugin-unicorn": "46.0.0",
+ "execa": "7.1.1",
"markdown-it-emoji": "2.0.2",
"markdown-it-for-inline": "0.1.1",
- "markdownlint-cli2-formatter-codequality": "0.0.1",
- "markdownlint-cli2-formatter-json": "0.0.6",
- "markdownlint-cli2-formatter-junit": "0.0.5",
- "markdownlint-cli2-formatter-pretty": "0.0.3",
- "markdownlint-cli2-formatter-summarize": "0.0.5",
+ "markdownlint-cli2-formatter-codequality": "0.0.4",
+ "markdownlint-cli2-formatter-json": "0.0.7",
+ "markdownlint-cli2-formatter-junit": "0.0.6",
+ "markdownlint-cli2-formatter-pretty": "0.0.4",
+ "markdownlint-cli2-formatter-summarize": "0.0.6",
"markdownlint-rule-titlecase": "0.1.0",
"npm-run-all": "4.1.5"
},
diff --git a/test/config-with-fix/.markdownlint-cli2.jsonc b/test/config-with-fix/.markdownlint-cli2.jsonc
new file mode 100644
index 00000000..3df10b6a
--- /dev/null
+++ b/test/config-with-fix/.markdownlint-cli2.jsonc
@@ -0,0 +1,5 @@
+{
+ "config": {
+ "single-title": false
+ }
+}
diff --git a/test/config-with-fix/config/.markdownlint-cli2.jsonc b/test/config-with-fix/config/.markdownlint-cli2.jsonc
new file mode 100644
index 00000000..dd8d364b
--- /dev/null
+++ b/test/config-with-fix/config/.markdownlint-cli2.jsonc
@@ -0,0 +1,6 @@
+{
+ "fix": true,
+ "config": {
+ "first-line-heading": false
+ }
+}
diff --git a/test/config-with-fix/info.md b/test/config-with-fix/info.md
new file mode 100644
index 00000000..fc9dba79
--- /dev/null
+++ b/test/config-with-fix/info.md
@@ -0,0 +1,3 @@
+## Information
+Text ` code1` text `code2 ` text
+
diff --git a/test/config-with-fix/viewme.md b/test/config-with-fix/viewme.md
new file mode 100644
index 00000000..d60ebf5a
--- /dev/null
+++ b/test/config-with-fix/viewme.md
@@ -0,0 +1,14 @@
+# Title
+
+> Tagline
+
+
+# Description
+
+Text text text
+Text text text
+Text text text
+
+## Summary
+
+Text text text
\ No newline at end of file
diff --git a/test/markdownlint-cli2-extends/cjs/.markdownlint-cli2.cjs b/test/markdownlint-cli2-extends/cjs/.markdownlint-cli2.cjs
new file mode 100644
index 00000000..557ba6bc
--- /dev/null
+++ b/test/markdownlint-cli2-extends/cjs/.markdownlint-cli2.cjs
@@ -0,0 +1,10 @@
+// @ts-check
+
+"use strict";
+
+module.exports = {
+ "config": {
+ "extends": "../outer.jsonc",
+ "no-multiple-blanks": false
+ }
+};
diff --git a/test/markdownlint-cli2-extends/cjs/viewme.md b/test/markdownlint-cli2-extends/cjs/viewme.md
new file mode 100644
index 00000000..d60ebf5a
--- /dev/null
+++ b/test/markdownlint-cli2-extends/cjs/viewme.md
@@ -0,0 +1,14 @@
+# Title
+
+> Tagline
+
+
+# Description
+
+Text text text
+Text text text
+Text text text
+
+## Summary
+
+Text text text
\ No newline at end of file
diff --git a/test/markdownlint-cli2-extends/inner.yaml b/test/markdownlint-cli2-extends/inner.yaml
new file mode 100644
index 00000000..f8c5f42f
--- /dev/null
+++ b/test/markdownlint-cli2-extends/inner.yaml
@@ -0,0 +1 @@
+single-trailing-newline: false
diff --git a/test/markdownlint-cli2-extends/jsonc/.markdownlint-cli2.jsonc b/test/markdownlint-cli2-extends/jsonc/.markdownlint-cli2.jsonc
new file mode 100644
index 00000000..5302f859
--- /dev/null
+++ b/test/markdownlint-cli2-extends/jsonc/.markdownlint-cli2.jsonc
@@ -0,0 +1,6 @@
+{
+ "config": {
+ "extends": "../outer.jsonc",
+ "no-multiple-blanks": false
+ }
+}
diff --git a/test/markdownlint-cli2-extends/jsonc/viewme.md b/test/markdownlint-cli2-extends/jsonc/viewme.md
new file mode 100644
index 00000000..d60ebf5a
--- /dev/null
+++ b/test/markdownlint-cli2-extends/jsonc/viewme.md
@@ -0,0 +1,14 @@
+# Title
+
+> Tagline
+
+
+# Description
+
+Text text text
+Text text text
+Text text text
+
+## Summary
+
+Text text text
\ No newline at end of file
diff --git a/test/markdownlint-cli2-extends/outer.jsonc b/test/markdownlint-cli2-extends/outer.jsonc
new file mode 100644
index 00000000..d74a01bc
--- /dev/null
+++ b/test/markdownlint-cli2-extends/outer.jsonc
@@ -0,0 +1,4 @@
+{
+ "extends": "./inner.yaml",
+ "single-title": false
+}
diff --git a/test/markdownlint-cli2-extends/package/.markdownlint-cli2.jsonc b/test/markdownlint-cli2-extends/package/.markdownlint-cli2.jsonc
new file mode 100644
index 00000000..5ecf259c
--- /dev/null
+++ b/test/markdownlint-cli2-extends/package/.markdownlint-cli2.jsonc
@@ -0,0 +1,5 @@
+{
+ "config": {
+ "extends": "markdownlint/style/prettier"
+ }
+}
diff --git a/test/markdownlint-cli2-extends/package/viewme.md b/test/markdownlint-cli2-extends/package/viewme.md
new file mode 100644
index 00000000..d60ebf5a
--- /dev/null
+++ b/test/markdownlint-cli2-extends/package/viewme.md
@@ -0,0 +1,14 @@
+# Title
+
+> Tagline
+
+
+# Description
+
+Text text text
+Text text text
+Text text text
+
+## Summary
+
+Text text text
\ No newline at end of file
diff --git a/test/markdownlint-cli2-extends/yaml/.markdownlint-cli2.yaml b/test/markdownlint-cli2-extends/yaml/.markdownlint-cli2.yaml
new file mode 100644
index 00000000..a9d12adf
--- /dev/null
+++ b/test/markdownlint-cli2-extends/yaml/.markdownlint-cli2.yaml
@@ -0,0 +1,3 @@
+config:
+ extends: '../outer.jsonc'
+ no-multiple-blanks: false
diff --git a/test/markdownlint-cli2-extends/yaml/viewme.md b/test/markdownlint-cli2-extends/yaml/viewme.md
new file mode 100644
index 00000000..d60ebf5a
--- /dev/null
+++ b/test/markdownlint-cli2-extends/yaml/viewme.md
@@ -0,0 +1,14 @@
+# Title
+
+> Tagline
+
+
+# Description
+
+Text text text
+Text text text
+Text text text
+
+## Summary
+
+Text text text
\ No newline at end of file
diff --git a/test/markdownlint-cli2-test-cases.js b/test/markdownlint-cli2-test-cases.js
index 285b2a33..f989f79b 100644
--- a/test/markdownlint-cli2-test-cases.js
+++ b/test/markdownlint-cli2-test-cases.js
@@ -41,6 +41,10 @@ const testCases =
path.join(directory, "markdownlint-cli2-codequality.json"),
"utf8"
).catch(empty),
+ fs.readFile(
+ path.join(directory, "custom-name-codequality.json"),
+ "utf8"
+ ).catch(empty),
fs.readFile(
path.join(directory, "markdownlint-cli2-results.json"),
"utf8"
@@ -64,6 +68,7 @@ const testCases =
const [
child,
formatterOutputCodeQuality,
+ formatterOutputCodeQualityCustom,
formatterOutputJson,
formatterOutputJsonCustom,
formatterOutputJunit,
@@ -73,7 +78,11 @@ const testCases =
"exitCode": child.exitCode,
"stdout": sanitize(child.stdout),
"stderr": sanitize(child.stderr),
- "formatterCodeQuality": sanitize(formatterOutputCodeQuality),
+ "formatterCodeQuality":
+ sanitize(
+ formatterOutputCodeQuality ||
+ formatterOutputCodeQualityCustom
+ ),
"formatterJson":
sanitize(formatterOutputJson || formatterOutputJsonCustom),
"formatterJunit":
@@ -266,7 +275,7 @@ const testCases =
testCase({
"name": "markdownlint-json-invalid",
"args": [ ".*" ],
- "stderrRe": /Unexpected end of JSON input/u
+ "stderrRe": /(?:Unexpected end)|(?:Expected property name)/u
});
testCase({
@@ -306,7 +315,7 @@ const testCases =
testCase({
"name": "markdownlint-cli2-jsonc-invalid",
"args": [ ".*" ],
- "stderrRe": /Unexpected end of JSON input/u
+ "stderrRe": /(?:Unexpected end)|(?:Expected property name)/u
});
testCase({
@@ -355,6 +364,12 @@ const testCases =
"usesRequire": true
});
+ testCase({
+ "name": "markdownlint-cli2-extends",
+ "args": [ "**/*.md" ],
+ "usesRequire": true
+ });
+
testCase({
"name": "config-overrides-options",
"args": [ "viewme.md" ]
@@ -487,10 +502,16 @@ const testCases =
}
const invalidConfigFiles = [
- [ "invalid.markdownlint-cli2.jsonc", /Unexpected end of JSON input/u ],
+ [
+ "invalid.markdownlint-cli2.jsonc",
+ /(?:Unexpected end)|(?:Expected property name)/u
+ ],
[ "invalid.markdownlint-cli2.cjs", /Unexpected end of input/u ],
[ "invalid.markdownlint-cli2.mjs", /Unexpected end of input/u ],
- [ "invalid.markdownlint.json", /Unexpected end of JSON input/u ],
+ [
+ "invalid.markdownlint.json",
+ /(?:Unexpected end)|(?:Expected property name)/u
+ ],
[ "invalid.markdownlint.yaml", /Map keys must be unique/u ],
[ "invalid.markdownlint.cjs", /Unexpected end of input/u ],
[ "invalid.markdownlint.mjs", /Unexpected end of input/u ]
@@ -553,6 +574,16 @@ const testCases =
"usesScript": true
});
+ testCase({
+ "name": "config-with-fix",
+ "script": "markdownlint-cli2-config.js",
+ "args": [ "config/.markdownlint-cli2.jsonc", "viewme.md", "info.md" ],
+ "cwd": directoryName("config-with-fix"),
+ "pre": copyDirectory,
+ "post": deleteDirectory,
+ "usesScript": true
+ });
+
testCase({
"name": "customRules",
"args": [ "**/*.md" ],
diff --git a/test/markdownlint-cli2-test.js b/test/markdownlint-cli2-test.js
index 6d9f67e9..99de0ebf 100644
--- a/test/markdownlint-cli2-test.js
+++ b/test/markdownlint-cli2-test.js
@@ -36,6 +36,7 @@ test("README files", (t) => {
t.plan(1);
const uncalled = (msg) => t.fail(`message logged: ${msg}`);
const argv = [
+ "CHANGELOG.md",
"README.md",
"./doc/OutputFormatters.md",
"./formatter-default/README.md",
diff --git a/test/outputFormatters-params-absolute/.markdownlint-cli2.cjs b/test/outputFormatters-params-absolute/.markdownlint-cli2.cjs
index 713e9a88..8794a5ea 100644
--- a/test/outputFormatters-params-absolute/.markdownlint-cli2.cjs
+++ b/test/outputFormatters-params-absolute/.markdownlint-cli2.cjs
@@ -6,6 +6,12 @@ const path = require("path");
module.exports = {
"outputFormatters": [
+ [
+ "../../formatter-codequality",
+ {
+ "name": path.resolve(__dirname, "custom-name-codequality.json")
+ }
+ ],
[
"../../formatter-json",
{
diff --git a/test/outputFormatters-params/.markdownlint-cli2.jsonc b/test/outputFormatters-params/.markdownlint-cli2.jsonc
index 4be335f3..5b2bab02 100644
--- a/test/outputFormatters-params/.markdownlint-cli2.jsonc
+++ b/test/outputFormatters-params/.markdownlint-cli2.jsonc
@@ -1,5 +1,6 @@
{
"outputFormatters": [
+ [ "../../formatter-codequality", { "name": "custom-name-codequality.json" } ],
[ "../../formatter-json", { "name": "custom-name.json", "spaces": 1 } ],
[ "../../formatter-junit", { "name": "custom-name.xml" } ]
]
diff --git a/test/snapshots/markdownlint-cli2-test-exec.js.md b/test/snapshots/markdownlint-cli2-test-exec.js.md
index 78a5d575..4b644ca3 100644
--- a/test/snapshots/markdownlint-cli2-test-exec.js.md
+++ b/test/snapshots/markdownlint-cli2-test-exec.js.md
@@ -1071,6 +1071,31 @@ Generated by [AVA](https://avajs.dev).
`,
}
+## markdownlint-cli2-extends (exec)
+
+> Snapshot 1
+
+ {
+ exitCode: 1,
+ formatterCodeQuality: '',
+ formatterJson: '',
+ formatterJunit: '',
+ stderr: `cjs/viewme.md:3:10 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1]␊
+ cjs/viewme.md:12:1 MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: "## Summary"]␊
+ jsonc/viewme.md:3:10 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1]␊
+ jsonc/viewme.md:12:1 MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: "## Summary"]␊
+ package/viewme.md:6 MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: "# Description"]␊
+ package/viewme.md:14:14 MD047/single-trailing-newline Files should end with a single newline character␊
+ yaml/viewme.md:3:10 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1]␊
+ yaml/viewme.md:12:1 MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: "## Summary"]␊
+ `,
+ stdout: `markdownlint-cli2 vX.Y.Z (markdownlint vX.Y.Z)␊
+ Finding: **/*.md␊
+ Linting: 4 file(s)␊
+ Summary: 8 error(s)␊
+ `,
+ }
+
## config-overrides-options (exec)
> Snapshot 1
@@ -2267,6 +2292,23 @@ Generated by [AVA](https://avajs.dev).
`,
}
+## config-with-fix (exec)
+
+> Snapshot 1
+
+ {
+ exitCode: 0,
+ formatterCodeQuality: '',
+ formatterJson: '',
+ formatterJunit: '',
+ stderr: '',
+ stdout: `markdownlint-cli2-config vX.Y.Z (markdownlint vX.Y.Z)␊
+ Finding: viewme.md info.md␊
+ Linting: 2 file(s)␊
+ Summary: 0 error(s)␊
+ `,
+ }
+
## customRules (exec)
> Snapshot 1
@@ -3424,7 +3466,73 @@ Generated by [AVA](https://avajs.dev).
{
exitCode: 1,
- formatterCodeQuality: '',
+ formatterCodeQuality: `[␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD009/no-trailing-spaces",␊
+ "description": "MD009/no-trailing-spaces: Trailing spaces [Expected: 0 or 2; Actual: 1]",␊
+ "severity": "minor",␊
+ "fingerprint": "f34a01e4a119d7df262993933665d4c97cc601702eeca2814ccad9606a3ccb48",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 3␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD012/no-multiple-blanks",␊
+ "description": "MD012/no-multiple-blanks: Multiple consecutive blank lines [Expected: 1; Actual: 2]",␊
+ "severity": "minor",␊
+ "fingerprint": "a3d9b647ce8d929904e64fbbb0a47223617e8985d0a4d31e674b22f919f736fb",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 5␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD025/single-title/single-h1",␊
+ "description": "MD025/single-title/single-h1: Multiple top-level headings in the same document",␊
+ "severity": "minor",␊
+ "fingerprint": "ef26889ac26be010b8bb6d2bd8c846c70bccf90506c0adffb763bef774f93f80",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 6␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD019/no-multiple-space-atx",␊
+ "description": "MD019/no-multiple-space-atx: Multiple spaces after hash on atx style heading",␊
+ "severity": "minor",␊
+ "fingerprint": "244fe04169875709c7854fc0ddef5c2639aa57bad8a9319e3a9ed6a5f8504c89",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 12␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD047/single-trailing-newline",␊
+ "description": "MD047/single-trailing-newline: Files should end with a single newline character",␊
+ "severity": "minor",␊
+ "fingerprint": "bf74eade0ee3301ccaa826907651e0d6925b60d517e1110c29b081c7b6ce1acf",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 14␊
+ }␊
+ }␊
+ }␊
+ ]`,
formatterJson: `[␊
{␊
"fileName": "viewme.md",␊
@@ -3552,7 +3660,73 @@ Generated by [AVA](https://avajs.dev).
{
exitCode: 1,
- formatterCodeQuality: '',
+ formatterCodeQuality: `[␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD009/no-trailing-spaces",␊
+ "description": "MD009/no-trailing-spaces: Trailing spaces [Expected: 0 or 2; Actual: 1]",␊
+ "severity": "minor",␊
+ "fingerprint": "f34a01e4a119d7df262993933665d4c97cc601702eeca2814ccad9606a3ccb48",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 3␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD012/no-multiple-blanks",␊
+ "description": "MD012/no-multiple-blanks: Multiple consecutive blank lines [Expected: 1; Actual: 2]",␊
+ "severity": "minor",␊
+ "fingerprint": "a3d9b647ce8d929904e64fbbb0a47223617e8985d0a4d31e674b22f919f736fb",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 5␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD025/single-title/single-h1",␊
+ "description": "MD025/single-title/single-h1: Multiple top-level headings in the same document",␊
+ "severity": "minor",␊
+ "fingerprint": "ef26889ac26be010b8bb6d2bd8c846c70bccf90506c0adffb763bef774f93f80",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 6␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD019/no-multiple-space-atx",␊
+ "description": "MD019/no-multiple-space-atx: Multiple spaces after hash on atx style heading",␊
+ "severity": "minor",␊
+ "fingerprint": "244fe04169875709c7854fc0ddef5c2639aa57bad8a9319e3a9ed6a5f8504c89",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 12␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD047/single-trailing-newline",␊
+ "description": "MD047/single-trailing-newline: Files should end with a single newline character",␊
+ "severity": "minor",␊
+ "fingerprint": "bf74eade0ee3301ccaa826907651e0d6925b60d517e1110c29b081c7b6ce1acf",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 14␊
+ }␊
+ }␊
+ }␊
+ ]`,
formatterJson: `[␊
{␊
"fileName": "viewme.md",␊
@@ -3794,7 +3968,7 @@ Generated by [AVA](https://avajs.dev).
formatterJunit: `␊
␊
␊
- ␊
+ ␊
␊
`,
stderr: '',
diff --git a/test/snapshots/markdownlint-cli2-test-exec.js.snap b/test/snapshots/markdownlint-cli2-test-exec.js.snap
index b2d19e3a..6b2aa522 100644
Binary files a/test/snapshots/markdownlint-cli2-test-exec.js.snap and b/test/snapshots/markdownlint-cli2-test-exec.js.snap differ
diff --git a/test/snapshots/markdownlint-cli2-test-main.js.md b/test/snapshots/markdownlint-cli2-test-main.js.md
index c30c10a9..6d89734a 100644
--- a/test/snapshots/markdownlint-cli2-test-main.js.md
+++ b/test/snapshots/markdownlint-cli2-test-main.js.md
@@ -921,6 +921,31 @@ Generated by [AVA](https://avajs.dev).
`,
}
+## markdownlint-cli2-extends (main)
+
+> Snapshot 1
+
+ {
+ exitCode: 1,
+ formatterCodeQuality: '',
+ formatterJson: '',
+ formatterJunit: '',
+ stderr: `cjs/viewme.md:3:10 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1]␊
+ cjs/viewme.md:12:1 MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: "## Summary"]␊
+ jsonc/viewme.md:3:10 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1]␊
+ jsonc/viewme.md:12:1 MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: "## Summary"]␊
+ package/viewme.md:6 MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: "# Description"]␊
+ package/viewme.md:14:14 MD047/single-trailing-newline Files should end with a single newline character␊
+ yaml/viewme.md:3:10 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1]␊
+ yaml/viewme.md:12:1 MD019/no-multiple-space-atx Multiple spaces after hash on atx style heading [Context: "## Summary"]␊
+ `,
+ stdout: `markdownlint-cli2 vX.Y.Z (markdownlint vX.Y.Z)␊
+ Finding: **/*.md␊
+ Linting: 4 file(s)␊
+ Summary: 8 error(s)␊
+ `,
+ }
+
## config-overrides-options (main)
> Snapshot 1
@@ -1847,7 +1872,73 @@ Generated by [AVA](https://avajs.dev).
{
exitCode: 1,
- formatterCodeQuality: '',
+ formatterCodeQuality: `[␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD009/no-trailing-spaces",␊
+ "description": "MD009/no-trailing-spaces: Trailing spaces [Expected: 0 or 2; Actual: 1]",␊
+ "severity": "minor",␊
+ "fingerprint": "f34a01e4a119d7df262993933665d4c97cc601702eeca2814ccad9606a3ccb48",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 3␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD012/no-multiple-blanks",␊
+ "description": "MD012/no-multiple-blanks: Multiple consecutive blank lines [Expected: 1; Actual: 2]",␊
+ "severity": "minor",␊
+ "fingerprint": "a3d9b647ce8d929904e64fbbb0a47223617e8985d0a4d31e674b22f919f736fb",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 5␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD025/single-title/single-h1",␊
+ "description": "MD025/single-title/single-h1: Multiple top-level headings in the same document",␊
+ "severity": "minor",␊
+ "fingerprint": "ef26889ac26be010b8bb6d2bd8c846c70bccf90506c0adffb763bef774f93f80",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 6␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD019/no-multiple-space-atx",␊
+ "description": "MD019/no-multiple-space-atx: Multiple spaces after hash on atx style heading",␊
+ "severity": "minor",␊
+ "fingerprint": "244fe04169875709c7854fc0ddef5c2639aa57bad8a9319e3a9ed6a5f8504c89",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 12␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD047/single-trailing-newline",␊
+ "description": "MD047/single-trailing-newline: Files should end with a single newline character",␊
+ "severity": "minor",␊
+ "fingerprint": "bf74eade0ee3301ccaa826907651e0d6925b60d517e1110c29b081c7b6ce1acf",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 14␊
+ }␊
+ }␊
+ }␊
+ ]`,
formatterJson: `[␊
{␊
"fileName": "viewme.md",␊
@@ -1975,7 +2066,73 @@ Generated by [AVA](https://avajs.dev).
{
exitCode: 1,
- formatterCodeQuality: '',
+ formatterCodeQuality: `[␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD009/no-trailing-spaces",␊
+ "description": "MD009/no-trailing-spaces: Trailing spaces [Expected: 0 or 2; Actual: 1]",␊
+ "severity": "minor",␊
+ "fingerprint": "f34a01e4a119d7df262993933665d4c97cc601702eeca2814ccad9606a3ccb48",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 3␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD012/no-multiple-blanks",␊
+ "description": "MD012/no-multiple-blanks: Multiple consecutive blank lines [Expected: 1; Actual: 2]",␊
+ "severity": "minor",␊
+ "fingerprint": "a3d9b647ce8d929904e64fbbb0a47223617e8985d0a4d31e674b22f919f736fb",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 5␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD025/single-title/single-h1",␊
+ "description": "MD025/single-title/single-h1: Multiple top-level headings in the same document",␊
+ "severity": "minor",␊
+ "fingerprint": "ef26889ac26be010b8bb6d2bd8c846c70bccf90506c0adffb763bef774f93f80",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 6␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD019/no-multiple-space-atx",␊
+ "description": "MD019/no-multiple-space-atx: Multiple spaces after hash on atx style heading",␊
+ "severity": "minor",␊
+ "fingerprint": "244fe04169875709c7854fc0ddef5c2639aa57bad8a9319e3a9ed6a5f8504c89",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 12␊
+ }␊
+ }␊
+ },␊
+ {␊
+ "type": "issue",␊
+ "check_name": "MD047/single-trailing-newline",␊
+ "description": "MD047/single-trailing-newline: Files should end with a single newline character",␊
+ "severity": "minor",␊
+ "fingerprint": "bf74eade0ee3301ccaa826907651e0d6925b60d517e1110c29b081c7b6ce1acf",␊
+ "location": {␊
+ "path": "viewme.md",␊
+ "lines": {␊
+ "begin": 14␊
+ }␊
+ }␊
+ }␊
+ ]`,
formatterJson: `[␊
{␊
"fileName": "viewme.md",␊
@@ -2217,7 +2374,7 @@ Generated by [AVA](https://avajs.dev).
formatterJunit: `␊
␊
␊
- ␊
+ ␊
␊
`,
stderr: '',
diff --git a/test/snapshots/markdownlint-cli2-test-main.js.snap b/test/snapshots/markdownlint-cli2-test-main.js.snap
index 09cdc89e..6f3dfaef 100644
Binary files a/test/snapshots/markdownlint-cli2-test-main.js.snap and b/test/snapshots/markdownlint-cli2-test-main.js.snap differ