@@ -1,9 +1,13 @@
1+use std::collections::{BTreeMap, BTreeSet};
1use std::fs::File;
2use std::fs::File;
2use std::io::{BufRead, BufReader, LineWriter, Lines, Write};
3use std::io::{BufRead, BufReader, LineWriter, Lines, Write};
3use std::path::Path;
4use std::path::Path;
5+use std::process::Command;
5pub fn clear() {
9pub fn clear() {
6− handle(|loc, _lines| match loc {
10+ handle(true, |loc, _lines| match loc {
7 // Add empty array to keep yaml valid
11 // Add empty array to keep yaml valid
8 Location::Lib => vec![" []".to_owned()],
12 Location::Lib => vec![" []".to_owned()],
9 Location::Test | Location::Bench => vec![],
13 Location::Test | Location::Bench => vec![],
@@ -11,7 +15,7 @@ pub fn clear() {
13pub fn add(lib: Vec<String>, test: Vec<String>, bench: Vec<String>) {
17pub fn add(lib: Vec<String>, test: Vec<String>, bench: Vec<String>) {
14− handle(|loc, mut lines| {
18+ handle(true, |loc, mut lines| {
15 lines.extend(match loc {
19 lines.extend(match loc {
16 Location::Lib => lib.clone(),
20 Location::Lib => lib.clone(),
17 Location::Test => test.clone(),
21 Location::Test => test.clone(),
@@ -22,6 +26,82 @@ pub fn add(lib: Vec<String>, test: Vec<String>, bench: Vec<String>) {
30+ let mut all = vec![];
31+ handle(false, |_loc, lines| {
35+ let mut map = BTreeMap::new();
36+ let mut support: BTreeMap<(String, String), BTreeSet<(String, String)>> = BTreeMap::new();
37+ for v in all.into_iter() {
38+ let caps = regex!("tried ([^ ]+)-([^,-]+),").captures(&v).unwrap();
39+ let package = caps.get(1).unwrap().as_str().to_owned();
40+ let version = caps.get(2).unwrap().as_str().to_owned();
41+ map.insert(package.clone(), version.clone());
43+ if let Some(caps) = regex!("does not support: ([^ ]+)-([^-]+)").captures(&v) {
44+ let dep_package = caps.get(1).unwrap().as_str().to_owned();
45+ let dep_version = caps.get(2).unwrap().as_str().to_owned();
47+ .entry((dep_package, dep_version))
49+ entry.insert((package, version));
53+ let entries = map.len() + support.len();
56+ for (package, version) in map {
58+ println!("{:02}%", ((i as f64 / entries as f64) * 100.0).floor());
61+ let latest = latest_version(&package);
62+ if version != latest {
64+ "{} mismatch, snapshot: {}, hackage: {}",
65+ package, version, latest
70+ for ((package, version), dependents) in support {
72+ println!("{:02}%", ((i as f64 / entries as f64) * 100.0).floor());
75+ let latest = latest_version(&package);
76+ if version != latest {
78+ "{} mismatch, snapshot: {}, hackage: {}, dependents: {}",
84+ .map(|(p, v)| format!("{}-{}", p, v))
85+ .collect::<Vec<String>>()
92+fn latest_version(pkg: &str) -> String {
94+ Command::new("latest-version")
25enum State {
105enum State {
26 LookingForLibBounds,
106 LookingForLibBounds,
27 ProcessingLibBounds,
107 ProcessingLibBounds,
@@ -32,9 +112,9 @@ enum State {
35−fn handle<F>(f: F)
115+fn handle<F>(write: bool, mut f: F)
37− F: Fn(Location, Vec<String>) -> Vec<String>,
117+ F: FnMut(Location, Vec<String>) -> Vec<String>,
39 let path = "build-constraints.yaml";
119 let path = "build-constraints.yaml";
40 let mut new_lines: Vec<String> = vec![];
120 let mut new_lines: Vec<String> = vec![];
@@ -100,13 +180,15 @@ where
103− let file = File::create(path).unwrap();
184+ let file = File::create(path).unwrap();
104− let mut file = LineWriter::new(file);
185+ let mut file = LineWriter::new(file);
106− for line in new_lines {
187+ for line in new_lines {
107− file.write_all((line + "\n").as_bytes()).unwrap();
188+ file.write_all((line + "\n").as_bytes()).unwrap();
190+ file.flush().unwrap();
109− file.flush().unwrap();
112enum Location {
194enum Location {