Semantic versions
Versions compared, matched against ranges as Cargo and npm write them, the newest in a range, and bumped.
Version 1.0.0 · 4 functions · 1 crate
Functions
What use semver.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use semver_compare, semver_matches from semver (Quillo 0.6).
semver_compare(a: str, b: str) → intor an error-1, 0 or 1 as a comes before, is, or comes after b (1.10.0 after 1.9.0; 2.0.0-rc.1 before 2.0.0).
semver_matches(version: str, req: str) → boolor an errorWhether version is in the range req: semver_matches("1.4.2", "^1.2").
semver_newest(versions: list, req: str) → str?or an errorThe newest of versions in the range req, or null; versions that do not parse are skipped.
semver_bump(version: str, part: str) → stror an errorThe version after version, by part: "major", "minor" or "patch".
Get it
$ quillo install semver # semver.qwer into this folder$ quillo install semver --example # and its example, semver.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/semver.qwer$ curl -O https://quillolang.org/plugins/files/semver.qweThen, in your program, all of it or only what you call:
use semver.qweruse semver_compare, semver_matches from semver // Quillo 0.6: only theseIt uses this crate, which cargo fetches the first time the plugin is built:
semver = "1"Example
// Which release a client should update to.//// quillo run semver.qwe then open http://localhost:8080/update?have=1.2.0use "semver.qwer"let releases = ["1.2.0", "1.2.5", "1.3.0", "2.0.0-rc.1", "2.0.0", "2.1.0"]route GET /update ? { have: str } = { same_major: semver_newest(releases, `^${have}`)?, newest: semver_newest(releases, "*")?, next_minor: semver_bump(have, "minor")?, behind: semver_compare(have, "2.1.0")? < 0,}$ quillo run semver.qwe$ curl 'localhost:8080/update?have=1.2.0'Source
//! Semantic versions compared and matched against ranges as Cargo and npm write them (`^1.2`, `>=2, <3`).//! version: 1.0.0//!//! [dependencies]//! semver = "1"use semver::{Version, VersionReq};fn v(s: &str) -> Result<Version, String> { Version::parse(s.trim().trim_start_matches('v')).map_err(|e| format!("{}: {}", s, e))}/// -1, 0 or 1 as `a` comes before, is, or comes after `b` (`1.10.0` after `1.9.0`; `2.0.0-rc.1` before `2.0.0`).pub fn semver_compare(a: &str, b: &str) -> Result<i64, String> { Ok(match v(a)?.cmp(&v(b)?) { std::cmp::Ordering::Less => -1, std::cmp::Ordering::Equal => 0, std::cmp::Ordering::Greater => 1 })}/// Whether `version` is in the range `req`: `semver_matches("1.4.2", "^1.2")`.pub fn semver_matches(version: &str, req: &str) -> Result<bool, String> { Ok(VersionReq::parse(req).map_err(|e| e.to_string())?.matches(&v(version)?))}/// The newest of `versions` in the range `req`, or null; versions that do not parse are skipped.pub fn semver_newest(versions: Vec<String>, req: &str) -> Result<Option<String>, String> { let r = VersionReq::parse(req).map_err(|e| e.to_string())?; Ok(versions.iter().filter_map(|s| v(s).ok().map(|p| (p, s))).filter(|(p, _)| r.matches(p)).max_by(|a, b| a.0.cmp(&b.0)).map(|(_, s)| s.clone()))}/// The version after `version`, by `part`: "major", "minor" or "patch".pub fn semver_bump(version: &str, part: &str) -> Result<String, String> { let mut x = v(version)?; x.pre = semver::Prerelease::EMPTY; x.build = semver::BuildMetadata::EMPTY; match part { "major" => { x.major += 1; x.minor = 0; x.patch = 0; } "minor" => { x.minor += 1; x.patch = 0; } "patch" => x.patch += 1, _ => return Err(format!("the part is major, minor or patch, not `{}`", part)), } Ok(x.to_string())}Related
Thread 0 posts
On Semantic versions: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.