os_checker_plugin_cargo/crates_io/
release_tarball.rs1use super::IndexFile;
2use crate::repo::local_base_dir;
3use cargo_metadata::semver::Version;
4use eyre::ContextCompat;
5use plugin::prelude::*;
6use std::os::linux::fs::MetadataExt;
7
8#[derive(Debug)]
9pub struct TarballInfo {
10 pub size: u64,
12 pub modified: Timestamp,
13}
14
15impl TarballInfo {
16 fn new(tarball: &Utf8Path) -> Result<Self> {
17 let meta = std::fs::metadata(tarball)?;
18 let size = meta.st_size();
19 let modified = Timestamp::from_second(meta.st_mtime())?;
20 Ok(Self { size, modified })
21 }
22}
23
24fn download_tarball(pkg: &str, version: &Version) -> Result<Utf8PathBuf> {
25 const TARBALL: &str = "download";
26
27 let url = url(pkg, version);
28 info!("wget {url}");
29
30 let dir = local_base_dir();
31
32 duct::cmd!("wget", url, "-O", TARBALL)
33 .dir(dir)
34 .stdout_null()
35 .stderr_null()
36 .run()?;
37
38 let tarball = dir.join(TARBALL);
39 Ok(tarball)
40}
41
42fn url(pkg: &str, version: &Version) -> String {
43 const PREFIX: &str = "https://static.crates.io/crates";
46 format!("{PREFIX}/{pkg}/{version}/download")
47}
48
49fn get_last_release_info(pkg: &str, version: &Version) -> Result<TarballInfo> {
50 let tarball = download_tarball(pkg, version)?;
51 TarballInfo::new(&tarball)
52}
53
54impl IndexFile {
55 pub fn get_last_release_info(&mut self) -> Result<()> {
56 let last = self.data.last();
57 let last = last.with_context(|| "index file is empty")?;
58 self.tarball = Some(get_last_release_info(&self.pkg, &last.vers)?);
59 Ok(())
60 }
61
62 pub fn last_release_size_and_time(&self) -> Option<(u64, Timestamp)> {
63 self.tarball
64 .as_ref()
65 .map(|tarball| (tarball.size, tarball.modified))
66 }
67}
68
69#[test]
70fn test_tarball_info() -> Result<()> {
71 dbg!(get_last_release_info("os-checker", &Version::new(0, 4, 1))?);
75
76 Ok(())
77}