Skip to content

Commit efca8b2

Browse files
committed
lint: Add --skip
This allows people to explicitly skip individual lints; especially useful for warnings. But maybe people have a legitimate reason to skip ones we're calling fatal too. Prep especially for supporting `--fix --skip`. Signed-off-by: Colin Walters <[email protected]>
1 parent dd9504e commit efca8b2

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

lib/src/cli.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,13 @@ pub(crate) enum ContainerOpts {
257257
/// maintaining this exact format; do not parse it via code or scripts.
258258
#[clap(long)]
259259
list: bool,
260+
261+
/// Skip checking the targeted lints, by name. Use `--list` to discover the set
262+
/// of available lints.
263+
///
264+
/// Example: --skip nonempty-boot --skip baseimage-root
265+
#[clap(long)]
266+
skip: Vec<String>,
260267
},
261268
}
262269

@@ -1044,6 +1051,7 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
10441051
rootfs,
10451052
fatal_warnings,
10461053
list,
1054+
skip,
10471055
} => {
10481056
if list {
10491057
return lints::lint_list(std::io::stdout().lock());
@@ -1060,7 +1068,8 @@ async fn run_from_opt(opt: Opt) -> Result<()> {
10601068
};
10611069

10621070
let root = &Dir::open_ambient_dir(rootfs, cap_std::ambient_authority())?;
1063-
lints::lint(root, warnings, root_type, std::io::stdout().lock())?;
1071+
let skip = skip.iter().map(|s| s.as_str());
1072+
lints::lint(root, warnings, root_type, skip, std::io::stdout().lock())?;
10641073
Ok(())
10651074
}
10661075
},

lib/src/lints.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,18 +140,25 @@ struct LintExecutionResult {
140140
fatal: usize,
141141
}
142142

143-
fn lint_inner(
143+
fn lint_inner<'skip>(
144144
root: &Dir,
145145
root_type: RootType,
146+
skip: impl IntoIterator<Item = &'skip str>,
146147
mut output: impl std::io::Write,
147148
) -> Result<LintExecutionResult> {
148149
let mut fatal = 0usize;
149150
let mut warnings = 0usize;
150151
let mut passed = 0usize;
151152
let mut skipped = 0usize;
153+
let skip: std::collections::HashSet<_> = skip.into_iter().collect();
152154
for lint in LINTS {
153155
let name = lint.name;
154156

157+
if skip.contains(name) {
158+
skipped += 1;
159+
continue;
160+
}
161+
155162
if let Some(lint_root_type) = lint.root_type {
156163
if lint_root_type != root_type {
157164
skipped += 1;
@@ -194,13 +201,14 @@ fn lint_inner(
194201
/// if it exists we need to check that it links to /run if not error
195202
/// if it does not exist error.
196203
#[context("Linting")]
197-
pub(crate) fn lint(
204+
pub(crate) fn lint<'skip>(
198205
root: &Dir,
199206
warning_disposition: WarningDisposition,
200207
root_type: RootType,
208+
skip: impl IntoIterator<Item = &'skip str>,
201209
mut output: impl std::io::Write,
202210
) -> Result<()> {
203-
let r = lint_inner(root, root_type, &mut output)?;
211+
let r = lint_inner(root, root_type, skip, &mut output)?;
204212
writeln!(output, "Checks passed: {}", r.passed)?;
205213
if r.skipped > 0 {
206214
writeln!(output, "Checks skipped: {}", r.skipped)?;
@@ -534,31 +542,43 @@ mod tests {
534542
let mut out = Vec::new();
535543
let warnings = WarningDisposition::FatalWarnings;
536544
let root_type = RootType::Running;
537-
lint(root, warnings, root_type, &mut out).unwrap();
545+
lint(root, warnings, root_type, [], &mut out).unwrap();
538546
root.create_dir_all("var/run/foo")?;
539547
let mut out = Vec::new();
540-
assert!(lint(root, warnings, root_type, &mut out).is_err());
548+
assert!(lint(root, warnings, root_type, [], &mut out).is_err());
541549
Ok(())
542550
}
543551

544552
#[test]
545553
fn test_lint_inner() -> Result<()> {
546554
let root = &passing_fixture()?;
555+
556+
// Verify that all lints run except one which is skipped for non-running roots
547557
let mut out = Vec::new();
548558
let root_type = RootType::Running;
549-
let r = lint_inner(root, root_type, &mut out).unwrap();
559+
let r = lint_inner(root, root_type, [], &mut out).unwrap();
550560
let allbut_one = LINTS.len().checked_sub(1).unwrap();
551561
assert_eq!(r.passed, allbut_one);
552562
assert_eq!(r.fatal, 0);
553563
assert_eq!(r.skipped, 1);
554564
assert_eq!(r.warnings, 0);
555-
root.create_dir_all("var/run/foo")?;
565+
566+
let r = lint_inner(root, root_type, ["var-log"], &mut out).unwrap();
567+
// Trigger a failure in var-log
568+
root.create_dir_all("var/log/dnf")?;
569+
root.write("var/log/dnf/dnf.log", b"dummy dnf log")?;
570+
assert_eq!(r.passed, allbut_one.checked_sub(1).unwrap());
571+
assert_eq!(r.fatal, 0);
572+
assert_eq!(r.skipped, 2);
573+
assert_eq!(r.warnings, 0);
574+
575+
// But verify that not skipping it results in an error
556576
let mut out = Vec::new();
557-
let r = lint_inner(root, root_type, &mut out).unwrap();
577+
let r = lint_inner(root, root_type, [], &mut out).unwrap();
558578
assert_eq!(r.passed, allbut_one.checked_sub(1).unwrap());
559-
assert_eq!(r.fatal, 1);
579+
assert_eq!(r.fatal, 0);
560580
assert_eq!(r.skipped, 1);
561-
assert_eq!(r.warnings, 0);
581+
assert_eq!(r.warnings, 1);
562582
Ok(())
563583
}
564584

0 commit comments

Comments
 (0)