Skip to content

Commit 46cf82e

Browse files
Compile the output of scalafix with all supported scala versions
1 parent af0c28e commit 46cf82e

28 files changed

+257
-81
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ migration tool on the input files and check whether the result matches the
6868
expected output files:
6969

7070
~~~
71-
> scalafixTests/test
71+
> scalafix-tests/test
7272
~~~
7373

7474
Fix the implementation of the rule (in the

build.sbt

Lines changed: 77 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,42 @@ lazy val root = project
66
.in(file("."))
77
.settings(dontPublish)
88
.aggregate(
9-
compatJVM, compatJS,
10-
scalafixRules, scalafixInput, scalafixTests,
11-
scalafixOutput212, scalafixOutput213
9+
compat211JVM,
10+
compat211JS,
11+
compat212JVM,
12+
compat212JS,
13+
compat213JVM,
14+
compat213JS,
15+
`scalafix-data211`,
16+
`scalafix-data212`,
17+
`scalafix-data213`,
18+
`scalafix-input`,
19+
`scalafix-output211`,
20+
`scalafix-output212`,
21+
`scalafix-output213`,
22+
// `scalafix-output213-failure`,
23+
`scalafix-rules`,
24+
`scalafix-tests`
1225
)
1326
.disablePlugins(ScalafixPlugin)
1427

1528
// == Core Libraries ==
1629

1730
lazy val junit = libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test
1831

19-
lazy val compat = crossProject(JSPlatform, JVMPlatform)
20-
.withoutSuffixFor(JVMPlatform)
21-
.crossType(CrossType.Pure)
22-
.in(file("compat"))
23-
.settings(scalaModuleSettings)
32+
lazy val scala211 = "2.11.12"
33+
lazy val scala212 = "2.12.6"
34+
lazy val scala213 = "2.13.0-M4"
35+
36+
lazy val compat = MultiScalaCrossProject(JSPlatform, JVMPlatform)("compat",
37+
_.settings(scalaModuleSettings)
2438
.jvmSettings(scalaModuleSettingsJVM)
2539
.settings(
2640
name := "scala-collection-compat",
2741
version := "0.2.0-SNAPSHOT",
2842
scalacOptions ++= Seq("-feature", "-language:higherKinds", "-language:implicitConversions"),
2943
unmanagedSourceDirectories in Compile += {
30-
val sharedSourceDir = baseDirectory.value.getParentFile / "src/main"
44+
val sharedSourceDir = (baseDirectory in ThisBuild).value / "compat/src/main"
3145
if (scalaVersion.value.startsWith("2.13.")) sharedSourceDir / "scala-2.13"
3246
else sharedSourceDir / "scala-2.11_2.12"
3347
}
@@ -63,9 +77,18 @@ lazy val compat = crossProject(JSPlatform, JVMPlatform)
6377
)
6478
.jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))
6579
.disablePlugins(ScalafixPlugin)
80+
)
81+
82+
val compat211 = compat(scala211)
83+
val compat212 = compat(scala212)
84+
val compat213 = compat(scala213)
6685

67-
lazy val compatJVM = compat.jvm
68-
lazy val compatJS = compat.js
86+
lazy val compat211JVM = compat211.jvm
87+
lazy val compat211JS = compat211.js
88+
lazy val compat212JVM = compat212.jvm
89+
lazy val compat212JS = compat212.js
90+
lazy val compat213JVM = compat213.jvm
91+
lazy val compat213JS = compat213.js
6992

7093
lazy val `binary-compat-old` = project
7194
.in(file("binary-compat/old"))
@@ -75,7 +98,7 @@ lazy val `binary-compat-old` = project
7598
lazy val `binary-compat-new` = project
7699
.in(file("binary-compat/new"))
77100
.settings(scalaVersion := scala212)
78-
.dependsOn(compatJVM)
101+
.dependsOn(compat212JVM)
79102
.disablePlugins(ScalafixPlugin)
80103

81104
lazy val `binary-compat` = project
@@ -97,11 +120,11 @@ lazy val `binary-compat` = project
97120
.enablePlugins(BuildInfoPlugin)
98121
.disablePlugins(ScalafixPlugin)
99122

100-
lazy val scalafixRules = project
123+
lazy val `scalafix-rules` = project
101124
.in(file("scalafix/rules"))
102125
.settings(
103-
organization := (organization in compatJVM).value,
104-
version := (version in compatJVM).value,
126+
organization := (organization in compat212JVM).value,
127+
version := (version in compat212JVM).value,
105128
name := "scala-collection-migrations",
106129
scalaVersion := scalafixScala212,
107130
libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion
@@ -120,43 +143,49 @@ lazy val sharedScalafixSettings = Seq(
120143
)
121144

122145
// common part between input/output
123-
lazy val scalafixData = project
124-
.in(file("scalafix/data"))
125-
.settings(sharedScalafixSettings)
126-
.settings(dontPublish)
127-
.settings(scalaVersion := scalafixScala212)
128-
.dependsOn(compatJVM)
146+
lazy val `scalafix-data` = MultiScalaProject("scalafix-data", "scalafix/data",
147+
_.settings(sharedScalafixSettings)
148+
.settings(dontPublish)
149+
)
150+
151+
val `scalafix-data211` = `scalafix-data`(scala211, _.dependsOn(compat211JVM))
152+
val `scalafix-data212` = `scalafix-data`(scalafixScala212, _.dependsOn(compat212JVM))
153+
val `scalafix-data213` = `scalafix-data`(scala213, _.dependsOn(compat213JVM))
129154

130-
lazy val scalafixInput = project
155+
lazy val `scalafix-input` = project
131156
.in(file("scalafix/input"))
132157
.settings(sharedScalafixSettings)
133158
.settings(dontPublish)
134159
.settings(
135160
scalaVersion := scalafixScala212,
136161
scalafixSourceroot := sourceDirectory.in(Compile).value
137162
)
138-
.dependsOn(compatJVM, scalafixData)
163+
.dependsOn(`scalafix-data212`)
139164

140-
lazy val scalafixOutput212 = project
141-
.in(file("scalafix/output212"))
142-
.settings(sharedScalafixSettings)
143-
.settings(scalaVersion := scalafixScala212)
144-
.settings(dontPublish)
145-
.dependsOn(compatJVM, scalafixData)
146165

147-
lazy val scalafixOutput213 = project
148-
.in(file("scalafix/output213"))
149-
.settings(sharedScalafixSettings)
150-
.settings(scala213Settings)
151-
.settings(dontPublish)
166+
val `scalafix-output` = MultiScalaProject("scalafix-output", "scalafix/output",
167+
_.settings(sharedScalafixSettings)
168+
.settings(dontPublish)
169+
.disablePlugins(ScalafixPlugin)
170+
)
171+
172+
lazy val output212 = Def.setting((baseDirectory in ThisBuild).value / "scalafix/output212/src/main")
173+
lazy val addOutput212 = unmanagedSourceDirectories in Compile += output212.value / "scala"
152174

153-
lazy val scalafixOutput213Failure = project
175+
lazy val output213 = Def.setting((baseDirectory in ThisBuild).value / "scalafix/output213/src/main")
176+
lazy val addOutput213 = unmanagedSourceDirectories in Compile += output213.value / "scala"
177+
178+
lazy val `scalafix-output211` = `scalafix-output`(scala211, _.dependsOn(`scalafix-data211`))
179+
lazy val `scalafix-output212` = `scalafix-output`(scala212, _.settings(addOutput212).dependsOn(`scalafix-data212`))
180+
lazy val `scalafix-output213` = `scalafix-output`(scala213, _.settings(addOutput213).dependsOn(`scalafix-data213`))
181+
182+
lazy val `scalafix-output213-failure` = project
154183
.in(file("scalafix/output213-failure"))
155184
.settings(sharedScalafixSettings)
156185
.settings(scala213Settings)
157186
.settings(dontPublish)
158187

159-
lazy val scalafixTests = project
188+
lazy val `scalafix-tests` = project
160189
.in(file("scalafix/tests"))
161190
.settings(sharedScalafixSettings)
162191
.settings(dontPublish)
@@ -166,22 +195,23 @@ lazy val scalafixTests = project
166195
buildInfoPackage := "fix",
167196
buildInfoKeys := Seq[BuildInfoKey](
168197
"inputSourceroot" ->
169-
sourceDirectory.in(scalafixInput, Compile).value,
170-
"output212Sourceroot" ->
171-
sourceDirectory.in(scalafixOutput212, Compile).value,
172-
"output213Sourceroot" ->
173-
sourceDirectory.in(scalafixOutput213, Compile).value,
198+
sourceDirectory.in(`scalafix-input`, Compile).value,
199+
"outputSourceroot" ->
200+
(baseDirectory in ThisBuild).value / "scalafix/output/src/main",
201+
"output212Sourceroot" -> output212.value,
202+
"output213Sourceroot" -> output213.value,
174203
"output213FailureSourceroot" ->
175-
sourceDirectory.in(scalafixOutput213Failure, Compile).value,
204+
sourceDirectory.in(`scalafix-output213-failure`, Compile).value,
176205
"inputClassdirectory" ->
177-
classDirectory.in(scalafixInput, Compile).value
206+
classDirectory.in(`scalafix-input`, Compile).value
178207
),
179208
test in Test := (test in Test).dependsOn(
180-
compile in (scalafixOutput212, Compile),
181-
compile in (scalafixOutput213, Compile)
209+
compile in (`scalafix-output211`, Compile),
210+
compile in (`scalafix-output212`, Compile),
211+
compile in (`scalafix-output213`, Compile)
182212
).value
183213
)
184-
.dependsOn(scalafixInput, scalafixRules)
214+
.dependsOn(`scalafix-input`, `scalafix-rules`)
185215
.enablePlugins(BuildInfoPlugin)
186216

187217
lazy val dontPublish = Seq(
@@ -191,17 +221,14 @@ lazy val dontPublish = Seq(
191221
publishLocal := {}
192222
)
193223

194-
lazy val scala212 = "2.12.6"
195-
lazy val scala213 = "2.13.0-M4"
196-
197224
lazy val scala213Settings = Seq(
198225
resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-integration/",
199226
scalaVersion := scala213
200227
)
201228

202229
// required by sbt-scala-module
203230
inThisBuild(Seq(
204-
crossScalaVersions := Seq(scala212, scala213, "2.11.12"),
231+
crossScalaVersions := Seq(scala211, scala212, scala213),
205232
commands += Command.command("noop") { state =>
206233
println("noop")
207234
state

project/MultiScalaProject.scala

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import sbt._
2+
import sbt.Keys._
3+
4+
import sbtcrossproject.{Platform, CrossProject}
5+
import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}
6+
import sbtcrossproject.CrossPlugin.autoImport._
7+
import scalajscrossproject.ScalaJSCrossPlugin.autoImport._
8+
9+
import java.io.File
10+
11+
trait MultiScala {
12+
def majorMinor(in: String): String = {
13+
val Array(major, minor, _) = in.split("\\.")
14+
major + minor
15+
}
16+
17+
def projectIdPerScala(name: String, scalaV: String): String = s"$name${majorMinor(scalaV)}"
18+
19+
def srcFull(base: String): Seq[Def.Setting[_]] = {
20+
Seq(
21+
unmanagedSourceDirectories in Compile +=
22+
(baseDirectory in ThisBuild).value / base / "src" / "main" / "scala",
23+
unmanagedSourceDirectories in Compile +=
24+
(baseDirectory in ThisBuild).value / base / "src" / "main" / ("scala-" + scalaBinaryVersion.value),
25+
unmanagedSourceDirectories in Test +=
26+
(baseDirectory in ThisBuild).value / base / "src" / "test" / "scala",
27+
unmanagedResourceDirectories in Compile +=
28+
(baseDirectory in ThisBuild).value / base / "src" / "main" / "resources",
29+
unmanagedResourceDirectories in Test +=
30+
(baseDirectory in ThisBuild).value / base / "src" / "test" / "resources"
31+
)
32+
}
33+
}
34+
35+
object MultiScalaCrossProject {
36+
def apply(platforms: Platform*)(
37+
name: String,
38+
configure: CrossProject => CrossProject): MultiScalaCrossProject =
39+
new MultiScalaCrossProject(platforms, name, configure)
40+
}
41+
42+
class MultiScalaCrossProject(
43+
platforms: Seq[Platform],
44+
name: String,
45+
configure: CrossProject => CrossProject)
46+
extends MultiScala {
47+
def apply(
48+
scalaV: String,
49+
configurePerScala: CrossProject => CrossProject = x => x
50+
): CrossProject = {
51+
val projectId = projectIdPerScala(name, scalaV)
52+
val resultingProject =
53+
CrossProject(
54+
id = projectId,
55+
base = file(s".cross/$projectId")
56+
)(platforms: _*)
57+
.crossType(CrossType.Full)
58+
.withoutSuffixFor(JVMPlatform)
59+
.settings(
60+
scalaVersion := scalaV,
61+
moduleName := name
62+
)
63+
.settings(srcFull(name))
64+
65+
configurePerScala(configure(resultingProject))
66+
}
67+
}
68+
69+
object MultiScalaProject {
70+
def apply(name: String, configure: Project => Project): MultiScalaProject =
71+
new MultiScalaProject(name, s"scalafix-$name", configure)
72+
73+
def apply(
74+
name: String,
75+
base: String,
76+
configure: Project => Project): MultiScalaProject =
77+
new MultiScalaProject(name, base, configure)
78+
}
79+
80+
class MultiScalaProject(
81+
name: String,
82+
base: String,
83+
configure: Project => Project)
84+
extends MultiScala {
85+
86+
def srcMain: String = s"$base/src/main"
87+
88+
def apply(
89+
scalaV: String,
90+
configurePerScala: Project => Project = x => x): Project = {
91+
val fullName = s"scalafix-$name"
92+
val projectId = projectIdPerScala(name, scalaV)
93+
val resultingProject =
94+
Project(id = projectId, base = file(s".cross/$projectId"))
95+
.settings(
96+
scalaVersion := scalaV,
97+
moduleName := fullName
98+
)
99+
.settings(srcFull(base))
100+
101+
configurePerScala(configure(resultingProject))
102+
}
103+
}
104+
105+
object TestProject {
106+
private def base(sub: String): String =
107+
s"scalafix/$sub"
108+
109+
def apply(
110+
sub: String,
111+
configure: (Project, String) => Project): MultiScalaProject =
112+
apply(sub, project => configure(project, s"${base(sub)}/src/main"))
113+
114+
def apply(sub: String, configure: Project => Project): MultiScalaProject =
115+
MultiScalaProject(
116+
s"tests${sub.capitalize}",
117+
base(sub),
118+
configure.andThen(_.disablePlugins(scalafix.sbt.ScalafixPlugin))
119+
)
120+
121+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
rule = "scala:fix.CrossCompat"
3+
*/
4+
package fix
5+
6+
import scala.collection.mutable
7+
import scala.collection.breakOut
8+
9+
object BreakoutSrc212 {
10+
List(1 -> "1").map(x => x)(breakOut): mutable.SortedMap[Int, String]
11+
List(1 -> "1").map(x => x)(breakOut): mutable.TreeMap[Int, String]
12+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
rule = "scala:fix.CrossCompat"
3+
*/
4+
package fix
5+
6+
import scala.collection.{mutable => m}
7+
8+
object SortedSrc212 {
9+
m.SortedMap(1 -> 1).from(0)
10+
m.TreeMap(1 -> 1).from(0)
11+
m.SortedMap(1 -> 1).to(0)
12+
m.TreeMap(1 -> 1).to(0)
13+
m.SortedMap(1 -> 1).until(0)
14+
m.TreeMap(1 -> 1).until(0)
15+
}

0 commit comments

Comments
 (0)