@@ -0,0 +1,133 @@
1+use std::collections::HashMap;
3+use std::io::{self, BufRead};
8+type H = HashMap<Header, Vec<(String, String, String)>>;
10+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12+ Versioned { package: String, version: String },
13+ Missing { package: String },
17+ let mut lib_exes: H = Default::default();
18+ let mut tests: H = Default::default();
19+ let mut benches: H = Default::default();
20+ let mut last_header: Option<Header> = None;
21+ let empty = Regex::new(r#"^\s*$"#).unwrap();
22+ let header_versioned =
23+ Regex::new(r#"^(?P<package>[a-zA-z]([a-zA-z0-9.-]*?))-(?P<version>(\d+(\.\d+)*)).+?is out of bounds for:$"#).unwrap();
25+ Regex::new(r#"^(?P<package>[a-zA-z]([a-zA-z0-9.-]*)).+?depended on by:$"#).unwrap();
27+ Regex::new(r#"^- \[ \] (?P<package>[a-zA-z]([a-zA-z0-9.-]*?))-(?P<version>(\d+(\.\d+)*)).+?Used by: (?P<component>.+)$"#)
30+ if let Ok(lines) = read_lines("./comments.txt") {
32+ if let Ok(line) = line {
33+ if empty.captures(&line).is_some() {
34+ } else if let Some(cap) = package.captures(&line) {
35+ let root = last_header.clone().unwrap();
36+ let package = cap.name("package").unwrap().as_str();
37+ let version = cap.name("version").unwrap().as_str();
38+ let component = cap.name("component").unwrap().as_str();
40+ "library" | "executable" => {
41+ insert(&mut lib_exes, root, package, version, component)
43+ "benchmark" => insert(&mut benches, root, package, version, "benchmarks"),
44+ "test-suite" => insert(&mut tests, root, package, version, component),
45+ _ => panic!("Bad component: {}", component),
47+ } else if let Some(cap) = header_versioned.captures(&line) {
48+ let package = cap.name("package").unwrap().as_str().to_owned();
49+ let version = cap.name("version").unwrap().as_str().to_owned();
50+ last_header = Some(Header::Versioned { package, version });
51+ } else if let Some(cap) = header_missing.captures(&line) {
52+ let package = cap.name("package").unwrap().as_str().to_owned();
53+ last_header = Some(Header::Missing { package });
55+ panic!("Unhandled: {:?}", line);
61+ if !lib_exes.is_empty() {
62+ println!("\nLIBS + EXES\n");
64+ for (header, packages) in lib_exes {
65+ for (package, version, component) in packages {
66+ printer(" ", &package, true, &version, &component, &header);
70+ if !tests.is_empty() {
71+ println!("\nTESTS\n");
73+ for (header, packages) in tests {
74+ for (package, version, component) in packages {
75+ printer(" ", &package, false, &version, &component, &header);
79+ if !benches.is_empty() {
80+ println!("\nBENCHMARKS\n");
82+ for (header, packages) in benches {
83+ for (package, version, component) in packages {
84+ printer(" ", &package, false, &version, &component, &header);
97+ let lt0 = if lt0 { " < 0" } else { "" };
99+ "{indent}- {package}{lt0} # tried {package}-{version}, but its *{component}* {cause}",
104+ component = component,
105+ cause = match header {
106+ Header::Versioned { package, version } => format!(
107+ "does not support: {package}-{version}",
111+ Header::Missing { package } => format!(
112+ "requires the disabled package: {package}",
119+fn insert(h: &mut H, header: Header, package: &str, version: &str, component: &str) {
120+ (*h.entry(header).or_insert_with(|| vec![])).push((
123+ component.to_owned(),
127+fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
131+ let file = File::open(filename)?;
132+ Ok(io::BufReader::new(file).lines())