Skip to content

Commit

Permalink
Add scalafix rules for 0.4.x -> 0.5.x
Browse files Browse the repository at this point in the history
(cherry picked from commit 9ea606f)
  • Loading branch information
CJSmith-0141 committed Jan 2, 2024
1 parent 72d0596 commit a01f200
Show file tree
Hide file tree
Showing 11 changed files with 325 additions and 0 deletions.
105 changes: 105 additions & 0 deletions scalafix/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
lazy val V = _root_.scalafix.sbt.BuildInfo

lazy val rulesCrossVersions = Seq(V.scala213)
lazy val scala3Version = "3.3.1"

inThisBuild(
List(
organization := "com.dwolla",
homepage := Some(url("https://github.com/dwolla/fs2-pgp")),
licenses := List(
"Apache-2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0")
),
developers := List(
Developer(
"cjsmith-0141",
"CJ Smith",
"connor.smith1@octoenergy.com",
url("https://kraken.tech")
)
),
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision
)
)

lazy val `fs2-pgp` = (project in file("."))
.aggregate(
rules.projectRefs ++
input.projectRefs ++
output.projectRefs ++
tests.projectRefs: _*
)
.settings(
publish / skip := true
)

lazy val rules = projectMatrix
.settings(
moduleName := "scalafix",
libraryDependencies ++= Seq(
"ch.epfl.scala" %% "scalafix-core" % V.scalafixVersion,
)
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(rulesCrossVersions)

lazy val input = projectMatrix
.settings(
publish / skip := true,
libraryDependencies ++= Seq(
"com.dwolla" %% "fs2-pgp" % "0.4.3",
"org.typelevel" %% "log4cats-noop" % "2.5.0"
)

)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(scalaVersions = rulesCrossVersions)

lazy val output = projectMatrix
.settings(
publish / skip := true,
libraryDependencies ++= Seq(
// TODO: This feels like a chicken/egg problem
// do we cut a release before merging this in?
"net.tazato" %% "fs2-pgp" % "0.5.0",
"org.typelevel" %% "log4cats-noop" % "2.5.0"
)
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(scalaVersions = rulesCrossVersions :+ scala3Version)

lazy val testsAggregate = Project("tests", file("target/testsAggregate"))
.aggregate(tests.projectRefs: _*)
.settings(
publish / skip := true
)

lazy val tests = projectMatrix
.settings(
publish / skip := true,
scalafixTestkitOutputSourceDirectories :=
TargetAxis
.resolve(output, Compile / unmanagedSourceDirectories)
.value,
scalafixTestkitInputSourceDirectories :=
TargetAxis
.resolve(input, Compile / unmanagedSourceDirectories)
.value,
scalafixTestkitInputClasspath :=
TargetAxis.resolve(input, Compile / fullClasspath).value,
scalafixTestkitInputScalacOptions :=
TargetAxis.resolve(input, Compile / scalacOptions).value,
scalafixTestkitInputScalaVersion :=
TargetAxis.resolve(input, Compile / scalaVersion).value
)
.defaultAxes(
rulesCrossVersions.map(VirtualAxis.scalaABIVersion) :+ VirtualAxis.jvm: _*
)
.jvmPlatform(
scalaVersions = Seq(V.scala213),
axisValues = Seq(TargetAxis(V.scala213)),
settings = Seq()
)
.dependsOn(rules)
.enablePlugins(ScalafixTestkitPlugin)
58 changes: 58 additions & 0 deletions scalafix/input/src/main/scala/fix/Fs2Pgp.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package fix
/*
rule = Fs2Pgp
*/
import cats.effect._
import cats.syntax.all._
import cats.effect.unsafe.implicits.global
import org.typelevel.log4cats._
import fs2._
import fs2.text._
import com.dwolla.security.crypto._
import eu.timepit.refined.types.numeric.PosInt
object Fs2Pgp {
implicit val lf: LoggerFactory[IO] = org.typelevel.log4cats.noop.NoOpFactory.impl[IO]
val key =
"""-----BEGIN PGP PUBLIC KEY BLOCK-----
|Version: GnuPG v1
|
|mQENBFVoyeYBCACy0S/9y/c/CpoYLL6aD3TMCV1Pe/0jcWN0ykULf9l4znYODZLr
|f10BGAJETj9ghrJCNXMib2ogz0wo43KVAp9o3mkg01vVyqs1rzM5jw+yCZmyGPFf
|GsE2lxZFMX+rS0dyq2w0FQN2IjYsELwIFeQ02GXTLyTlhY+u5wwCXo4e7AEXaEo7
|jl8129NA46gf6l+6lUMyFpKnunO7L4W5rCCrIizP4Fmll1adYfClSX6cztIfz4vg
|Fs2HuViPin5y8THodkg9cIkCfyNHivEbfBbx0xfx67BCwxFcYgF/84H8TASRhjRl
|4s1fZDA7rETWDJIcC+neNV/qtF0kY1ECSd3nABEBAAG0IFRlc3QgVXNlciA8ZnJl
|ZCt0ZXN0QGR3b2xsYS5jb20+iQE4BBMBAgAiBQJVaMnmAhsDBgsJCAcDAgYVCAIJ
|CgsEFgIDAQIeAQIXgAAKCRA2OYfNakCqV1bYB/9QNR5DN5J27Z4DIGoOto/PuVvs
|bQHZj8NLcvIZL1cUyKOg+oRICq2z4BXHAMqyouhs/GLiR5P74I9cJTSIudAvBhwi
|du9AcMQy+Qg3K1rUQGlNU+iamD8DFNUhLoK+Oicij0Mw4TSWBsoR3+Pg/jZ5SDUc
|dUsGGaBJthYoiJR8vZ6Uf9oCn+mpVhrso0zemBDud4AHKaVa+8o7VUWGa6jeyRHX
|RKVbHn7GGYiHZkl+qfpthcxyPHOIkZo+t8GVTItLpvVuU+X36N70+rIzXj5t8NDZ
|KfD3M4p6BSq6Cu6DtJOZ1F28hwaWiRoCdbPrJfW33fo1RxLB6+nLf/ttYGmhuQEN
|BFVoyeYBCADiZfKA98YQip/kvj5rBS2ilQDycBX7Ls2IftuwzO6Q9QSF2lDiz708
|zyvg0czQPZYaZkFgziZEmjbvOc7hDG+icVWRLCjCcZk4i2TXy7bGcTZmBQ31iVMJ
|ia7GxsJhu4ngrP15pZakAYcCwEk3QH17TdhOwvV8ixHmv9USCMJyiNnuhVAP2tY/
|Ef0EoCV6qAMoP3dNPT30sFI8+55Ce9yAtWQItT5q4vYOmC9Q34XtSxvpLsLzVByd
|rdvgXe0acjvMiTGcYBdjitawFYeLuz2s5mQAi4X1vcJqxBSBjG7X+1PiDqFFIid3
|+6rIQtR3ho+Xqz/ucGglKxtn6m49wMHJABEBAAGJAR8EGAECAAkFAlVoyeYCGwwA
|CgkQNjmHzWpAqldxFgf/SZIT1AiBAOLkqdWEObg0cU7n1YOXbj56sUeUCFxdbnl9
|V2paf2SaMB6EEGLTk9PN0GG3hPyDkl4O6w3mn2J46uP8ecVaNvTSxoq2OmkMmD1H
|/OSnF8a/jB6R1ODiAwekVuUMtAS7JiaAAcKcenG1f0XRKwQs52uavGXPgUuJbVtK
|bB0SyLBhvGG8YIWTXRMHoJRt/Ls4JEuYaoBYqfV2eDn4WhW1LVuXP13gXixy0RiV
|8rHs9aH8BAU7Dy0BBnaS3R9m8vtfdFxMI3/+1iGt0+xh/B4w++9oFE2DgyoZXUF8
|mbjKYhiRPKNoj6Rn/mHUGcnuPlKvKP+1X5bObpDbQQ==
|=TJUS
|-----END PGP PUBLIC KEY BLOCK-----""".stripMargin
val wrappedKey = PGPKeyAlg[IO].readPublicKey(key).unsafeRunSync()
val pos = PosInt(100)
val chunkSize = tagChunkSize(PosInt(100))
val chunkSize2 = tagChunkSize(pos)
(for {
crypto <- Stream.resource(CryptoAlg[IO])
output <- Stream.emit("hello world")
.through(utf8.encode)
.through(crypto.encrypt(wrappedKey, fileName = "BigMoney.txt".some))
.through(crypto.armor())
.through(utf8.decode)
} yield output).compile.string.unsafeRunSync()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package fix

object Fs2PgpSignificantIndentation:
val a = 1
// Add code that needs fixing here.
56 changes: 56 additions & 0 deletions scalafix/output/src/main/scala/fix/Fs2Pgp.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package fix

import cats.effect._
import cats.syntax.all._
import cats.effect.unsafe.implicits.global
import org.typelevel.log4cats._
import fs2._
import fs2.text._
import com.dwolla.security.crypto._
import eu.timepit.refined.types.numeric.PosInt
object Fs2Pgp {
implicit val lf: LoggerFactory[IO] = org.typelevel.log4cats.noop.NoOpFactory.impl[IO]
val key =
"""-----BEGIN PGP PUBLIC KEY BLOCK-----
|Version: GnuPG v1
|
|mQENBFVoyeYBCACy0S/9y/c/CpoYLL6aD3TMCV1Pe/0jcWN0ykULf9l4znYODZLr
|f10BGAJETj9ghrJCNXMib2ogz0wo43KVAp9o3mkg01vVyqs1rzM5jw+yCZmyGPFf
|GsE2lxZFMX+rS0dyq2w0FQN2IjYsELwIFeQ02GXTLyTlhY+u5wwCXo4e7AEXaEo7
|jl8129NA46gf6l+6lUMyFpKnunO7L4W5rCCrIizP4Fmll1adYfClSX6cztIfz4vg
|Fs2HuViPin5y8THodkg9cIkCfyNHivEbfBbx0xfx67BCwxFcYgF/84H8TASRhjRl
|4s1fZDA7rETWDJIcC+neNV/qtF0kY1ECSd3nABEBAAG0IFRlc3QgVXNlciA8ZnJl
|ZCt0ZXN0QGR3b2xsYS5jb20+iQE4BBMBAgAiBQJVaMnmAhsDBgsJCAcDAgYVCAIJ
|CgsEFgIDAQIeAQIXgAAKCRA2OYfNakCqV1bYB/9QNR5DN5J27Z4DIGoOto/PuVvs
|bQHZj8NLcvIZL1cUyKOg+oRICq2z4BXHAMqyouhs/GLiR5P74I9cJTSIudAvBhwi
|du9AcMQy+Qg3K1rUQGlNU+iamD8DFNUhLoK+Oicij0Mw4TSWBsoR3+Pg/jZ5SDUc
|dUsGGaBJthYoiJR8vZ6Uf9oCn+mpVhrso0zemBDud4AHKaVa+8o7VUWGa6jeyRHX
|RKVbHn7GGYiHZkl+qfpthcxyPHOIkZo+t8GVTItLpvVuU+X36N70+rIzXj5t8NDZ
|KfD3M4p6BSq6Cu6DtJOZ1F28hwaWiRoCdbPrJfW33fo1RxLB6+nLf/ttYGmhuQEN
|BFVoyeYBCADiZfKA98YQip/kvj5rBS2ilQDycBX7Ls2IftuwzO6Q9QSF2lDiz708
|zyvg0czQPZYaZkFgziZEmjbvOc7hDG+icVWRLCjCcZk4i2TXy7bGcTZmBQ31iVMJ
|ia7GxsJhu4ngrP15pZakAYcCwEk3QH17TdhOwvV8ixHmv9USCMJyiNnuhVAP2tY/
|Ef0EoCV6qAMoP3dNPT30sFI8+55Ce9yAtWQItT5q4vYOmC9Q34XtSxvpLsLzVByd
|rdvgXe0acjvMiTGcYBdjitawFYeLuz2s5mQAi4X1vcJqxBSBjG7X+1PiDqFFIid3
|+6rIQtR3ho+Xqz/ucGglKxtn6m49wMHJABEBAAGJAR8EGAECAAkFAlVoyeYCGwwA
|CgkQNjmHzWpAqldxFgf/SZIT1AiBAOLkqdWEObg0cU7n1YOXbj56sUeUCFxdbnl9
|V2paf2SaMB6EEGLTk9PN0GG3hPyDkl4O6w3mn2J46uP8ecVaNvTSxoq2OmkMmD1H
|/OSnF8a/jB6R1ODiAwekVuUMtAS7JiaAAcKcenG1f0XRKwQs52uavGXPgUuJbVtK
|bB0SyLBhvGG8YIWTXRMHoJRt/Ls4JEuYaoBYqfV2eDn4WhW1LVuXP13gXixy0RiV
|8rHs9aH8BAU7Dy0BBnaS3R9m8vtfdFxMI3/+1iGt0+xh/B4w++9oFE2DgyoZXUF8
|mbjKYhiRPKNoj6Rn/mHUGcnuPlKvKP+1X5bObpDbQQ==
|=TJUS
|-----END PGP PUBLIC KEY BLOCK-----""".stripMargin
val wrappedKey = PGPKeyAlg[IO].readPublicKey(key).unsafeRunSync()
val pos = PosInt.unsafeFrom(100)
val chunkSize = ChunkSize(PosInt.unsafeFrom(100))
val chunkSize2 = ChunkSize(pos)
(for {
crypto <- Stream.resource(CryptoAlg.resource[IO])
output <- Stream.emit("hello world")
.through(utf8.encode)
.through(crypto.encrypt(EncryptionConfig().withFileName("BigMoney.txt".some), wrappedKey))
.through(crypto.armor)
.through(utf8.decode)
} yield output).compile.string.unsafeRunSync()
}
47 changes: 47 additions & 0 deletions scalafix/project/TargetAxis.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import sbt._
import sbt.internal.ProjectMatrix
import sbtprojectmatrix.ProjectMatrixPlugin.autoImport._

/** Use on ProjectMatrix rows to tag an affinity to a custom scalaVersion */
case class TargetAxis(scalaVersion: String) extends VirtualAxis.WeakAxis {

private val scalaBinaryVersion = CrossVersion.binaryScalaVersion(scalaVersion)

override val idSuffix = s"Target${scalaBinaryVersion.replace('.', '_')}"
override val directorySuffix = s"target$scalaBinaryVersion"
}

object TargetAxis {

private def targetScalaVersion(virtualAxes: Seq[VirtualAxis]): String =
virtualAxes.collectFirst { case a: TargetAxis => a.scalaVersion }.get

/** When invoked on a ProjectMatrix with a TargetAxis, lookup the project
* generated by `matrix` with a scalaVersion matching the one declared in
* that TargetAxis, and resolve `key`.
*/
def resolve[T](
matrix: ProjectMatrix,
key: TaskKey[T]
): Def.Initialize[Task[T]] =
Def.taskDyn {
val sv = targetScalaVersion(virtualAxes.value)
val project = matrix.finder().apply(sv)
Def.task((project / key).value)
}

/** When invoked on a ProjectMatrix with a TargetAxis, lookup the project
* generated by `matrix` with a scalaVersion matching the one declared in
* that TargetAxis, and resolve `key`.
*/
def resolve[T](
matrix: ProjectMatrix,
key: SettingKey[T]
): Def.Initialize[T] =
Def.settingDyn {
val sv = targetScalaVersion(virtualAxes.value)
val project = matrix.finder().apply(sv)
Def.setting((project / key).value)
}

}
1 change: 1 addition & 0 deletions scalafix/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.9.8
3 changes: 3 additions & 0 deletions scalafix/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resolvers += Resolver.sonatypeRepo("releases")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.11.1")
addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.9.1")
7 changes: 7 additions & 0 deletions scalafix/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Scalafix rules for FS2 PGP

To develop rule:
```
sbt ~tests/test
# edit rules/src/main/scala/fix/Fs2Pgp.scala
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fix.Fs2Pgp
34 changes: 34 additions & 0 deletions scalafix/rules/src/main/scala/fix/Fs2Pgp.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package fix

import scalafix.v1._
import scala.meta._

class Fs2Pgp extends SemanticRule("Fs2Pgp") {

override def fix(implicit doc: SemanticDocument): Patch = {
doc.tree.collect {
case t@Term.ApplyType.After_4_6_0(Term.Name("CryptoAlg"), Type.ArgClause(List(Type.Name(name)))) =>
Patch.replaceTree(t, s"CryptoAlg.resource[$name]").atomic
case t@Term.Apply.After_4_6_0(Term.Select(Term.Name(name), Term.Name("armor")), Term.ArgClause(List(), None)) =>
Patch.replaceTree(t, s"$name.armor").atomic
case t@Term.Apply.After_4_6_0(Term.Name("tagChunkSize"), _) =>
Patch.renameSymbol(t.symbol, "ChunkSize")
case t@Term.Apply.After_4_6_0(
Term.Name("PosInt"),
Term.ArgClause(List(Lit.Int(posIntArg)), None)
) => Patch.replaceTree(t, s"PosInt.unsafeFrom($posIntArg)").atomic
case t@
Term.Apply.After_4_6_0(
Term.Select(Term.Name(cryptoRName), Term.Name("encrypt")),
Term.ArgClause(
List(
Term.Name(keyName),
Term.Assign( Term.Name("fileName"), fileNameTerm )
),
None
)
) =>
Patch.replaceTree(t, s"$cryptoRName.encrypt(EncryptionConfig().withFileName($fileNameTerm), $keyName)")
}.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 scalafix.testkit._
import org.scalatest.funsuite.AnyFunSuiteLike

class RuleSuite extends AbstractSemanticRuleSuite with AnyFunSuiteLike {
runAllTests()
}

0 comments on commit a01f200

Please sign in to comment.