dtolnay / semver Goto Github PK
View Code? Open in Web Editor NEWParser and evaluator for Cargo's flavor of Semantic Versioning
License: Apache License 2.0
Parser and evaluator for Cargo's flavor of Semantic Versioning
License: Apache License 2.0
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);
}
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?
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
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) }
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.
I could have used this today for parsing versions in a config file.
#[derive(Serialize, Deserialize)]
struct Package {
version: semver::Version,
}
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: [] }] }
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 )
Because the variants of the Identifier enum have been made private, it is no longer possible to set a version as a static variable.
Given a version requirement parsed by semver (such as ^3.2), I'd like to ask semver to translate that to a minimum and maximum version (both as Option<Version>
), similar to the examples shown in http://doc.crates.io/specifying-dependencies.html. That would make it easier to translate a semver to a version range in a packaging system's dependencies.
There are cases where calling Version::parse
will return an error. We should document these cases in an Errors section on that method.
Replace uses of .unwrap
in examples with ?
so they're a bit more idiomatic. Have a look at the API guideline examples for some ideas on how to do this.
This is part of doing releases better. Ideally I would like to see bullet points about what changed in each version on the releases page. Why would I upgrade to 0.4.0? What are the risks?
Per https://docs.npmjs.com/misc/semver#ranges, comparators can be joined by whitespace to form a comparator set. But version_req.rs currently requires comparator sets to be comma-delimited.
VersionReq::parse(">= 0.4 < 0.5")
currently returns an OpAlreadySet error, but it should be equivalent to VersionReq::parse(">= 0.4, < 0.5")
.
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();
I've already started bumping versions after we cut a release, rather than before, but we should do better.
Anything else?
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!
Now that this has been transferred, I will need to ensure all URLs and upload tokens work
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?
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
}
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
VersionReq
currently implements PartialEq
. It would be nice if it implemented Eq
and Hash
too, so that it can be put in a HashSet
.
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.
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).
The version on crates.io is 0.2.2 while the source shows 0.2.3.
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.");
This test fails:
#[test]
pub fn test_pre() {
let r = req("2.1.1-really.0");
assert_match(&r, &["2.1.1-really.0"]);
}
Discovered in rust-lang/cargo#2337
The readme recommends to put the following in your dependencies:
semver = "0.5.0"
But the current semver version is "0.5.1"
Please add traits related to Eq to be able easily of checking errors at tests of libraries which are using your package.
figure out which commits were which releases and tag them
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.
Only when the "serde" feature is enabled. It's implemented for Version
but not VersionReq
. I imagine this wants a custom serializer, not a derived one. Maybe @steveklabnik you can say more about how this should be implemented and tag it help wanted.
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"
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)
The rule would be
x ≤ y = { v : x.matches(v) } ⊂ { v : y.matches(v) }
or in English, a version requirement is considered less than another if everything it matches the other also matches.
(Also, note to self if I implement it, this is textbook thing to use https://github.com/BurntSushi/quickcheck to test)
This should fail, but passes: https://play.rust-lang.org/?gist=fb9ab8b08c460ff4b0bb514f560cb079&version=stable
Originally found in rust-lang/cargo#4479
@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.
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?
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!
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
?
It would be cool if tests could grab the crates.io index and test every version to make sure they still parse.
Rust itself follows the SemVer specification, as does its standard libraries. The two are not tied together.
The version requirement 1.2.3 - 2.3.4
should be equivalent to >=1.2.3 <=2.3.4
.
Spec: https://docs.npmjs.com/misc/semver#hyphen-ranges-x-y-z-a-b-c
Where there are references to types in the crate documentation (like the references to Version
here) we should convert them into links to that type so users can find their way around the crate more easily.
It'd be nice to be able to look directly at the set of constraints in a VersionReq
. For example, the implementation of RFC 1241 wants to check if a VersionReq
corresponds to a wildcard but the implementation is forced to just compare for equality agaist VersionReq::parse("*").unwrap()
: https://github.com/rust-lang/cargo/pull/2005/files#diff-e23c793746a7be78139a4e37509a74acR112
This is probably very similar to #130
There are cases where calling VersionReq::parse
will return an error. We should document these cases in an Errors section on that method.
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
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 range1.2.7 || >=1.2.9 <2.0.0
would match the versions1.2.7
,1.2.9
, and1.4.6
, but not the versions1.2.8
or2.0.0
.
I believe it should be d497710
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.