-
Notifications
You must be signed in to change notification settings - Fork 113
Implement version string validation and comparison #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'm a big fan of semantic versioning. This means 3 parts to a version number, The requirements are basically:
If semantic versioning is followed, users know that patch and minor version updates are safe (won't break anything), and major version upgrades may require some rework. |
You can probably already guess my opinion: I suggest we require semantic versioning, just like Cargo. |
I'm all for encouraging semantic versioning. It won't hurt to give fpm at least the ability to make sense from version numbers not strictly following this scheme to make it a more robust. A good example is the conda-forge-pinning feedstock, not because it uses a timestamp as version, but because it has a long list of important packages not following semantic versioning. |
This looks good @awvwgk. I agree that understanding versions will be important in fpm for dependencies. I agree with everything that @everythingfunctional has said; semantic versioning is easy and intuitive to understand. However many user packages won't be destined for publishing so I don't think fpm should require a version string for packages or attempt to enforce the rules of semantic versioning beyond the format of the field. Enforcement of semantic versioning rules should happen at package registry level (fpm-registry) with fpm simply having helper options to automatically set and bump the version as is required. fpm-registry already requires a version field to be present in package manifests during its CI checks. On PR, fpm-registry can check interfaces against any prior registry versions and throw an error if the rules aren't met. I don't believe this will be difficult to implement in our current checks. |
Semantic versioning is fine, up to the point where the developer applying it fails to follow its convention, on purpose or by accident. Also, API breakage is not always a good measure for versioning, not every compatibility breakage is defined by an API or ABI change. I'm not advocating against semantic versioning. Just keep in mind that versioning can be complicated and even requiring semantic versioning might not be enough. It would be thoughtful of fpm to allow for some flexibility in this regard, even if it is just to make an already painful job of sorting out dependency versions not more painful. |
I very much agree with what @LKedward said. True, semantic versioning isn't bullet proof - despite our best efforts, users can (intentionally or not) end up depending on internal implementation details - but it's still helpful and worth utilizing. I could envision allowing some additional info in the version string, but it would not be used for ordering of versions, and for any packages that supply it, that would be a necessary piece for the users of the library to include when specifying a version. The most obvious use case that comes to mind would be different versions for different operating systems, and still allow users use wildcard version specification (i.e. |
Maybe this is just some misunderstanding. Would this mean the version string must match the regex
Sorry for derailing this conversation, the better solution than mangling this into the version string would be allowing the registry to specify variants and fpm use them with some_lib.version = "2"
some_lib.variant = "linux" |
I think we could allow the absence of the minor or patch versions to simply imply that they are zero. The variant route might be an interesting approach instead of complicating the version. |
272b6e6
to
38edbc6
Compare
I set the maximum subversion limit to three, resulting effectively in “semantic versioning,” with optional minor and patch version. The match operator between two versions would work like this: some_dep1 = "2" # >=2 and <3
some_dep2 = "0.7" # >=0.7 and <0.8
some_dep3 = "1.3" # >=1.3 and <1.4
some_dep4 = "1.0.7" # >=1.0.7 and <1.0.8 <=> ==1.0.7
# to discuss: version numbers ending on zero
some_dep5 = "2.0" # currently >=2 and <3, not >=2.1 and <3.1 This might not be the best choice to determine the version number to match against: fpm/fpm/src/fpm/versioning.f90 Lines 366 to 371 in 5191bef
Probably, we should not compare against a version data type at all, but have a separate version-constraint data type for this purpose. |
I do not understand the second part of the explanation:
some_dep5 = "2.0" # currently >= 2 and < 3, not >= 2.1 and < 3
that is: >= 2.1. But apart from that, I would say that "2.0" should be
interpreted as >= 2.0.x and < 2.1.
Op di 22 sep. 2020 om 20:45 schreef Sebastian Ehlert <
notifications@github.com>:
… I set the maximum subversion limit to three, resulting effectively in
semantic versioning, with optional minor and patch version.
Also implemented a “semantic version” matching for the version date type
as well, while trying to keep it as flexible as possible.
The match operator between two versions would work like this:
some_dep1 = "2" # >=2 and <3
some_dep2 = "0.7" # >=0.7 and <0.8
some_dep3 = "1.3" # >=1.3 and <1.4
some_dep4 = "1.0.7" # >=1.0.7 and <1.0.8 <=> ==1.0.7
# to discuss: version numbers ending on zero
some_dep5 = "2.0" # currently >= 2 and < 3, not >= 2.1 and < 3
This might not be the best choice to determine the version number to match
against:
https://github.com/fortran-lang/fpm/blob/5191befcc8a2c6dd67f0e0ab819b82fa68f39348/fpm/src/fpm/versioning.f90#L366-L371
Probably, we should not compare against a version data type at all, but
have a separate version-constraint data type for this purpose.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#186 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAN6YR3CKLRALOI5CGCYZP3SHDWDRANCNFSM4RVA5MLQ>
.
|
Agreed, I'm just using the number of subversions to create the matching now. |
I believe most package managers use a different type for the package version versus the specified version of a dependency. They then use some sort of constraint solver for selecting the appropriate version from the repository/registry. I agree with @arjenmarkus that most users would probably expect |
Thanks for the input and discussion so far. I guess I will just mark it as ready for review now. The some_dep1 = "2" # >=2 and <3
some_dep2 = "0.7" # >=0.7 and <0.8
some_dep3 = "1.3" # >=1.3 and <1.4
some_dep4 = "1.0.7" # >=1.0.7 and <1.0.8 <=> ==1.0.7
some_dep5 = "2.0" # >=2.0 and <2.1 All comparison operators are implemented as elemental, so they should play nicely together with array operations and any or all reductions. |
Didn't check the code for it, but I think your example
should be
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice clean and general solution which will be very useful.
Thanks @awvwgk. 👍
@awvwgk, can you please address @everythingfunctional's question, and then resolve conflicts? After that this is ready to merge. |
- allow semantic version matching
Rebased against 90ddc6f |
@awvwgk Please merge when ready. |
This is probably not immediately useful, therefore I'm opening it as draft for discussion.
This PR implements a version type, somewhat similar to Python's
StrictVersion
, which allows parsing version numbers and comparing them, if they follow a strict format. Version numbers can become complicated, the most involved versioning scheme I have seen so far is the Arch Linux PKGBUILD version, featuring a version epoch, a version number (probably semantic, but not necessarily) and a build number:[<int>:]<int>[.<int>...]-<int>
.Here support for a version of the form of
<int>[.<int>...]
is implemented, where the number of subversions is limited to an arbitrarily chosen10 (probably way too much)3 (for semantic versioning<major>[.<minor>[.<patch>]]
). Have a look at the tests to see what is possible.