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).
pull/30034/head
willcl-ark 6 months ago
parent 43a66c55ec
commit 4b7d984269
No known key found for this signature in database
GPG Key ID: CE6EC49945C17EA6

@ -57,3 +57,8 @@ SHELLCHECK_VERSION=v0.8.0
curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | \
tar --xz -xf - --directory /tmp/
mv "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/bin/
MLC_VERSION=v0.16.3
MLC_BIN=mlc-x86_64-linux
curl -sL "https://github.com/becheran/mlc/releases/download/${MLC_VERSION}/${MLC_BIN}" -o "/usr/bin/mlc"
chmod +x /usr/bin/mlc

@ -37,6 +37,7 @@ Then you can use:
| [`lint-python-dead-code.py`](/test/lint/lint-python-dead-code.py) | [vulture](https://github.com/jendrikseipp/vulture)
| [`lint-shell.py`](/test/lint/lint-shell.py) | [ShellCheck](https://github.com/koalaman/shellcheck)
| [`lint-spelling.py`](/test/lint/lint-spelling.py) | [codespell](https://github.com/codespell-project/codespell)
| markdown link check | [mlc](https://github.com/becheran/mlc)
In use versions and install instructions are available in the [CI setup](../../ci/lint/04_install.sh).

@ -4,9 +4,9 @@
use std::env;
use std::fs;
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::process::ExitCode;
use std::process::{Command, ExitCode, Stdio};
type LintError = String;
type LintResult = Result<(), LintError>;
@ -292,6 +292,51 @@ fn lint_doc() -> LintResult {
}
}
fn lint_markdown() -> LintResult {
let bin_name = "mlc";
let mut md_ignore_paths = get_subtrees();
md_ignore_paths.push("./doc/README_doxygen.md");
let md_ignore_path_str = md_ignore_paths.join(",");
let mut cmd = Command::new(bin_name);
cmd.args([
"--offline",
"--ignore-path",
md_ignore_path_str.as_str(),
"--root-dir",
".",
])
.stdout(Stdio::null()); // Suppress overly-verbose output
match cmd.output() {
Ok(output) if output.status.success() => Ok(()),
Ok(output) => {
let stderr = String::from_utf8_lossy(&output.stderr);
let filtered_stderr: String = stderr // Filter out this annoying trailing line
.lines()
.filter(|&line| line != "The following links could not be resolved:")
.collect::<Vec<&str>>()
.join("\n");
Err(format!(
r#"
One or more markdown links are broken.
Relative links are preferred (but not required) as jumping to file works natively within Emacs.
Markdown link errors found:
{}
"#,
filtered_stderr
))
}
Err(e) if e.kind() == ErrorKind::NotFound => {
println!("`mlc` was not found in $PATH, skipping markdown lint check.");
Ok(())
}
Err(e) => Err(format!("Error running mlc: {}", e)), // Misc errors
}
}
fn lint_all() -> LintResult {
let mut good = true;
let lint_dir = get_git_root().join("test/lint");
@ -325,6 +370,7 @@ fn main() -> ExitCode {
("no-tabs check", lint_tabs_whitespace),
("build config includes check", lint_includes_build_config),
("-help=1 documentation check", lint_doc),
("markdown hyperlink check", lint_markdown),
("lint-*.py scripts", lint_all),
];

Loading…
Cancel
Save