list_invalid_files/
main.rs

1use {
2    clap::Parser,
3    codesort::*,
4    std::{
5        fs,
6        io,
7        path::PathBuf,
8    },
9    termimad::crossterm::style::Stylize,
10};
11
12static EXCLUDED_DIRS: &[&str] = &[".git", "build", "target"];
13
14/// Launch arguments
15#[derive(Debug, Parser)]
16#[command(about, version)]
17pub struct Args {
18    /// directories normally excluded to include
19    #[clap(long, default_value = "")]
20    pub include: Vec<String>,
21
22    /// Path to the file(s)
23    pub path: PathBuf,
24}
25
26pub fn get_all_rust_files(
27    root: PathBuf,
28    include: &[String],
29) -> io::Result<Vec<PathBuf>> {
30    let mut files = Vec::new();
31    // if we're given a single file, it's probably because the user
32    // wants to sort it, so we don't check the extension
33    if !root.is_dir() {
34        files.push(root);
35        return Ok(files);
36    }
37    let mut dirs = vec![root];
38    while let Some(dir) = dirs.pop() {
39        for entry in fs::read_dir(dir)? {
40            let path = entry?.path();
41            let Some(file_name) = path.file_name().and_then(|s| s.to_str()) else {
42                continue;
43            };
44            if path.is_dir() {
45                if file_name.starts_with('.') {
46                    continue;
47                }
48                if EXCLUDED_DIRS.contains(&file_name) {
49                    if !include.iter().any(|inc| inc == file_name) {
50                        eprintln!("{} {:?}", "Excluded".yellow(), path);
51                        continue;
52                    }
53                }
54                dirs.push(path.to_path_buf());
55                continue;
56            }
57            if let Some(ext) = path.extension() {
58                if ext.to_str() == Some("rs") {
59                    files.push(path.to_path_buf());
60                }
61            }
62        }
63    }
64    Ok(files)
65}
66
67fn main() {
68    let args = Args::parse();
69    let files = get_all_rust_files(args.path, &args.include).unwrap();
70    eprintln!("Found {} rust files", files.len());
71    let mut no_complete_count = 0;
72    let mut errors = 0;
73    let mut ok_count = 0;
74    for file in files {
75        let loc_list = LocList::read_file(file.to_str().unwrap(), Language::Rust);
76        let loc_list = match loc_list {
77            Ok(loc_list) => loc_list,
78            Err(e) => {
79                eprintln!("{} {:?} : {}", "ERROR".red(), file, e);
80                errors += 1;
81                continue;
82            }
83        };
84        if loc_list.is_complete() {
85            ok_count += 1;
86            continue;
87        }
88        if !loc_list.has_content() {
89            eprintln!("{} {:?}", "EMPTY".yellow(), file);
90            ok_count += 1;
91            continue;
92        }
93        eprintln!("{} {:?}", "NOT COMPLETE".yellow(), file);
94        no_complete_count += 1;
95    }
96    eprintln!("OK files: {}", ok_count);
97    eprintln!("Erroring files: {}", errors);
98    eprintln!("Uncomplete files: {}", no_complete_count);
99}