Skip to content

Commit eedab49

Browse files
committed
Other changes based on the discussion in the review
1 parent 1dc49fe commit eedab49

File tree

1 file changed

+36
-9
lines changed

1 file changed

+36
-9
lines changed

blog/_posts/2021-02-16-improving-scala-library-ecosystem.md renamed to blog/_posts/2021-02-16-preventing-version-conflicts-with-versionscheme.md

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
layout: blog-detail
33
post-type: blog
44
by: Eugene Yokota, Julien Richard-Foy
5-
title: Improving the Scala Library Ecosystem
5+
title: Preventing Version Conflicts with versionScheme
66
---
77

88
One of the things that makes Scala powerful and fun to use is its library ecosystem — spanning across the Maven ecosystem for JVM, and npm for Scala.js. We can use libraries to do operations like download files from the web, or we can use it to adopt different programming paradigms. The library ecosystem allows us to write more useful programs with less effort.
@@ -34,11 +34,11 @@ Unfortunately, these two versions of Circe are not binary compatible. Such versi
3434

3535
The Scala Center, Alexandre Archambault (author of Coursier), and Eugene Yokota have been working on a solution to improve this situation so that we can be confident about creating libraries, and using them.
3636

37-
In the next section, we will explain the mechanism that was in place so far in sbt to address this issue, and we will discuss its limits. Then, we will introduce a new solution, which concerns both library authors, and library users.
37+
In the next section, we will explain the mechanism that was in place so far in sbt to address this issue, and we will discuss its limits. Then, we will introduce a new solution, which requires library authors to declare the versioning scheme of their libraries with a new sbt key, `versionScheme`.
3838

3939
## Eviction warnings
4040

41-
Actually this is not the first time We have thought of this issue. In 2014, we added [eviction warning][1] feature to sbt 0.13.6. When you have two candidate versions 0.11.1 and 0.13.0, and when it picks 0.13.0, 0.11.1 is said to be "evicted".
41+
Actually this is not the first time we have thought of this issue. In 2014, we added [eviction warning][1] feature to sbt 0.13.6. When you have two candidate versions 0.11.1 and 0.13.0, and when it picks 0.13.0, 0.11.1 is said to be "evicted".
4242

4343
~~~ text
4444
sbt:killer-app> evicted
@@ -57,7 +57,7 @@ Unfortunately, the reality was different and while some Scala libraries use PVP
5757

5858
## Early SemVer and sbt-version-policy
5959

60-
If you're maintaining a library, the first thing you could do to help is picking a version scheme. Our recommendation for libraries going forward is adopting **Early Semver** as described in the documentation page [Binary Compatibility for Library Authors][4]. Please read the linked post by Jacob Wang for more details on binary compatibility and source compatibility.
60+
If you are maintaining a library, the first thing you could do to help is picking a version scheme. Our recommendation for libraries going forward is adopting **Early Semver** as described in the documentation page [Binary Compatibility for Library Authors][4]. Please read the linked post by Jacob Wang for more details on binary compatibility and source compatibility.
6161

6262
Given a version number `major.minor.patch`, you MUST increment the:
6363

@@ -96,25 +96,52 @@ During the minor upgrade (feature release), we aggressively add new features, wh
9696

9797
As mentioned earlier, sbt contains a built-in eviction warning feature, but there are too many false positives right now because it needs to guess.
9898

99-
Since sbt 1.4.0, there is a new setting `versionScheme`, which can be used by library authors as follows in `build.sbt`:
99+
Since sbt 1.4.0, there is a new setting `versionScheme`, which can be used by library authors
100+
to declare the versioning scheme they use:
100101

101102
~~~ scala
102103
ThisBuild / versionScheme := Some("early-semver")
103104
~~~
104105

105106
sbt 1.4.0 includes this information into `pom.xml` and `ivy.xml` as a property. In addition, sbt uses the information to take the guessing out of eviction warning when this information is available.
106107

107-
In sbt 1.5.0, eviction warnings will be replaced with [eviction errors][8]. Since we can now reliably detect whether two dependencies with different versions are compatible, or if they conflict, the build will fail if an incompatibility is detected in your dependencies.
108+
In sbt 1.5.0, eviction warnings will be replaced with [eviction errors][8]. Since it can now reliably detect whether two dependencies with different versions are compatible, or if they conflict, the build will fail if an incompatibility is detected in your dependencies.
108109

109-
It might take a few years for the `versionScheme` information to become prevalent in the ecosystem, but once it happens the eviction warning could become more accurate. In the meantime, as a user of libraries you can manually configure the versioning scheme used by your libraries by using a new setting, `libraryDependencySchemes`. For instance, here is how we can tell sbt that Circe’s artifacts follow the Early SemVer scheme:
110+
It might take a few years for the `versionScheme` information to become prevalent in the ecosystem. In the meantime, as a user of libraries you can manually configure the versioning scheme used by your libraries by using a new setting, `libraryDependencySchemes`. For instance, here is how you can tell sbt that the `circe-core` artifact follows the Early SemVer scheme:
110111

111112
~~~ scala
112-
ThisBuild / libraryDependencySchemes += "io.circe" %% "circe-*" % "early-semver"
113+
ThisBuild / libraryDependencySchemes += "io.circe" %% "circe-core" % "early-semver"
114+
~~~
115+
116+
With this setting, the warning caused by the conflicting versions of circe-core
117+
becomes an error because the version number 0.13.0 is not binary compatible
118+
with the version number 0.11.1 according to the Early SemVer scheme:
119+
120+
~~~ text
121+
sbt:killer-app> update
122+
[error] stack trace is suppressed; run last update for the full output
123+
[error] (update) found version conflict(s) in library dependencies; some are suspected to be binary incompatible:
124+
[error]
125+
[error] * io.circe:circe-core_2.12:0.13.0 (early-semver) is selected over 0.11.1
126+
[error] +- org.tpolecat:doobie-postgres-circe_2.12:0.10.0 (depends on 0.13.0)
127+
[error] +- de.heikoseeberger:akka-http-circe_2.12:1.26.0 (depends on 0.11.1)
128+
[error]
129+
[error]
130+
[error] this can be overridden using libraryDependencySchemes or evictionErrorLevel
113131
~~~
114132

115133
## Summary
116134

117-
If you are a library author, check out [sbt-version-policy][5] to enforce the recommended versioning scheme. Or, at least declare the versioning scheme you use with the `versionScheme` key. If you are a library user, keep in mind that starting from sbt 1.5.0 you should configure your `libraryDependencySchemes` to get accurate eviction errors.
135+
If you are a library author, set `ThisBuild / versionScheme` to declare the versioning scheme
136+
used by your library, so that build tools can reliably detect conflicting versions pulled by
137+
transitive dependencies.
138+
139+
You might also want to have a look at the plugin [sbt-version-policy][5], which helps you
140+
to implement the versioning scheme that you declare in your build, by detecting the binary
141+
and source incompatibilities introduced between releases.
142+
143+
As a library user, starting from sbt 1.5.0 you should configure your
144+
`libraryDependencySchemes` to get accurate eviction errors.
118145

119146
[1]: https://github.com/sbt/sbt/pull/147
120147
[2]: https://semver.org/

0 commit comments

Comments
 (0)