diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b886351..2bda2ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,6 +43,9 @@ jobs: - name: Setup sbt uses: sbt/setup-sbt@v1 + - name: Check formatting + run: sbt '++ ${{ matrix.scala }}' scalafmtSbtCheck scalafmtCheckAll + - name: Check that workflows are up to date run: sbt '++ ${{ matrix.scala }}' githubWorkflowCheck @@ -95,7 +98,8 @@ jobs: tar xf targets.tar rm targets.tar - - env: + - name: Release + env: PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} PGP_SECRET: ${{ secrets.PGP_SECRET }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 0000000..49fa214 --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,33 @@ +version = "3.8.3" +runner.dialect = scala212 + +maxColumn = 100 +lineEndings=preserve +binPack.literalArgumentLists = true + +continuationIndent { + callSite = 2 + defnSite = 2 +} + +newlines { + alwaysBeforeMultilineDef = false + sometimesBeforeColonInMethodReturnType = true +} + +docstrings.oneline = fold +docstrings.style = Asterisk + +project.git = false + +rewrite { + rules = [ + PreferCurlyFors, + SortImports, + RedundantBraces, + RedundantParens, + SortModifiers + ] + redundantBraces.generalExpressions = false + redundantBraces.maxLines = 1 +} diff --git a/build.sbt b/build.sbt index bb66765..e3ffc2d 100644 --- a/build.sbt +++ b/build.sbt @@ -13,51 +13,62 @@ ThisBuild / githubWorkflowBuild := Seq( ThisBuild / githubWorkflowTargetBranches := Seq("main") ThisBuild / githubWorkflowJavaVersions := Seq(JavaSpec.temurin("11")) ThisBuild / githubWorkflowTargetTags := Seq("v*") +ThisBuild / githubWorkflowBuildPreamble := Seq( + WorkflowStep.Sbt( + name = Some("Check formatting"), + commands = List("scalafmtSbtCheck", "scalafmtCheckAll") + ) +) ThisBuild / githubWorkflowPublishTargetBranches := Seq(RefPredicate.StartsWith(Ref.Tag("v"))) -ThisBuild / githubWorkflowPublish := Seq(WorkflowStep.Sbt( - commands = List("ci-release"), - env = Map( - "PGP_PASSPHRASE" -> "${{ secrets.PGP_PASSPHRASE }}", - "PGP_SECRET" -> "${{ secrets.PGP_SECRET }}", - "SONATYPE_PASSWORD" -> "${{ secrets.SONATYPE_PASSWORD }}", - "SONATYPE_USERNAME" -> "${{ secrets.SONATYPE_USERNAME }}" +ThisBuild / githubWorkflowPublish := Seq( + WorkflowStep.Sbt( + name = Some("Release"), + commands = List("ci-release"), + env = Map( + "PGP_PASSPHRASE" -> "${{ secrets.PGP_PASSPHRASE }}", + "PGP_SECRET" -> "${{ secrets.PGP_SECRET }}", + "SONATYPE_PASSWORD" -> "${{ secrets.SONATYPE_PASSWORD }}", + "SONATYPE_USERNAME" -> "${{ secrets.SONATYPE_USERNAME }}" + ) ) -)) +) lazy val `sbt-avro`: Project = project - .in(file(".")) - .enablePlugins(SbtPlugin) - .settings( - organization := "com.github.sbt", - organizationName := "sbt", - organizationHomepage := Some(url("https://www.scala-sbt.org/")), - homepage := Some(url("https://github.com/sbt/sbt-avro")), - licenses += ("BSD 3-Clause", url("https://github.com/sbt/sbt-avro/blob/main/LICENSE")), - description := "Sbt plugin for compiling Avro sources", - scmInfo := Some(ScmInfo(url("https://github.com/sbt/sbt-avro"), "scm:git:git@github.com:sbt/sbt-avro.git")), - developers := List( - Developer( - id = "nevillelyh", - name = "Neville Li", - email = "@nevillelyh", - url = url("https://www.lyh.me/") - ), - Developer( - id = "RustedBones", - name = "Michel Davit", - email = "michel@davit.fr", - url = url("https://michel.davit.fr") - ) + .in(file(".")) + .enablePlugins(SbtPlugin) + .settings( + organization := "com.github.sbt", + organizationName := "sbt", + organizationHomepage := Some(url("https://www.scala-sbt.org/")), + homepage := Some(url("https://github.com/sbt/sbt-avro")), + licenses += ("BSD 3-Clause", url("https://github.com/sbt/sbt-avro/blob/main/LICENSE")), + description := "Sbt plugin for compiling Avro sources", + scmInfo := Some( + ScmInfo(url("https://github.com/sbt/sbt-avro"), "scm:git:git@github.com:sbt/sbt-avro.git") + ), + developers := List( + Developer( + id = "nevillelyh", + name = "Neville Li", + email = "@nevillelyh", + url = url("https://www.lyh.me/") ), - pluginCrossBuild / sbtVersion := "1.3.0", - Compile / scalacOptions ++= Seq("-deprecation"), - libraryDependencies ++= Seq( - Dependencies.Provided.AvroCompiler, - Dependencies.Test.Specs2Core - ), - scriptedLaunchOpts ++= Seq( - "-Xmx1024M", - "-Dplugin.version=" + version.value, - ), - scriptedBufferLog := false, - ) + Developer( + id = "RustedBones", + name = "Michel Davit", + email = "michel@davit.fr", + url = url("https://michel.davit.fr") + ) + ), + pluginCrossBuild / sbtVersion := "1.3.0", + Compile / scalacOptions ++= Seq("-deprecation"), + libraryDependencies ++= Seq( + Dependencies.Provided.AvroCompiler, + Dependencies.Test.Specs2Core + ), + scriptedLaunchOpts ++= Seq( + "-Xmx1024M", + "-Dplugin.version=" + version.value + ), + scriptedBufferLog := false + ) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a5d1d35..93c6052 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -8,7 +8,7 @@ object Dependencies { } object Provided { - val AvroCompiler = "org.apache.avro" % "avro-compiler" % Versions.Avro % "provided" + val AvroCompiler = "org.apache.avro" % "avro-compiler" % Versions.Avro % "provided" } object Test { diff --git a/project/plugins.sbt b/project/plugins.sbt index 5ce3383..519c935 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,2 +1,3 @@ addSbtPlugin("com.github.sbt" % "sbt-github-actions" % "0.24.0") addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.8.0") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") diff --git a/src/main/scala/com/github/sbt/avro/DefaultSchemaParserBuilder.scala b/src/main/scala/com/github/sbt/avro/DefaultSchemaParserBuilder.scala index 86dacf4..61d633a 100644 --- a/src/main/scala/com/github/sbt/avro/DefaultSchemaParserBuilder.scala +++ b/src/main/scala/com/github/sbt/avro/DefaultSchemaParserBuilder.scala @@ -6,7 +6,8 @@ import org.apache.avro.Schema object DefaultSchemaParserBuilder { def default(): SchemaParserBuilder = { - val Array(1, minor, _) = classOf[Schema].getPackage.getImplementationVersion.split("\\.").take(3).map(_.toInt) + val Array(1, minor, _) = + classOf[Schema].getPackage.getImplementationVersion.split("\\.").take(3).map(_.toInt) if (minor >= 12) { NameValidatorSchemaParserBuilder() } else { diff --git a/src/main/scala/com/github/sbt/avro/LegacySchemaParserBuilder.scala b/src/main/scala/com/github/sbt/avro/LegacySchemaParserBuilder.scala index 1e4979c..979dc29 100644 --- a/src/main/scala/com/github/sbt/avro/LegacySchemaParserBuilder.scala +++ b/src/main/scala/com/github/sbt/avro/LegacySchemaParserBuilder.scala @@ -11,8 +11,8 @@ import scala.collection.JavaConverters.* case class LegacySchemaParserBuilder( types: Iterable[Schema] = LegacySchemaParserBuilder.DefaultTypes, validate: Boolean = LegacySchemaParserBuilder.DefaultValidate, - validateDefaults: Boolean = LegacySchemaParserBuilder.DefaultValidateDefaults) -extends SchemaParserBuilder { + validateDefaults: Boolean = LegacySchemaParserBuilder.DefaultValidateDefaults +) extends SchemaParserBuilder { override def build(): Schema.Parser = { val parser = new Schema.Parser @@ -33,10 +33,10 @@ object LegacySchemaParserBuilder { .asInstanceOf[Schema.Parser] private def getValidate(parser: Schema.Parser): Boolean = - classOf[Schema.Parser] - .getMethod("getValidate") - .invoke(parser) - .asInstanceOf[Boolean] + classOf[Schema.Parser] + .getMethod("getValidate") + .invoke(parser) + .asInstanceOf[Boolean] private val defaultParser = new Schema.Parser diff --git a/src/main/scala/com/github/sbt/avro/SbtAvro.scala b/src/main/scala/com/github/sbt/avro/SbtAvro.scala index 62d5103..1a537c3 100644 --- a/src/main/scala/com/github/sbt/avro/SbtAvro.scala +++ b/src/main/scala/com/github/sbt/avro/SbtAvro.scala @@ -17,9 +17,7 @@ import java.io.File import java.util.jar.JarFile import scala.collection.JavaConverters._ -/** - * Simple plugin for generating the Java sources for Avro schemas and protocols. - */ +/** Simple plugin for generating the Java sources for Avro schemas and protocols. */ object SbtAvro extends AutoPlugin { val AvroClassifier = "avro" @@ -68,7 +66,10 @@ object SbtAvro extends AutoPlugin { lazy val avroArtifactTasks: Seq[TaskKey[File]] = Seq(Compile, Test).map(_ / packageAvro) lazy val defaultSettings: Seq[Setting[_]] = Seq( - avroDependencyIncludeFilter := artifactFilter(`type` = Artifact.SourceType, classifier = AvroClassifier), + avroDependencyIncludeFilter := artifactFilter( + `type` = Artifact.SourceType, + classifier = AvroClassifier + ), avroIncludes := Seq(), // addArtifact doesn't take publishArtifact setting in account artifacts ++= Classpaths.artifactDefs(avroArtifactTasks).value, @@ -95,7 +96,7 @@ object SbtAvro extends AutoPlugin { compile := compile.dependsOn(avroGenerate).value, // packaging packageAvro / artifactClassifier := Some(AvroClassifier), - packageAvro / publishArtifact := false, + packageAvro / publishArtifact := false ) ++ packageTaskSettings(packageAvro, packageAvroMappings) ++ Seq( packageAvro / artifact := (packageAvro / artifact).value.withType(Artifact.SourceType) ) @@ -168,8 +169,7 @@ object SbtAvro extends AutoPlugin { crossPaths.value ) val conf = configuration.value.toConfigRef - val avroArtifacts = update - .value + val avroArtifacts = update.value .filter(avroDependencyIncludeFilter.value) .toSeq .collect { case (`conf`, _, _, file) => file } @@ -180,7 +180,7 @@ object SbtAvro extends AutoPlugin { extractTarget = (key / target).value, includeFilter = (key / includeFilter).value, excludeFilter = (key / excludeFilter).value, - streams = (key / streams).value, + streams = (key / streams).value ) } @@ -303,14 +303,56 @@ object SbtAvro extends AutoPlugin { builder: SchemaParserBuilder ): Set[File] = { val avdls = srcDirs.flatMap(d => (d ** AvroAvdlFilter).get) - val avscs = srcDirs.flatMap(d => (d ** AvroAvscFilter).get.map(avsc => new AvroFileRef(d, avsc.relativeTo(d).get.toString))) + val avscs = srcDirs.flatMap(d => + (d ** AvroAvscFilter).get.map(avsc => new AvroFileRef(d, avsc.relativeTo(d).get.toString)) + ) val avprs = srcDirs.flatMap(d => (d ** AvroAvrpFilter).get) log.info(s"Avro compiler $avroCompilerVersion using stringType=$stringType") - recompile(records, target, log, stringType, fieldVisibility, enableDecimalLogicalType, useNamespace, optionalGetters, createSetters, builder) - compileIdls(avdls, target, log, stringType, fieldVisibility, enableDecimalLogicalType, optionalGetters, createSetters) - compileAvscs(avscs, target, log, stringType, fieldVisibility, enableDecimalLogicalType, useNamespace, optionalGetters, createSetters, builder) - compileAvprs(avprs, target, log, stringType, fieldVisibility, enableDecimalLogicalType, optionalGetters, createSetters) + recompile( + records, + target, + log, + stringType, + fieldVisibility, + enableDecimalLogicalType, + useNamespace, + optionalGetters, + createSetters, + builder + ) + compileIdls( + avdls, + target, + log, + stringType, + fieldVisibility, + enableDecimalLogicalType, + optionalGetters, + createSetters + ) + compileAvscs( + avscs, + target, + log, + stringType, + fieldVisibility, + enableDecimalLogicalType, + useNamespace, + optionalGetters, + createSetters, + builder + ) + compileAvprs( + avprs, + target, + log, + stringType, + fieldVisibility, + enableDecimalLogicalType, + optionalGetters, + createSetters + ) (target ** JavaFileFilter).get.toSet } @@ -330,7 +372,7 @@ object SbtAvro extends AutoPlugin { val createSetters = avroCreateSetters.value val optionalGetters = partialVersion(avroCompilerVersion) match { case Some((1, minor)) if minor >= 10 => Some(avroOptionalGetters.value) - case _ => None + case _ => None } val builder = avroSchemaParserBuilder.value val cachedCompile = { @@ -339,9 +381,11 @@ object SbtAvro extends AutoPlugin { val cacheStoreFactory = CacheStoreFactory(out.cacheDirectory / "avro") val lastCache = { (action: Option[Set[File]] => Set[File]) => - Tracked.lastOutput[Unit, Set[File]](cacheStoreFactory.make("last-cache")) { - case (_, l) => action(l) - }.apply(()) + Tracked + .lastOutput[Unit, Set[File]](cacheStoreFactory.make("last-cache")) { case (_, l) => + action(l) + } + .apply(()) } val inCache = Difference.inputs(cacheStoreFactory.make("in-cache"), FileInfo.lastModified) val outCache = Difference.outputs(cacheStoreFactory.make("out-cache"), FileInfo.exists) @@ -350,7 +394,9 @@ object SbtAvro extends AutoPlugin { lastCache { lastCache => inCache(inputs) { inReport => outCache { outReport => - if ((lastCache.isEmpty && records.nonEmpty) || inReport.modified.nonEmpty || outReport.modified.nonEmpty) { + if ( + (lastCache.isEmpty && records.nonEmpty) || inReport.modified.nonEmpty || outReport.modified.nonEmpty + ) { // compile if // - no previous cache and we have records to recompile // - input files have changed diff --git a/src/test/scala/com/github/sbt/avro/SbtAvroSpec.scala b/src/test/scala/com/github/sbt/avro/SbtAvroSpec.scala index b8adcdb..f24db24 100644 --- a/src/test/scala/com/github/sbt/avro/SbtAvroSpec.scala +++ b/src/test/scala/com/github/sbt/avro/SbtAvroSpec.scala @@ -14,7 +14,6 @@ class SbtAvroSpec extends Specification { val builder = DefaultSchemaParserBuilder.default() val sourceDir = new File(getClass.getClassLoader.getResource("avro").toURI) - val targetDir = Files.createTempDirectory("sbt-avro").toFile val packageDir = new File(targetDir, "com/github/sbt/avro/test") val logger = Logger.Null @@ -25,14 +24,16 @@ class SbtAvroSpec extends Specification { new File(sourceDir, "b.avsc"), new File(sourceDir, "c.avsc"), new File(sourceDir, "d.avsc"), - new File(sourceDir, "e.avsc")) + new File(sourceDir, "e.avsc") + ) val simpleNames = Seq( new File(sourceDir, "_a.avsc"), new File(sourceDir, "_b.avsc"), new File(sourceDir, "_c.avsc"), new File(sourceDir, "_d.avsc"), - new File(sourceDir, "_e.avsc")) + new File(sourceDir, "_e.avsc") + ) val sourceFiles = fullyQualifiedNames ++ simpleNames