Onset: version control where nobody waits and nothing gets lost. The on command, its core and onset-server.
| 5 |
| 6 | use crate::Id; |
| 7 | use crate::id::sha256; |
| 8 |
| 9 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] |
| 10 | pub struct Version { |
| 11 | pub n: u64, |
| 12 | pub tree: Id, |
| 13 | /// The previous version's ID (None for version 1). |
| 14 | pub prev: Option<Id>, |
| 15 | /// The change that landed (empty for imported history). |
| 16 | pub change: String, |
| 17 | /// "Name <email>", the person (or agent acting for one) who wrote it. |
| 18 | pub author: String, |
| 19 | /// Seconds since the epoch. |
| 20 | pub time: i64, |
| 21 | pub title: String, |
| 22 | #[serde(default)] |
| 23 | pub body: String, |
| 24 | /// The git commit this version is in the project's git view, once known. |
| 25 | #[serde(default)] |
| 26 | pub git: Option<String>, |
| 27 | } |
| 28 |
| 29 | impl Version { |
| 30 | /// The version's ID: a hash of everything but its git mapping, which is |
| 31 | /// filled in later. |
| 32 | pub fn id(&self, project: &str) -> Id { |
| 33 | let text = format!( |
| 34 | "vcs version\nproject {project}\nn {}\ntree {}\nprev {}\nchange {}\nauthor {}\ntime {}\n\n{}\n\n{}", |
| 35 | self.n, |
| 36 | self.tree, |
| 37 | self.prev.map(|p| p.hex()).unwrap_or_else(|| "-".into()), |
| 38 | self.change, |
| 39 | self.author, |
| 40 | self.time, |
| 41 | self.title, |
| 42 | self.body |
| 43 | ); |
| 44 | sha256(&[text.as_bytes()]) |
| 45 | } |
| 46 |
| 47 | /// The description as one text: title, a blank line, then the body. |
| 48 | pub fn message(&self) -> String { |
| 49 | if self.body.is_empty() { self.title.clone() } else { format!("{}\n\n{}", self.title, self.body) } |
| 50 | } |
| 51 | } |
| 52 |
| 53 | #[cfg(test)] |
| 54 | mod tests { |
| 55 | use super::*; |
| 56 |
| 57 | #[test] |
| 58 | fn ids_chain() { |
| 59 | let v1 = Version { n: 1, tree: Id::ZERO, prev: None, change: "bcdf".into(), author: "a <a@x>".into(), time: 1, title: "t".into(), body: String::new(), git: None }; |
| 60 | let v2 = Version { n: 2, prev: Some(v1.id("p")), ..v1.clone() }; |
| 61 | assert_ne!(v1.id("p"), v2.id("p")); |
| 62 | let mut mapped = v1.clone(); |
| 63 | mapped.git = Some("abc".into()); |
| 64 | assert_eq!(mapped.id("p"), v1.id("p")); |
| 65 | } |
| 66 | } |
| 67 |