Skip to content

Commit 4b7d984

Browse files
committed
lint: add markdown hyperlink checker
This adds a markdown hyperlink check task to the lint test_runner. It relies on having the [`mlc`](https://crates.io/crates/mlc) binary found on $PATH, but will fail with `success` if the binary is not found. `mlc` is also added to the ci/04_install.sh script run by the containerfile. Note that broken markdown hyperlinks will be detected in untracked markdown files found in a dirty working directory (including e.g. .venv).
1 parent 43a66c5 commit 4b7d984

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

ci/lint/04_install.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,8 @@ SHELLCHECK_VERSION=v0.8.0
5757
curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | \
5858
tar --xz -xf - --directory /tmp/
5959
mv "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/bin/
60+
61+
MLC_VERSION=v0.16.3
62+
MLC_BIN=mlc-x86_64-linux
63+
curl -sL "https://github.com/becheran/mlc/releases/download/${MLC_VERSION}/${MLC_BIN}" -o "/usr/bin/mlc"
64+
chmod +x /usr/bin/mlc

test/lint/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Then you can use:
3737
| [`lint-python-dead-code.py`](/test/lint/lint-python-dead-code.py) | [vulture](https://github.com/jendrikseipp/vulture)
3838
| [`lint-shell.py`](/test/lint/lint-shell.py) | [ShellCheck](https://github.com/koalaman/shellcheck)
3939
| [`lint-spelling.py`](/test/lint/lint-spelling.py) | [codespell](https://github.com/codespell-project/codespell)
40+
| markdown link check | [mlc](https://github.com/becheran/mlc)
4041

4142
In use versions and install instructions are available in the [CI setup](../../ci/lint/04_install.sh).
4243

test/lint/test_runner/src/main.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
use std::env;
66
use std::fs;
7+
use std::io::ErrorKind;
78
use std::path::{Path, PathBuf};
8-
use std::process::Command;
9-
use std::process::ExitCode;
9+
use std::process::{Command, ExitCode, Stdio};
1010

1111
type LintError = String;
1212
type LintResult = Result<(), LintError>;
@@ -292,6 +292,51 @@ fn lint_doc() -> LintResult {
292292
}
293293
}
294294

295+
fn lint_markdown() -> LintResult {
296+
let bin_name = "mlc";
297+
let mut md_ignore_paths = get_subtrees();
298+
md_ignore_paths.push("./doc/README_doxygen.md");
299+
let md_ignore_path_str = md_ignore_paths.join(",");
300+
301+
let mut cmd = Command::new(bin_name);
302+
cmd.args([
303+
"--offline",
304+
"--ignore-path",
305+
md_ignore_path_str.as_str(),
306+
"--root-dir",
307+
".",
308+
])
309+
.stdout(Stdio::null()); // Suppress overly-verbose output
310+
311+
match cmd.output() {
312+
Ok(output) if output.status.success() => Ok(()),
313+
Ok(output) => {
314+
let stderr = String::from_utf8_lossy(&output.stderr);
315+
let filtered_stderr: String = stderr // Filter out this annoying trailing line
316+
.lines()
317+
.filter(|&line| line != "The following links could not be resolved:")
318+
.collect::<Vec<&str>>()
319+
.join("\n");
320+
Err(format!(
321+
r#"
322+
One or more markdown links are broken.
323+
324+
Relative links are preferred (but not required) as jumping to file works natively within Emacs.
325+
326+
Markdown link errors found:
327+
{}
328+
"#,
329+
filtered_stderr
330+
))
331+
}
332+
Err(e) if e.kind() == ErrorKind::NotFound => {
333+
println!("`mlc` was not found in $PATH, skipping markdown lint check.");
334+
Ok(())
335+
}
336+
Err(e) => Err(format!("Error running mlc: {}", e)), // Misc errors
337+
}
338+
}
339+
295340
fn lint_all() -> LintResult {
296341
let mut good = true;
297342
let lint_dir = get_git_root().join("test/lint");
@@ -325,6 +370,7 @@ fn main() -> ExitCode {
325370
("no-tabs check", lint_tabs_whitespace),
326371
("build config includes check", lint_includes_build_config),
327372
("-help=1 documentation check", lint_doc),
373+
("markdown hyperlink check", lint_markdown),
328374
("lint-*.py scripts", lint_all),
329375
];
330376

0 commit comments

Comments
 (0)