lockdiff/
go.rs

1use crate::Package;
2use anyhow::{bail, Result};
3use std::collections::BTreeMap;
4
5pub(crate) fn parse_go_sum(contents: &str) -> Result<Vec<Package>> {
6    // For some reason go.mod contains several versions for the same package,
7    // so we keep the latest one
8    let mut version_map = BTreeMap::<&str, &str>::new();
9    for line in contents.lines() {
10        if line.is_empty() {
11            continue;
12        }
13        let words: Vec<_> = line.split(' ').collect();
14        if words.len() != 3 {
15            bail!("Expected line {line} to contains exactly 3 words");
16        }
17        let name = &words[0];
18        let version = &words[1];
19        let version = version.split('/').next().expect("version cannot be empty");
20        version_map.insert(name, version);
21    }
22    Ok(version_map
23        .into_iter()
24        .map(|(name, version)| Package::new(name, version))
25        .collect())
26}
27
28#[cfg(test)]
29mod tests {
30
31    use super::*;
32
33    #[test]
34    fn test_go_sum() {
35        let contents = r#"
36cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
37cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
38cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
39"#;
40        let packages = parse_go_sum(contents).unwrap();
41        assert_eq!(
42            &packages,
43            &[
44                Package::new("cloud.google.com/go", "v0.34.0"),
45                Package::new("cloud.google.com/go/storage", "v1.14.0")
46            ]
47        );
48    }
49}