tools/checkpatch: Add Markdown linter support

Use 'pymarkdownlnt' to lint Markdown files and enforce a strict style.
If the linter is not found, a single error message is printed and the
Markdown checks are skipped.

Example checkpatch output (line breaks added for commit message only):

ERROR:MARKDOWN_LINT: ./README.md:1:1: MD041: First line in file should
be a top level heading (first-line-heading,first-line-h1)

ERROR:MARKDOWN_LINT: ./README.md:272:1: MD012: Multiple consecutive
blank lines [Expected: 1, Actual: 4] (no-multiple-blanks)

ERROR:MARKDOWN_LINT: ./README.md:273:35: MD026: Trailing punctuation
present in heading text. (no-trailing-punctuation)

Change-Id: I460ef881b83eb0a2eb46ee62d520b514785ad4e1
Signed-off-by: Marc Schink <dev@zapb.de>
Reviewed-on: https://review.openocd.org/c/openocd/+/9474
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
Marc Schink
2026-02-17 11:21:34 +01:00
committed by Antonio Borneo
parent c3b4bcc6e6
commit 092282c7d2
2 changed files with 54 additions and 0 deletions

View File

@@ -262,6 +262,7 @@ Optional development script checkpatch needs:
- perl
- python
- python-ply
- pymarkdownlnt
### Compiling OpenOCD

View File

@@ -92,6 +92,12 @@ my $git_command ='export LANGUAGE=en_US.UTF-8; git';
my $tabsize = 8;
my ${CONFIG_} = "CONFIG_";
# OpenOCD specific: Begin: check markdown with pymarkdownlnt
# Remember which Markdown (*.md) files were already linted.
my %md_checked;
my $md_linter_not_found;
# OpenOCD specific: End
sub help {
my ($exitcode) = @_;
@@ -2435,6 +2441,44 @@ sub report_dump {
our @report;
}
# OpenOCD specific: Begin: check markdown with pymarkdownlnt
sub run_md_linter {
my ($file) = @_;
my $md_linter = "pymarkdownlnt";
return if !$file || !-f $file;
if (!defined($md_linter_not_found)) {
$md_linter_not_found = (which($md_linter) eq "");
}
if ($md_linter_not_found) {
return;
}
my @cmd = ($md_linter, "scan", $file);
my @out = qx{@cmd 2>&1};
my $rc = $? >> 8;
foreach my $line (@out) {
chomp $line;
next if $line eq "";
if ($line =~ m/^(.*?):(\d+):(\d+):\s*([A-Z0-9]+):\s*(.*)$/) {
my ($path, $ln, $col, $code, $msg) = ($1, $2, $3, $4, $5);
WARN("MARKDOWN_LINT", "$file:$ln:$col: $code: $msg\n");
} else {
WARN("MARKDOWN_LINT: Failed to parse output: $line\n");
}
}
if ($rc != 0 && !@out) {
WARN("MARKDOWN_LINT", "Markdown linter exited with status $rc for $file\n");
}
}
# OpenOCD specific: End
sub fixup_current_range {
my ($lineRef, $offset, $length) = @_;
@@ -2965,6 +3009,15 @@ sub process {
}
}
# OpenOCD specific: Begin: check markdown with pymarkdownlnt
# Lint Markdown files.
if ($realfile =~ /\.md$/ && !$md_checked{$realfile}) {
my $fullpath = $root ? "$root/$realfile" : $realfile;
run_md_linter($fullpath);
$md_checked{$realfile} = 1;
}
# OpenOCD specific: End
next;
}