1use std::ffi::OsStr;2use std::path::{Path,PathBuf};3use std::process::Command;4use std::{fs, process};56constEXTENSIONS:&[&str]=7&["rs","py","js","sh","c","cpp","h","md","css","ftl","toml","yml","yaml"];89fn has_supported_extension(path:&Path)->bool{10 path.extension().is_some_and(|ext|EXTENSIONS.iter().any(|e| ext ==OsStr::new(e)))11}1213fn list_tracked_files()->Result<Vec<PathBuf>,String>{14let output =Command::new("git")15.args(["ls-files","-z"])16.output()17.map_err(|e| format!("Failed to run `git ls-files`: {e}"))?;1819if!output.status.success(){20let stderr =String::from_utf8_lossy(&output.stderr);21returnErr(format!("`git ls-files` failed: {stderr}"));22}2324letmut files =Vec::new();25for entry in output.stdout.split(|b|*b ==0){26if entry.is_empty(){27continue;28}29let path = std::str::from_utf8(entry).unwrap();30 files.push(PathBuf::from(path));31}3233Ok(files)34}3536pub(crate)fn run()->!{37let files = list_tracked_files().unwrap();38letmut error_count =0;39// Avoid embedding the task marker in source so greps only find real occurrences.40let todo_marker ="todo".to_ascii_uppercase();4142for file in files {43if!has_supported_extension(&file){44continue;45}4647let bytes = fs::read(&file).unwrap();48let contents = std::str::from_utf8(&bytes).unwrap();4950for(i, line)in contents.split('\n').enumerate(){51let trimmed = line.trim();52if trimmed.contains(&todo_marker){53 eprintln!(54"{}:{}: {} is used for tasks that should be done before merging a PR; if you want to leave a message in the codebase use FIXME",55 file.display(),56 i +1,57 todo_marker58);59 error_count +=1;60}61}62}6364if error_count ==0{65 process::exit(0);66}6768 eprintln!("found {} {}(s)", error_count, todo_marker);69 process::exit(1);70}
Code quality findings 7
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
Warning: '.unwrap()' will panic on None/Err variants. Prefer using pattern matching (match, if let), combinators (map, and_then), or the '?' operator for robust error handling.
let contents = std::str::from_utf8(&bytes).unwrap();
Performance Info: Calling .push() repeatedly inside a loop without prior capacity reservation can lead to multiple reallocations. Consider using `Vec::with_capacity(n)` or `vec.reserve(n)` if the approximate number of elements is known.
Info: Direct printing to stdout/stderr. For application logging, prefer using a logging facade like `log` or `tracing` for better control over levels, formatting, and output destinations.
Info: Direct printing to stdout/stderr. For application logging, prefer using a logging facade like `log` or `tracing` for better control over levels, formatting, and output destinations.