find_timestamp/
find-timestamp.rs

1//! $ cargo run --release --example find-timestamp -- 2023-01-13T23:42:25.800721Z
2//! Reverse lookup what crate got published at a particular time. Useful for
3//! attributing discontinuities in a `cargo tally` graph.
4
5use chrono::DateTime;
6use db_dump::crates::CrateId;
7use semver::Version;
8use std::collections::BTreeMap as Map;
9use std::env;
10use std::io::{self, Write as _};
11use std::process;
12
13fn main() -> db_dump::Result<()> {
14    let mut query = Vec::new();
15    for arg in env::args_os().skip(1) {
16        let arg = arg.to_str().unwrap();
17        let datetime = DateTime::parse_from_rfc3339(arg).unwrap();
18        query.push(datetime.to_utc());
19    }
20
21    if query.is_empty() {
22        let _ = writeln!(
23            io::stderr(),
24            "Usage: cargo run --release --example find-timestamp -- 2023-01-13T23:42:25.800721Z",
25        );
26        process::exit(1);
27    }
28
29    let mut crates: Map<CrateId, String> = Map::new();
30    let mut versions: Vec<(CrateId, Version)> = Vec::new();
31    db_dump::Loader::new()
32        .crates(|row| {
33            crates.insert(row.id, row.name);
34        })
35        .versions(|row| {
36            if query.contains(&row.created_at) {
37                versions.push((row.crate_id, row.num));
38            }
39        })
40        .load("./db-dump.tar.gz")?;
41
42    for (crate_id, version) in versions {
43        println!("{} v{}", crates[&crate_id], version);
44    }
45
46    Ok(())
47}