|
4 | 4 |
|
5 | 5 | use std::env;
|
6 | 6 | use std::fs;
|
| 7 | +use std::io::ErrorKind; |
7 | 8 | use std::path::{Path, PathBuf};
|
8 |
| -use std::process::Command; |
9 |
| -use std::process::ExitCode; |
| 9 | +use std::process::{Command, ExitCode, Stdio}; |
10 | 10 |
|
11 | 11 | type LintError = String;
|
12 | 12 | type LintResult = Result<(), LintError>;
|
@@ -292,6 +292,51 @@ fn lint_doc() -> LintResult {
|
292 | 292 | }
|
293 | 293 | }
|
294 | 294 |
|
| 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 | + |
295 | 340 | fn lint_all() -> LintResult {
|
296 | 341 | let mut good = true;
|
297 | 342 | let lint_dir = get_git_root().join("test/lint");
|
@@ -325,6 +370,7 @@ fn main() -> ExitCode {
|
325 | 370 | ("no-tabs check", lint_tabs_whitespace),
|
326 | 371 | ("build config includes check", lint_includes_build_config),
|
327 | 372 | ("-help=1 documentation check", lint_doc),
|
| 373 | + ("markdown hyperlink check", lint_markdown), |
328 | 374 | ("lint-*.py scripts", lint_all),
|
329 | 375 | ];
|
330 | 376 |
|
|
0 commit comments