GithubHelp home page GithubHelp logo

semver's Introduction

semver

github crates.io docs.rs build status

A parser and evaluator for Cargo's flavor of Semantic Versioning.

Semantic Versioning (see https://semver.org) is a guideline for how version numbers are assigned and incremented. It is widely followed within the Cargo/crates.io ecosystem for Rust.

[dependencies]
semver = "1.0"

Compiler support: requires rustc 1.31+


Example

use semver::{BuildMetadata, Prerelease, Version, VersionReq};

fn main() {
    let req = VersionReq::parse(">=1.2.3, <1.8.0").unwrap();

    // Check whether this requirement matches version 1.2.3-alpha.1 (no)
    let version = Version {
        major: 1,
        minor: 2,
        patch: 3,
        pre: Prerelease::new("alpha.1").unwrap(),
        build: BuildMetadata::EMPTY,
    };
    assert!(!req.matches(&version));

    // Check whether it matches 1.3.0 (yes it does)
    let version = Version::parse("1.3.0").unwrap();
    assert!(req.matches(&version));
}

Scope of this crate

Besides Cargo, several other package ecosystems and package managers for other languages also use SemVer: RubyGems/Bundler for Ruby, npm for JavaScript, Composer for PHP, CocoaPods for Objective-C...

The semver crate is specifically intended to implement Cargo's interpretation of Semantic Versioning.

Where the various tools differ in their interpretation or implementation of the spec, this crate follows the implementation choices made by Cargo. If you are operating on version numbers from some other package ecosystem, you will want to use a different semver library which is appropriate to that ecosystem.

The extent of Cargo's SemVer support is documented in the Specifying Dependencies chapter of the Cargo reference.


License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

semver's People

Contributors

alexcrichton avatar bjgill avatar bors avatar brendanzab avatar brson avatar burtonageo avatar cgati avatar cruzbishop avatar dirk avatar dr-bonez avatar dtolnay avatar errordeveloper avatar geal avatar globin avatar hone avatar huonw avatar jtgeibel avatar kamalmarhubi avatar matklad avatar mikrostew avatar muzikmoe avatar omasanori avatar opilar avatar pcwalton avatar richo avatar sfackler avatar sgrif avatar steveklabnik avatar udoprog avatar zzeroo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

semver's Issues

VersionReq with build metadata ignored?

This program produces surprising results (to me at least):

extern crate semver;                                          
                                                              
fn main() {                                                   
    let a = semver::VersionReq::parse("=1.0.1+1.7.3").unwrap()
    println!("{:?}", a);                                      
    let b = semver::Version::parse("1.0.1+1.7.5").unwrap();   
    println!("{:?}", b);                                      
    println!("{}", a.matches(&b));                            
}                                                             

The last line prints true, but I'd expect it to print false? It looks like the +1.7.3 isn't being parsed in a?

Implement comparison rules for pre-release tags

The comparison functions in version_req.rs currently ignore prerelease tags. They should instead follow the NPM rules for prerelease tags:

If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it will only be allowed to satisfy comparator sets if at least one comparator with the same [major, minor, patch] tuple also has a prerelease tag.

Update the readme version

The readme recommends to put the following in your dependencies:

semver = "0.5.0"

But the current semver version is "0.5.1"

Compile errors with latest rust

With my current rustc version (0.13.0-dev (c56e59c72 2014-12-09 07:51:52 +0000)), there are multiple compile errors when building Semver, all of which are due to moving values from &-pointers

Misleading error for this invalid versionreq

Version 0.5.0

semver::VersionReq::parse("0.14.00").unwrap() fails with OpAlreadySet. Maybe it should fail with InvalidVersionRequirement

I assume the current behavior is because it's being treated like "0.14.0 0"

0.0.z not compatible with 0.0.z+1

@eddyb brought this up in #rust-internals today. If y != 0, any z is compatible, but if y == 0, they're not. This feels wrong.

I haven't reproduced yet, though.

Support the `||` operator in version ranges

Spec: https://docs.npmjs.com/misc/semver#ranges

A range is composed of one or more comparator sets, joined by ||. A version matches a range if and only if every comparator in at least one of the ||-separated comparator sets is satisfied by the version.

The range 1.2.7 || >=1.2.9 <2.0.0 would match the versions 1.2.7, 1.2.9, and 1.4.6, but not the versions 1.2.8 or 2.0.0.

Provide serde impls behind a cfg

I could have used this today for parsing versions in a config file.

#[derive(Serialize, Deserialize)]
struct Package {
    version: semver::Version,
}

Merge semver and semver-parser

The parsers for versions and version ranges are currently in a separate crate, called semver-parser. This crate also redefines all the data structures, such that the main semver crate has to recurse through the parsed result and convert everything into the correct type.

Is there a reason for this separation? semver does have an extra serde dependency, but we can hide that behind a feature flag if users don't want it. I don't see any other use case for keeping the crates separate, and merging the two crates will avoid this duplicate work.

<= X parsed as X

I was trying this in cargo: >= 0.1, <= 0.2. It's not valid syntax, but it is accepted without error. Output suggests it was interpreted as >= 0.1, 0.2.

(>= 0.1, < 0.3 ended up being what I wanted).

Ensure `=` works with build metadata

Right now,

 // this works
 "= 1.2.3-alpha".parse::<VersionReq>().unwrap();
 // this doesn't    
 "= 1.2.3+250".parse::<VersionReq>().unwrap();

We should support build metadata in the exact same way as we do prereleases.

Inconsistency when patch version is leaved out in VersionReq

If I have a requirement like 0.30, it would match 0.30.0. However if the requirement is 0.30-beta.1, it does not match 0.30.0-beta.1.

I just went through the SemVer documentation without finding much related info. Actually I doubt whether such a requirement is really allowed?

Playground

extern crate semver;

use semver::{Version, VersionReq};

fn main() {
    let req = VersionReq::parse("0.30").unwrap();
    let ver = Version::parse("0.30.0").unwrap();
    println!("{}", req.matches(&ver)); // true

    let req = VersionReq::parse("0.30-beta.1").unwrap();
    let ver = Version::parse("0.30.0-beta.1").unwrap();
    println!("{}", req.matches(&ver)); // false
}

VersionReq to_string does not retain patch in output

Found this while fuzzing this crate.

extern crate semver;

fn main() {
    let str_input = "8.*.7";
    println!("input:\n\t{:?}", str_input);

    let parsed1 = semver::VersionReq::parse(str_input).unwrap();
    println!("parsed:\n\t{:?}", parsed1);

    let version_req_s = parsed1.to_string();
    println!("parsed to_string:\n\t{:?}", version_req_s);

    let parsed2 = semver::VersionReq::parse(&version_req_s).unwrap();
    println!("parsed to_string parsed:\n\t{:?}", parsed2);
}
input:
	"8.*.7"
parsed:
	VersionReq { predicates: [Predicate { op: Wildcard(Minor), major: 8, minor: None, patch: Some(7), pre: [] }] }
parsed to_string:
	"8.*"
parsed to_string parsed:
	VersionReq { predicates: [Predicate { op: Wildcard(Minor), major: 8, minor: None, patch: None, pre: [] }] }

Do releases better

I've already started bumping versions after we cut a release, rather than before, but we should do better.

  1. Changelog
  2. Document the actual release process

Anything else?

How to create a match pattern for an Identifier?

let v = Version::parse("1.2.3+4").unwrap();
let b = &v.build[0];

I'm having trouble getting the u64 value 4 out of b, which seems to be a private enum Identifier. I have solved it like this for now:

let v: u64 = b.to_string().parse::<u64>().unwrap();

Equality with build metadata ignored?

I may be misunderstanding what pre is used for, but I'd expect this program to pass?

extern crate semver;                                       
                                                           
fn main() {                                                
    let a = semver::Version::parse("1.0.1+1.7.3").unwrap();
    let b = semver::Version::parse("1.0.1+1.7.5").unwrap();
    assert!(a != b);                                       
}                                                          

Display format of Version does not respect width/precision settings.

The following should all pass, but currently just all formatted to the same string "1.0.0-rc1".

let version = Version::parse("1.0.0-rc1").unwrap();
assert_eq!(format!("{:20}", version), "1.0.0-rc1           ");
assert_eq!(format!("{:*^20}", version), "*****1.0.0-rc1******");
assert_eq!(format!("{:.4}", version),  "1.0.");

semver binary

Hello,

I ran into a problem with my CI scripts needing to be bumped by 1 minor version + added a -ci at the end. I couldn't find any "easy" way to do it in bash (except for some crazy AWK scripts which didn't work).

I wanted to write this binary in rust, but since most of the work is done here, I just wanted to ask if you'd be opposed to me writing a binary version to semver (which could be included, or as separate project).

The idea is following:

# A bump example. (+patch)
OLD_VERSION = "1.2.3"
echo $OLD_VERSION | semver [patch]
"1.2.4"
# Minor update.
OLD_VERSION = "1.2.3"
echo $OLD_VERSION | semver minor
"1.3.0"
# Major update.
OLD_VERSION = "1.2.3"
echo $OLD_VERSION | semver major
"2.0.0"
# CI example.
OLD_VERSION = "1.2.3"
echo $OLD_VERSION | semver --meta=ci  # this may contain git-commit tag
"1.2.3+ci"

The main usage is for gitlab CI/CD scripts, which need to parse previous program version, and deploy +CI version in metadata. Since I have multiple programming environments, each uses diferent tools to manage versions and some (docker) don't have any.

I wanted to start rust-semver project on my github profile, but I didn't want to rip-off this project (since it will do most of the work).

Thank you!

Need to keep up with std::ascii reform

When building cargo with (very) recent rustc, the following error is reported:

/home/akiss/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.6/src/version.rs:75:15: 75:25 error: type `&str` does not implement any method in scope named `is_ascii`
/home/akiss/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.6/src/version.rs:75         if !s.is_ascii() {

This seems to be the case since rust-lang/rust@070ab63 , and the cause of the error is also present in current HEAD of semver.

(This is very similar to alexcrichton/curl-rust#45 )

unresolved import `version::Numeric` in 0.1.1 via cargo repo

Looking at the commit history, it looks like this should have been fixed by 1672853. But I just tried installing semver via the cargo repo and I got this:

   Compiling semver v0.1.1
     Running `rustc /home/stephen/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.1/src/lib.rs --crate-name semver --crate-type lib -g -C metadata=b4dcdc26bf699f6e -C extra-filename=-b4dcdc26bf699f6e --out-dir /home/stephen/Documents/personal/rust/hello_world/target/deps --dep-info /home/stephen/Documents/personal/rust/hello_world/target/.fingerprint/semver-b4dcdc26bf699f6e/dep-lib-semver -L /home/stephen/Documents/personal/rust/hello_world/target/deps -L /home/stephen/Documents/personal/rust/hello_world/target/deps -Awarnings`  
/home/stephen/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.1/src/lib.rs:132:52: 132:59 error: unresolved import `version::Numeric`. There is no `Numeric` in `version`
/home/stephen/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.1/src/lib.rs:132 pub use version::{Version, Identifier, ParseError, Numeric, AlphaNumeric};

/home/stephen/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.1/src/lib.rs:132:61: 132:73 error: unresolved import `version::AlphaNumeric`. There is no `AlphaNumeric` in `version`
/home/stephen/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.1/src/lib.rs:132 pub use version::{Version, Identifier, ParseError, Numeric, AlphaNumeric};

error: aborting due to 2 previous errors
Could not compile `semver`.

Caused by:
  Process didn't exit successfully: `rustc /home/stephen/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.1/src/lib.rs --crate-name semver --crate-type lib -g -C metadata=b4dcdc26bf699f6e -C extra-filename=-b4dcdc26bf699f6e --out-dir /home/stephen/Documents/personal/rust/hello_world/target/deps --dep-info /home/stephen/Documents/personal/rust/hello_world/target/.fingerprint/semver-b4dcdc26bf699f6e/dep-lib-semver -L /home/stephen/Documents/personal/rust/hello_world/target/deps -L /home/stephen/Documents/personal/rust/hello_world/target/deps -Awarnings` (status=101)

On closer inspection of src/lib.rs, it seems to not have the changes from that commit somehow. The Cargo.toml contains this:

[package]

name = "semver"
version = "0.1.1"
authors = ["The Rust Project Developers"]

Perhaps it got published twice at 0.1.1 and the wrong one stuck?

Prerelease tags handling too strict for Rust versions

I am trying to update https://github.com/Kimundi/rustc-version-rs from semver 0.1 to 0.2 (in order to reduce the number of crates with more than one versions in Servo’s dependency graph).

One of its tests is that the current Rust version matches >= 1.0.0. On beta or nightly, with a version like Version { major: 1, minor: 17, patch: 0, pre: [AlphaNumeric("nightly")], build: [] }, this test fails. This seems to be because of the pre_tag_is_compatible method which has a comment with the URL https://docs.npmjs.com/misc/semver#prerelease-tags

There we can read:

If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it will only be allowed to satisfy comparator sets if at least one comparator with the same [major, minor, patch] tuple also has a prerelease tag.

[...]

The purpose for this behavior is twofold. First, prerelease versions frequently are updated very quickly, and contain many breaking changes that are (by the author's design) not yet fit for public consumption. Therefore, by default, they are excluded from range matching semantics.

But this description does not apply to Rust at all. Rust Nightly is not expected to contain breaking changes from 1.0.0. Bugs happen of course, but they’re the exception rather than the rule.

Is it possible to opt into a different behavior such that rustc_version::version_matches(">= 1.0.0") is true on Nightly?

tag releases

figure out which commits were which releases and tag them

Update crates.io

The version on crates.io is 0.2.2 while the source shows 0.2.3.

Please define Predicate to not allow patch version without minor version

The definition of Predicate includes an Option<u64> for minor and for patch; that type would allow a predicate with a patch but no minor. That causes a match expression on a Predicate to complain about missing cases. Please consider using an enum that doesn't allow that case; for instance:

enum Something { M(u64), MM(u64,u64), MMP(u64,u64,u64) }

Add Eq trait in main error

Please add traits related to Eq to be able easily of checking errors at tests of libraries which are using your package.

Wildcard VersionReq doesn't match if a Version have pre-release

I believe * should match any version and currently it is not matching if a Version have a pre-release. For example:

extern crate semver;

fn main() {
    let wildcard_ver = semver::VersionReq::parse("*").unwrap();
    let another_ver = semver::Version::parse("0.1.0-pre.0").unwrap();

    assert!(wildcard_ver.matches(&another_ver));  // there is no match :(
}

This issue is also affecting cargo. For example symtern only released versions with a pre-release string and using any range syntax in Cargo.toml doesn't work. Including: *, 0.1, ^0.1, 0.1.0 etc.

I tried node's semver and * is matching (satisfying) fine with 0.1.0-pre.0.

> semver.satisfies('0.1.0-pre.0', '*')
true
> semver.satisfies('0.1.0', '*')
true

Ref: onur/docs.rs#80

New Release?

Hey,

I was pretty unlucky to get [my change][fb6e633] merged immediately after the 0.8 release. But I would really appreciate having a version on crates with that feature.

Could you do another release?

Thanks!

Running cargo run with semver is failing

With this cargo configuration


name = "30min_concepts"
version = "0.0.1"
authors = [""]

[dependencies]
semver = "*"

And rustc version:
rustc 1.0.0-nightly (a954663db 2015-02-10 22:08:30 +0000)
When running cargo run I receive:

   Compiling semver v0.1.16
     Running `rustc /Users/vitornavarro/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.16/src/lib.rs --crate-name semver --crate-type lib -g -C metadata=d7f360ec5a0ce45e -C extra-filename=-d7f360ec5a0ce45e --out-dir /Users/vitornavarro/Workspace/Rust/Basics/30min_concepts/target/deps --emit=dep-info,link -L dependency=/Users/vitornavarro/Workspace/Rust/Basics/30min_concepts/target/deps -L dependency=/Users/vitornavarro/Workspace/Rust/Basics/30min_concepts/target/deps -Awarnings`
/Users/vitornavarro/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.16/src/version.rs:180:6: 180:16 error: wrong number of type arguments: expected 1, found 0 [E0243]
/Users/vitornavarro/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.16/src/version.rs:180 impl hash::Hash for Version {
                                                                                                          ^~~~~~~~~~
Could not compile `semver`.

Caused by:
  Process didn't exit successfully: `rustc /Users/vitornavarro/.cargo/registry/src/github.com-1ecc6299db9ec823/semver-0.1.16/src/lib.rs --crate-name semver --crate-type lib -g -C metadata=d7f360ec5a0ce45e -C extra-filename=-d7f360ec5a0ce45e --out-dir /Users/vitornavarro/Workspace/Rust/Basics/30min_concepts/target/deps --emit=dep-info,link -L dependency=/Users/vitornavarro/Workspace/Rust/Basics/30min_concepts/target/deps -L dependency=/Users/vitornavarro/Workspace/Rust/Basics/30min_concepts/target/deps -Awarnings` (status=101)

Compatibility regarding hyphens with npm version parsing

Some weirder examples which are parsed successfully with npm but not with this library:

failed to parse version of cordova, version: 3.0.0-rc1-1
failed to parse version of npm, version: 1.5.0-alpha-0
failed to parse version of karma, version: 0.12.11-beta-3029418

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.