Skip to content

Commit

Permalink
docs: Add linter for the documentation
Browse files Browse the repository at this point in the history
Add mdl as a linter for new cnf-testsuite documentation
Add custom rules for keeping format of the documentation
Add lint to git pipelines to run mdl.

Signed-off-by: Konstantin Yarovoy <[email protected]>
  • Loading branch information
Konstantin Yarovoy committed Apr 22, 2024
1 parent 355a26f commit b7a499a
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@ on:
- '**'
- '!**.md'
jobs:
lint-docs:
name: Lint Docs
runs-on: ubuntu-latest
container:
image: ruby:latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install mdl
run: gem install mdl
- name: Run mdl
run: mdl -s docs/mdl-style.rb -u docs/mdl-custom-rules.rb docs/TEST_DOCUMENTATION.md

tests:
name: Fetch Matrix Tests
runs-on: [ubuntu-latest]
Expand Down
111 changes: 111 additions & 0 deletions docs/mdl-TTDS-rules.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# TTDS stands for Testsuite Test Documentation Style
rule "TTDS001", "Testsuite documentation header format" do
tags :documentation
check do |doc|
parsed = doc.parsed
violation_lines = []
parsed.root.children.each do |element|
if element.type == :header
text = element.options[:raw_text]
line_number = element.options[:location]
case element.options[:level]
when 2
unless text == "Table of Contents" || text.start_with?("Category:")
violation_lines << line_number
end
when 4
allowed_texts = ["Overview", "Rationale", "Remediation", "Usage"]
unless allowed_texts.include?(text)
violation_lines << line_number
end
end
end
end
violation_lines.empty? ? nil : violation_lines
end
end

rule "TTDS002", "All categories and tests are present in TOC" do
tags :documentation
check do |doc|
toc_regex = /## Table of Contents\n\n[\s\S]*?\n## /m
doc_text = doc.lines.join("\n")
toc_text = doc_text.scan(toc_regex).first
parsed = doc.parsed
violation_lines = []
if toc_text.nil?
puts "Table of Contents not found"
violation_lines << 1
end
parsed.root.children.each do |element|
if element.type == :header
text = element.options[:raw_text]
line_number = element.options[:location]
case element.options[:level]
when 2
unless toc_text.include?(text)
violation_lines << line_number
end
when 3
unless text == "Usage" || toc_text.include?(text)
violation_lines << line_number
end
end
end
end
violation_lines.empty? ? nil : violation_lines
end
end

rule "TTDS003", "Separators before tests and categories are present" do
tags :documentation
check do |doc|
parsed = doc.parsed
violation_lines = []
parsed.root.children.each do |element|
if element.type == :header
text = element.options[:raw_text]
line_number = element.options[:location]
case element.options[:level]
when 2, 3
unless text == "Table of Contents" || text == "Usage"
separator_line_number = line_number - 3
separator_line = doc.lines[separator_line_number.clamp(0, doc.lines.length - 1)]
unless separator_line.strip =~ /---/
violation_lines << line_number
end
end
end
end
end
violation_lines.empty? ? nil : violation_lines
end
end

rule "TTDS004", "Tests should have all required sub-sections" do
tags :documentation
check do |doc|
parsed = doc.parsed
violation_lines = []
required_subsections = ["Overview", "Rationale", "Remediation", "Usage"]
current_test_header = nil
found_subsections = []
parsed.root.children.each do |element|
if element.type == :header
if element.options[:level] == 3 && element.options[:raw_text] != "Usage"
unless found_subsections.sort == required_subsections.sort || current_test_header.nil?
violation_lines << current_test_header.options[:location]
end
current_test_header = element
found_subsections = []
elsif element.options[:level] == 4
found_subsections << element.options[:raw_text]
end
end
end
unless found_subsections.sort == required_subsections.sort
violation_lines << current_test_header.options[:location]
end
violation_lines.empty? ? nil : violation_lines
end
end
5 changes: 5 additions & 0 deletions docs/mdl-style.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
all
exclude_rule 'MD013' # Line length
exclude_rule 'MD024' # Multiple headers with the same content
exclude_rule 'MD057' # Table has missing or invalid header separation
exclude_rule 'MD055' # Table row doesn't begin/end with pipes

0 comments on commit b7a499a

Please sign in to comment.