2023-07-30 17:24:33 +02:00
|
|
|
use semver::{Prerelease, Version};
|
|
|
|
|
|
|
|
use super::conventional_parse::VersionIncrement;
|
|
|
|
|
|
|
|
pub trait NextVersion {
|
|
|
|
fn next<I>(&self, commits: I) -> Self
|
|
|
|
where
|
|
|
|
I: IntoIterator,
|
|
|
|
I::Item: AsRef<str>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl NextVersion for Version {
|
|
|
|
fn next<I>(&self, commits: I) -> Self
|
|
|
|
where
|
|
|
|
I: IntoIterator,
|
|
|
|
I::Item: AsRef<str>,
|
|
|
|
{
|
|
|
|
let increment = VersionIncrement::from(self, commits);
|
|
|
|
|
|
|
|
match increment {
|
|
|
|
Some(increment) => match increment {
|
|
|
|
VersionIncrement::Major => Self {
|
|
|
|
major: self.major + 1,
|
|
|
|
minor: 0,
|
|
|
|
patch: 0,
|
|
|
|
pre: Prerelease::EMPTY,
|
|
|
|
..self.clone()
|
|
|
|
},
|
|
|
|
VersionIncrement::Minor => Self {
|
|
|
|
minor: self.minor + 1,
|
|
|
|
patch: 0,
|
|
|
|
pre: Prerelease::EMPTY,
|
|
|
|
..self.clone()
|
|
|
|
},
|
|
|
|
VersionIncrement::Patch => Self {
|
|
|
|
patch: self.patch + 1,
|
|
|
|
pre: Prerelease::EMPTY,
|
|
|
|
..self.clone()
|
|
|
|
},
|
|
|
|
VersionIncrement::Prerelease => Self {
|
|
|
|
pre: {
|
|
|
|
let release = &self.pre;
|
2023-07-31 13:34:23 +02:00
|
|
|
let release_version = match release.rsplit_once('.') {
|
2023-07-30 17:24:33 +02:00
|
|
|
Some((tag, version)) => match version.parse::<usize>() {
|
|
|
|
Ok(version) => format!("{tag}.{}", version + 1),
|
|
|
|
Err(_) => format!("{tag}.1"),
|
|
|
|
},
|
|
|
|
None => format!("{release}.1"),
|
|
|
|
};
|
|
|
|
Prerelease::new(&release_version).expect("prerelease is not valid semver")
|
|
|
|
},
|
|
|
|
..self.clone()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
None => self.clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use semver::Version;
|
|
|
|
use tracing_test::traced_test;
|
|
|
|
|
|
|
|
use crate::versioning::next_version::NextVersion;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_no_bump() {
|
|
|
|
let version = Version::parse("0.0.0-prerelease").unwrap();
|
|
|
|
let commits: Vec<&str> = vec![];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("0.0.0-prerelease", actual.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_prerelease_initial() {
|
|
|
|
let version = Version::parse("0.0.0-prerelease").unwrap();
|
|
|
|
let commits: Vec<&str> = vec!["feat: something"];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("0.0.0-prerelease.1", actual.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_prerelease_invalid() {
|
|
|
|
let version = Version::parse("0.0.0-prerelease.invalid").unwrap();
|
|
|
|
let commits: Vec<&str> = vec!["feat: something"];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("0.0.0-prerelease.1", actual.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_prerelease_next() {
|
|
|
|
let version = Version::parse("0.0.0-prerelease.1").unwrap();
|
|
|
|
let commits: Vec<&str> = vec!["feat: something"];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("0.0.0-prerelease.2", actual.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_patch() {
|
|
|
|
let version = Version::parse("0.0.0").unwrap();
|
|
|
|
let commits: Vec<&str> = vec!["fix: something"];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("0.0.1", actual.to_string())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_minor() {
|
|
|
|
let version = Version::parse("0.1.0").unwrap();
|
|
|
|
let commits: Vec<&str> = vec!["feat: something"];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("0.2.0", actual.to_string())
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_minor_clears_patch() {
|
|
|
|
let version = Version::parse("0.1.1").unwrap();
|
|
|
|
let commits: Vec<&str> = vec!["feat: something"];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("0.2.0", actual.to_string())
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_major() {
|
|
|
|
let version = Version::parse("0.0.0").unwrap();
|
|
|
|
let commits: Vec<&str> = vec![
|
|
|
|
"feat: something
|
|
|
|
|
|
|
|
BREAKING CHANGE: something",
|
|
|
|
];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("1.0.0", actual.to_string())
|
|
|
|
}
|
|
|
|
#[test]
|
|
|
|
#[traced_test]
|
|
|
|
fn is_major_clears_minor_patch() {
|
|
|
|
let version = Version::parse("1.2.3").unwrap();
|
|
|
|
let commits: Vec<&str> = vec![
|
|
|
|
"feat: something
|
|
|
|
|
|
|
|
BREAKING CHANGE: something",
|
|
|
|
];
|
|
|
|
|
|
|
|
let actual = version.next(commits);
|
|
|
|
|
|
|
|
assert_eq!("2.0.0", actual.to_string())
|
|
|
|
}
|
|
|
|
}
|