Skip to content

Commit

Permalink
Add scalafix 0.7 migration rule
Browse files Browse the repository at this point in the history
  • Loading branch information
RustedBones committed Feb 12, 2024
1 parent 271c20f commit 27c2eb1
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 0 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/scalafix.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Scalafix Migration Rules

on:
pull_request:
branches: [main]
paths:
- 'scalafix/**'

push:
branches: [main]
paths:
- 'scalafix/**'

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
scalafix:
name: Test
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout current branch (full)
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Java (corretto@11)
id: setup-java-corretto-11
uses: actions/setup-java@v3
with:
distribution: corretto
java-version: 11
cache: sbt

- name: sbt update
if: steps.setup-java-corretto-11.outputs.cache-hit == 'false'
run: sbt scalafix/update

- name: Test
run: sbt test
working-directory: scalafix
7 changes: 7 additions & 0 deletions scalafix/.sbtopts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-J-Xms2G
-J-Xmx8G
-J-XX:ReservedCodeCacheSize=512m
-J-XX:+TieredCompilation
-J-XX:+UseParallelGC
-Dfile.encoding=UTF8

98 changes: 98 additions & 0 deletions scalafix/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
lazy val V = _root_.scalafix.sbt.BuildInfo

inThisBuild(
List(
resolvers ++= Resolver.sonatypeOssRepos("snapshots"),
organization := "com.spotify",
scalaVersion := V.scala212,
scalacOptions ++= List("-Yrangepos"),
publish / skip := true,
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision,
semanticdbIncludeInJar := true,
scalafmtOnCompile := false,
scalafmtConfig := baseDirectory.value / ".." / ".scalafmt.conf",
)
)

lazy val root = project
.in(file("."))
.aggregate(
tests.projectRefs ++ Seq[sbt.ProjectReference](
// 0.7
`input-0_7`,
`output-0_7`,
// scalafix
rules
): _*
)

lazy val rules = project
.settings(
moduleName := "scalafix",
libraryDependencies ++= Seq(
"ch.epfl.scala" %% "scalafix-core" % V.scalafixVersion
)
)

def magnolify(version: String): List[ModuleID] = {
val modules = List(
"magnolify-avro",
"magnolify-bigquery",
"magnolify-bigtable",
"magnolify-cats",
"magnolify-datastore",
"magnolify-guava",
"magnolify-neo4j",
"magnolify-parquet",
"magnolify-protobuf",
"magnolify-refined",
"magnolify-shared",
"magnolify-scalacheck",
"magnolify-tensorflow"
)

val libs = List (
"org.apache.avro" % "avro" % "1.11.2",
"com.google.apis" % "google-api-services-bigquery" % "v2-rev20231111-2.0.0",
"com.google.api.grpc" % "proto-google-cloud-bigtable-v2" % "2.32.0",
"org.typelevel" %% "cats-core" % "2.10.0",
"com.google.cloud.datastore" % "datastore-v1-proto-client" % "2.18.2",
"com.google.guava" % "guava" % "33.0.0-jre",
"org.neo4j.driver" % "neo4j-java-driver" % "4.4.12",
"org.apache.parquet" % "parquet-hadoop" % "1.13.1",
"com.google.protobuf" % "protobuf-java" % "3.25.2",
"eu.timepit" %% "refined" % "0.11.1",
"org.scalacheck" %% "scalacheck" % "1.17.0",
"org.tensorflow" % "tensorflow-core-api" % "0.5.0"
)

modules.map("com.spotify" %% _ % version) ++ libs
}

lazy val `input-0_7` = project
.settings(
libraryDependencies ++= magnolify("0.6.0")
)

lazy val `output-0_7` = project
.settings(
libraryDependencies ++= magnolify("0.7.0")
)


lazy val magnolify0_7 = ConfigAxis("-magnolify-0_7", "-0_7-")

lazy val tests = projectMatrix
.in(file("tests"))
.enablePlugins(ScalafixTestkitPlugin)
.customRow(
scalaVersions = Seq(V.scala212),
axisValues = Seq(magnolify0_7, VirtualAxis.jvm),
_.settings(
moduleName := name.value + magnolify0_7.idSuffix,
scalafixTestkitOutputSourceDirectories := (`output-0_7` / Compile / unmanagedSourceDirectories).value,
scalafixTestkitInputSourceDirectories := (`input-0_7` / Compile / unmanagedSourceDirectories).value,
scalafixTestkitInputClasspath := (`input-0_7` / Compile / fullClasspath).value
).dependsOn(rules)
)
19 changes: 19 additions & 0 deletions scalafix/input-0_7/src/main/scala/fix/MapBasedConverters.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
rule = MapBasedConverters
*/
package fix

import magnolify.tensorflow._
import org.tensorflow.proto.example.Example

object MapBasedConverters {

final case class Person(name: String, age: Int)

// ExampleType
val etPerson: ExampleType[Person] = ???
val e: Example = ???
val p: Person = ???
etPerson.from(e)
etPerson.to(p)
}
16 changes: 16 additions & 0 deletions scalafix/output-0_7/src/main/scala/fix/MapBasedConverters.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package fix

import magnolify.tensorflow._
import org.tensorflow.proto.example.Example

object MapBasedConverters {

final case class Person(name: String, age: Int)

// ExampleType
val etPerson: ExampleType[Person] = ???
val e: Example = ???
val p: Person = ???
etPerson(e)
etPerson(p)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fix.v0_7_0.MapBasedConverters

31 changes: 31 additions & 0 deletions scalafix/rules/src/main/scala/fix/MapBasedConverters.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package fix.v0_7_0

import scalafix.v1._

import scala.meta._

object MapBasedConverters {
private val ExampleType: SymbolMatcher =
SymbolMatcher.normalized("magnolify/tensorflow/ExampleType")

private val ConverterFn: SymbolMatcher =
SymbolMatcher.normalized("magnolify/shared/Converter#from") +
SymbolMatcher.normalized("magnolify/shared/Converter#to")
}

class MapBasedConverters extends SemanticRule("MapBasedConverters") {
import MapBasedConverters._

def isExampleType(term: Term)(implicit doc: SemanticDocument): Boolean =
term.symbol.info.map(_.signature) match {
case Some(MethodSignature(_, _, TypeRef(_, sym, _))) => ExampleType.matches(sym)
case _ => false
}

override def fix(implicit doc: SemanticDocument): Patch =
doc.tree.collect {
case t @ q"$qual.$fn(..$params)" if isExampleType(qual) && ConverterFn.matches(fn) =>
Patch.replaceTree(t, q"$qual(..$params)".syntax)
}.asPatch

}
8 changes: 8 additions & 0 deletions scalafix/tests/src/test/scala/fix/RuleSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package fix

import org.scalatest.funsuite.AnyFunSuiteLike
import scalafix.testkit.AbstractSemanticRuleSuite

class RuleSuite extends AbstractSemanticRuleSuite with AnyFunSuiteLike {
runAllTests()
}

0 comments on commit 27c2eb1

Please sign in to comment.