Add scan depth, exit codes, and fix validation test

This commit is contained in:
2025-12-31 22:38:24 -05:00
parent 8b4273e7cb
commit 7188cee3e2
6 changed files with 215 additions and 36 deletions

View File

@@ -3,7 +3,6 @@ use std::process::Command;
use anyhow::{Context, Result};
use fs_err as fs;
use tempfile::NamedTempFile;
use crate::config::Config;
use crate::fix::{FixKind, FixOutcome, FixPlan};
@@ -102,11 +101,19 @@ struct OutputPaths {
}
fn prepare_output_path(path: &Path, config: &Config) -> Result<OutputPaths> {
let suffix = path
.extension()
.and_then(|ext| ext.to_str())
.map(|ext| format!(".{}", ext))
.unwrap_or_else(|| ".tmp".to_string());
if config.repair.output_dir.is_empty() {
let parent = path
.parent()
.context("Input file has no parent directory")?;
let temp = NamedTempFile::new_in(parent)
let temp = tempfile::Builder::new()
.suffix(&suffix)
.tempfile_in(parent)
.with_context(|| format!("Failed to create temp file in {}", parent.display()))?;
let temp_path = temp.path().to_path_buf();
temp.keep()?;
@@ -126,9 +133,10 @@ fn prepare_output_path(path: &Path, config: &Config) -> Result<OutputPaths> {
.to_os_string();
let final_path = output_dir.join(file_name);
let temp = NamedTempFile::new_in(&output_dir).with_context(|| {
format!("Failed to create temp file in {}", output_dir.display())
})?;
let temp = tempfile::Builder::new()
.suffix(&suffix)
.tempfile_in(&output_dir)
.with_context(|| format!("Failed to create temp file in {}", output_dir.display()))?;
let temp_path = temp.path().to_path_buf();
temp.keep()?;

View File

@@ -5,6 +5,7 @@ use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use anyhow::{Context, Result};
use crate::config::ScanDepth;
use crate::rules::RuleSet;
#[derive(Debug)]
@@ -13,12 +14,18 @@ pub struct DecodeOutput {
pub early_stop: bool,
}
pub fn run_decode(path: &Path, ffmpeg_path: &str, ruleset: &RuleSet) -> Result<DecodeOutput> {
pub fn run_decode(
path: &Path,
ffmpeg_path: &str,
ruleset: &RuleSet,
depth: ScanDepth,
) -> Result<DecodeOutput> {
let mut child = Command::new(ffmpeg_path)
.arg("-v")
.arg("error")
.arg("-i")
.arg(path)
.args(depth_args(depth))
.arg("-f")
.arg("null")
.arg("-")
@@ -58,6 +65,14 @@ pub fn run_decode(path: &Path, ffmpeg_path: &str, ruleset: &RuleSet) -> Result<D
})
}
fn depth_args(depth: ScanDepth) -> Vec<&'static str> {
match depth {
ScanDepth::Quick => vec!["-t", "5"],
ScanDepth::Standard => vec!["-t", "30"],
ScanDepth::Deep => vec![],
}
}
fn should_stop(line: &str, ruleset: &RuleSet) -> bool {
for rule in &ruleset.rules {
if !rule.rule.stop_scan {

View File

@@ -2,7 +2,7 @@ use std::path::Path;
use anyhow::Result;
use crate::config::Config;
use crate::config::{Config, ScanDepth};
use crate::rules::{build_context, RuleMatch, RuleSet};
mod decode;
@@ -14,10 +14,19 @@ pub use types::{Issue, ProbeData, ScanOutcome, ScanRequest};
pub fn scan_file(path: &Path, config: &Config, ruleset: &RuleSet) -> Result<ScanOutcome> {
let probe = ffprobe::run_ffprobe(path, &config.ffprobe_path)?;
let decode = decode::run_decode(path, &config.ffmpeg_path, ruleset)?;
let mut decode = decode::run_decode(path, &config.ffmpeg_path, ruleset, config.scan.depth)?;
let context = build_context(&probe);
let matches = ruleset.match_lines(&decode.lines, &context);
let mut matches = ruleset.match_lines(&decode.lines, &context);
if config.scan.auto_escalate
&& config.scan.depth != ScanDepth::Deep
&& !decode.early_stop
&& !matches.is_empty()
{
decode = decode::run_decode(path, &config.ffmpeg_path, ruleset, ScanDepth::Deep)?;
matches = ruleset.match_lines(&decode.lines, &context);
}
let issues = matches
.iter()