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

Implement Caret-style version range operator #3705

Merged
merged 1 commit into from
Sep 1, 2016

Conversation

hvr
Copy link
Member

@hvr hvr commented Aug 20, 2016

This implements a new syntactic sugar: The version range operator
^>= which is equivalent to >= intersected with an
automatically inferred major upper bound.

This new syntax is only allowed for cabal-version: >=2.0, and
allows to describe the most common use of version
bounds more conveniently:

build-depends: foo ^>= 1.2.3.4,
               bar ^>= 1

The declaration above is exactly equivalent to

build-depends: foo >= 1.2.3.4 && < 1.3,
               bar >= 1 && < 1.1

The ^-symbol was chosen because it can serve as a mnemonic when the
> sign is rotated and interpreted as "less than ceiling"

Moreover, ^ appears to become a quasi-standard to denote morally
equivalent operator that way in other language ecosystems which similiar
to Haskell have adopted semantic versioning:

Ruby, on the other hand, uses a Tilde operator (~>) for that
purpose (but with a less robust semantic):

And Python is currently planing to use an ~= operator:

@phadej
Copy link
Collaborator

phadej commented Aug 20, 2016

LGTM. But I'll like to see tests. (which would break in parsec branch)

@23Skidoo
Copy link
Member

/cc @dcoutts

@23Skidoo
Copy link
Member

Would be nice to add a changelog note.

@hvr hvr force-pushed the pr/caret-version-range-op branch 2 times, most recently from ae63fb8 to 5036c46 Compare September 1, 2016 15:53
This implements a new syntactic sugar: The version range operator
`^>=` which is equivalent to `>=` intersected with an
automatically inferred major upper bound.

This new syntax is only allowed for `cabal-version: >=2.0`, and
allows to describe the most common use of version
bounds more conveniently:

    build-depends: foo ^>= 1.2.3.4,
                   bar ^>= 1

The declaration above is exactly equivalent to

    build-depends: foo >= 1.2.3.4 && < 1.3,
                   bar >= 1 && < 1.1

The `^`-symbol was chosen because it can serve as a mnemonic when the
`>` sign is rotated and interpreted as "less than ceiling"

Moreover, `^` appears to become a quasi-standard to denote morally
equivalent operator that way in other language ecosystems which similiar
to Haskell have adopted semantic versioning:

 - Node: https://nodesource.com/blog/semver-tilde-and-caret/
 - Bower: https://bower.io/docs/api/#install
 - PHP: https://getcomposer.org/doc/articles/versions.md#caret

Ruby, on the other hand, uses a Tilde operator (`~>`) for that
purpose (but with a less robust semantic):

 - https://blog.codeship.com/optimists-guide-pessimistic-library-versioning

And Python is currently planing to use an `~=` operator:

 - https://www.python.org/dev/peps/pep-0440/#compatible-release
@hvr hvr force-pushed the pr/caret-version-range-op branch from 5036c46 to 0f2193a Compare September 1, 2016 15:56
@hvr
Copy link
Member Author

hvr commented Sep 1, 2016

I've changed the syntax from ^> to ^>= because it's more accurate/self-descriptive (since it's more evident that ^+>= translates to < + >= than the original syntax, and it's easier to convert between one and the other in a text-editor) in my opinion.

@23Skidoo changelog entry added

@phadej finally brought myself to try to come up with a simple parser test... getting there took longer than it should have...

@23Skidoo
Copy link
Member

23Skidoo commented Sep 1, 2016

Thanks! So I think this can be merged once Travis is green.

@hvr hvr merged commit c7f788a into haskell:master Sep 1, 2016
@ezyang ezyang modified the milestones: Cabal 2.0, 2.0 (planned for next feature release) Sep 6, 2016
@hvr hvr deleted the pr/caret-version-range-op branch August 10, 2017 08:48
@unclechu
Copy link

unclechu commented Jul 5, 2021

That’s a bit confusing since in other platforms ^ has a different meaning:

semver.toComparators('^1.2.3')
// [ [ '>=1.2.3-0', '<2.0.0-0' ] ]

// compare upper limit for ~
semver.toComparators('~1.2.3')
// [ [ '>=1.2.3-0', '<1.3.0-0' ] ]

I’d prefer to see ~>= instead. But it seems it’s too late to change.

@unclechu
Copy link

unclechu commented Jul 5, 2021

Or maybe I’m missing something?

@gbaz
Copy link
Collaborator

gbaz commented Jul 5, 2021

Or maybe I’m missing something?

In the haskell pvp (https://pvp.haskell.org/), which predates semver btw, the first two components indicate major version, while in semver, only the first component indicates major version. So semantically the caret operator means the same thing in both cases -- picking the range up to the next major version. It just so happens that "major version" covers a different number of components.

@fgaz

This comment has been minimized.

@unclechu
Copy link

unclechu commented Jul 5, 2021

@gbaz thanks for this clarification!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants