Skip to content

Commit

Permalink
Merge pull request #1528 from bjaglin/projectmatrix
Browse files Browse the repository at this point in the history
better test infrastructure for Scala 3
  • Loading branch information
bjaglin committed Apr 11, 2022
2 parents f9a511e + 599f129 commit c5633c6
Show file tree
Hide file tree
Showing 20 changed files with 320 additions and 198 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ jobs:
- uses: actions/checkout@v3
- uses: olafurpg/setup-scala@v13
- run: git fetch --unshallow
- run: sbt +versionPolicyCheck
- run: sbt versionPolicyCheck
2 changes: 1 addition & 1 deletion .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ jobs:
fetch-depth: 0
- uses: olafurpg/setup-scala@v13
- name: Publish ${{ github.ref }}
run: sbt docs/docusaurusPublishGhpages
run: sbt docs2_13/docusaurusPublishGhpages
env:
GITHUB_DEPLOY_KEY: ${{ secrets.DOC }}
25 changes: 18 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,33 @@ hesitate to ask in the [gitter channel](https://gitter.im/scalacenter/scalafix).
## IntelliJ import

The project should import normally into IntelliJ and there should not be any
false red squiggles. To use the debugger or run tests from withing IntelliJ, run
at least once `sbt unit/test` to generate a `BuildInfo` file and property files
for Scalafix testkit.
false red squiggles. To use the debugger or run tests from within IntelliJ, run
at least once `sbt unit2_13Target2_13/test` to generate a `BuildInfo` file and
property files for Scalafix testkit.

## Testing

Start the SBT shell with `$ sbt`. The commands below assume you have a running
sbt shell.

```sh
> unit/test # Fast unit tests for rules, cli, core. Contains a lot
# of different test suites, so it's recommended to use testOnly.
> unit/testOnly *RuleSuite # Only run tests for rules, using scalafix-testkit.
> unit/testOnly *RuleSuite -- -z ProcedureSyntax # Only run only ProcedureSyntax unit test.
# Fast unit tests for rules, cli, core. Contains a lot
# of different test suites, so it's recommended to use testOnly.
> unit2_13Target2_13/test

# Only run tests for rules, using scalafix-testkit.
> unit2_13Target2_13/testOnly *RuleSuite

# Only run only ProcedureSyntax unit test.
> unit2_13Target2_13/testOnly *RuleSuite -- -z ProcedureSyntax
```

[sbt-projectmatrix](https://github.com/sbt/sbt-projectmatrix) is used to
generate several sbt projects `unitXTargetY` with the same source code,
but for a combination of Scala versions:
- used for compiling the framework and rules (`X`)
- used for compiling and generating SemanticDB files for the test input (`Y`)

Unit tests for rules are written using scalafix-testkit

```
Expand Down
139 changes: 102 additions & 37 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import sbt.Keys.scalacOptions
inThisBuild(
List(
onLoadMessage := s"Welcome to scalafix ${version.value}",
scalaVersion := scala213,
crossScalaVersions := List(scala213, scala212, scala211),
fork := true,
scalacOptions ++= List("-P:semanticdb:synthetics:on"),
semanticdbEnabled := true,
semanticdbVersion := scalametaV,
scalafixScalaBinaryVersion := scalaBinaryVersion.value,
scalafixScalaBinaryVersion := "2.13",
scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.5.0"
)
)
Expand All @@ -28,7 +26,7 @@ def inferJavaHome() = {
Some(actualHome)
}

lazy val interfaces = project
lazy val interfaces = projectMatrix
.in(file("scalafix-interfaces"))
.settings(
Compile / resourceGenerators += Def.task {
Expand Down Expand Up @@ -57,9 +55,11 @@ lazy val interfaces = project
crossPaths := false,
autoScalaLibrary := false
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.disablePlugins(ScalafixPlugin)

lazy val core = project
lazy val core = projectMatrix
.in(file("scalafix-core"))
.settings(
moduleName := "scalafix-core",
Expand All @@ -81,9 +81,11 @@ lazy val core = project
)
}
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions, Seq(), p => p)
.enablePlugins(BuildInfoPlugin)

lazy val rules = project
lazy val rules = projectMatrix
.in(file("scalafix-rules"))
.settings(
moduleName := "scalafix-rules",
Expand All @@ -96,10 +98,12 @@ lazy val rules = project
collectionCompat
)
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.dependsOn(core)
.enablePlugins(BuildInfoPlugin)

lazy val reflect = project
lazy val reflect = projectMatrix
.in(file("scalafix-reflect"))
.settings(
moduleName := "scalafix-reflect",
Expand All @@ -109,9 +113,11 @@ lazy val reflect = project
"org.scala-lang" % "scala-reflect" % scalaVersion.value
)
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.dependsOn(core)

lazy val cli = project
lazy val cli = projectMatrix
.in(file("scalafix-cli"))
.settings(
moduleName := "scalafix-cli",
Expand All @@ -121,23 +127,33 @@ lazy val cli = project
nailgunServer,
jgit,
commonText
)
),
publishLocalTransitive := Def.taskDyn {
val ref = thisProjectRef.value
publishLocal.all(ScopeFilter(inDependencies(ref)))
}.value
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.dependsOn(reflect, interfaces, rules)

lazy val testsShared = project
lazy val testsShared = projectMatrix
.in(file("scalafix-tests/shared"))
.settings(
noPublishAndNoMima,
scalacOptions --= (if (isScala3.value)
Seq("-P:semanticdb:synthetics:on")
else Nil),
coverageEnabled := false
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(testTargetScalaVersions)
.disablePlugins(ScalafixPlugin)

lazy val testsInput = project
lazy val testsInput = projectMatrix
.in(file("scalafix-tests/input"))
.settings(
noPublishAndNoMima,
crossScalaVersions := List(scala3, scala213, scala212, scala211),
scalacOptions --= (if (isScala3.value)
Seq("-P:semanticdb:synthetics:on")
else Nil),
Expand All @@ -149,9 +165,11 @@ lazy val testsInput = project
libraryDependencies ++= testsDependencies.value,
coverageEnabled := false
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(testTargetScalaVersions)
.disablePlugins(ScalafixPlugin)

lazy val testsOutput = project
lazy val testsOutput = projectMatrix
.in(file("scalafix-tests/output"))
.settings(
noPublishAndNoMima,
Expand All @@ -162,9 +180,11 @@ lazy val testsOutput = project
libraryDependencies ++= testsDependencies.value,
coverageEnabled := false
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(testTargetScalaVersions)
.disablePlugins(ScalafixPlugin)

lazy val testkit = project
lazy val testkit = projectMatrix
.in(file("scalafix-testkit"))
.settings(
moduleName := "scalafix-testkit",
Expand All @@ -174,9 +194,11 @@ lazy val testkit = project
scalatest
)
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.dependsOn(cli)

lazy val unit = project
lazy val unit = projectMatrix
.in(file("scalafix-tests/unit"))
.settings(
noPublishAndNoMima,
Expand All @@ -197,9 +219,9 @@ lazy val unit = project
Compile / compile / compileInputs := {
(Compile / compile / compileInputs)
.dependsOn(
testsInput / Compile / compile,
testsOutput / Compile / compile,
testsShared / Compile / compile
TargetAxis.resolve(testsInput, Compile / compile),
TargetAxis.resolve(testsOutput, Compile / compile),
TargetAxis.resolve(testsShared, Compile / compile)
)
.value
},
Expand All @@ -214,20 +236,33 @@ lazy val unit = project
}
put(
"inputClasspath",
(testsInput / Compile / fullClasspath).value.map(_.data)
TargetAxis
.resolve(testsInput, Compile / fullClasspath)
.value
.map(_.data)
)
put(
"inputSourceDirectories",
(testsInput / Compile / sourceDirectories).value
TargetAxis
.resolve(testsInput, Compile / unmanagedSourceDirectories)
.value
)
put(
"outputSourceDirectories",
(testsOutput / Compile / sourceDirectories).value
TargetAxis
.resolve(testsOutput, Compile / unmanagedSourceDirectories)
.value
)
props.put(
"scalaVersion",
TargetAxis.resolve(testsInput, Compile / scalaVersion).value
)
props.put("scalaVersion", (testsInput / Compile / scalaVersion).value)
props.put(
"scalacOptions",
(testsInput / Compile / scalacOptions).value.mkString("|")
TargetAxis
.resolve(testsInput, Compile / scalacOptions)
.value
.mkString("|")
)
val out =
(Test / managedResourceDirectories).value.head /
Expand All @@ -239,45 +274,75 @@ lazy val unit = project
"scalametaVersion" -> scalametaV,
"baseDirectory" ->
(ThisBuild / baseDirectory).value,
"inputSourceroot" ->
(testsInput / Compile / sourceDirectory).value,
"outputSourceroot" ->
(testsOutput / Compile / sourceDirectory).value,
"unitResourceDirectory" -> (Compile / resourceDirectory).value,
"testsInputResources" ->
(testsInput / Compile / sourceDirectory).value / "resources",
"semanticClasspath" ->
Seq(
(testsInput / Compile / semanticdbTargetRoot).value,
(testsShared / Compile / semanticdbTargetRoot).value
TargetAxis.resolve(testsInput, Compile / semanticdbTargetRoot).value,
TargetAxis.resolve(testsShared, Compile / semanticdbTargetRoot).value
),
"sharedSourceroot" ->
(ThisBuild / baseDirectory).value /
"scalafix-tests" / "shared" / "src" / "main",
"sharedClasspath" ->
(testsShared / Compile / classDirectory).value
TargetAxis.resolve(testsShared, Compile / classDirectory).value
),
Test / test := (Test / test)
.dependsOn(cli / crossPublishLocalBinTransitive)
.value
.dependsOn(cli.projectRefs.map(_ / publishLocalTransitive): _*)
.value,
Test / unmanagedSourceDirectories ++= {
val sourceDir = (Test / sourceDirectory).value
val maybeTargetScalaVersion =
TargetAxis
.targetScalaVersion(virtualAxes.value)
.flatMap(CrossVersion.partialVersion(_))
maybeTargetScalaVersion match {
case Some((n, m)) =>
Seq(
sourceDir / s"scala-target$n",
sourceDir / s"scala-target$n.$m"
)
case _ => Seq()
}
}
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(
scalaVersions = Seq(scala212),
axisValues = Seq(TargetAxis(scala3)),
settings = Seq()
)
.jvmPlatform(
scalaVersions = Seq(scala213),
axisValues = Seq(TargetAxis(scala213)),
settings = Seq()
)
.jvmPlatform(
scalaVersions = Seq(scala212),
axisValues = Seq(TargetAxis(scala212)),
settings = Seq()
)
.jvmPlatform(
scalaVersions = Seq(scala211),
axisValues = Seq(TargetAxis(scala211)),
settings = Seq()
)
.enablePlugins(BuildInfoPlugin)
.dependsOn(testkit)

lazy val docs = project
lazy val docs = projectMatrix
.in(file("scalafix-docs"))
.settings(
noPublishAndNoMima,
run / baseDirectory := (ThisBuild / baseDirectory).value,
moduleName := "scalafix-docs",
scalaVersion := scala213,
scalacOptions += "-Wconf:msg='match may not be exhaustive':s", // silence exhaustive pattern matching warning for documentation
scalacOptions += "-Xfatal-warnings",
mdoc := (Compile / run).evaluated,
crossScalaVersions := List(scala213),
libraryDependencies += (if (isScala211.value) metaconfigDocFor211
else metaconfigDoc)
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(scalaVersions = Seq(scala213))
.dependsOn(testkit, core, cli)
.enablePlugins(DocusaurusPlugin)
.disablePlugins(ScalafixPlugin)
4 changes: 4 additions & 0 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ object Dependencies {
val scala212 = "2.12.15"
val scala213 = "2.13.8"
val scala3 = "3.1.1"

val buildScalaVersions = Seq(scala211, scala212, scala213)
val testTargetScalaVersions = Seq(scala211, scala212, scala213, scala3)

// we support 3 last binary versions of scala212 and scala213
val testedPreviousScalaVersions: Map[String, List[String]] =
List(scala213, scala212).map(version => version -> previousVersions(version)).toMap
Expand Down
Loading

0 comments on commit c5633c6

Please sign in to comment.