| 1 | // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT |
| 2 | // file at the top-level directory of this distribution and at |
| 3 | // http://rust-lang.org/COPYRIGHT. |
| 4 | // |
| 5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| 6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| 7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
| 8 | // option. This file may not be copied, modified, or distributed |
| 9 | // except according to those terms. |
| 10 | |
| 11 | //! Semantic version parsing and comparison. |
| 12 | //! |
| 13 | //! Semantic versioning (see http://semver.org/) is a set of rules for |
| 14 | //! assigning version numbers. |
| 15 | //! |
| 16 | //! ## SemVer overview |
| 17 | //! |
| 18 | //! Given a version number MAJOR.MINOR.PATCH, increment the: |
| 19 | //! |
| 20 | //! 1. MAJOR version when you make incompatible API changes, |
| 21 | //! 2. MINOR version when you add functionality in a backwards-compatible |
| 22 | //! manner, and |
| 23 | //! 3. PATCH version when you make backwards-compatible bug fixes. |
| 24 | //! |
| 25 | //! Additional labels for pre-release and build metadata are available as |
| 26 | //! extensions to the MAJOR.MINOR.PATCH format. |
| 27 | //! |
| 28 | //! Any references to 'the spec' in this documentation refer to [version 2.0 of |
| 29 | //! the SemVer spec](http://semver.org/spec/v2.0.0.html). |
| 30 | //! |
| 31 | //! ## SemVer and the Rust ecosystem |
| 32 | //! |
| 33 | //! Rust itself follows the SemVer specification, as does its standard |
| 34 | //! libraries. The two are not tied together. |
| 35 | //! |
| 36 | //! [Cargo](http://crates.io), Rust's package manager, uses SemVer to determine |
| 37 | //! which versions of packages you need installed. |
| 38 | //! |
| 39 | //! ## Versions |
| 40 | //! |
| 41 | //! At its simplest, the `semver` crate allows you to construct `Version` |
| 42 | //! objects using the `parse` method: |
| 43 | //! |
| 44 | //! ```{rust} |
| 45 | //! use semver::Version; |
| 46 | //! |
| 47 | //! assert!(Version::parse("1.2.3") == Ok(Version { |
| 48 | //! major: 1, |
| 49 | //! minor: 2, |
| 50 | //! patch: 3, |
| 51 | //! pre: vec!(), |
| 52 | //! build: vec!(), |
| 53 | //! })); |
| 54 | //! ``` |
| 55 | //! |
| 56 | //! If you have multiple `Version`s, you can use the usual comparison operators |
| 57 | //! to compare them: |
| 58 | //! |
| 59 | //! ```{rust} |
| 60 | //! use semver::Version; |
| 61 | //! |
| 62 | //! assert!(Version::parse("1.2.3-alpha") != Version::parse("1.2.3-beta")); |
| 63 | //! assert!(Version::parse("1.2.3-alpha2") > Version::parse("1.2.0")); |
| 64 | //! ``` |
| 65 | //! |
| 66 | //! If you explicitly need to modify a Version, SemVer also allows you to |
| 67 | //! increment the major, minor, and patch numbers in accordance with the spec. |
| 68 | //! |
| 69 | //! Please note that in order to do this, you must use a mutable Version: |
| 70 | //! |
| 71 | //! ```{rust} |
| 72 | //! use semver::Version; |
| 73 | //! |
| 74 | //! let mut bugfix_release = Version::parse("1.0.0").unwrap(); |
| 75 | //! bugfix_release.increment_patch(); |
| 76 | //! |
| 77 | //! assert_eq!(Ok(bugfix_release), Version::parse("1.0.1")); |
| 78 | //! ``` |
| 79 | //! |
| 80 | //! When incrementing the minor version number, the patch number resets to zero |
| 81 | //! (in accordance with section 7 of the spec) |
| 82 | //! |
| 83 | //! ```{rust} |
| 84 | //! use semver::Version; |
| 85 | //! |
| 86 | //! let mut feature_release = Version::parse("1.4.6").unwrap(); |
| 87 | //! feature_release.increment_minor(); |
| 88 | //! |
| 89 | //! assert_eq!(Ok(feature_release), Version::parse("1.5.0")); |
| 90 | //! ``` |
| 91 | //! |
| 92 | //! Similarly, when incrementing the major version number, the patch and minor |
| 93 | //! numbers reset to zero (in accordance with section 8 of the spec) |
| 94 | //! |
| 95 | //! ```{rust} |
| 96 | //! use semver::Version; |
| 97 | //! |
| 98 | //! let mut chrome_release = Version::parse("41.5.5377").unwrap(); |
| 99 | //! chrome_release.increment_major(); |
| 100 | //! |
| 101 | //! assert_eq!(Ok(chrome_release), Version::parse("42.0.0")); |
| 102 | //! ``` |
| 103 | //! |
| 104 | //! ## Requirements |
| 105 | //! |
| 106 | //! The `semver` crate also provides the ability to compare requirements, which |
| 107 | //! are more complex comparisons. |
| 108 | //! |
| 109 | //! For example, creating a requirement that only matches versions greater than |
| 110 | //! or equal to 1.0.0: |
| 111 | //! |
| 112 | //! ```{rust} |
| 113 | //! # #![allow(unstable)] |
| 114 | //! use semver::Version; |
| 115 | //! use semver::VersionReq; |
| 116 | //! |
| 117 | //! let r = VersionReq::parse(">= 1.0.0").unwrap(); |
| 118 | //! let v = Version::parse("1.0.0").unwrap(); |
| 119 | //! |
| 120 | //! assert!(r.to_string() == ">= 1.0.0".to_string()); |
| 121 | //! assert!(r.matches(&v)) |
| 122 | //! ``` |
| 123 | //! |
| 124 | //! It also allows parsing of `~x.y.z` and `^x.y.z` requirements as defined at |
| 125 | //! https://www.npmjs.org/doc/misc/semver.html |
| 126 | //! |
| 127 | //! **Tilde requirements** specify a minimal version with some updates: |
| 128 | //! |
| 129 | //! ```notrust |
| 130 | //! ~1.2.3 := >=1.2.3 <1.3.0 |
| 131 | //! ~1.2 := >=1.2.0 <1.3.0 |
| 132 | //! ~1 := >=1.0.0 <2.0.0 |
| 133 | //! ``` |
| 134 | //! |
| 135 | //! **Caret requirements** allow SemVer compatible updates to a specified |
| 136 | //! verion, `0.x` and `0.x+1` are not considered compatible, but `1.x` and |
| 137 | //! `1.x+1` are. |
| 138 | //! |
| 139 | //! `0.0.x` is not considered compatible with any other version. |
| 140 | //! Missing minor and patch versions are desugared to `0` but allow flexibility |
| 141 | //! for that value. |
| 142 | //! |
| 143 | //! ```notrust |
| 144 | //! ^1.2.3 := >=1.2.3 <2.0.0 |
| 145 | //! ^0.2.3 := >=0.2.3 <0.3.0 |
| 146 | //! ^0.0.3 := >=0.0.3 <0.0.4 |
| 147 | //! ^0.0 := >=0.0.0 <0.1.0 |
| 148 | //! ^0 := >=0.0.0 <1.0.0 |
| 149 | //! ``` |
| 150 | //! |
| 151 | //! **Wildcard requirements** allows parsing of version requirements of the |
| 152 | //! formats `*`, `x.*` and `x.y.*`. |
| 153 | //! |
| 154 | //! ```notrust |
| 155 | //! * := >=0.0.0 |
| 156 | //! 1.* := >=1.0.0 <2.0.0 |
| 157 | //! 1.2.* := >=1.2.0 <1.3.0 |
| 158 | //! ``` |
| 159 | |
| 160 | #![doc (html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png" , |
| 161 | html_favicon_url = "https://www.rust-lang.org/favicon.ico" )] |
| 162 | #![deny (missing_docs)] |
| 163 | #![cfg_attr (test, deny(warnings))] |
| 164 | |
| 165 | extern crate semver_parser; |
| 166 | |
| 167 | // Serialization and deserialization support for version numbers |
| 168 | #[cfg (feature = "serde" )] |
| 169 | extern crate serde; |
| 170 | |
| 171 | // We take the common approach of keeping our own module system private, and |
| 172 | // just re-exporting the interface that we want. |
| 173 | |
| 174 | pub use version::{Version, Identifier, SemVerError}; |
| 175 | pub use version::Identifier::{Numeric, AlphaNumeric}; |
| 176 | pub use version_req::{VersionReq, ReqParseError}; |
| 177 | |
| 178 | // SemVer-compliant versions. |
| 179 | mod version; |
| 180 | |
| 181 | // advanced version comparisons |
| 182 | mod version_req; |
| 183 | |