aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/scalafmt-example/README.md16
-rw-r--r--examples/scalafmt-example/build/build.scala29
-rw-r--r--examples/scalafmt-example/build/build/build.scala5
-rw-r--r--examples/scalafmt-example/resources/reference.conf8
-rw-r--r--examples/scalafmt-example/src/Main.scala16
-rw-r--r--examples/scalariform-example/README.md15
-rw-r--r--examples/scalariform-example/build/build.scala10
-rw-r--r--plugins/scalafmt/Scalafmt.scala69
-rw-r--r--plugins/scalafmt/build/build.scala9
-rw-r--r--plugins/scalariform/Scalariform.scala9
-rw-r--r--stage1/logger.scala38
-rw-r--r--stage2/BuildBuild.scala1
-rw-r--r--test/test.scala4
13 files changed, 199 insertions, 30 deletions
diff --git a/examples/scalafmt-example/README.md b/examples/scalafmt-example/README.md
new file mode 100644
index 0000000..0a59f96
--- /dev/null
+++ b/examples/scalafmt-example/README.md
@@ -0,0 +1,16 @@
+This example shows integration with scalafmt plugin.
+
+Reformat executed on every `cbt compile` call, and affects only *.scala source files.
+
+You can provide your custom scalfmt preferences in build via `scalafmtConfig`.
+
+To see formatting in action: execute `cbt breakFormatting` to break formatting and then execute`cbt scalafmt` to get formatting back.
+
+To check if your code is properly formatted(for example as part of CI validation), you can execute:
+
+```
+cbt scalafmt
+git diff --exit-code
+```
+
+Last command will return non-zero code, if your code isn't properly formatted.
diff --git a/examples/scalafmt-example/build/build.scala b/examples/scalafmt-example/build/build.scala
new file mode 100644
index 0000000..6f77108
--- /dev/null
+++ b/examples/scalafmt-example/build/build.scala
@@ -0,0 +1,29 @@
+import cbt._
+import org.scalafmt.ScalafmtStyle
+
+class Build(val context: Context) extends BuildBuild with Scalafmt {
+ override def compile = {
+ scalafmt
+ super.compile
+ }
+
+ override def scalafmtConfig: ScalafmtStyle = ScalafmtStyle.defaultWithAlign
+
+ def breakFormatting = {
+ import java.nio.file._
+ import java.nio.charset.Charset
+ import scala.collection.JavaConverters._
+ val utf8 = Charset.forName("UTF-8")
+ sourceFiles foreach { file =>
+ try {
+ val path = file.toPath
+ val fileLines = Files.readAllLines(path, utf8).asScala
+ val brokenLines = fileLines map (_.dropWhile(_ ==' '))
+ Files.write(path, brokenLines.asJava, utf8)
+ } catch {
+ case e: Exception => System.err.print(s"Error happend when breaking formatting: ${e}")
+ }
+ }
+ System.err.println("Done breaking formatting")
+ }
+}
diff --git a/examples/scalafmt-example/build/build/build.scala b/examples/scalafmt-example/build/build/build.scala
new file mode 100644
index 0000000..aa70f36
--- /dev/null
+++ b/examples/scalafmt-example/build/build/build.scala
@@ -0,0 +1,5 @@
+import cbt._
+
+class Build(val context: Context) extends BuildBuild {
+ override def dependencies = super.dependencies :+ plugins.scalafmt
+}
diff --git a/examples/scalafmt-example/resources/reference.conf b/examples/scalafmt-example/resources/reference.conf
new file mode 100644
index 0000000..f3e122d
--- /dev/null
+++ b/examples/scalafmt-example/resources/reference.conf
@@ -0,0 +1,8 @@
+// should not reformat this, cause it is not in source files
+some {
+ inside {
+ foo: 22
+ bar: false
+ baz: "hello"
+ }
+}
diff --git a/examples/scalafmt-example/src/Main.scala b/examples/scalafmt-example/src/Main.scala
new file mode 100644
index 0000000..595cede
--- /dev/null
+++ b/examples/scalafmt-example/src/Main.scala
@@ -0,0 +1,16 @@
+import scala.concurrent.{Await, Future}
+import scala.concurrent.duration._
+
+object Main extends App {
+ println("fooo")
+ val futureRes = Await.result(Future.successful(1), 5.seconds)
+ List(1, 2, 4, 5, 6) match {
+ case h :: _ => println("not empty list")
+ case Nil => println("empty list")
+ }
+
+ List(1 -> 2, 2 -> 3, 3 -> 4) match {
+ case (1, 2) :: _ => 90 -> 1
+ case (22, 44) :: _ => 1 -> 150
+ }
+}
diff --git a/examples/scalariform-example/README.md b/examples/scalariform-example/README.md
index e599b5b..28ad226 100644
--- a/examples/scalariform-example/README.md
+++ b/examples/scalariform-example/README.md
@@ -1,5 +1,16 @@
This example shows integration with scalariform plugin.
+
Reformat executed on every `cbt compile` call, and affects only *.scala source files.
+
You can provide your custom scalariform preferences in build via `scalariformPreferences`.
-To test formatting in action you can execute: `cbt breakFormatting` to break formatting
-and `cbt scalariformReformat` to get formatting back.
+
+To see formatting in action: execute `cbt breakFormatting` to break formatting and then execute `cbt scalariformFormat` to get formatting back.
+
+To check if your code is properly formatted(for example as part of CI validation), you can execute:
+
+```
+cbt scalariformFormat
+git diff --exit-code
+```
+
+Last command will return non-zero code, if your code isn't properly formatted.
diff --git a/examples/scalariform-example/build/build.scala b/examples/scalariform-example/build/build.scala
index b9caa59..5f7b7ff 100644
--- a/examples/scalariform-example/build/build.scala
+++ b/examples/scalariform-example/build/build.scala
@@ -1,7 +1,7 @@
import cbt._
import scalariform.formatter.preferences._
-class Build(val context: Context) extends BuildBuild with Scalariform {
+class Build(val context: Context) extends BaseBuild with Scalariform {
override def compile = {
scalariformFormat
super.compile
@@ -13,15 +13,17 @@ class Build(val context: Context) extends BuildBuild with Scalariform {
.setPreference(DoubleIndentClassDeclaration, true)
.setPreference(RewriteArrowSymbols, true)
- def breakFormatting = {
+ final def breakFormatting = {
import java.nio.file._
+ import java.nio.charset.Charset
import scala.collection.JavaConverters._
+ val utf8 = Charset.forName("UTF-8")
sourceFiles foreach { file =>
try {
val path = file.toPath
- val fileLines = Files.readAllLines(path).asScala
+ val fileLines = Files.readAllLines(path, utf8).asScala
val brokenLines = fileLines map (_.dropWhile(_ ==' '))
- Files.write(path, brokenLines.asJava)
+ Files.write(path, brokenLines.asJava, utf8)
} catch {
case e: Exception => System.err.print(s"Error happend when breaking formatting: ${e}")
}
diff --git a/plugins/scalafmt/Scalafmt.scala b/plugins/scalafmt/Scalafmt.scala
new file mode 100644
index 0000000..94670cb
--- /dev/null
+++ b/plugins/scalafmt/Scalafmt.scala
@@ -0,0 +1,69 @@
+package cbt
+
+import org.scalafmt.{FormatResult, ScalafmtStyle}
+
+import java.io.File
+import java.nio.file.Files._
+import java.nio.file.{FileSystems, Path}
+
+/**
+ * This plugin provides scalafmt support for cbt.
+ *
+ */
+trait Scalafmt extends BaseBuild {
+ /**
+ * Reformat scala source code according to `scalafmtConfig` rules
+ *
+ * @return always returns `ExitCode.Success`
+ */
+ final def scalafmt: ExitCode = {
+ Scalafmt.format(sourceFiles, scalafmtConfig)
+ ExitCode.Success
+ }
+
+ /**
+ * Scalafmt formatting config
+ */
+ def scalafmtConfig: ScalafmtStyle = Scalafmt.defaultConfig
+}
+
+object Scalafmt {
+
+ val defaultConfig = ScalafmtStyle.default
+
+ def format(files: Seq[File], style: ScalafmtStyle): Unit = {
+ var reformattedCount: Int = 0
+ scalaSourceFiles(files) foreach { path =>
+ handleFormatted(path, style) { case (original, result) =>
+ result match {
+ case FormatResult.Success(formatted) =>
+ if (original != formatted) {
+ write(path, formatted.getBytes)
+ reformattedCount += 1
+ }
+ case FormatResult.Failure(e) =>
+ System.err.println(s"Failed to format file: $path, cause: ${e}")
+ case FormatResult.Incomplete(e) =>
+ System.err.println(s"Couldn't complete file reformat: $path")
+ }
+ }
+ }
+ if (reformattedCount > 0) System.err.println(s"Formatted $reformattedCount Scala sources")
+ }
+
+ private val scalaFileMatcher = FileSystems.getDefault.getPathMatcher("glob:**.scala")
+
+ private def scalaSourceFiles(files: Seq[File]): Seq[Path] = {
+ files collect {
+ case f if f.exists
+ && scalaFileMatcher.matches(f.toPath) => f.toPath
+ }
+ }
+
+ private def handleFormatted[T](path: Path, style: ScalafmtStyle)(handler: (String, FormatResult) => T): T = {
+ val original = new String(readAllBytes(path))
+ val result = org.scalafmt.Scalafmt.format(original, style)
+ handler(original, result)
+ }
+
+}
diff --git a/plugins/scalafmt/build/build.scala b/plugins/scalafmt/build/build.scala
new file mode 100644
index 0000000..e8ce270
--- /dev/null
+++ b/plugins/scalafmt/build/build.scala
@@ -0,0 +1,9 @@
+import cbt._
+
+class Build(val context: Context) extends Plugin {
+ override def dependencies =
+ super.dependencies ++
+ Resolver( mavenCentral ).bind(
+ ScalaDependency("com.geirsson", "scalafmt", "0.2.5")
+ )
+}
diff --git a/plugins/scalariform/Scalariform.scala b/plugins/scalariform/Scalariform.scala
index 1f6e51f..0612469 100644
--- a/plugins/scalariform/Scalariform.scala
+++ b/plugins/scalariform/Scalariform.scala
@@ -4,13 +4,12 @@ import java.io.File
import java.nio.file.FileSystems
import java.nio.file.Files._
-import scala.util.Try
import scalariform.formatter.ScalaFormatter
import scalariform.formatter.preferences.FormattingPreferences
import scalariform.parser.ScalaParserException
trait Scalariform extends BaseBuild {
- def scalariformFormat: ExitCode = {
+ final def scalariformFormat: ExitCode = {
Scalariform.format(sourceFiles, scalariformPreferences, scalaVersion)
ExitCode.Success
}
@@ -35,7 +34,7 @@ object Scalariform {
private val scalaFileMatcher = FileSystems.getDefault.getPathMatcher("glob:**.scala")
- def format(files: Seq[File], preferences: FormattingPreferences, scalaVersion: String) = {
+ def format(files: Seq[File], preferences: FormattingPreferences, scalaVersion: String): Unit = {
var reformattedCount: Int = 0
for (file <- files if file.exists) {
val path = file.toPath
@@ -52,11 +51,11 @@ object Scalariform {
reformattedCount += 1
}
} catch {
- case e: ScalaParserException => System.err.println(s"Scalariform parser error: ${e.getMessage} when formatting source: $file")
+ case e: ScalaParserException => System.err.println(s"Scalariform parser error: ${e.getMessage} when formatting: $file")
}
}
}
- System.err.println(s"Reformatted $reformattedCount Scala sources")
+ if (reformattedCount > 0) System.err.println(s"Formatted $reformattedCount Scala sources")
}
}
diff --git a/stage1/logger.scala b/stage1/logger.scala
index 1e0a693..0b352a1 100644
--- a/stage1/logger.scala
+++ b/stage1/logger.scala
@@ -11,22 +11,26 @@ case class Logger(enabledLoggers: Set[String], start: Long) {
def this(enabledLoggers: Option[String], start: Long) = this( enabledLoggers.toVector.flatMap( _.split(",") ).toSet, start )
def log(name: String, msg: => String) = {
- val timeTaken = ((System.currentTimeMillis.toDouble - start) / 1000).toString
- System.err.println( s"[$timeTaken][$name] $msg" )
+ if(
+ (enabledLoggers contains name)
+ || (enabledLoggers contains "all")
+ ){
+ logUnguarded(name, msg)
+ }
}
def showInvocation(method: String, args: Any) = method ++ "( " ++ args.toString ++ " )"
- final def stage1(msg: => String) = logGuarded(names.stage1, msg)
- final def stage2(msg: => String) = logGuarded(names.stage2, msg)
- final def loop(msg: => String) = logGuarded(names.loop, msg)
- final def task(msg: => String) = logGuarded(names.task, msg)
- final def composition(msg: => String) = logGuarded(names.composition, msg)
- final def resolver(msg: => String) = logGuarded(names.resolver, msg)
- final def lib(msg: => String) = logGuarded(names.lib, msg)
- final def test(msg: => String) = logGuarded(names.test, msg)
- final def git(msg: => String) = logGuarded(names.git, msg)
- final def pom(msg: => String) = logGuarded(names.pom, msg)
+ final def stage1(msg: => String) = log(names.stage1, msg)
+ final def stage2(msg: => String) = log(names.stage2, msg)
+ final def loop(msg: => String) = log(names.loop, msg)
+ final def task(msg: => String) = log(names.task, msg)
+ final def composition(msg: => String) = log(names.composition, msg)
+ final def resolver(msg: => String) = log(names.resolver, msg)
+ final def lib(msg: => String) = log(names.lib, msg)
+ final def test(msg: => String) = log(names.test, msg)
+ final def git(msg: => String) = log(names.git, msg)
+ final def pom(msg: => String) = log(names.pom, msg)
private object names{
val stage1 = "stage1"
@@ -41,12 +45,8 @@ case class Logger(enabledLoggers: Set[String], start: Long) {
val git = "git"
}
- private def logGuarded(name: String, msg: => String) = {
- if(
- (enabledLoggers contains name)
- || (enabledLoggers contains "all")
- ){
- log(name, msg)
- }
+ private def logUnguarded(name: String, msg: => String) = {
+ val timeTaken = ((System.currentTimeMillis.toDouble - start) / 1000).toString
+ System.err.println( s"[$timeTaken][$name] $msg" )
}
}
diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala
index 83ea7ec..dec438b 100644
--- a/stage2/BuildBuild.scala
+++ b/stage2/BuildBuild.scala
@@ -12,6 +12,7 @@ trait BuildBuild extends BaseBuild{
final val sbtLayout = DirectoryDependency( managedContext.cbtHome ++ "/plugins/sbt_layout" )
final val scalaJs = DirectoryDependency( managedContext.cbtHome ++ "/plugins/scalajs" )
final val scalariform = DirectoryDependency( managedContext.cbtHome ++ "/plugins/scalariform" )
+ final val scalafmt = DirectoryDependency( managedContext.cbtHome ++ "/plugins/scalafmt" )
}
override def dependencies =
diff --git a/test/test.scala b/test/test.scala
index 050be1f..4ed7e97 100644
--- a/test/test.scala
+++ b/test/test.scala
@@ -158,8 +158,12 @@ object Main{
compile("simple-fixed")
compile("../plugins/sbt_layout")
+ compile("../plugins/scalafmt")
compile("../plugins/scalajs")
+ compile("../plugins/scalariform")
compile("../plugins/scalatest")
+ compile("../examples/scalafmt-example")
+ compile("../examples/scalariform-example")
compile("../examples/scalatest-example")
compile("../examples/scalajs-react-example/js")
compile("../examples/scalajs-react-example/jvm")