@@ -81,12 +81,74 @@ object DottyJSPlugin extends AutoPlugin {
81
81
object Build {
82
82
import ScaladocConfigs ._
83
83
84
+ /** Version of the Scala compiler used to build the artifacts.
85
+ * Reference version should track the latest version pushed to Maven:
86
+ * - In main branch it should be the last RC version
87
+ * - In release branch it should be the last stable release
88
+ *
89
+ * Warning: Change of this variable needs to be consulted with `expectedTastyVersion`
90
+ */
84
91
val referenceVersion = " 3.3.5"
85
92
86
- val baseVersion = " 3.3.6-RC1"
93
+ /** Version of the Scala compiler targeted in the current release cycle
94
+ * Contains a version without RC/SNAPSHOT/NIGHTLY specific suffixes
95
+ * Should be updated ONLY after release or cutoff for previous release cycle.
96
+ *
97
+ * Should only be referred from `dottyVersion` or settings/tasks requiring simplified version string,
98
+ * eg. `compatMode` or Windows native distribution version.
99
+ *
100
+ * Warning: Change of this variable might require updating `expectedTastyVersion`
101
+ */
102
+ val developedVersion = " 3.3.6"
103
+
104
+ /** The version of the compiler including the RC prefix.
105
+ * Defined as common base before calculating environment specific suffixes in `dottyVersion`
106
+ *
107
+ * By default, during development cycle defined as `${developedVersion}-RC1`;
108
+ * During release candidate cycle incremented by the release officer before publishing a subsequent RC version;
109
+ * During final, stable release is set exactly to `developedVersion`.
110
+ */
111
+ val baseVersion = s " $developedVersion-RC1 "
112
+
113
+ /** The version of TASTY that should be emitted, checked in runtime test
114
+ * For defails on how TASTY version should be set see related discussions:
115
+ * - https://github.com/scala/scala3/issues/13447#issuecomment-912447107
116
+ * - https://github.com/scala/scala3/issues/14306#issuecomment-1069333516
117
+ * - https://github.com/scala/scala3/pull/19321
118
+ *
119
+ * Simplified rules, given 3.$minor.$patch = $developedVersion
120
+ * - Major version is always 28
121
+ * - TASTY minor version:
122
+ * - in main (NIGHTLY): {if $patch == 0 || ${referenceVersion.matches(raw"3.$minor.0-RC\d")} then $minor else ${minor + 1}}
123
+ * - in LTS branch (NIGHTLY): always equal to $minor
124
+ * - in release branch is always equal to $minor
125
+ * - TASTY experimental version:
126
+ * - in main (NIGHTLY) is always experimental
127
+ * - in LTS branch (NIGHTLY) is always non-experimental
128
+ * - in release candidate branch is experimental if {patch == 0}
129
+ * - in stable release is always non-experimetnal
130
+ */
131
+ val expectedTastyVersion = " 28.3"
132
+ checkReleasedTastyVersion()
133
+
134
+ /** Final version of Scala compiler, controlled by environment variables. */
135
+ val dottyVersion = {
136
+ if (isRelease) baseVersion
137
+ else if (isNightly) s " ${baseVersion}-bin- ${VersionUtil .commitDate}- ${VersionUtil .gitHash}-NIGHTLY "
138
+ else s " ${baseVersion}-bin-SNAPSHOT "
139
+ }
140
+ def isRelease = sys.env.get(" RELEASEBUILD" ).contains(" yes" )
141
+ def isNightly = sys.env.get(" NIGHTLYBUILD" ).contains(" yes" )
142
+
143
+ /** Version calculate for `nonbootstrapped` projects */
144
+ val dottyNonBootstrappedVersion = {
145
+ // Make sure sbt always computes the scalaBinaryVersion correctly
146
+ val bin = if (! dottyVersion.contains(" -bin" )) " -bin" else " "
147
+ dottyVersion + bin + " -nonbootstrapped"
148
+ }
87
149
88
150
// LTS or Next
89
- val versionLine = " LTS"
151
+ final val versionLine = " LTS"
90
152
91
153
// Versions used by the vscode extension to create a new project
92
154
// This should be the latest published releases.
@@ -95,23 +157,22 @@ object Build {
95
157
val publishedDottyVersion = referenceVersion
96
158
val sbtDottyVersion = " 0.5.5"
97
159
98
- /** Version against which we check binary compatibility.
160
+ /** LTS version against which we check binary compatibility.
99
161
*
100
- * This must be the latest published release in the same versioning line.
101
- * For example, if the next version is going to be 3.1.4, then this must be
102
- * set to 3.1.3. If it is going to be 3.1.0, it must be set to the latest
103
- * 3.0.x release.
162
+ * This must be the earliest published release in the LTS versioning line.
163
+ * For example, if the latest LTS release is be 3.3.4, then this must be
164
+ * set to 3.3.0.
104
165
*/
105
- val previousDottyVersion = " 3.3.5 "
166
+ val mimaPreviousLTSDottyVersion = " 3.3.0 "
106
167
107
168
object CompatMode {
108
169
final val BinaryCompatible = 0
109
170
final val SourceAndBinaryCompatible = 1
110
171
}
111
172
112
173
val compatMode = {
113
- val VersionRE = """ ^\d+\.(\d+).(\d+).* """ .r
114
- baseVersion match {
174
+ val VersionRE = """ ^\d+\.(\d+)\ .(\d+)""" .r
175
+ developedVersion match {
115
176
case VersionRE (_, " 0" ) => CompatMode .BinaryCompatible
116
177
case _ => CompatMode .SourceAndBinaryCompatible
117
178
}
@@ -132,24 +193,6 @@ object Build {
132
193
val dottyGithubUrl = " https://github.com/scala/scala3"
133
194
val dottyGithubRawUserContentUrl = " https://raw.githubusercontent.com/scala/scala3"
134
195
135
-
136
- val isRelease = sys.env.get(" RELEASEBUILD" ) == Some (" yes" )
137
-
138
- val dottyVersion = {
139
- def isNightly = sys.env.get(" NIGHTLYBUILD" ) == Some (" yes" )
140
- if (isRelease)
141
- baseVersion
142
- else if (isNightly)
143
- baseVersion + " -bin-" + VersionUtil .commitDate + " -" + VersionUtil .gitHash + " -NIGHTLY"
144
- else
145
- baseVersion + " -bin-SNAPSHOT"
146
- }
147
- val dottyNonBootstrappedVersion = {
148
- // Make sure sbt always computes the scalaBinaryVersion correctly
149
- val bin = if (! dottyVersion.contains(" -bin" )) " -bin" else " "
150
- dottyVersion + bin + " -nonbootstrapped"
151
- }
152
-
153
196
val sbtCommunityBuildVersion = " 0.1.0-SNAPSHOT"
154
197
155
198
val agentOptions = List (
@@ -477,7 +520,7 @@ object Build {
477
520
case cv : Disabled => thisProjectID.name
478
521
case cv : Binary => s " ${thisProjectID.name}_ ${cv.prefix}3 ${cv.suffix}"
479
522
}
480
- (thisProjectID.organization % crossedName % previousDottyVersion )
523
+ (thisProjectID.organization % crossedName % mimaPreviousLTSDottyVersion )
481
524
},
482
525
483
526
mimaCheckDirection := (compatMode match {
@@ -2032,6 +2075,9 @@ object Build {
2032
2075
settings(disableDocSetting).
2033
2076
settings(
2034
2077
versionScheme := Some (" semver-spec" ),
2078
+ Test / envVars ++= Map (
2079
+ " EXPECTED_TASTY_VERSION" -> expectedTastyVersion,
2080
+ ),
2035
2081
if (mode == Bootstrapped ) Def .settings(
2036
2082
commonMiMaSettings,
2037
2083
mimaBinaryIssueFilters ++= MiMaFilters .TastyCore ,
@@ -2066,6 +2112,49 @@ object Build {
2066
2112
case Bootstrapped => commonBootstrappedSettings
2067
2113
})
2068
2114
}
2115
+
2116
+ /* Tests TASTy version invariants during NIGHLY, RC or Stable releases */
2117
+ def checkReleasedTastyVersion (): Unit = {
2118
+ case class ScalaVersion (minor : Int , patch : Int , isRC : Boolean )
2119
+ def parseScalaVersion (version : String ): ScalaVersion = version.split(" \\ .|-" ).take(4 ) match {
2120
+ case Array (" 3" , minor, patch) => ScalaVersion (minor.toInt, patch.toInt, false )
2121
+ case Array (" 3" , minor, patch, _) => ScalaVersion (minor.toInt, patch.toInt, true )
2122
+ case other => sys.error(s " Invalid Scala base version string: $baseVersion" )
2123
+ }
2124
+ lazy val version = parseScalaVersion(baseVersion)
2125
+ lazy val referenceV = parseScalaVersion(referenceVersion)
2126
+ lazy val (tastyMinor, tastyIsExperimental) = expectedTastyVersion.split(" \\ .|-" ).take(4 ) match {
2127
+ case Array (" 28" , minor) => (minor.toInt, false )
2128
+ case Array (" 28" , minor, " experimental" , _) => (minor.toInt, true )
2129
+ case other => sys.error(s " Invalid TASTy version string: $expectedTastyVersion" )
2130
+ }
2131
+ val isLTS = versionLine == " LTS"
2132
+
2133
+ if (isNightly) {
2134
+ assert(tastyIsExperimental || isLTS, " TASTY needs to be experimental in nightly builds" )
2135
+ val expectedTastyMinor = version.patch match {
2136
+ case 0 => version.minor
2137
+ case 1 if referenceV.patch == 0 && referenceV.isRC =>
2138
+ // Special case for a period when reference version is a new unstable minor
2139
+ // Needed for non_bootstrapped tests requiring either stable tasty or the same experimental version produced by both reference and bootstrapped compiler
2140
+ assert(version.minor == referenceV.minor, " Expected reference and base version to use the same minor" )
2141
+ version.minor
2142
+ case _ =>
2143
+ if (isLTS) version.minor
2144
+ else version.minor + 1
2145
+ }
2146
+ assert(tastyMinor == expectedTastyMinor, s " Invalid TASTy minor version, expected $expectedTastyMinor, got $tastyMinor" )
2147
+ }
2148
+
2149
+ if (isRelease) {
2150
+ assert(version.minor == tastyMinor, " Minor versions of TASTY vesion and Scala version should match in release builds" )
2151
+ assert(! referenceV.isRC, " Stable release needs to use stable compiler version" )
2152
+ if (version.isRC && version.patch == 0 )
2153
+ assert(tastyIsExperimental, " TASTy should be experimental when releasing a new minor version RC" )
2154
+ else
2155
+ assert(! tastyIsExperimental, " Stable version cannot use experimental TASTY" )
2156
+ }
2157
+ }
2069
2158
}
2070
2159
2071
2160
object ScaladocConfigs {
0 commit comments