From d6f6e188c426227adf58fc3afd065e24ed8e7424 Mon Sep 17 00:00:00 2001 From: Jacob Barber Date: Wed, 12 Jun 2019 14:48:04 -0400 Subject: [PATCH] Update for sbt 1.x --- build.sbt | 10 +-- project/build.properties | 2 +- project/plugins.sbt | 2 +- .../scala/com/dscleaver/sbt/SbtQuickFix.scala | 32 ++++--- .../sbt/quickfix/QuickFixAppender.scala | 84 +++++++++++++++++++ .../sbt/quickfix/QuickFixLogger.scala | 48 ----------- .../sbt/quickfix/QuickFixTestListener.scala | 6 +- .../sbt/quickfix/VimInteraction.scala | 2 +- .../dscleaver/sbt/quickfix/VimPlugin.scala | 4 +- 9 files changed, 117 insertions(+), 73 deletions(-) create mode 100644 src/main/scala/com/dscleaver/sbt/quickfix/QuickFixAppender.scala delete mode 100644 src/main/scala/com/dscleaver/sbt/quickfix/QuickFixLogger.scala diff --git a/build.sbt b/build.sbt index 7942484..58e7832 100644 --- a/build.sbt +++ b/build.sbt @@ -4,7 +4,7 @@ name := "sbt-quickfix" organization := "com.dscleaver.sbt" -scalaVersion := "2.10.6" +scalaVersion := "2.12.8" licenses += ("BSD 3-Clause", url("https://opensource.org/licenses/BSD-3-Clause")) @@ -12,7 +12,7 @@ versionWithGit //version := "0.4.1-LOCAL" -git.baseVersion := "0.4.1" +git.baseVersion := "1.0.0" resolvers += "sonatype-releases" at "https://oss.sonatype.org/service/local/repositories/releases/content/" @@ -36,11 +36,11 @@ scalacOptions ++= Seq( publishMavenStyle := false libraryDependencies ++= Seq( - "org.scalatest" %% "scalatest" % "2.2.6" % "provided" + "org.scalatest" %% "scalatest" % "3.0.5" % "provided" ) -publishTo <<= (version) { v => +publishTo := { def scalasbt(repo: String) = ("scalasbt " + repo, "http://repo.scala-sbt.org/scalasbt/sbt-plugin-" + repo) - val (name, repo) = if (v.endsWith("-SNAPSHOT")) scalasbt("snapshots") else scalasbt("releases") + val (name, repo) = if (version.value.endsWith("-SNAPSHOT")) scalasbt("snapshots") else scalasbt("releases") Some(Resolver.url(name, url(repo))(Resolver.ivyStylePatterns)) } diff --git a/project/build.properties b/project/build.properties index 43b8278..c0bab04 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.11 +sbt.version=1.2.8 diff --git a/project/plugins.sbt b/project/plugins.sbt index b9c9161..6c59ac2 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ resolvers += "jgit-repo" at "http://download.eclipse.org/jgit/maven" -addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.6.2") +addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") diff --git a/src/main/scala/com/dscleaver/sbt/SbtQuickFix.scala b/src/main/scala/com/dscleaver/sbt/SbtQuickFix.scala index b34501c..8561fff 100644 --- a/src/main/scala/com/dscleaver/sbt/SbtQuickFix.scala +++ b/src/main/scala/com/dscleaver/sbt/SbtQuickFix.scala @@ -2,14 +2,15 @@ package com.dscleaver.sbt import sbt._ import Keys._ -import sbt.IO._ -import quickfix.{ QuickFixLogger, VimPlugin, QuickFixTestListener } +import quickfix.{ QuickFixAppender, VimPlugin, QuickFixTestListener } +import sbt.internal.util.ConsoleAppender object SbtQuickFix extends AutoPlugin { object QuickFixKeys { - val quickFixDirectory = target in config("quickfix") + val quickFixDirectory = SettingKey[File]("quickfix-directory", "The directory that the sbt.quickfix file will be placed in.") val quickFixInstall = TaskKey[Unit]("install-vim-plugin") + val quickFixIgnoreErrors = SettingKey[Boolean]("quickfix-ignore-errors", "If exceptions are thrown in the quickfix file writer, ignore them when this is true. (defaults to true)") val vimEnableServer = SettingKey[Boolean]("vim-enable-server", "Enables communication with the Vim server - requires that Vim has been compiled with +clientserver") val vimExecutable = SettingKey[String]("vim-executable", "The path to the vim executable, or just 'vim' if it's in the PATH already") val vimPluginBaseDirectory = SettingKey[File]("vim-plugin-directory", "The path where vim plugins should be installed") @@ -20,23 +21,30 @@ object SbtQuickFix extends AutoPlugin { override def trigger = allRequirements override val projectSettings = Seq( - quickFixDirectory <<= (target (_ / "quickfix")), + quickFixDirectory := (target (_ / "quickfix")).value, vimPluginBaseDirectory in ThisBuild := file(System.getProperty("user.home")) / ".vim" / "bundle", vimEnableServer in ThisBuild := true, - extraLoggers <<= (quickFixDirectory, extraLoggers, vimExecutable, vimEnableServer) apply { (target, currentFunction, vimExec, enableServer) => + quickFixIgnoreErrors in ThisBuild := true, + extraLoggers := { (key: ScopedKey[_]) => { - val loggers = currentFunction(key) + val loggers = extraLoggers.value(key) val taskOption = key.scope.task.toOption - if (taskOption.exists(_.label.startsWith("compile"))) - new QuickFixLogger(target / "sbt.quickfix", vimExec, enableServer) +: loggers + if (taskOption.exists(_.label.startsWith("compile"))) { + val appender = new QuickFixAppender( + quickFixDirectory.value / "sbt.quickfix", + vimExecutable.value, vimEnableServer.value, + quickFixIgnoreErrors.value, + ConsoleAppender("sbt-vim-quickfix-error") + ) + + appender +: loggers + } else loggers } }, - testListeners <+= (quickFixDirectory, sources in Test, vimExecutable, vimEnableServer) map { (target, testSources, vimExec, enableServer) => - QuickFixTestListener(target / "sbt.quickfix", testSources, vimExec, enableServer) - }, - quickFixInstall in ThisBuild <<= (vimPluginBaseDirectory, streams) map VimPlugin.install, + testListeners += QuickFixTestListener(quickFixDirectory.value / "sbt.quickfix", (sources in Test).value, vimExecutable.value, vimEnableServer.value), + quickFixInstall in ThisBuild := VimPlugin.install(vimPluginBaseDirectory.value, streams.value), vimExecutable in ThisBuild := (if (System.getProperty("os.name").startsWith("Win")) "gvim.bat" else "gvim") ) } diff --git a/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixAppender.scala b/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixAppender.scala new file mode 100644 index 0000000..671d888 --- /dev/null +++ b/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixAppender.scala @@ -0,0 +1,84 @@ +package com.dscleaver.sbt.quickfix + +import sbt.{Level => _, State => _, _} +import org.apache.logging.log4j.core.{ Appender, LogEvent } +import org.apache.logging.log4j.Level +import org.apache.logging.log4j.core.ErrorHandler +import org.apache.logging.log4j.core.Layout +import org.apache.logging.log4j.core.LifeCycle + +object QuickFixAppender { + def append(output: File, prefix: String, message: String): Unit = + IO.append(output, "[%s] %s\n".format(prefix, message)) + + def append(output: File, prefix: String, file: File, line: Int, message: String): Unit = + append(output, prefix, "%s:%d: %s".format(file, line, message)) +} + +class QuickFixAppender(val output: File, vimExec: String, ignoreExceptions: Boolean, enableServer: Boolean, errorAppender: Appender) extends Appender { + import VimInteraction._ + + var handler: ErrorHandler = errorAppender.getHandler() + + override def getHandler(): ErrorHandler = handler + override def getLayout(): Layout[_] = null + override def getName(): String = "sbt-vim-quickfix" + override def ignoreExceptions(): Boolean = ignoreExceptions + override def setHandler(eh: ErrorHandler): Unit = handler = eh + override def getState(): LifeCycle.State = LifeCycle.State.STARTED + override def initialize(): Unit = {} + override def isStarted(): Boolean = true + override def isStopped(): Boolean = false + override def start(): Unit = {} + override def stop(): Unit = {} + + override def append(event: LogEvent): Unit = log( + event.getLevel(), + event.getMessage().getFormattedMessage() + ) + + // New messages have a weird format: + // [error] ObjectEvent(error, [Error] /Users/jacobbarber/projects/sbt-quickfix/src/main/scala/com/dscleaver/sbt/SbtQuickFix.scala:37: not found: value CasonsoleAppender, Some(console0), Some(a0cfcd86-16e3-4b94-997d-3561d8e399d4), xsbti.Problem, JObject([Lsjsonnew.shaded.scalajson.ast.unsafe.JField;@74df44fc)) + // [error] ObjectEvent(error, [Error] /Users/jacobbarber/projects/sbt-quickfix/src/main/scala/com/dscleaver/sbt/SbtQuickFix.scala:6: Unused import, Some(console0), Some(a0cfcd86-16e3-4b94-997d-3561d8e399d4), xsbti.Problem, JObject([Lsjsonnew.shaded.scalajson.ast.unsafe.JField;@2f7b4be1)) + // [error] StringEvent(error, two errors found, Some(console0), Some(a0cfcd86-16e3-4b94-997d-3561d8e399d4)) + // [error] StringEvent(error, (Compile / compileIncremental) Compilation failed, Some(console0), Some(a0cfcd86-16e3-4b94-997d-3561d8e399d4)) + // + // so we need to parse them first, and remove the stuff we don't care about. + // The parsing I'm doing below should be sufficient for most cases. + + def log(level: Level, message: String): Unit = { + val parsedMessage = + if(message.startsWith("StringEvent") || message.startsWith("ObjectEvent")) + message + .split(",") + .drop(1).head + .replaceAll("\\[(Error|Info|Warn|Debug)\\]", "") + .trim() + else + message + + level match { + case Level.INFO => handleInfoMessage(parsedMessage) + case Level.ERROR => handleErrorMessage(parsedMessage) + case Level.WARN => handleWarnMessage(parsedMessage) + case _ => handleDebugMessage(parsedMessage) + } + } + + def handleDebugMessage(message: String): Unit = + if (enableServer && message.toLowerCase.contains("compilation failed")) { + val _ = call(vimExec, ":cfile %s".format(output.toString)) + } + + def handleInfoMessage(message: String): Unit = { + if(message startsWith "Compiling") { + IO.delete(output) + IO.touch(List(output)) + } else () + } + + + def handleErrorMessage(message: String): Unit = QuickFixAppender.append(output, "error", message) + + def handleWarnMessage(message: String): Unit = QuickFixAppender.append(output, "warn", message) +} diff --git a/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixLogger.scala b/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixLogger.scala deleted file mode 100644 index 58b5b68..0000000 --- a/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixLogger.scala +++ /dev/null @@ -1,48 +0,0 @@ -package com.dscleaver.sbt.quickfix - -import sbt._ - -object QuickFixLogger { - def append(output: File, prefix: String, message: String): Unit = - IO.append(output, "[%s] %s\n".format(prefix, message)) - - def append(output: File, prefix: String, file: File, line: Int, message: String): Unit = - append(output, prefix, "%s:%d: %s".format(file, line, message)) -} - -class QuickFixLogger(val output: File, vimExec: String, enableServer: Boolean) extends BasicLogger { - import QuickFixLogger._ - import VimInteraction._ - - def log(level: Level.Value, message: => String): Unit = level match { - case Level.Info => handleInfoMessage(message) - case Level.Error => handleErrorMessage(message) - case Level.Warn => handleWarnMessage(message) - case _ => handleDebugMessage(message) - } - - def handleDebugMessage(message: String): Unit = - if (enableServer && message.toLowerCase.contains("compilation failed")) { - val _ = call(vimExec, ":cfile %s".format(output.toString)) - } - - def handleInfoMessage(message: String): Unit = { - if(message startsWith "Compiling") { - IO.delete(output) - IO.touch(List(output)) - } else () - } - - def handleErrorMessage(message: String): Unit = append(output, "error", message) - - def handleWarnMessage(message: String): Unit = append(output, "warn", message) - - def control(event: ControlEvent.Value, message: => String): Unit = () - - def logAll(events: Seq[LogEvent]): Unit = () - - def success(message: => String): Unit = () - - def trace(t: => Throwable): Unit = () - -} diff --git a/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixTestListener.scala b/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixTestListener.scala index ff610ee..04e447c 100644 --- a/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixTestListener.scala +++ b/src/main/scala/com/dscleaver/sbt/quickfix/QuickFixTestListener.scala @@ -3,12 +3,12 @@ package com.dscleaver.sbt.quickfix import org.scalatest.exceptions.StackDepth import scala.util.control.NonFatal import sbt._ -import sbt.TestResult.Value +import sbt.protocol.testing.TestResult import sbt.testing.Status._ import sbt.testing.Event class QuickFixTestListener(output: File, srcFiles: => Seq[File], vimExec: String, enableServer: Boolean) extends TestReportListener { - import QuickFixLogger._ + import QuickFixAppender._ import VimInteraction._ IO.delete(output) @@ -25,7 +25,7 @@ class QuickFixTestListener(output: File, srcFiles: => Seq[File], vimExec: String def endGroup(name: String, t: Throwable): Unit = {} - def endGroup(name: String, v: Value): Unit = {} + def endGroup(name: String, v: TestResult): Unit = {} def writeFailure(event: TestEvent): Unit = for { diff --git a/src/main/scala/com/dscleaver/sbt/quickfix/VimInteraction.scala b/src/main/scala/com/dscleaver/sbt/quickfix/VimInteraction.scala index 7197499..dbde578 100644 --- a/src/main/scala/com/dscleaver/sbt/quickfix/VimInteraction.scala +++ b/src/main/scala/com/dscleaver/sbt/quickfix/VimInteraction.scala @@ -1,6 +1,6 @@ package com.dscleaver.sbt.quickfix -import sbt._ +import scala.sys.process._ object VimInteraction { def call(vimExec: String, command: Seq[String]): Int = Process(List(vimExec, "--remote-send") ++ command).! diff --git a/src/main/scala/com/dscleaver/sbt/quickfix/VimPlugin.scala b/src/main/scala/com/dscleaver/sbt/quickfix/VimPlugin.scala index 56e5815..edd32a4 100644 --- a/src/main/scala/com/dscleaver/sbt/quickfix/VimPlugin.scala +++ b/src/main/scala/com/dscleaver/sbt/quickfix/VimPlugin.scala @@ -13,7 +13,7 @@ object VimPlugin { } s.log.info("Installing to " + plugin) IO.createDirectory(plugin) - val jar = IO.classLocationFile[VimPlugin.type] - val files = IO.unzip(jar, baseDirectory, "vim-sbt/*") + val jar = IO.classLocationFileOption[VimPlugin.type].get + val _ = IO.unzip(jar, baseDirectory, "vim-sbt/*") } }