版本控制
分析并增加版本字符串。
构建一个semver::Version
从字符串文本使用Version::parse
,然后逐个递增补丁、次要版本和主要版本号。
注意,根据[语义版本规范],递增次要版本号将补丁版本号重置为0,递增主要版本号将次要版本号和补丁版本号重置为0。
extern crate semver; use semver::{Version, SemVerError}; fn main() -> Result<(), SemVerError> { let mut parsed_version = Version::parse("0.2.6")?; assert_eq!( parsed_version, Version { major: 0, minor: 2, patch: 6, pre: vec![], build: vec![], } ); parsed_version.increment_patch(); assert_eq!(parsed_version.to_string(), "0.2.7"); println!("New patch release: v{}", parsed_version); parsed_version.increment_minor(); assert_eq!(parsed_version.to_string(), "0.3.0"); println!("New minor release: v{}", parsed_version); parsed_version.increment_major(); assert_eq!(parsed_version.to_string(), "1.0.0"); println!("New major release: v{}", parsed_version); Ok(()) }
分析复杂的版本字符串。
使用Version::parse
从复杂版本字符串,构建一个semver::Version
。 该字符串包含预发布和构建的元数据,正如[语义版本规范]所定义的。
注意,根据规范,构建元数据虽然解析了,但在比较版本时,不考虑。换句话说,即使构建字符串不同,两个版本也可能相同。
extern crate semver; use semver::{Identifier, Version, SemVerError}; fn main() -> Result<(), SemVerError> { let version_str = "1.0.49-125+g72ee7853"; let parsed_version = Version::parse(version_str)?; assert_eq!( parsed_version, Version { major: 1, minor: 0, patch: 49, pre: vec![Identifier::Numeric(125)], build: vec![], } ); assert_eq!( parsed_version.build, vec![Identifier::AlphaNumeric(String::from("g72ee7853"))] ); let serialized_version = parsed_version.to_string(); assert_eq!(&serialized_version, version_str); Ok(()) }
检查给定版本,是否为预发布版本。
给出两个版本,is_prerelease
断言一个是预发布,另一个不是。
extern crate semver; use semver::{Version, SemVerError}; fn main() -> Result<(), SemVerError> { let version_1 = Version::parse("1.0.0-alpha")?; let version_2 = Version::parse("1.0.0")?; assert!(version_1.is_prerelease()); assert!(!version_2.is_prerelease()); Ok(()) }
查找满足给定范围的最新版本
给定版本 &str
的一个列表,查找最新的semver::Version
。 semver::VersionReq
能用VersionReq::matches
筛选列表。还可以,给出预发布semver
的首选项。
# #[macro_use] # extern crate error_chain; extern crate semver; use semver::{Version, VersionReq}; # # error_chain! { # foreign_links { # SemVer(semver::SemVerError); # SemVerReq(semver::ReqParseError); # } # } fn find_max_matching_version<'a, I>(version_req_str: &str, iterable: I) -> Result<Option<Version>> where I: IntoIterator<Item = &'a str>, { let vreq = VersionReq::parse(version_req_str)?; Ok( iterable .into_iter() .filter_map(|s| Version::parse(s).ok()) .filter(|s| vreq.matches(s)) .max(), ) } fn run() -> Result<()> { assert_eq!( find_max_matching_version("<= 1.0.0", vec!["0.9.0", "1.0.0", "1.0.1"])?, Some(Version::parse("1.0.0")?) ); assert_eq!( find_max_matching_version( ">1.2.3-alpha.3", vec![ "1.2.3-alpha.3", "1.2.3-alpha.4", "1.2.3-alpha.10", "1.2.3-beta.4", "3.4.5-alpha.9", ] )?, Some(Version::parse("1.2.3-beta.4")?) ); Ok(()) } # # quick_main!(run);
检查外部命令版本的兼容性
使用Command
运行git --version
,然后用Version::parse
,将版本号解析为semver::Version
。 VersionReq::matches
会比较semver::VersionReq
与已解析的版本。命令输出,类似于”git version x.y.z”。
# #[macro_use] # extern crate error_chain; extern crate semver; use std::process::Command; use semver::{Version, VersionReq}; # # error_chain! { # foreign_links { # Io(std::io::Error); # Utf8(std::string::FromUtf8Error); # SemVer(semver::SemVerError); # SemVerReq(semver::ReqParseError); # } # } fn run() -> Result<()> { let version_constraint = "> 1.12.0"; let version_test = VersionReq::parse(version_constraint)?; let output = Command::new("git").arg("--version").output()?; if !output.status.success() { bail!("Command executed with failing error code"); } let stdout = String::from_utf8(output.stdout)?; let version = stdout.split(" ").last().ok_or_else(|| { "Invalid command output" })?; let parsed_version = Version::parse(version)?; if !version_test.matches(&parsed_version) { bail!("Command version lower than minimum supported version (found {}, need {})", parsed_version, version_constraint); } Ok(()) } # # quick_main!(run);