Skip to content
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

Version range union containing prerelease versions does not work #55

Open
joshcooper opened this issue Jan 6, 2025 · 0 comments
Open
Labels

Comments

@joshcooper
Copy link
Contributor

joshcooper commented Jan 6, 2025

Describe the Bug

Semantic puppet version ranges do not handle prereleases correctly.

Expected Behavior

Given a version range '>=1.0.0 || >=2.0.0-rc0' I would expect both 1.0.0 and 2.0.0-rc0 to be included in the range. But that is not the observed behavior.

Steps to Reproduce

Apply the fix from #54

Run the following. I would expect true to be printed both times:

❯ cat test.rb 
require 'semantic_puppet'
range = SemanticPuppet::VersionRange.parse('>=1.0.0 || >=2.0.0-rc0')
puts range.include?(SemanticPuppet::Version.parse('1.0.0'))
puts range.include?(SemanticPuppet::Version.parse('2.0.0-rc0'))


❯ bundle exec ruby test.rb
true
false

SemanticPuppet generally follows the npm implementation of semver. Using that nomenclature, >=1.0.0 is a comparator set containing a single element. Same for >=2.0.0-rc0. And they are joined together using || to create a union. npm says https://github.com/npm/node-semver

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.

As a result, both 1.0.0 and 2.0.0-rc0 should be included in the range.

The bug is that SemanticPuppet attempts to merge ranges to reduce overlaps, for example >=1.0.0 || >=2.0.0 is redundant as the former includes the latter. So it attempts to merge the two ranges (comparator sets)

and drops the second range >=2.0.0 However, it shouldn't do that if the second range contains a prerelease >=2.0.0-rc0 This is because

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. ... 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.

It also behaves inconsistently if the order of ranges is reversed >= 2.0.0-rc0 || >= 1.0.0

Environment

❯ bundle exec ruby -rsemantic_puppet -e "puts SemanticPuppet::VERSION"        
1.1.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant