diff options
author | MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> | 2024-09-04 11:15:27 +0200 |
---|---|---|
committer | MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> | 2024-09-05 13:09:34 +0200 |
commit | fa3a7ebe5b5db63e4cb4fb6974c028cc7af0b898 (patch) | |
tree | e8cbfa3da9d8644847c1cbe5b9769f77bd5d224a /test/lint/test_runner | |
parent | 93e48240bfdc25c2760d33da69e739ba1f92da9b (diff) |
lint: Check for release note snippets in the wrong folder
Diffstat (limited to 'test/lint/test_runner')
-rw-r--r-- | test/lint/test_runner/src/main.rs | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/test/lint/test_runner/src/main.rs b/test/lint/test_runner/src/main.rs index 1cd3d9287b..64a1486a4c 100644 --- a/test/lint/test_runner/src/main.rs +++ b/test/lint/test_runner/src/main.rs @@ -5,9 +5,12 @@ use std::env; use std::fs; use std::io::ErrorKind; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::process::{Command, ExitCode, Stdio}; +/// A possible error returned by any of the linters. +/// +/// The error string should explain the failure type and list all violations. type LintError = String; type LintResult = Result<(), LintError>; type LintFn = fn() -> LintResult; @@ -46,6 +49,11 @@ fn get_linter_list() -> Vec<&'static Linter> { lint_fn: lint_std_filesystem }, &Linter { + description: "Check that release note snippets are in the right folder", + name: "doc_release_note_snippets", + lint_fn: lint_doc_release_note_snippets + }, + &Linter { description: "Check that subtrees are pure subtrees", name: "subtree", lint_fn: lint_subtree @@ -125,20 +133,27 @@ fn parse_lint_args(args: &[String]) -> Vec<&'static Linter> { } /// Return the git command +/// +/// Lint functions should use this command, so that only files tracked by git are considered and +/// temporary and untracked files are ignored. For example, instead of 'grep', 'git grep' should be +/// used. fn git() -> Command { let mut git = Command::new("git"); git.arg("--no-pager"); git } -/// Return stdout +/// Return stdout on success and a LintError on failure, when invalid UTF8 was detected or the +/// command did not succeed. fn check_output(cmd: &mut std::process::Command) -> Result<String, LintError> { let out = cmd.output().expect("command error"); if !out.status.success() { return Err(String::from_utf8_lossy(&out.stderr).to_string()); } Ok(String::from_utf8(out.stdout) - .map_err(|e| format!("{e}"))? + .map_err(|e| { + format!("All path names, source code, messages, and output must be valid UTF8!\n{e}") + })? .trim() .to_string()) } @@ -276,6 +291,30 @@ fs:: namespace, which has unsafe filesystem functions marked as deleted. } } +fn lint_doc_release_note_snippets() -> LintResult { + let non_release_notes = check_output(git().args([ + "ls-files", + "--", + "doc/release-notes/", + ":(exclude)doc/release-notes/*.*.md", // Assume that at least one dot implies a proper release note + ]))?; + if non_release_notes.is_empty() { + Ok(()) + } else { + Err(format!( + r#" +{} +^^^ +Release note snippets and other docs must be put into the doc/ folder directly. + +The doc/release-notes/ folder is for archived release notes of previous releases only. Snippets are +expected to follow the naming "/doc/release-notes-<PR number>.md". + "#, + non_release_notes + )) + } +} + /// Return the pathspecs for whitespace related excludes fn get_pathspecs_exclude_whitespace() -> Vec<String> { let mut list = get_pathspecs_exclude_subtrees(); |