Версионирование
Анализ и инкремент строки с версией
Пример строит semver::Version
из строкового значения используя Version::parse
,
затем осуществляет инкремент номера патча, минорного и мажорного номера версии один за одним.
Заметим, что в соответствии со спецификацией Semantic Versioning Specification увеличение минорного номера версии сбрасывает счётчик патча на 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(()) }
Разбор строки содержащей сложную версию
Строит semver::Version
из строки используя Version::parse
. Строка содержит номер
предварительного релиза и метаданные сборки как определяется в спецификации Semantic Versioning Specification.
Заметим, что в соответствии со спецификации метаданные сборки анализируются, но не принимаются во внимание в процессе сравнения версий. Другими словами, две версии могут быть равны даже если их данные сборки различаются.
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 main() -> 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(()) }
Проверка версии внешней команды на совместимость
Код в рецепте выполняет git --version
используя Command
а затем анализирует
номер версии и преобразует в semver::Version
используя Version::parse
.
Метод 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 main() -> 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(()) }