Skip to content

Commit a344604

Browse files
Compile the output of scalafix with all supported scala versions
1 parent 80548cc commit a344604

27 files changed

+255
-79
lines changed

build.sbt

Lines changed: 76 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,40 @@ 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

17-
lazy val compat = crossProject(JSPlatform, JVMPlatform)
18-
.withoutSuffixFor(JVMPlatform)
19-
.crossType(CrossType.Pure)
20-
.in(file("compat"))
21-
.settings(scalaModuleSettings)
30+
lazy val scala211 = "2.11.12"
31+
lazy val scala212 = "2.12.6"
32+
lazy val scala213 = "2.13.0-M4"
33+
34+
lazy val compat = MultiScalaCrossProject(JSPlatform, JVMPlatform)("compat",
35+
_.settings(scalaModuleSettings)
2236
.jvmSettings(scalaModuleSettingsJVM)
2337
.settings(
2438
name := "scala-collection-compat",
2539
version := "0.2.0-SNAPSHOT",
2640
scalacOptions ++= Seq("-feature", "-language:higherKinds", "-language:implicitConversions"),
2741
unmanagedSourceDirectories in Compile += {
28-
val sharedSourceDir = baseDirectory.value.getParentFile / "src/main"
42+
val sharedSourceDir = (baseDirectory in ThisBuild).value / "compat/src/main"
2943
if (scalaVersion.value.startsWith("2.13.")) sharedSourceDir / "scala-2.13"
3044
else sharedSourceDir / "scala-2.11_2.12"
3145
}
@@ -61,15 +75,24 @@ lazy val compat = crossProject(JSPlatform, JVMPlatform)
6175
)
6276
.jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin))
6377
.disablePlugins(ScalafixPlugin)
78+
)
79+
80+
val compat211 = compat(scala211)
81+
val compat212 = compat(scala212)
82+
val compat213 = compat(scala213)
6483

65-
lazy val compatJVM = compat.jvm
66-
lazy val compatJS = compat.js
84+
lazy val compat211JVM = compat211.jvm
85+
lazy val compat211JS = compat211.js
86+
lazy val compat212JVM = compat212.jvm
87+
lazy val compat212JS = compat212.js
88+
lazy val compat213JVM = compat213.jvm
89+
lazy val compat213JS = compat213.js
6790

68-
lazy val scalafixRules = project
91+
lazy val `scalafix-rules` = project
6992
.in(file("scalafix/rules"))
7093
.settings(
71-
organization := (organization in compatJVM).value,
72-
version := (version in compatJVM).value,
94+
organization := (organization in compat212JVM).value,
95+
version := (version in compat212JVM).value,
7396
name := "scala-collection-migrations",
7497
scalaVersion := scalafixScala212,
7598
libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion
@@ -88,43 +111,49 @@ lazy val sharedScalafixSettings = Seq(
88111
)
89112

90113
// common part between input/output
91-
lazy val scalafixData = project
92-
.in(file("scalafix/data"))
93-
.settings(sharedScalafixSettings)
94-
.settings(dontPublish)
95-
.settings(scalaVersion := scalafixScala212)
96-
.dependsOn(compatJVM)
114+
lazy val `scalafix-data` = MultiScalaProject("scalafix-data", "scalafix/data",
115+
_.settings(sharedScalafixSettings)
116+
.settings(dontPublish)
117+
)
118+
119+
val `scalafix-data211` = `scalafix-data`(scala211, _.dependsOn(compat211JVM))
120+
val `scalafix-data212` = `scalafix-data`(scalafixScala212, _.dependsOn(compat212JVM))
121+
val `scalafix-data213` = `scalafix-data`(scala213, _.dependsOn(compat213JVM))
97122

98-
lazy val scalafixInput = project
123+
lazy val `scalafix-input` = project
99124
.in(file("scalafix/input"))
100125
.settings(sharedScalafixSettings)
101126
.settings(dontPublish)
102127
.settings(
103128
scalaVersion := scalafixScala212,
104129
scalafixSourceroot := sourceDirectory.in(Compile).value
105130
)
106-
.dependsOn(compatJVM, scalafixData)
131+
.dependsOn(`scalafix-data212`)
107132

108-
lazy val scalafixOutput212 = project
109-
.in(file("scalafix/output212"))
110-
.settings(sharedScalafixSettings)
111-
.settings(scalaVersion := scalafixScala212)
112-
.settings(dontPublish)
113-
.dependsOn(compatJVM, scalafixData)
114133

115-
lazy val scalafixOutput213 = project
116-
.in(file("scalafix/output213"))
117-
.settings(sharedScalafixSettings)
118-
.settings(scala213Settings)
119-
.settings(dontPublish)
134+
val `scalafix-output` = MultiScalaProject("scalafix-output", "scalafix/output",
135+
_.settings(sharedScalafixSettings)
136+
.settings(dontPublish)
137+
.disablePlugins(ScalafixPlugin)
138+
)
139+
140+
lazy val output212 = Def.setting((baseDirectory in ThisBuild).value / "scalafix/output212/src/main")
141+
lazy val addOutput212 = unmanagedSourceDirectories in Compile += output212.value / "scala"
120142

121-
lazy val scalafixOutput213Failure = project
143+
lazy val output213 = Def.setting((baseDirectory in ThisBuild).value / "scalafix/output213/src/main")
144+
lazy val addOutput213 = unmanagedSourceDirectories in Compile += output213.value / "scala"
145+
146+
lazy val `scalafix-output211` = `scalafix-output`(scala211, _.dependsOn(`scalafix-data211`))
147+
lazy val `scalafix-output212` = `scalafix-output`(scala212, _.settings(addOutput212).dependsOn(`scalafix-data212`))
148+
lazy val `scalafix-output213` = `scalafix-output`(scala213, _.settings(addOutput213).dependsOn(`scalafix-data213`))
149+
150+
lazy val `scalafix-output213-failure` = project
122151
.in(file("scalafix/output213-failure"))
123152
.settings(sharedScalafixSettings)
124153
.settings(scala213Settings)
125154
.settings(dontPublish)
126155

127-
lazy val scalafixTests = project
156+
lazy val `scalafix-tests` = project
128157
.in(file("scalafix/tests"))
129158
.settings(sharedScalafixSettings)
130159
.settings(dontPublish)
@@ -134,22 +163,23 @@ lazy val scalafixTests = project
134163
buildInfoPackage := "fix",
135164
buildInfoKeys := Seq[BuildInfoKey](
136165
"inputSourceroot" ->
137-
sourceDirectory.in(scalafixInput, Compile).value,
138-
"output212Sourceroot" ->
139-
sourceDirectory.in(scalafixOutput212, Compile).value,
140-
"output213Sourceroot" ->
141-
sourceDirectory.in(scalafixOutput213, Compile).value,
166+
sourceDirectory.in(`scalafix-input`, Compile).value,
167+
"outputSourceroot" ->
168+
(baseDirectory in ThisBuild).value / "scalafix/output/src/main",
169+
"output212Sourceroot" -> output212.value,
170+
"output213Sourceroot" -> output213.value,
142171
"output213FailureSourceroot" ->
143-
sourceDirectory.in(scalafixOutput213Failure, Compile).value,
172+
sourceDirectory.in(`scalafix-output213-failure`, Compile).value,
144173
"inputClassdirectory" ->
145-
classDirectory.in(scalafixInput, Compile).value
174+
classDirectory.in(`scalafix-input`, Compile).value
146175
),
147176
test in Test := (test in Test).dependsOn(
148-
compile in (scalafixOutput212, Compile),
149-
compile in (scalafixOutput213, Compile)
177+
compile in (`scalafix-output211`, Compile),
178+
compile in (`scalafix-output212`, Compile),
179+
compile in (`scalafix-output213`, Compile)
150180
).value
151181
)
152-
.dependsOn(scalafixInput, scalafixRules)
182+
.dependsOn(`scalafix-input`, `scalafix-rules`)
153183
.enablePlugins(BuildInfoPlugin)
154184

155185
lazy val dontPublish = Seq(
@@ -159,17 +189,14 @@ lazy val dontPublish = Seq(
159189
publishLocal := {}
160190
)
161191

162-
lazy val scala212 = "2.12.6"
163-
lazy val scala213 = "2.13.0-M4"
164-
165192
lazy val scala213Settings = Seq(
166193
resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-integration/",
167194
scalaVersion := scala213
168195
)
169196

170197
// required by sbt-scala-module
171198
inThisBuild(Seq(
172-
crossScalaVersions := Seq(scala212, scala213, "2.11.12"),
199+
crossScalaVersions := Seq(scala211, scala212, scala213),
173200
commands += Command.command("noop") { state =>
174201
println("noop")
175202
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+
}

scalafix/input/src/main/scala/fix/BreakoutSrc.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class BreakoutSrc(ts: Traversable[Int], vec: Vector[Int], list: List[Int], seq:
5858
(ts ++ ts )(breakOut): Set[Int]
5959

6060
// `TraversableLike ++:`
61-
(ts ++: ts)(breakOut): Set[Int]
61+
// (ts ++: ts)(breakOut): Set[Int]
6262

6363
// `TraversableLike.collect`
6464
ts.collect{ case x => x }(breakOut): Set[Int]
@@ -97,10 +97,8 @@ class BreakoutSrc(ts: Traversable[Int], vec: Vector[Int], list: List[Int], seq:
9797
List(1 -> "1").map(x => x)(breakOut): immutable.HashMap[Int, String]
9898
List(1 -> "1").map(x => x)(breakOut): immutable.ListMap[Int, String]
9999
List(1 -> "1").map(x => x)(breakOut): immutable.TreeMap[Int, String]
100-
List(1 -> "1").map(x => x)(breakOut): mutable.SortedMap[Int, String]
101100
List(1 -> "1").map(x => x)(breakOut): mutable.HashMap[Int, String]
102101
List(1 -> "1").map(x => x)(breakOut): mutable.ListMap[Int, String]
103-
List(1 -> "1").map(x => x)(breakOut): mutable.TreeMap[Int, String]
104102
List(1 -> "1").map(x => x)(breakOut): mutable.Map[Int, String]
105103
List(1 -> "1").map(x => x)(breakOut): immutable.IntMap[String]
106104
List(1L -> "1").map(x => x)(breakOut): immutable.LongMap[String]

0 commit comments

Comments
 (0)