1use git2::{DescribeFormatOptions, DescribeOptions, Repository};
2use pyrinas_shared::ota::OTAPackageVersion;
3use semver::Version;
4use thiserror::Error;
6
7use std::{convert::TryInto, io, num};
9
10#[derive(Debug, Error)]
11pub enum GitError {
12 #[error("filesystem error: {source}")]
13 FileError {
14 #[from]
15 source: io::Error,
16 },
17
18 #[error("git repo not found!")]
19 GitNotFound,
20
21 #[error("git error: {source}")]
22 GitError {
23 #[from]
24 source: git2::Error,
25 },
26
27 #[error("parse error: {source}")]
28 ParseError {
29 #[from]
30 source: num::ParseIntError,
31 },
32
33 #[error("semver error: {source}")]
34 SemVerError {
35 #[from]
36 source: semver::Error,
37 },
38
39 #[error("unable to convert hash")]
40 HashError,
41}
42
43pub fn get_git_describe() -> Result<String, GitError> {
44 let mut path = std::env::current_dir()?;
45
46 let repo: Repository;
47
48 loop {
50 repo = match Repository::open(path.clone()) {
51 Ok(repo) => repo,
52 Err(_e) => {
53 if !path.pop() {
54 return Err(GitError::GitNotFound);
55 }
56
57 continue;
58 }
59 };
60
61 break;
62 }
63
64 let mut opts = DescribeOptions::new();
66 let opts = opts.describe_all().describe_tags();
67
68 let mut desc_format_opts = DescribeFormatOptions::new();
70 desc_format_opts
71 .always_use_long_format(true)
72 .dirty_suffix("-dirty");
73
74 let des = repo.describe(opts)?.format(Some(&desc_format_opts))?;
76
77 Ok(des)
78}
79
80pub fn get_ota_package_version(ver: &str) -> Result<(OTAPackageVersion, bool), GitError> {
81 let version = Version::parse(ver)?;
83
84 log::info!("ver: {:?}", version);
85
86 let dirty = ver.contains("dirty");
88 let pre: Vec<&str> = ver.split('-').collect();
89 let commit: u8 = pre[1].parse()?;
90 let hash: [u8; 8] = get_hash(pre[2].as_bytes().to_vec())?;
91
92 Ok((
93 OTAPackageVersion {
94 major: version.major as u8,
95 minor: version.minor as u8,
96 patch: version.patch as u8,
97 commit,
98 hash,
99 },
100 dirty,
101 ))
102}
103
104fn get_hash(v: Vec<u8>) -> Result<[u8; 8], GitError> {
105 match v.try_into() {
106 Ok(r) => Ok(r),
107 Err(_e) => Err(GitError::HashError),
108 }
109}