mol_core/
bump.rs

1use std::collections::{HashMap, HashSet};
2
3use crate::changeset::Changeset;
4use crate::package::PackageGraph;
5use crate::version::{VersionEditor, VersionMod};
6
7#[derive(Debug, Default)]
8pub struct Bump<T> {
9  changesets: Vec<Changeset<T>>,
10  package_update: HashMap<String, VersionMod<T>>,
11  package_changesets: HashMap<String, HashSet<usize>>,
12}
13
14impl<'a, T: VersionEditor> Bump<T> {
15  fn set_package_update(
16    package_update: &mut HashMap<String, VersionMod<T>>,
17    name: &str,
18    version: VersionMod<T>,
19  ) {
20    if let Some(concat_version) = package_update.get_mut(name) {
21      if &version > concat_version {
22        *concat_version = version;
23      }
24    } else {
25      package_update.insert(name.to_owned(), version);
26    }
27  }
28
29  pub fn add(&mut self, changeset: Changeset<T>, graph: &PackageGraph<'_, T>) {
30    let min_update = T::options().into_iter().min().unwrap_or_default();
31    let index = self.changesets.len();
32    self.changesets.insert(index, changeset);
33    let changeset = &self.changesets[index];
34
35    for (name, version) in &changeset.packages {
36      if let Some(changesets) = self.package_changesets.get_mut(name) {
37        changesets.insert(index);
38      } else {
39        self
40          .package_changesets
41          .insert(name.clone(), vec![index].into_iter().collect());
42      }
43
44      Self::set_package_update(&mut self.package_update, name, version.clone());
45
46      for package in graph.child_changes(name) {
47        Self::set_package_update(
48          &mut self.package_update,
49          &package.name,
50          VersionMod::new(min_update.clone()),
51        );
52      }
53    }
54  }
55
56  pub fn is_empty(&self) -> bool {
57    self.changesets.is_empty()
58  }
59
60  pub fn package(&'a self, name: &'a str) -> PackageBump<'a, T> {
61    PackageBump { name, bump: self }
62  }
63}
64
65pub struct PackageBump<'a, T> {
66  name: &'a str,
67  bump: &'a Bump<T>,
68}
69
70impl<'a, T> PackageBump<'a, T> {
71  pub fn changesets(&self) -> Option<Vec<&'a Changeset<T>>> {
72    self.bump.package_changesets.get(self.name).map(|indexes| {
73      indexes
74        .iter()
75        .map(|index| &self.bump.changesets[*index])
76        .collect()
77    })
78  }
79
80  pub fn name(&self) -> &str {
81    self.name
82  }
83
84  pub fn version(&self) -> Option<&VersionMod<T>> {
85    self.bump.package_update.get(self.name)
86  }
87}
88
89#[cfg(test)]
90mod tests {
91
92  use super::*;
93  use crate::prelude::*;
94
95  #[test]
96  fn add() {
97    let packages = vec![];
98
99    let mut bump = Bump::default();
100    let graph = packages.as_package_graph();
101
102    bump.add(
103      Changeset {
104        packages: vec![("mol".to_owned(), VersionMod::new(Semantic::minor()))]
105          .into_iter()
106          .collect(),
107        message: "Hi".to_owned(),
108      },
109      &graph,
110    );
111    bump.add(
112      Changeset {
113        packages: vec![
114          ("mol".to_owned(), VersionMod::new(Semantic::patch())),
115          ("mol-core".to_owned(), VersionMod::new(Semantic::major())),
116        ]
117        .into_iter()
118        .collect(),
119        message: "Too bad we dont play games".to_owned(),
120      },
121      &graph,
122    );
123
124    assert_eq!(bump.changesets.len(), 2);
125    assert_eq!(
126      bump.package_changesets.get("mol-core"),
127      Some(&vec![1].into_iter().collect())
128    );
129    assert_eq!(
130      bump.package_changesets.get("mol"),
131      Some(&vec![0, 1].into_iter().collect())
132    );
133    assert_eq!(
134      bump.package_update.get("mol"),
135      Some(&VersionMod::new(Semantic::minor()))
136    );
137    assert_eq!(
138      bump.package_update.get("mol-core"),
139      Some(&VersionMod::new(Semantic::major()))
140    );
141  }
142
143  #[test]
144  fn changesets() {
145    let packages = vec![];
146
147    let mut bump = Bump::default();
148    let graph = packages.as_package_graph();
149
150    bump.add(
151      Changeset {
152        packages: vec![("mol".to_owned(), VersionMod::new(Semantic::minor()))]
153          .into_iter()
154          .collect(),
155        message: "Hi".to_owned(),
156      },
157      &graph,
158    );
159    bump.add(
160      Changeset {
161        packages: vec![("mol-core".to_owned(), VersionMod::new(Semantic::major()))]
162          .into_iter()
163          .collect(),
164        message: "Too bad we dont play games".to_owned(),
165      },
166      &graph,
167    );
168
169    let changesets = bump.package("mol").changesets();
170
171    assert!(changesets.is_some());
172
173    let changesets = changesets.unwrap();
174
175    assert_eq!(changesets.len(), 1);
176    assert_eq!(changesets[0].message, "Hi");
177
178    let changesets = bump.package("mol-core").changesets();
179
180    assert!(changesets.is_some());
181
182    let changesets = changesets.unwrap();
183
184    assert_eq!(changesets.len(), 1);
185    assert_eq!(changesets[0].message, "Too bad we dont play games");
186  }
187
188  #[test]
189  fn dependecy_bump() {
190    let packages = vec![
191      Package {
192        name: "mol-core".to_owned(),
193        path: "".into(),
194        version: "0.1.0".into(),
195        dependencies: vec![],
196      },
197      Package {
198        name: "mol".to_owned(),
199        path: "".into(),
200        version: "0.1.0".into(),
201        dependencies: vec![("mol-core".to_owned(), "0.1".to_owned())],
202      },
203      Package {
204        name: "mol-cargo".to_owned(),
205        path: "".into(),
206        version: "0.1.0".into(),
207        dependencies: vec![("mol-core".to_owned(), "0.1".to_owned())],
208      },
209    ];
210
211    let mut bump = Bump::default();
212    let graph = packages.as_package_graph();
213
214    bump.add(
215      Changeset {
216        packages: vec![("mol-core".to_owned(), VersionMod::new(Semantic::minor()))]
217          .into_iter()
218          .collect(),
219        message: "Too bad we dont play games".to_owned(),
220      },
221      &graph,
222    );
223
224    assert_eq!(
225      bump.package_update,
226      vec![
227        ("mol-core".to_owned(), VersionMod::new(Semantic::minor())),
228        ("mol".to_owned(), VersionMod::new(Semantic::patch())),
229        ("mol-cargo".to_owned(), VersionMod::new(Semantic::patch()))
230      ]
231      .into_iter()
232      .collect()
233    );
234  }
235}