From 9ff48caa0096e5b88a91396064cfe66ce613c00f Mon Sep 17 00:00:00 2001 From: MeilCli Date: Mon, 10 May 2021 13:12:51 +0900 Subject: [PATCH] feature: add markdownlint transformer --- README.md | 2 + __test__/transformer/markdownlint.test.ts | 41 +++++++++++++++++ data/markdownlint.txt | 3 ++ data/markdownlint/command.md | 2 + data/markdownlint/test.md | 3 ++ documents/transformer/markdownlint.md | 22 +++++++++ src/transformer/markdownlint.ts | 55 +++++++++++++++++++++++ transformer/markdownlint/action.yml | 19 ++++++++ webpack.config.js | 1 + 9 files changed, 148 insertions(+) create mode 100644 __test__/transformer/markdownlint.test.ts create mode 100644 data/markdownlint.txt create mode 100644 data/markdownlint/command.md create mode 100644 data/markdownlint/test.md create mode 100644 documents/transformer/markdownlint.md create mode 100644 src/transformer/markdownlint.ts create mode 100644 transformer/markdownlint/action.yml diff --git a/README.md b/README.md index 6ab316e4..c71ffae5 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Focuses on: Current supporting lint file format: - eslint(JSON) - textlint(JSON) +- markdownlint - checkstyle - junit - compatibility: eslint, textlint @@ -63,6 +64,7 @@ jobs: - Transformer - [eslint](documents/transformer/eslint.md) - [textlint](documents/transformer/textlint.md) + - [markdownlint](documents/transformer/markdownlint.md) - [checkstyle](documents/transformer/checkstyle.md) - [junit](documents/transformer/junit.md) - Operator diff --git a/__test__/transformer/markdownlint.test.ts b/__test__/transformer/markdownlint.test.ts new file mode 100644 index 00000000..24d152b4 --- /dev/null +++ b/__test__/transformer/markdownlint.test.ts @@ -0,0 +1,41 @@ +import { MarkdownLintTransformer } from "../../src/transformer/markdownlint"; +import { LintResult } from "../../src/lint-result"; +import * as fs from "fs"; + +test("transform", async () => { + const text = fs.readFileSync("data/markdownlint.txt", "utf-8"); + const transformer = new MarkdownLintTransformer(); + const result = transformer.parse(text); + + expect(result.length).toBe(3); + expect(result[0]).toMatchObject({ + path: "data/markdownlint/test.md", + rule: "MD022/blanks-around-headings/blanks-around-headers", + message: "Headings should be surrounded by blank lines", + startLine: 1, + endLine: undefined, + startColumn: undefined, + endColumn: undefined, + level: "warning", + } as LintResult); + expect(result[1]).toMatchObject({ + path: "data/markdownlint/test.md", + rule: "MD041/first-line-heading/first-line-h1", + message: "First line in a file should be a top-level heading", + startLine: 1, + endLine: undefined, + startColumn: undefined, + endColumn: undefined, + level: "warning", + } as LintResult); + expect(result[2]).toMatchObject({ + path: "data/markdownlint/test.md", + rule: "MD047/single-trailing-newline", + message: "Files should end with a single newline character", + startLine: 3, + endLine: undefined, + startColumn: undefined, + endColumn: undefined, + level: "warning", + } as LintResult); +}); diff --git a/data/markdownlint.txt b/data/markdownlint.txt new file mode 100644 index 00000000..9c17161c --- /dev/null +++ b/data/markdownlint.txt @@ -0,0 +1,3 @@ +data/markdownlint/test.md:1 MD022/blanks-around-headings/blanks-around-headers Headings should be surrounded by blank lines [Expected: 1; Actual: 0; Below] [Context: "## Summary"] +data/markdownlint/test.md:1 MD041/first-line-heading/first-line-h1 First line in a file should be a top-level heading [Context: "## Summary"] +data/markdownlint/test.md:3:13 MD047/single-trailing-newline Files should end with a single newline character diff --git a/data/markdownlint/command.md b/data/markdownlint/command.md new file mode 100644 index 00000000..aeaab3df --- /dev/null +++ b/data/markdownlint/command.md @@ -0,0 +1,2 @@ +1. `npm install -g markdownlint-cli` +1. `markdownlint -o data/markdownlint.txt data/markdownlint/test.md ` \ No newline at end of file diff --git a/data/markdownlint/test.md b/data/markdownlint/test.md new file mode 100644 index 00000000..ca4ccdd5 --- /dev/null +++ b/data/markdownlint/test.md @@ -0,0 +1,3 @@ +## Summary +test message +test`message` \ No newline at end of file diff --git a/documents/transformer/markdownlint.md b/documents/transformer/markdownlint.md new file mode 100644 index 00000000..69a1f566 --- /dev/null +++ b/documents/transformer/markdownlint.md @@ -0,0 +1,22 @@ +# Transformer of markdownlint +```yml +- uses: MeilCli/common-lint-reporter/transformer/markdownlint@v0 + with: + report_files: | + markdownlint_report.txt +``` + +**must save markdownlint result to file** + +## Option +### Input +- `report_files`: + - report file glob pattern + - required +- `report_files_follow_symbolic_links`: + - report file glob pattern option + - value: `true` or `false` +- `output_path`: + - output path + - required + - default: `common_lint.json` \ No newline at end of file diff --git a/src/transformer/markdownlint.ts b/src/transformer/markdownlint.ts new file mode 100644 index 00000000..f21a8af0 --- /dev/null +++ b/src/transformer/markdownlint.ts @@ -0,0 +1,55 @@ +import * as core from "@actions/core"; +import { getOption } from "./option"; +import { LintResult } from "../lint-result"; +import { Transformer } from "./transformer"; + +export class MarkdownLintTransformer extends Transformer { + parse(body: string): LintResult[] { + const lintResults: LintResult[] = []; + for (const line of body.split(/(\r\n)|\n|\r/g)) { + if (line == undefined || line.length == 0) { + continue; + } + const pathAndLineAndColumnEndIndex = line.indexOf(" "); + if (pathAndLineAndColumnEndIndex < 0) { + continue; + } + const pathAndLineAndColumn = line.slice(0, pathAndLineAndColumnEndIndex); + const locations = pathAndLineAndColumn.split(":"); + const path = locations[0]; + const startLine = + 1 <= locations.length && Number.isInteger(parseInt(locations[1])) ? parseInt(locations[1]) : undefined; + const ruleEndIndex = line.indexOf(" ", pathAndLineAndColumnEndIndex + 1); + if (ruleEndIndex < 0) { + continue; + } + const rule = line.slice(pathAndLineAndColumnEndIndex + 1, ruleEndIndex); + const message = line.slice(ruleEndIndex + 1).replace(/^(.+?)\s?(\[.+\])*?$/, "$1"); + lintResults.push({ + path: path, + message: message, + rule: rule, + startLine: startLine, + startColumn: undefined, + endLine: undefined, + endColumn: undefined, + level: "warning", + }); + } + return lintResults; + } +} + +async function run() { + try { + const option = getOption(); + const transformer = new MarkdownLintTransformer(); + await transformer.transform(option); + } catch (error) { + core.setFailed(error.message); + } +} + +if (process.env.NODE_ENV != "test") { + run(); +} diff --git a/transformer/markdownlint/action.yml b/transformer/markdownlint/action.yml new file mode 100644 index 00000000..f9978d7b --- /dev/null +++ b/transformer/markdownlint/action.yml @@ -0,0 +1,19 @@ +name: 'markdownlint transformer of common lint reporter' +description: 'transformer of markdownlint report file to common lint report' +author: 'MeilCli' +branding: + icon: layers + color: orange +inputs: + report_files: + description: 'report file glob pattern' + required: true + report_files_follow_symbolic_links: + description: 'report file glob pattern option' + output_path: + description: 'output path' + required: true + default: 'common_lint.json' +runs: + using: 'node12' + main: '../../dist/transformer-markdownlint.js' diff --git a/webpack.config.js b/webpack.config.js index 22668757..1e103148 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,6 +8,7 @@ module.exports = { "transformer-checkstyle": "./src/transformer/checkstyle.ts", "transformer-eslint": "./src/transformer/eslint.ts", "transformer-textlint": "./src/transformer/textlint.ts", + "transformer-markdownlint": "./src/transformer/markdownlint.ts", "transformer-junit": "./src/transformer/junit.ts", "operator-filter": "./src/operator/filter.ts", "operator-filter-by-file-changed": "./src/operator/filter-by-file-changed.ts",