Files
Peter Atashian a6dd551021 Get rid of the copyright year header
It isn't legally necessary and effort is wasted maintaining it
2019-02-21 13:27:29 -05:00

148 lines
5.0 KiB
Rust

// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
// All files in the project carrying such notice may not be copied, modified, or distributed
// except according to those terms.
use std::collections::HashMap;
use std::fmt::Debug;
use std::fs::read_dir;
use std::io::{self, Write};
use std::path::Path;
use utils::{get_between_quotes, read_file};
const TO_IGNORE: &'static [&'static str] = &["src/um/sspi.rs"];
fn check_if_in_build<P: Debug>(
path: &P,
include: &str,
entries: &[String],
errors: &mut u32
) -> bool {
for entry in entries {
if &include == &entry {
return true
}
}
writeln!(&mut io::stderr(), "{:?}: include not found: \"{}\"\n", path, include).unwrap();
*errors += 1;
false
}
fn should_be_ignored(path: &Path) -> bool {
let path_str = &path.to_str().unwrap().replace("\\", "/");
TO_IGNORE.iter().find(|x| *x == path_str).is_some()
}
fn check_file_deps<P: AsRef<Path>>(
p: P,
files_deps: &mut HashMap<String, Vec<String>>,
errors: &mut u32,
level: u32
) {
let r_p = p.as_ref();
if should_be_ignored(&r_p) {
return
}
let filename = if level < 2 {
r_p.file_name().unwrap().to_str().unwrap().to_owned()
} else {
let values: Vec<String> = r_p.iter().skip(1)
.map(|x| x.to_str().unwrap().to_owned()).collect();
values[values.len() - 2..].join("-")
};
let mut found: Vec<String> = Vec::new();
{
if let Some(entries) = files_deps.get_mut(&filename) {
let file_content = read_file(r_p);
for line in file_content.lines() {
if !line.starts_with("use ") && !line.starts_with("pub use ") {
continue
}
let include: Vec<&str> = line.split("::").skip(1).collect();
if include.len() < 2 || include[0].starts_with('{') {
continue
}
let include = if include.len() > 2 {
include[..include.len() - 1].join("-").to_owned()
} else {
include[0].to_owned()
};
if check_if_in_build(&r_p, &include, &entries, errors)
&& found.iter().find(|x| **x == include).is_none() {
found.push(include);
}
}
if found.len() != entries.len() {
for found in found {
if let Some(pos) = entries.iter().position(|x| **x == found) {
entries.remove(pos);
}
}
if !entries.is_empty() {
writeln!(&mut io::stderr(), "{}: include not used: {:?}", filename, entries)
.expect("stderr::write failed");
*errors += 1;
}
}
} else if level > 0 && filename != "mod.rs" && !filename.ends_with("-mod.rs") {
writeln!(&mut io::stderr(), "\"{}\" not found in build.rs",
p.as_ref().to_str().unwrap()).unwrap();
*errors += 1;
}
}
files_deps.remove(&filename);
}
fn read_dirs<P: AsRef<Path>>(
dir: P,
files_deps: &mut HashMap<String, Vec<String>>,
errors: &mut u32,
level: u32
) {
for entry in read_dir(dir).expect("read_dir failed") {
let entry = entry.expect("entry failed");
let path = entry.path();
if path.is_dir() {
read_dirs(path, files_deps, errors, level + 1);
} else {
check_file_deps(path, files_deps, errors, level);
}
}
}
#[test]
fn check_imports() {
let content = read_file("build.rs");
let mut inside = false;
let mut files_deps: HashMap<String, Vec<String>> = HashMap::new();
for line in content.lines() {
let line = line.trim_left();
if !inside && line.starts_with("const DATA: ") {
inside = true;
} else if inside == true {
let line = line.trim_left();
if line.starts_with("//") {
continue;
} else if !line.starts_with("(\"") {
break;
}
let parts: Vec<&str> = line.split("&[").collect();
files_deps.insert(format!("{}.rs", get_between_quotes(parts[0])),
parts[1].split(',')
.map(|x| get_between_quotes(x).to_owned())
.filter(|x| !x.is_empty())
.collect());
}
}
let mut errors = 0;
read_dirs("src", &mut files_deps, &mut errors, 0);
assert!(errors == 0, "Missing or extra declaration(s) found");
let keys: Vec<&String> = files_deps.keys().collect();
if !keys.is_empty() {
writeln!(&mut io::stderr(), "file(s) not found: {:?}\n", keys).unwrap();
panic!();
}
}