Skip to content

Commit fa3a7eb

Browse files
author
MarcoFalke
committed
lint: Check for release note snippets in the wrong folder
1 parent 93e4824 commit fa3a7eb

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

test/lint/test_runner/src/main.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55
use std::env;
66
use std::fs;
77
use std::io::ErrorKind;
8-
use std::path::{Path, PathBuf};
8+
use std::path::PathBuf;
99
use std::process::{Command, ExitCode, Stdio};
1010

11+
/// A possible error returned by any of the linters.
12+
///
13+
/// The error string should explain the failure type and list all violations.
1114
type LintError = String;
1215
type LintResult = Result<(), LintError>;
1316
type LintFn = fn() -> LintResult;
@@ -45,6 +48,11 @@ fn get_linter_list() -> Vec<&'static Linter> {
4548
name: "std_filesystem",
4649
lint_fn: lint_std_filesystem
4750
},
51+
&Linter {
52+
description: "Check that release note snippets are in the right folder",
53+
name: "doc_release_note_snippets",
54+
lint_fn: lint_doc_release_note_snippets
55+
},
4856
&Linter {
4957
description: "Check that subtrees are pure subtrees",
5058
name: "subtree",
@@ -125,20 +133,27 @@ fn parse_lint_args(args: &[String]) -> Vec<&'static Linter> {
125133
}
126134

127135
/// Return the git command
136+
///
137+
/// Lint functions should use this command, so that only files tracked by git are considered and
138+
/// temporary and untracked files are ignored. For example, instead of 'grep', 'git grep' should be
139+
/// used.
128140
fn git() -> Command {
129141
let mut git = Command::new("git");
130142
git.arg("--no-pager");
131143
git
132144
}
133145

134-
/// Return stdout
146+
/// Return stdout on success and a LintError on failure, when invalid UTF8 was detected or the
147+
/// command did not succeed.
135148
fn check_output(cmd: &mut std::process::Command) -> Result<String, LintError> {
136149
let out = cmd.output().expect("command error");
137150
if !out.status.success() {
138151
return Err(String::from_utf8_lossy(&out.stderr).to_string());
139152
}
140153
Ok(String::from_utf8(out.stdout)
141-
.map_err(|e| format!("{e}"))?
154+
.map_err(|e| {
155+
format!("All path names, source code, messages, and output must be valid UTF8!\n{e}")
156+
})?
142157
.trim()
143158
.to_string())
144159
}
@@ -276,6 +291,30 @@ fs:: namespace, which has unsafe filesystem functions marked as deleted.
276291
}
277292
}
278293

294+
fn lint_doc_release_note_snippets() -> LintResult {
295+
let non_release_notes = check_output(git().args([
296+
"ls-files",
297+
"--",
298+
"doc/release-notes/",
299+
":(exclude)doc/release-notes/*.*.md", // Assume that at least one dot implies a proper release note
300+
]))?;
301+
if non_release_notes.is_empty() {
302+
Ok(())
303+
} else {
304+
Err(format!(
305+
r#"
306+
{}
307+
^^^
308+
Release note snippets and other docs must be put into the doc/ folder directly.
309+
310+
The doc/release-notes/ folder is for archived release notes of previous releases only. Snippets are
311+
expected to follow the naming "/doc/release-notes-<PR number>.md".
312+
"#,
313+
non_release_notes
314+
))
315+
}
316+
}
317+
279318
/// Return the pathspecs for whitespace related excludes
280319
fn get_pathspecs_exclude_whitespace() -> Vec<String> {
281320
let mut list = get_pathspecs_exclude_subtrees();

0 commit comments

Comments
 (0)