diff --git a/build.sbt b/build.sbt index ba8d7a1..a280675 100644 --- a/build.sbt +++ b/build.sbt @@ -16,7 +16,10 @@ lazy val plugin = project ScmInfo(url("https://github.com/sbt/sbt-java-formatter"), "scm:git:git@github.com:sbt/sbt-java-formatter.git")), developers := List( Developer("ktoso", "Konrad 'ktoso' Malawski", "", url("https://github.com/ktoso"))), - libraryDependencies ++= Seq("com.google.googlejavaformat" % "google-java-format" % "1.24.0"), + libraryDependencies ++= Seq( + "com.google.googlejavaformat" % "google-java-format" % "1.24.0", + "com.palantir.javaformat" % "palantir-java-format" % "2.62.0" + ), startYear := Some(2015), description := "Formats Java code in your project.", licenses += ("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.html")), diff --git a/plugin/src/main/java/com/github/sbt/javaformatter/Formatter.java b/plugin/src/main/java/com/github/sbt/javaformatter/Formatter.java new file mode 100644 index 0000000..61f58a3 --- /dev/null +++ b/plugin/src/main/java/com/github/sbt/javaformatter/Formatter.java @@ -0,0 +1,21 @@ +/* + * Copyright 2015 sbt community + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.github.sbt.javaformatter; + +public enum Formatter { + GOOGLE, PALANTIR +} diff --git a/plugin/src/main/scala/com/github/sbt/JavaFormatterPlugin.scala b/plugin/src/main/scala/com/github/sbt/JavaFormatterPlugin.scala index 3fbe045..dee83a3 100644 --- a/plugin/src/main/scala/com/github/sbt/JavaFormatterPlugin.scala +++ b/plugin/src/main/scala/com/github/sbt/JavaFormatterPlugin.scala @@ -18,8 +18,9 @@ package com.github.sbt import _root_.sbt.Keys._ import _root_.sbt.{ Def, _ } +import com.github.sbt.javaformatter.{ Formatter, JavaFormatter } import com.google.googlejavaformat.java.JavaFormatterOptions -import com.github.sbt.javaformatter.JavaFormatter +import com.palantir.javaformat.java.{ JavaFormatterOptions => PalantirJavaFormatterOptions } @deprecated("Use javafmtOnCompile setting instead", "0.5.1") object AutomateJavaFormatterPlugin extends AutoPlugin { @@ -42,10 +43,15 @@ object JavaFormatterPlugin extends AutoPlugin { "Execute the javafmtCheck task for all configurations in which it is enabled. " + "(By default this means the Compile and Test configurations.)") val javafmtOnCompile = settingKey[Boolean]("Format Java source files on compile, off by default.") + val javafmtFormatter = settingKey[Formatter]("Define formatter, Google (default) or Palantir") val javafmtStyle = settingKey[JavaFormatterOptions.Style]("Define formatting style, Google Java Style (default) or AOSP") val javafmtOptions = settingKey[JavaFormatterOptions]( "Define all formatting options such as style or enabling Javadoc formatting. See _JavaFormatterOptions_ for more") + val javafmtPalantirStyle = + settingKey[PalantirJavaFormatterOptions.Style]("Define formatting style, Palantir (default) or Google or AOSP") + val javafmtPalantirOptions = settingKey[PalantirJavaFormatterOptions]( + "Define all formatting options such as style or enabling Javadoc formatting. See _JavaFormatterOptions_ for more") } import autoImport._ @@ -69,20 +75,27 @@ object JavaFormatterPlugin extends AutoPlugin { } override def globalSettings: Seq[Def.Setting[?]] = - Seq(javafmtOnCompile := false, javafmtStyle := JavaFormatterOptions.Style.GOOGLE) + Seq( + javafmtOnCompile := false, + javafmtStyle := JavaFormatterOptions.Style.GOOGLE, + javafmtFormatter := Formatter.GOOGLE, + javafmtPalantirStyle := PalantirJavaFormatterOptions.Style.PALANTIR) def toBeScopedSettings: Seq[Setting[?]] = List( (javafmt / sourceDirectories) := List(javaSource.value), javafmtOptions := JavaFormatterOptions.builder().style(javafmtStyle.value).build(), + javafmtPalantirOptions := PalantirJavaFormatterOptions.builder().style(javafmtPalantirStyle.value).build(), javafmt := { val streamz = streams.value val sD = (javafmt / sourceDirectories).value.toList val iF = (javafmt / includeFilter).value val eF = (javafmt / excludeFilter).value val cache = streamz.cacheStoreFactory + val formatter = javafmtFormatter.value val options = javafmtOptions.value - JavaFormatter(sD, iF, eF, streamz, cache, options) + val palantirOptions = javafmtPalantirOptions.value + JavaFormatter(sD, iF, eF, streamz, cache, formatter, options, palantirOptions) }, javafmtCheck := { val streamz = streams.value @@ -91,8 +104,10 @@ object JavaFormatterPlugin extends AutoPlugin { val iF = (javafmt / includeFilter).value val eF = (javafmt / excludeFilter).value val cache = (javafmt / streams).value.cacheStoreFactory + val formatter = javafmtFormatter.value val options = javafmtOptions.value - JavaFormatter.check(baseDir, sD, iF, eF, streamz, cache, options) + val palantirOptions = javafmtPalantirOptions.value + JavaFormatter.check(baseDir, sD, iF, eF, streamz, cache, formatter, options, palantirOptions) }, javafmtDoFormatOnCompile := Def.settingDyn { if (javafmtOnCompile.value) { diff --git a/plugin/src/main/scala/com/github/sbt/javaformatter/JavaFormatter.scala b/plugin/src/main/scala/com/github/sbt/javaformatter/JavaFormatter.scala index 73576e2..7e3d6d6 100644 --- a/plugin/src/main/scala/com/github/sbt/javaformatter/JavaFormatter.scala +++ b/plugin/src/main/scala/com/github/sbt/javaformatter/JavaFormatter.scala @@ -20,7 +20,15 @@ import _root_.sbt.Keys._ import _root_.sbt._ import _root_.sbt.util.CacheImplicits._ import _root_.sbt.util.{ CacheStoreFactory, FileInfo, Logger } -import com.google.googlejavaformat.java.{ Formatter, JavaFormatterOptions } +import com.google.googlejavaformat.java.{ + Formatter => GoogleFormatter, + JavaFormatterOptions => GoogleJavaFormatterOptions +} +import com.palantir.javaformat.java.{ + Formatter => PalantirFormatter, + JavaFormatterOptions => PalantirJavaFormatterOptions +} + import scala.collection.immutable.Seq object JavaFormatter { @@ -31,9 +39,14 @@ object JavaFormatter { excludeFilter: FileFilter, streams: TaskStreams, cacheStoreFactory: CacheStoreFactory, - options: JavaFormatterOptions): Unit = { + formatter: Formatter, + options: GoogleJavaFormatterOptions, + palantirOptions: PalantirJavaFormatterOptions): Unit = { val files = sourceDirectories.descendantsExcept(includeFilter, excludeFilter).get().toList - cachedFormatSources(cacheStoreFactory, files, streams.log)(new Formatter(options)) + cachedFormatSources(cacheStoreFactory, files, streams.log)( + formatter, + new GoogleFormatter(options), + PalantirFormatter.createFormatter(palantirOptions)) } def check( @@ -43,9 +56,15 @@ object JavaFormatter { excludeFilter: FileFilter, streams: TaskStreams, cacheStoreFactory: CacheStoreFactory, - options: JavaFormatterOptions): Boolean = { + formatter: Formatter, + options: GoogleJavaFormatterOptions, + palantirOptions: PalantirJavaFormatterOptions): Boolean = { val files = sourceDirectories.descendantsExcept(includeFilter, excludeFilter).get().toList - val analysis = cachedCheckSources(cacheStoreFactory, baseDir, files, streams.log)(new Formatter(options)) + val analysis = + cachedCheckSources(cacheStoreFactory, baseDir, files, streams.log)( + formatter, + new GoogleFormatter(options), + PalantirFormatter.createFormatter(palantirOptions)) trueOrBoom(analysis) } @@ -73,7 +92,10 @@ object JavaFormatter { } private def cachedCheckSources(cacheStoreFactory: CacheStoreFactory, baseDir: File, sources: Seq[File], log: Logger)( - implicit formatter: Formatter): Analysis = { + implicit + formatter: Formatter, + googleFormatter: GoogleFormatter, + palantirFormatter: PalantirFormatter): Analysis = { trackSourcesViaCache(cacheStoreFactory, sources) { (outDiff, prev) => log.debug(outDiff.toString) val updatedOrAdded = outDiff.modified & outDiff.checked @@ -89,7 +111,10 @@ object JavaFormatter { log.warn(s"${file.toString} isn't formatted properly!") } - private def checkSources(baseDir: File, sources: Seq[File], log: Logger)(implicit formatter: Formatter): Analysis = { + private def checkSources(baseDir: File, sources: Seq[File], log: Logger)(implicit + formatter: Formatter, + googleFormatter: GoogleFormatter, + palantirFormatter: PalantirFormatter): Analysis = { if (sources.nonEmpty) { log.info(s"Checking ${sources.size} Java source${plural(sources.size)}...") } @@ -104,7 +129,9 @@ object JavaFormatter { } private def cachedFormatSources(cacheStoreFactory: CacheStoreFactory, sources: Seq[File], log: Logger)(implicit - formatter: Formatter): Unit = { + formatter: Formatter, + googleFormatter: GoogleFormatter, + palantirFormatter: PalantirFormatter): Unit = { trackSourcesViaCache(cacheStoreFactory, sources) { (outDiff, prev) => log.debug(outDiff.toString) val updatedOrAdded = outDiff.modified & outDiff.checked @@ -117,7 +144,10 @@ object JavaFormatter { } } - private def formatSources(sources: Set[File], log: Logger)(implicit formatter: Formatter): Unit = { + private def formatSources(sources: Set[File], log: Logger)(implicit + formatter: Formatter, + googleFormatter: GoogleFormatter, + palantirFormatter: PalantirFormatter): Unit = { val cnt = withFormattedSources(sources.toList, log)((file, input, output) => { if (input != output) { IO.write(file, output) @@ -142,11 +172,16 @@ object JavaFormatter { } private def withFormattedSources[T](sources: Seq[File], log: Logger)(onFormat: (File, String, String) => T)(implicit - formatter: Formatter): Seq[Option[T]] = { + formatter: Formatter, + googleFormatter: GoogleFormatter, + palantirFormatter: PalantirFormatter): Seq[Option[T]] = { sources.map { file => val input = IO.read(file) try { - val output = formatter.formatSourceAndFixImports(input) + val output = formatter match { + case Formatter.PALANTIR => palantirFormatter.formatSourceAndFixImports(input) + case _ => googleFormatter.formatSourceAndFixImports(input) + } Some(onFormat(file, input, output)) } catch { case e: Exception => Some(onFormat(file, input, input)) diff --git a/plugin/src/sbt-test/sbt-java-formatter/palantir-style/build.sbt b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/build.sbt new file mode 100644 index 0000000..d32cfae --- /dev/null +++ b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/build.sbt @@ -0,0 +1,5 @@ +import com.github.sbt.javaformatter.Formatter +// no settings needed + +ThisBuild / javafmtFormatter := Formatter.PALANTIR +ThisBuild / javafmtOnCompile := true diff --git a/plugin/src/sbt-test/sbt-java-formatter/palantir-style/project/plugins.sbt b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/project/plugins.sbt new file mode 100644 index 0000000..7ef9c15 --- /dev/null +++ b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.github.sbt" % "sbt-java-formatter" % System.getProperty("plugin.version")) diff --git a/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/main/java-expected/com/lightbend/BadFormatting.java b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/main/java-expected/com/lightbend/BadFormatting.java new file mode 100644 index 0000000..4c57952 --- /dev/null +++ b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/main/java-expected/com/lightbend/BadFormatting.java @@ -0,0 +1,19 @@ +package com.lightbend; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class BadFormatting { + BadFormatting() { + example(); + } + + public void example() { + var a = List.of("", "a", "b", "c", "d").stream() + .filter(s -> !s.isEmpty()) + .map(s -> String.format("%s-%s-%s", s, s.toLowerCase(), s.toUpperCase())) + .map(Objects::toString) + .collect(Collectors.joining()); + } +} diff --git a/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/main/java/com/lightbend/BadFormatting.java b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/main/java/com/lightbend/BadFormatting.java new file mode 100644 index 0000000..94e7d05 --- /dev/null +++ b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/main/java/com/lightbend/BadFormatting.java @@ -0,0 +1,12 @@ +package com.lightbend; + +import java.util.stream.Collectors; +import java.util.Objects; +import java.util.List; + +public class BadFormatting { + BadFormatting () {example();} + public void example () { + var a = List.of("", "a", "b", "c", "d").stream().filter(s -> !s.isEmpty()).map(s -> String.format("%s-%s-%s", s, s.toLowerCase(), s.toUpperCase())).map(Objects::toString).collect(Collectors.joining()); + } +} diff --git a/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/test/java-expected/com/lightbend/BadFormatting.java b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/test/java-expected/com/lightbend/BadFormatting.java new file mode 100644 index 0000000..4c57952 --- /dev/null +++ b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/test/java-expected/com/lightbend/BadFormatting.java @@ -0,0 +1,19 @@ +package com.lightbend; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class BadFormatting { + BadFormatting() { + example(); + } + + public void example() { + var a = List.of("", "a", "b", "c", "d").stream() + .filter(s -> !s.isEmpty()) + .map(s -> String.format("%s-%s-%s", s, s.toLowerCase(), s.toUpperCase())) + .map(Objects::toString) + .collect(Collectors.joining()); + } +} diff --git a/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/test/java/com/lightbend/BadFormatting.java b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/test/java/com/lightbend/BadFormatting.java new file mode 100644 index 0000000..94e7d05 --- /dev/null +++ b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/src/test/java/com/lightbend/BadFormatting.java @@ -0,0 +1,12 @@ +package com.lightbend; + +import java.util.stream.Collectors; +import java.util.Objects; +import java.util.List; + +public class BadFormatting { + BadFormatting () {example();} + public void example () { + var a = List.of("", "a", "b", "c", "d").stream().filter(s -> !s.isEmpty()).map(s -> String.format("%s-%s-%s", s, s.toLowerCase(), s.toUpperCase())).map(Objects::toString).collect(Collectors.joining()); + } +} diff --git a/plugin/src/sbt-test/sbt-java-formatter/palantir-style/test b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/test new file mode 100644 index 0000000..20edd74 --- /dev/null +++ b/plugin/src/sbt-test/sbt-java-formatter/palantir-style/test @@ -0,0 +1,12 @@ +# compile should trigger formatting +> Test/compile + +#$ exec echo "====== FORMATTED ======" +#$ exec cat src/main/java/com/lightbend/BadFormatting.java +#$ exec echo "====== EXPECTED ======" +#$ exec cat src/main/java-expected/com/lightbend/BadFormatting.java + +#$ exec echo "====== DIFF ======" +$ exec diff src/main/java/com/lightbend/BadFormatting.java src/main/java-expected/com/lightbend/BadFormatting.java + +$ exec diff src/test/java/com/lightbend/BadFormatting.java src/test/java-expected/com/lightbend/BadFormatting.java