File tree Expand file tree Collapse file tree 7 files changed +76
-12
lines changed
Expand file tree Collapse file tree 7 files changed +76
-12
lines changed Original file line number Diff line number Diff line change @@ -14,7 +14,10 @@ import createMarkdownParser from '../src/parsers/markdown.mjs';
1414import createNodeReleases from '../src/releases.mjs' ;
1515import createLinter from '../src/linter/index.mjs' ;
1616import reporters from '../src/linter/reporters/index.mjs' ;
17- import rules from '../src/linter/rules/index.mjs' ;
17+ import {
18+ multiEntryRules ,
19+ singleEntryRules ,
20+ } from '../src/linter/rules/index.mjs' ;
1821
1922const availableGenerators = Object . keys ( generators ) ;
2023
@@ -61,7 +64,9 @@ program
6164 )
6265 . addOption (
6366 new Option ( '--disable-rule [rule...]' , 'Disable a specific linter rule' )
64- . choices ( Object . keys ( rules ) )
67+ . choices (
68+ Object . keys ( multiEntryRules ) . concat ( Object . keys ( singleEntryRules ) )
69+ )
6570 . default ( [ ] )
6671 )
6772 . addOption (
Original file line number Diff line number Diff line change @@ -425,4 +425,5 @@ export const LINT_MESSAGES = {
425425 missingIntroducedIn : "Missing 'introduced_in' field in the API doc entry" ,
426426 missingChangeVersion : 'Missing version field in the API doc entry' ,
427427 invalidChangeVersion : 'Invalid version number: {{version}}' ,
428+ duplicateStabilityNode : 'Duplicate stability node' ,
428429} ;
Original file line number Diff line number Diff line change 33/**
44 * Creates a linter engine instance to validate ApiDocMetadataEntry entries
55 *
6- * @param {import('./types').LintRule } rules Lint rules to validate the entries against
6+ * @param {{
7+ * multiEntryRules: import('./types').MultipleEntriesLintRules[]
8+ * singleEntryRules: import('./types').SingleEntryLintRule[]
9+ * }} rules Lint rules to validate the entries against
710 */
8- const createLinterEngine = rules => {
11+ const createLinterEngine = ( { multiEntryRules , singleEntryRules } ) => {
912 /**
1013 * Validates a ApiDocMetadataEntry entry against all defined rules
1114 *
@@ -15,7 +18,7 @@ const createLinterEngine = rules => {
1518 const lint = entry => {
1619 const issues = [ ] ;
1720
18- for ( const rule of rules ) {
21+ for ( const rule of singleEntryRules ) {
1922 const ruleIssues = rule ( entry ) ;
2023
2124 if ( ruleIssues . length > 0 ) {
@@ -35,6 +38,10 @@ const createLinterEngine = rules => {
3538 const lintAll = entries => {
3639 const issues = [ ] ;
3740
41+ for ( const rule of multiEntryRules ) {
42+ issues . push ( ...rule ( entries ) ) ;
43+ }
44+
3845 for ( const entry of entries ) {
3946 issues . push ( ...lint ( entry ) ) ;
4047 }
Original file line number Diff line number Diff line change 22
33import createLinterEngine from './engine.mjs' ;
44import reporters from './reporters/index.mjs' ;
5- import rules from './rules/index.mjs' ;
5+ import { multiEntryRules , singleEntryRules } from './rules/index.mjs' ;
66
77/**
88 * Creates a linter instance to validate ApiDocMetadataEntry entries
@@ -13,16 +13,19 @@ import rules from './rules/index.mjs';
1313const createLinter = ( dryRun , disabledRules ) => {
1414 /**
1515 * Retrieves all enabled rules
16- *
16+ * @param { Record<string, import('./types').LintRule> } rules
1717 * @returns {import('./types').LintRule[] }
1818 */
19- const getEnabledRules = ( ) => {
19+ const getEnabledRules = rules => {
2020 return Object . entries ( rules )
2121 . filter ( ( [ ruleName ] ) => ! disabledRules . includes ( ruleName ) )
2222 . map ( ( [ , rule ] ) => rule ) ;
2323 } ;
2424
25- const engine = createLinterEngine ( getEnabledRules ( disabledRules ) ) ;
25+ const engine = createLinterEngine ( {
26+ multiEntryRules : getEnabledRules ( multiEntryRules ) ,
27+ singleEntryRules : getEnabledRules ( singleEntryRules ) ,
28+ } ) ;
2629
2730 /**
2831 * Lint issues found during validations
Original file line number Diff line number Diff line change 1+ import { LINT_MESSAGES } from '../../constants.mjs' ;
2+
3+ /**
4+ * Checks if there are multiple stability nodes within a chain.
5+ *
6+ * @param {ApiDocMetadataEntry[] } entries
7+ * @returns {Array<import('../types').LintIssue> }
8+ */
9+ export const duplicateStabilityNodes = entries => {
10+ const issues = [ ] ;
11+ let currentDepth = 0 ;
12+ let currentStability = - 1 ;
13+
14+ for ( const entry of entries ) {
15+ const { depth } = entry . heading . data ;
16+ const entryStability = entry . stability . children [ 0 ] ?. data . index ?? - 1 ;
17+
18+ if (
19+ depth > currentDepth &&
20+ entryStability >= 0 &&
21+ entryStability === currentStability
22+ ) {
23+ issues . push ( {
24+ level : 'warn' ,
25+ message : LINT_MESSAGES . duplicateStabilityNode ,
26+ location : {
27+ path : entry . api_doc_source ,
28+ position : entry . yaml_position ,
29+ } ,
30+ } ) ;
31+ } else {
32+ currentDepth = depth ;
33+ currentStability = entryStability ;
34+ }
35+ }
36+
37+ return issues ;
38+ } ;
Original file line number Diff line number Diff line change 11'use strict' ;
22
3+ import { duplicateStabilityNodes } from './duplicate-stability-nodes.mjs' ;
34import { invalidChangeVersion } from './invalid-change-version.mjs' ;
45import { missingChangeVersion } from './missing-change-version.mjs' ;
56import { missingIntroducedIn } from './missing-introduced-in.mjs' ;
67
78/**
8- * @type {Record<string, import('../types').LintRule > }
9+ * @type {Record<string, import('../types').SingleEntryLintRule > }
910 */
10- export default {
11+ export const singleEntryRules = {
1112 'invalid-change-version' : invalidChangeVersion ,
1213 'missing-change-version' : missingChangeVersion ,
1314 'missing-introduced-in' : missingIntroducedIn ,
1415} ;
16+
17+ /**
18+ * @type {Record<string, import('../types').MultipleEntriesLintRule> }
19+ */
20+ export const multiEntryRules = {
21+ 'duplicate-stability-nodes' : duplicateStabilityNodes ,
22+ } ;
Original file line number Diff line number Diff line change @@ -13,6 +13,8 @@ export interface LintIssue {
1313 location : LintIssueLocation ;
1414}
1515
16- type LintRule = ( input : ApiDocMetadataEntry ) => LintIssue [ ] ;
16+ type LintRule = MultipleEntriesLintRules | SingleEntryLintRule ;
17+ type MultipleEntriesLintRules = ( input : ApiDocMetadataEntry [ ] ) => LintIssue [ ] ;
18+ type SingleEntryLintRule = ( input : ApiDocMetadataEntry ) => LintIssue [ ] ;
1719
1820export type Reporter = ( msg : LintIssue ) => void ;
You can’t perform that action at this time.
0 commit comments