Skip to content

Commit ab78eeb

Browse files
authored
Merge pull request #39739 from github/repo-sync
Repo sync
2 parents 47cd7a9 + 391fb60 commit ab78eeb

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

src/content-linter/scripts/lint-content.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,8 @@ function getMarkdownLintConfig(errorsOnly, runRules) {
551551
continue
552552
}
553553

554-
if (runRules && !runRules.includes(ruleName)) continue
554+
// Check if the rule should be included based on user-specified rules
555+
if (runRules && !shouldIncludeRule(ruleName, runRules)) continue
555556

556557
// Skip british-english-quotes rule in CI/PRs (only run in pre-commit)
557558
if (ruleName === 'british-english-quotes' && !isPrecommit) continue
@@ -638,6 +639,29 @@ function getCustomRule(ruleName) {
638639
return rule
639640
}
640641

642+
// Check if a rule should be included based on user-specified rules
643+
// Handles both short names (e.g., GHD053, MD001) and long names (e.g., header-content-requirement, heading-increment)
644+
export function shouldIncludeRule(ruleName, runRules) {
645+
// First check if the rule name itself is in the list
646+
if (runRules.includes(ruleName)) {
647+
return true
648+
}
649+
650+
// For custom rules, check if any of the rule's names (short or long) are in the runRules list
651+
const customRule = customRules.find((rule) => rule.names.includes(ruleName))
652+
if (customRule) {
653+
return customRule.names.some((name) => runRules.includes(name))
654+
}
655+
656+
// For built-in markdownlint rules, check if any of the rule's names are in the runRules list
657+
const builtinRule = allRules.find((rule) => rule.names.includes(ruleName))
658+
if (builtinRule) {
659+
return builtinRule.names.some((name) => runRules.includes(name))
660+
}
661+
662+
return false
663+
}
664+
641665
/*
642666
The severity of the search-replace custom rule is embedded in
643667
each individual search rule. This function returns the severity
@@ -681,9 +705,7 @@ function isOptionsValid() {
681705
}
682706

683707
// rules should only contain existing, correctly spelled rules
684-
const allRulesList = Object.values(allRules)
685-
.map((rule) => rule.names)
686-
.flat()
708+
const allRulesList = [...allRules.map((rule) => rule.names).flat(), ...Object.keys(allConfig)]
687709
const rules = program.opts().rules || []
688710
for (const rule of rules) {
689711
if (!allRulesList.includes(rule)) {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { describe, test, expect, vi } from 'vitest'
2+
import { shouldIncludeRule } from '../../scripts/lint-content.js'
3+
4+
// Mock the get-rules module to provide test data for rule definitions
5+
vi.mock('../../lib/helpers/get-rules', () => ({
6+
allRules: [
7+
{
8+
names: ['MD001', 'heading-increment'],
9+
description: 'Heading levels should only increment by one level at a time',
10+
},
11+
{
12+
names: ['MD002', 'first-heading-h1'],
13+
description: 'First heading should be a top level heading',
14+
},
15+
],
16+
customRules: [
17+
{
18+
names: ['GHD053', 'header-content-requirement'],
19+
description: 'Headers must have content below them',
20+
},
21+
{
22+
names: ['GHD030', 'code-fence-line-length'],
23+
description: 'Code fence content should not exceed line length limit',
24+
},
25+
],
26+
allConfig: {},
27+
}))
28+
29+
describe('shouldIncludeRule', () => {
30+
test('includes rule by long name', () => {
31+
expect(shouldIncludeRule('heading-increment', ['heading-increment'])).toBe(true)
32+
expect(shouldIncludeRule('header-content-requirement', ['header-content-requirement'])).toBe(
33+
true,
34+
)
35+
})
36+
37+
test('includes built-in rule by short code', () => {
38+
expect(shouldIncludeRule('heading-increment', ['MD001'])).toBe(true)
39+
expect(shouldIncludeRule('first-heading-h1', ['MD002'])).toBe(true)
40+
})
41+
42+
test('includes custom rule by short code', () => {
43+
expect(shouldIncludeRule('header-content-requirement', ['GHD053'])).toBe(true)
44+
expect(shouldIncludeRule('code-fence-line-length', ['GHD030'])).toBe(true)
45+
})
46+
47+
test('excludes rule not in list', () => {
48+
expect(shouldIncludeRule('heading-increment', ['MD002'])).toBe(false)
49+
expect(shouldIncludeRule('header-content-requirement', ['GHD030'])).toBe(false)
50+
})
51+
52+
test('handles multiple rules', () => {
53+
const runRules = ['MD001', 'GHD053', 'some-other-rule']
54+
expect(shouldIncludeRule('heading-increment', runRules)).toBe(true)
55+
expect(shouldIncludeRule('header-content-requirement', runRules)).toBe(true)
56+
expect(shouldIncludeRule('first-heading-h1', runRules)).toBe(false)
57+
})
58+
59+
test('handles unknown rules gracefully', () => {
60+
expect(shouldIncludeRule('non-existent-rule', ['MD001'])).toBe(false)
61+
})
62+
})

0 commit comments

Comments
 (0)