#[derive(Debug, PartialEq, Eq)]
pub(crate) enum Provenance {
Release,
Commit { commit: String, dirty: bool },
Unknown,
}
pub(crate) fn describe(version: &str, provenance: &Provenance) -> String {
match provenance {
Provenance::Release => version.to_owned(),
Provenance::Commit {
commit,
dirty: false,
} => format!("{version}+{commit}"),
Provenance::Commit {
commit,
dirty: true,
} => format!("{version}+{commit}.dirty"),
Provenance::Unknown => format!("{version}+unknown"),
}
}
pub(crate) fn from_vcs_info(json: &str) -> Provenance {
let commit = json
.split("\"sha1\"")
.nth(1)
.and_then(|rest| rest.split('"').nth(1))
.map(|sha| sha.chars().take(SHORT).collect::<String>());
let dirty = json.contains("\"dirty\": true") || json.contains("\"dirty\":true");
match commit {
Some(commit) if dirty => Provenance::Commit {
commit,
dirty: true,
},
Some(_) => Provenance::Release,
None => Provenance::Unknown,
}
}
pub(crate) fn from_checkout(version: &str, commit: &str, tags: &str, dirty: bool) -> Provenance {
if !dirty && tags.lines().any(|tag| tag.trim() == version) {
Provenance::Release
} else {
Provenance::Commit {
commit: commit.chars().take(SHORT).collect(),
dirty,
}
}
}
pub(crate) const SHORT: usize = 7;
#[cfg(test)]
mod tests {
use super::*;
const COMMIT: &str = "abcdef0123456789abcdef0123456789abcdef01";
#[test]
fn a_release_reports_its_version_alone_and_anything_else_names_its_source() {
let commit = |dirty| Provenance::Commit {
commit: "abcdef0".to_owned(),
dirty,
};
assert_eq!(describe("1.2.3", &Provenance::Release), "1.2.3");
assert_eq!(describe("1.2.3", &commit(false)), "1.2.3+abcdef0");
assert_eq!(describe("1.2.3", &commit(true)), "1.2.3+abcdef0.dirty");
assert_eq!(describe("1.2.3", &Provenance::Unknown), "1.2.3+unknown");
}
#[test]
fn a_checkout_is_a_release_only_at_its_own_tag_with_nothing_changed() {
let commit = |dirty| Provenance::Commit {
commit: "abcdef0".to_owned(),
dirty,
};
assert_eq!(
from_checkout("1.2.3", COMMIT, "1.2.3\n", false),
Provenance::Release
);
assert_eq!(
from_checkout("1.2.3", COMMIT, "1.2.3\n", true),
commit(true),
"the tag with changes on top is not the release"
);
assert_eq!(
from_checkout("1.2.3", COMMIT, "1.2.2\n", false),
commit(false),
"another version's tag is not this one's"
);
assert_eq!(from_checkout("1.2.3", COMMIT, "", false), commit(false));
}
#[test]
fn a_package_reads_its_commit_and_whether_it_was_dirty_from_what_cargo_recorded() {
let clean = format!(
"{{\n \"git\": {{\n \"sha1\": \"{COMMIT}\"\n }},\n \"path_in_vcs\": \"\"\n}}"
);
let dirty = format!(
"{{\n \"git\": {{\n \"sha1\": \"{COMMIT}\",\n \"dirty\": true\n }},\n \"path_in_vcs\": \"\"\n}}"
);
assert_eq!(from_vcs_info(&clean), Provenance::Release);
assert_eq!(
from_vcs_info(&dirty),
Provenance::Commit {
commit: "abcdef0".to_owned(),
dirty: true
}
);
assert_eq!(from_vcs_info("{}"), Provenance::Unknown);
}
}