release_manager/
status.rs

1// This file is part of Release Manager
2
3// Release Manager is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7
8// Release Manager is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12
13// You should have received a copy of the GNU General Public License
14// along with Release Manager  If not, see <http://www.gnu.org/licenses/>.
15
16use std::collections::HashMap;
17use std::path::Path;
18use std::fs::File;
19use std::io::Write;
20
21use super::parse_toml;
22use super::Error;
23
24use toml;
25
26type Version = String;
27type BuildName = String;
28
29pub type Status = HashMap<Version, VersionStatus>;
30
31pub struct StatusWrapper<'a> {
32    pub filepath: &'a Path,
33    pub status: Status,
34}
35
36impl<'a> StatusWrapper<'a> {
37    pub fn new(filepath: &'a Path) -> Self {
38        StatusWrapper {
39            status: Status::new(),
40            filepath: filepath,
41        }
42    }
43
44    pub fn read(&mut self) -> Result<(), Error> {
45        self.status = parse_toml(self.filepath)?;
46
47        Ok(())
48    }
49
50    pub fn write(&self) -> Result<(), Error> {
51        let mut f = File::create(self.filepath)?;
52        write!(f, "{}", toml::to_string(&self.status)?)?;
53
54        Ok(())
55    }
56
57    pub fn published(&mut self, version: &str) {
58        self.status.entry(version.into()).and_modify(
59            |version_status| {
60                version_status.published = true;
61            },
62        );
63    }
64
65    pub fn clear_missing_targets(&mut self, version: &str, target_strings: &[String]) {
66        let mut version_info = self.status.get_mut(version);
67        if let Some(ref mut version_info) = version_info {
68            version_info.build_names.retain(|k, _| {
69                let contains = target_strings.contains(&k);
70                if !contains {
71                    debug!(
72                        "{} not in supplied release config, removing from status file",
73                        k
74                    )
75                }
76                contains
77            });
78        }
79    }
80
81    pub fn needs_compile(&self, build_name: &str, version: &str) -> bool {
82        let build_names = self.status.get(version);
83        let vs = if let Some(vs) = build_names {
84            vs
85        } else {
86            return true;
87        };
88
89        let build_status = vs.build_names.get(build_name);
90        let build_status = if let Some(build_status) = build_status {
91            build_status
92        } else {
93            return true;
94        };
95
96        match *build_status {
97            BuildStatus::Success => false,
98            _ => true,
99        }
100    }
101
102    fn set_status(&mut self, build_name: &str, version: &str, status: BuildStatus) {
103        let version_status = self.status.entry(version.into()).or_insert(
104            VersionStatus::default(),
105        );
106        version_status.build_names.insert(build_name.into(), status);
107    }
108
109    pub fn start(&mut self, build_name: &str, version: &str) {
110        self.set_status(build_name, version, BuildStatus::Started);
111    }
112
113    pub fn succeed(&mut self, build_name: &str, version: &str) {
114        self.set_status(build_name, version, BuildStatus::Success);
115    }
116
117    pub fn fail(&mut self, build_name: &str, version: &str) {
118        self.set_status(build_name, version, BuildStatus::Failed);
119    }
120
121    pub fn reset_all(&mut self, version: &str) {
122        let version_status = self.status.entry(version.into()).or_insert(
123            VersionStatus::default(),
124        );
125
126        for value in version_status.build_names.values_mut() {
127            *value = BuildStatus::Waiting;
128        }
129    }
130
131    pub fn all_clear(&self, version: &str) -> bool {
132        let version_status = self.status.get(version);
133
134        if let Some(ref version_status) = version_status {
135            for build_status in version_status.build_names.values() {
136                if build_status != &BuildStatus::Success {
137                    return false;
138                }
139            }
140        }
141
142        return true;
143    }
144
145    pub fn publish(&mut self, version: &str) {
146        let version_status = self.status.entry(version.into()).or_insert(
147            VersionStatus::default(),
148        );
149        version_status.published = true;
150    }
151
152    pub fn is_published(&self, version: &str) -> bool {
153        let version_status = self.status.get(version);
154
155        if let Some(version_status) = version_status {
156            version_status.published
157        } else {
158            false
159        }
160    }
161}
162
163#[derive(Serialize, Deserialize)]
164pub struct VersionStatus {
165    published: bool,
166    build_names: HashMap<BuildName, BuildStatus>,
167}
168
169impl Default for VersionStatus {
170    fn default() -> Self {
171        VersionStatus {
172            published: false,
173            build_names: HashMap::new(),
174        }
175    }
176}
177
178#[derive(Serialize, Deserialize, PartialEq)]
179pub enum BuildStatus {
180    Waiting,
181    Started,
182    Success,
183    Failed,
184}