diff --git a/bin/lint-markdown-api-history.ts b/bin/lint-markdown-api-history.ts
index 019a609..80656bd 100644
--- a/bin/lint-markdown-api-history.ts
+++ b/bin/lint-markdown-api-history.ts
@@ -11,7 +11,7 @@ import * as minimist from 'minimist';
import type { Literal, Node } from 'unist';
import type { visit as VisitFunction } from 'unist-util-visit';
import { URI } from 'vscode-uri';
-import { parse as parseYaml } from 'yaml';
+import { parseDocument, visit as yamlVisit } from 'yaml';
import { dynamicImport } from '../lib/helpers';
import { DocsWorkspace } from '../lib/markdown';
@@ -42,6 +42,8 @@ interface Options {
checkStrings: boolean;
// Check if the API history block contains descriptions that aren't surrounded by double quotation marks
checkDescriptions: boolean;
+ // Check if the API history block contains comments
+ disallowComments: boolean;
// Array of glob patterns to ignore when processing files
ignoreGlobs: string[];
// Check if the API history block's YAML adheres to the JSON schema at this filepath
@@ -106,6 +108,7 @@ async function main(
breakingChangesFile,
checkStrings,
checkDescriptions,
+ disallowComments,
schema,
ignoreGlobs = [],
}: Options,
@@ -290,10 +293,12 @@ async function main(
}
}
+ let unsafeHistoryDocument = null;
let unsafeHistory = null;
try {
- unsafeHistory = parseYaml(codeBlock.value);
+ unsafeHistoryDocument = parseDocument(codeBlock.value);
+ unsafeHistory = unsafeHistoryDocument.toJS();
} catch (error) {
console.error(
'Error occurred while parsing Markdown document:\n\n' +
@@ -306,6 +311,33 @@ async function main(
continue;
}
+ if (disallowComments) {
+ let commentFound = false;
+
+ yamlVisit(unsafeHistoryDocument, (_, node) => {
+ if (
+ typeof node === 'object' &&
+ node !== null &&
+ ('comment' in node || 'commentBefore' in node)
+ ) {
+ commentFound = true;
+ return yamlVisit.BREAK;
+ }
+ });
+
+ if (commentFound) {
+ console.error(
+ 'Error occurred while parsing Markdown document:\n\n' +
+ `'${filepath}'\n\n` +
+ 'API History cannot contain YAML comments.\n\n' +
+ 'API history block:\n\n' +
+ `${possibleHistoryBlock.value}\n`,
+ );
+ errorCounter++;
+ continue;
+ }
+ }
+
if (!schema || validateAgainstSchema === null) continue;
const isValid = validateAgainstSchema(unsafeHistory);
@@ -380,7 +412,7 @@ function parseCommandLine() {
console.log(
'Usage: lint-roller-markdown-api-history [--root
] ' +
' [-h|--help]' +
- ' [--check-placement] [--breaking-changes-file ] [--check-strings] [--check-descriptions]' +
+ ' [--check-placement] [--breaking-changes-file ] [--check-strings] [--check-descriptions] [--disallow-comments]' +
' [--schema ]' +
' [--ignore ] [--ignore-path ]',
);
@@ -391,13 +423,20 @@ function parseCommandLine() {
};
const opts = minimist(process.argv.slice(2), {
- boolean: ['help', 'check-placement', 'check-strings', 'check-descriptions'],
+ boolean: [
+ 'help',
+ 'check-placement',
+ 'check-strings',
+ 'check-descriptions',
+ 'disallow-comments',
+ ],
string: ['root', 'ignore', 'ignore-path', 'schema', 'breaking-changes-file'],
unknown: showUsage,
default: {
'check-placement': true,
'check-strings': true,
'check-descriptions': true,
+ 'disallow-comments': true,
},
});
@@ -444,6 +483,7 @@ async function init() {
breakingChangesFile: opts['breaking-changes-file'],
checkStrings: opts['check-strings'],
checkDescriptions: opts['check-descriptions'],
+ disallowComments: opts['disallow-comments'],
ignoreGlobs: opts.ignore,
schema: opts.schema,
},
diff --git a/tests/fixtures/api-history-line-comment.md b/tests/fixtures/api-history-line-comment.md
new file mode 100644
index 0000000..251f7ad
--- /dev/null
+++ b/tests/fixtures/api-history-line-comment.md
@@ -0,0 +1,18 @@
+#### `win.setTrafficLightPosition(position)` _macOS_ _Deprecated_
+
+
+
+Set a custom position for the traffic light buttons in frameless window.
+Passing `{ x: 0, y: 0 }` will reset the position to default.
diff --git a/tests/fixtures/api-history-separated-comment.md b/tests/fixtures/api-history-separated-comment.md
new file mode 100644
index 0000000..796fdc5
--- /dev/null
+++ b/tests/fixtures/api-history-separated-comment.md
@@ -0,0 +1,17 @@
+#### `win.setTrafficLightPosition(position)` _macOS_ _Deprecated_
+
+
+
+Set a custom position for the traffic light buttons in frameless window.
+Passing `{ x: 0, y: 0 }` will reset the position to default.
diff --git a/tests/fixtures/api-history-valid-hashtags.md b/tests/fixtures/api-history-valid-hashtags.md
new file mode 100644
index 0000000..6003cc9
--- /dev/null
+++ b/tests/fixtures/api-history-valid-hashtags.md
@@ -0,0 +1,17 @@
+#### `win.setTrafficLightPosition(position)` _macOS_ _Deprecated_
+
+
+
+Set a custom position for the traffic light buttons in frameless window.
+Passing `{ x: 0, y: 0 }` will reset the position to default.
diff --git a/tests/lint-roller-markdown-api-history.spec.ts b/tests/lint-roller-markdown-api-history.spec.ts
index 8b4a6c7..3485cde 100644
--- a/tests/lint-roller-markdown-api-history.spec.ts
+++ b/tests/lint-roller-markdown-api-history.spec.ts
@@ -162,6 +162,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'api-history-valid.md',
);
@@ -185,10 +186,11 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'api-history-yaml-invalid.md',
);
- expect(stderr).toMatch(/YAMLParseError: Nested mappings are not allowed/);
+ expect(stderr).toMatch(/must be array/);
const [blocks, documents, errors, warnings] = stdoutRegex.exec(stdout)?.slice(1, 5) ?? [];
@@ -208,6 +210,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'api-history-schema-invalid.md',
);
@@ -231,6 +234,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'api-history-format-invalid.md',
);
@@ -256,6 +260,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'api-history-heading-missing.md',
);
@@ -281,6 +286,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'api-history-placement-invalid.md',
);
@@ -306,11 +312,12 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'api-history-string-invalid.md',
);
expect(stderr).toMatch(/Possible string value starts\/ends with a non-alphanumeric character/);
- expect(stderr).toMatch(/YAMLParseError: Nested mappings are not allowed/);
+ expect(stderr).toMatch(/must be string/);
const [blocks, documents, errors, warnings] = stdoutRegex.exec(stdout)?.slice(1, 5) ?? [];
@@ -332,6 +339,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'api-history-description-invalid.md',
);
@@ -346,6 +354,32 @@ describe('lint-roller-markdown-api-history', () => {
expect(status).toEqual(1);
});
+ it('should not run clean when there are yaml comments', () => {
+ const { status, stdout, stderr } = runLintMarkdownApiHistory(
+ '--root',
+ FIXTURES_DIR,
+ '--schema',
+ API_HISTORY_SCHEMA,
+ '--breaking-changes-file',
+ BREAKING_CHANGES_FILE,
+ '--check-placement',
+ '--check-strings',
+ '--check-descriptions',
+ '--disallow-comments',
+ '{api-history-line-comment,api-history-separated-comment,api-history-valid-hashtags}.md',
+ );
+
+ expect(stderr).toMatch(/API History cannot contain YAML comments./);
+
+ const [blocks, documents, errors, warnings] = stdoutRegex.exec(stdout)?.slice(1, 5) ?? [];
+
+ expect(Number(blocks)).toEqual(3);
+ expect(Number(documents)).toEqual(3);
+ expect(Number(errors)).toEqual(2);
+ expect(Number(warnings)).toEqual(0);
+ expect(status).toEqual(1);
+ });
+
it('can ignore a glob', () => {
const { status, stdout } = runLintMarkdownApiHistory(
'--root',
@@ -355,6 +389,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'--ignore',
'**/api-history-yaml-invalid.md',
'{api-history-valid,api-history-yaml-invalid}.md',
@@ -378,6 +413,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'--ignore',
'**/api-history-valid.md',
'--ignore',
@@ -405,6 +441,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'{api-history-valid,api-history-yaml-invalid}.md',
);
@@ -428,6 +465,7 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
'{api-history-valid,api-history-yaml-invalid,api-history-heading-missing}.md',
);
@@ -463,6 +501,8 @@ describe('lint-roller-markdown-api-history', () => {
'--check-placement',
'--check-strings',
'--check-descriptions',
+ '--disallow-comments',
+ 'false',
'*.md',
);