@@ -27,12 +27,16 @@ import scala.util.control.NonFatal
2727
2828object ScalaVersionUtil {
2929
30- private def scala2Library = cmod " org.scala-lang:scala-library "
31- private def scala3Library = cmod " org.scala-lang:scala3-library_3 "
32- def scala212Nightly = " 2.12.nightly"
33- def scala213Nightly = List (" 2.13.nightly" , " 2.nightly" )
34- def scala3Nightly = " 3.nightly"
35- def scala3Lts = List (" 3.lts" , " lts" )
30+ private def scala2Library = cmod " org.scala-lang:scala-library "
31+ private def scala3Library = cmod " org.scala-lang:scala3-library_3 "
32+ def scala212Nightly = " 2.12.nightly"
33+ def scala213Nightly = List (" 2.13.nightly" , " 2.nightly" )
34+ def scala3Nightly = " 3.nightly"
35+ private def rcAlias (prefix : String ) = s " $prefix.rc "
36+ def scala2LatestRc = List (rcAlias(" 2" ), rcAlias(" 2.12" ), rcAlias(" 2.13" ))
37+ def scala3LatestRc = List (" rc" , rcAlias(" 3" ))
38+ def scala3LtsLatestRc = List (rcAlias(" lts" ), rcAlias(" 3.lts" ), rcAlias(Constants .scala3LtsPrefix))
39+ def scala3Lts = List (" 3.lts" , " lts" )
3640 // not valid versions, defined only for informative error messages
3741 def scala2Lts = List (" 2.13.lts" , " 2.12.lts" , " 2.lts" )
3842 extension (cache : FileCache [Task ]) {
@@ -182,53 +186,55 @@ object ScalaVersionUtil {
182186 cache.versionsWithTtl0(scala3Library, repositories).verify(versionString)
183187 }
184188
185- def validateNonStable (
189+ def validate (
186190 scalaVersionStringArg : String ,
187191 cache : FileCache [Task ],
188- repositories : Seq [Repository ]
189- ): Either [ScalaVersionError , String ] = {
192+ repositories : Seq [Repository ],
193+ isExactVersion : Boolean
194+ )(validationFunction : String => Boolean ): Either [ScalaVersionError , String ] = {
190195 val versionPool =
191196 ScalaVersionUtil .allMatchingVersions(Some (scalaVersionStringArg), cache, repositories)
197+ .filter(validationFunction)
192198
193- if (versionPool.contains(scalaVersionStringArg))
194- if (isSupportedVersion(scalaVersionStringArg))
195- Right (scalaVersionStringArg)
196- else
197- Left (new UnsupportedScalaVersionError (scalaVersionStringArg))
198- else
199- Left (new InvalidBinaryScalaVersionError (scalaVersionStringArg))
199+ val prefix =
200+ if Util .isFullScalaVersion(scalaVersionStringArg) then scalaVersionStringArg
201+ else if scalaVersionStringArg.endsWith(" ." ) then scalaVersionStringArg
202+ else scalaVersionStringArg + " ."
203+ val matchingVersions = versionPool.filter(_.startsWith(prefix)).map(Version (_))
204+ if matchingVersions.isEmpty ||
205+ (isExactVersion && ! matchingVersions.contains(scalaVersionStringArg))
206+ then Left (new InvalidBinaryScalaVersionError (scalaVersionStringArg))
207+ else {
208+ val supportedMatchingVersions = matchingVersions.filter(v => isSupportedVersion(v.repr))
209+ supportedMatchingVersions.find(_.repr == scalaVersionStringArg) match {
210+ case Some (v) => Right (v.repr)
211+ case None if supportedMatchingVersions.nonEmpty && ! isExactVersion =>
212+ Right (supportedMatchingVersions.max.repr)
213+ case _ => Left (new UnsupportedScalaVersionError (scalaVersionStringArg))
214+ }
215+ }
200216 }
201217
218+ def validateExactVersion (
219+ scalaVersionStringArg : String ,
220+ cache : FileCache [Task ],
221+ repositories : Seq [Repository ]
222+ ): Either [ScalaVersionError , String ] =
223+ validate(scalaVersionStringArg, cache, repositories, isExactVersion = true )(_ => true )
224+
202225 def validateStable (
203226 scalaVersionStringArg : String ,
204227 cache : FileCache [Task ],
205228 repositories : Seq [Repository ]
206- ): Either [ScalaVersionError , String ] = {
207- val versionPool =
208- ScalaVersionUtil .allMatchingVersions(Some (scalaVersionStringArg), cache, repositories)
209- .filter(ScalaVersionUtil .isStable)
229+ ): Either [ScalaVersionError , String ] =
230+ validate(scalaVersionStringArg, cache, repositories, isExactVersion = false )(isStable)
210231
211- val prefix =
212- if (Util .isFullScalaVersion(scalaVersionStringArg)) scalaVersionStringArg
213- else if (scalaVersionStringArg.endsWith(" ." )) scalaVersionStringArg
214- else scalaVersionStringArg + " ."
215- val matchingStableVersions = versionPool.filter(_.startsWith(prefix)).map(Version (_))
216- if (matchingStableVersions.isEmpty)
217- Left (new InvalidBinaryScalaVersionError (scalaVersionStringArg))
218- else {
219- val supportedMatchingStableVersions =
220- matchingStableVersions.filter(v => isSupportedVersion(v.repr))
221-
222- supportedMatchingStableVersions.find(_.repr == scalaVersionStringArg) match {
223- case Some (v) => Right (v.repr)
224- case None if supportedMatchingStableVersions.nonEmpty =>
225- Right (supportedMatchingStableVersions.max.repr)
226- case _ => Left (
227- new UnsupportedScalaVersionError (scalaVersionStringArg)
228- )
229- }
230- }
231- }
232+ def validateRc (
233+ scalaVersionStringArg : String ,
234+ cache : FileCache [Task ],
235+ repositories : Seq [Repository ]
236+ ): Either [ScalaVersionError , String ] =
237+ validate(scalaVersionStringArg, cache, repositories, isExactVersion = false )(isRc)
232238
233239 private def isSupportedVersion (version : String ): Boolean =
234240 version.startsWith(" 2.12." ) || version.startsWith(" 2.13." ) || version.startsWith(" 3." )
@@ -241,6 +247,12 @@ object ScalaVersionUtil {
241247 (version.startsWith(" 3" ) && version.endsWith(" -NIGHTLY" )) || version == scala3Nightly
242248 def isStable (version : String ): Boolean =
243249 ! version.exists(_.isLetter)
250+ def isRc (version : String ): Boolean = {
251+ val lowerCasedVersion = version.toLowerCase
252+ lowerCasedVersion.contains(" rc" ) &&
253+ ! lowerCasedVersion.contains(" -nightly" ) &&
254+ ! lowerCasedVersion.contains(" -snapshot" )
255+ }
244256
245257 def allMatchingVersions (
246258 maybeScalaVersionArg : Option [String ],
0 commit comments