crystal-lang / shards

Dependency manager for the Crystal language
Other
763 stars 100 forks source link

Support intersection of versions #394

Closed waj closed 4 years ago

waj commented 4 years ago

This adds support for version specifiers like: >= 1.0.0, < 2.0 I need this to implement #365, but I think it's also nice addition. Other dependency managers also support expressions like that.

Sija commented 4 years ago

@waj FWIW, I believe that a compound keyword is more apt in this case than intersection. I'd use compound requirement - as in bundler, see:

https://github.com/rubygems/rubygems/blob/6f1037c67557a33a81ead0a6b2b5867d601f0d08/bundler/spec/install/gems/resolving_spec.rb#L241

Blacksmoke16 commented 4 years ago

Composer calls them version ranges.

They also seem to allow || together ranges. >=1.0 <1.1 || >=1.2.

Sija commented 4 years ago

@Blacksmoke16 I don't know about the Composer, but they're not ranges, that's for sure :)

Blacksmoke16 commented 4 years ago

@Sija How is it not? >= 1.0.0, < 2.0 would be 1.0.0...2.0.0, i.e. any version greater than or equal to 1.0.0 but less than 2.0.0.

Sija commented 4 years ago

@Blacksmoke16 because >= 1.0.0, < 2.0, != 1.1

Blacksmoke16 commented 4 years ago

@Sija Still could be interpreted as 1.0.0...1.1.0 || 1.2.0...2.0.0. 🀷.

Sija commented 4 years ago

@Blacksmoke16 Yeah, that's a compound (range) statement you've got there...

waj commented 4 years ago

I prefer the word "intersection" because it's more explicit about how the expressions are composed. In the future, if we add other operators like || or ... the text can be rephrased.

Sija commented 4 years ago

@waj That's not intersection though... And the comma used there is analogous to && (and) logical operator.

waj commented 4 years ago

@Sija It's the intersection of the version sets defined by each expression. In math intersection and logical and are very close concepts. Also, I'm not the only one using this term for this: https://dart.dev/tools/pub/dependencies#traditional-syntax

Sija commented 4 years ago

@waj Not if you add != operator to the mix.

bcardiff commented 4 years ago

@Sija It’s intersection. All comma separated constraints need to be satisfied. Even if != is supported. https://www.siyavula.com/read/maths/grade-10/probability/14-probability-03

If or/union is added later is another matter.

Sija commented 4 years ago

Intersection

The intersection of two sets is a new set that contains all of the elements that are in both sets. The intersection is written as 𝐴∩𝐡 or β€œπ΄ and 𝐡”.

Quite likely I'm misunderstanding the term in this context but I don't see any (intersecting) sets here. I mean we have constraints, yes, but not sets.

By set intersection I'd understand having 1.0-1.2, 1.1-1.3 (two ranges - sets with an overlap). OTOH >= 1.0.0, < 2.0 defines a set of versions between 1.0 and 2.0, which is closer to a range in this case than to a intersection... adding multiple clauses turns that into a compound statement.

But maybe my brain is playing tricks on me πŸ€·β€β™‚οΈ

waj commented 4 years ago

@Sija do you realise we're discussing for a word it doesn't even appear in the documentation, right? It's just the issue name and a spec description at most πŸ˜„

It's not brain tricks. Just different ways to see the same. When you say >= 1.0.0 that's a range too. Just an unbounded range. And a range is a set. And sets can be intersected to create a new set. But while all ranges are sets, not all sets are ranges. For example, >= 1.0.0, < 2.0, != 1.2.3 cannot be expressed as a single range (note that != is currently not supported). Still can be interpreted as the intersection of three sets. Or a union of two ranges if you want, but for me it's harder to think in ranges because is more complicated to generalize.

Sija commented 4 years ago

With this merged in, it would be good to add support for != operator.