assorted_debian_utils/
autoremovals.rs

1// Copyright 2022 Sebastian Ramacher
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4//! # Helpers to handle `autoremovals.yaml`
5//!
6//! This module provides helpers to deserialize [autoremovals.yaml](https://udd.debian.org/cgi-bin/autoremovals.yaml.cgi)
7//! with [serde].
8
9use std::{collections::HashMap, io};
10
11use chrono::{DateTime, Utc};
12use serde::Deserialize;
13
14use crate::{package::PackageName, utils::DateTimeVisitor, version::PackageVersion};
15
16/// Deserialize a datetime string into a `DateTime<Utc>`
17fn deserialize_datetime<'de, D>(deserializer: D) -> std::result::Result<DateTime<Utc>, D::Error>
18where
19    D: serde::Deserializer<'de>,
20{
21    deserializer.deserialize_str(DateTimeVisitor("%Y-%m-%d %H:%M:%S"))
22}
23
24/// All autoremovals
25pub type AutoRemovals = HashMap<PackageName, AutoRemoval>;
26
27/// An autoremoval
28#[derive(Debug, Deserialize, PartialEq, Eq)]
29pub struct AutoRemoval {
30    /// The package's RC bugs causing auto-removal.
31    pub bugs: Vec<String>,
32    /// The RC bugs of dependencies causing auto-removal.
33    pub bugs_dependencies: Option<Vec<String>>,
34    /// List of RC-buggy dependencies causing auto-removal.
35    pub buggy_dependencies: Option<Vec<PackageName>>,
36    /// Auto-removal is caused by dependencies.
37    pub dependencies_only: bool,
38    /// Date of the last check.
39    #[serde(deserialize_with = "deserialize_datetime")]
40    pub last_checked: DateTime<Utc>,
41    /// Auto-removal date.
42    #[serde(deserialize_with = "deserialize_datetime")]
43    pub removal_date: DateTime<Utc>,
44    /// Source package name.
45    pub source: String,
46    /// Package version.
47    pub version: PackageVersion,
48    /// List of reverse dependencies that will also be auto-removed.
49    pub rdeps: Option<Vec<PackageName>>,
50}
51
52/// Result type
53pub type Result<T> = serde_yaml::Result<T>;
54
55/// Read autoremovals from a reader
56pub fn from_reader(reader: impl io::Read) -> Result<AutoRemovals> {
57    serde_yaml::from_reader(reader)
58}
59
60/// Read autoremovals from a string
61pub fn from_str(data: &str) -> Result<AutoRemovals> {
62    serde_yaml::from_str(data)
63}
64
65#[cfg(test)]
66mod test {
67    use super::from_str;
68
69    #[test]
70    fn base() {
71        let data = r"---
72mplayer:
73  bugs:
74  - '1005899'
75  dependencies_only: false
76  last_checked: 2022-04-10 17:55:40
77  rdeps:
78  - devede
79  - diffoscope
80  - dradio
81  - mplayer-blue
82  - ogmrip
83  - qwinff
84  - reprotest
85  - vdr-plugin-mp3
86  - videotrans
87  removal_date: 2022-05-01 19:42:01
88  source: mplayer
89  version: 2:1.4+ds1-3
90mplayer-blue:
91  buggy_dependencies:
92  - mplayer
93  bugs: []
94  bugs_dependencies:
95  - '1005899'
96  dependencies_only: true
97  last_checked: 2022-04-10 17:55:40
98  removal_date: 2022-05-01 19:42:01
99  source: mplayer-blue
100  version: 1.13-2
101";
102        let autoremovals = from_str(data).unwrap();
103
104        assert!(autoremovals.contains_key(&"mplayer".try_into().unwrap()));
105        let mplayer = autoremovals.get(&"mplayer".try_into().unwrap()).unwrap();
106        assert_eq!(mplayer.source, "mplayer");
107        assert_eq!(mplayer.version.to_string(), "2:1.4+ds1-3");
108        assert_eq!(mplayer.bugs, vec!["1005899"]);
109        assert_eq!(
110            mplayer.rdeps.as_ref().unwrap(),
111            &vec![
112                "devede",
113                "diffoscope",
114                "dradio",
115                "mplayer-blue",
116                "ogmrip",
117                "qwinff",
118                "reprotest",
119                "vdr-plugin-mp3",
120                "videotrans"
121            ]
122        );
123        assert!(!mplayer.dependencies_only);
124
125        assert!(autoremovals.contains_key(&"mplayer-blue".try_into().unwrap()));
126        let mplayer_blue = autoremovals
127            .get(&"mplayer-blue".try_into().unwrap())
128            .unwrap();
129        assert_eq!(mplayer_blue.source, "mplayer-blue");
130        assert_eq!(mplayer_blue.version.to_string(), "1.13-2");
131        assert_eq!(mplayer_blue.bugs.len(), 0);
132        assert_eq!(
133            mplayer_blue.buggy_dependencies.as_ref().unwrap(),
134            &vec!["mplayer"]
135        );
136        assert_eq!(
137            mplayer_blue.bugs_dependencies.as_ref().unwrap(),
138            &vec!["1005899"]
139        );
140        assert!(mplayer_blue.dependencies_only);
141    }
142}