mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 06:28:31 +01:00
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).
This commit is contained in:
@@ -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" | \
|
curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | \
|
||||||
tar --xz -xf - --directory /tmp/
|
tar --xz -xf - --directory /tmp/
|
||||||
mv "/tmp/shellcheck-${SHELLCHECK_VERSION}/shellcheck" /usr/bin/
|
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-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-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)
|
| [`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).
|
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::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::io::ErrorKind;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::{Command, ExitCode, Stdio};
|
||||||
use std::process::ExitCode;
|
|
||||||
|
|
||||||
type LintError = String;
|
type LintError = String;
|
||||||
type LintResult = Result<(), LintError>;
|
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 {
|
fn lint_all() -> LintResult {
|
||||||
let mut good = true;
|
let mut good = true;
|
||||||
let lint_dir = get_git_root().join("test/lint");
|
let lint_dir = get_git_root().join("test/lint");
|
||||||
@@ -325,6 +370,7 @@ fn main() -> ExitCode {
|
|||||||
("no-tabs check", lint_tabs_whitespace),
|
("no-tabs check", lint_tabs_whitespace),
|
||||||
("build config includes check", lint_includes_build_config),
|
("build config includes check", lint_includes_build_config),
|
||||||
("-help=1 documentation check", lint_doc),
|
("-help=1 documentation check", lint_doc),
|
||||||
|
("markdown hyperlink check", lint_markdown),
|
||||||
("lint-*.py scripts", lint_all),
|
("lint-*.py scripts", lint_all),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user