git_calver/
repo_release.rs1use std::vec::Vec;
2
3use git2::Oid;
4use git2::Repository;
5
6use crate::calver::CalVer;
7use crate::calver::ToCalVer;
8use crate::repo::RepositoryExt;
9
10#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord)]
11pub struct Release {
12 pub version: CalVer,
13 pub commit_id: Oid,
14}
15
16impl Release {
17 pub fn zero() -> Release {
18 Release {
19 commit_id: Oid::zero(),
20 version: CalVer::zero(),
21 }
22 }
23}
24
25pub trait RepositoryWithRelease {
26 fn find_releases(&self) -> Vec<Release>;
27 fn find_latest_release(&self) -> Option<Release>;
28}
29
30impl RepositoryWithRelease for Repository {
31 fn find_releases(&self) -> Vec<Release> {
32 let tag_names = self
33 .tag_names(None)
34 .ok()
35 .map(|a| {
36 a.iter()
37 .flatten()
38 .map(|s| s.to_string())
39 .collect::<Vec<_>>()
40 })
41 .unwrap_or_default();
42 let all_releases = tag_names
43 .iter()
44 .flat_map(|t| t.calver())
45 .flat_map(|v| {
46 self.resolve_reference_from_short_name(v.to_string().as_str())
47 .ok()
48 .and_then(|r| r.peel_to_commit().ok())
49 .map(|c| Release {
50 commit_id: c.id(),
51 version: v,
52 })
53 })
54 .collect::<Vec<_>>();
55 if let Some(head) = self.head().ok().and_then(|r| r.peel_to_commit().ok()) {
56 let mut releases = self
57 .iter_commit_id(&head)
58 .flat_map(|cid| {
59 all_releases
60 .iter()
61 .filter(|r| cid == r.commit_id)
62 .copied()
63 .next()
64 })
65 .collect::<Vec<_>>();
66 releases.sort();
67 releases.reverse();
68 releases
69 } else {
70 vec![]
71 }
72 }
73
74 fn find_latest_release(&self) -> Option<Release> {
75 self.find_releases().into_iter().next()
76 }
77}