From 0f299d09a8878077642d1981613694013310da2e Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Fri, 16 Oct 2020 21:15:54 +0200 Subject: [PATCH 1/4] Update utest to version 0.7.5 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 6ee7fb8..bc104b7 100644 --- a/build.sbt +++ b/build.sbt @@ -8,7 +8,7 @@ enablePlugins(SbtPlugin) scalaVersion in ThisBuild := "2.12.8" // utest -libraryDependencies += "com.lihaoyi" %% "utest" % "0.7.4" % Test +libraryDependencies += "com.lihaoyi" %% "utest" % "0.7.5" % Test testFrameworks += new TestFramework("utest.runner.Framework") bintrayPackageLabels := Seq("sbt","plugin") From afa227a41557a123ab901c2ab0a5724d724ad9a5 Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Fri, 16 Oct 2020 21:16:34 +0200 Subject: [PATCH 2/4] Update sbt to version 1.2.8 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 72f9028..c0bab04 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.7 +sbt.version=1.2.8 From deed23e49ec4d5668bac02e1cce0b460dcdde016 Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Fri, 16 Oct 2020 21:19:56 +0200 Subject: [PATCH 3/4] Update sbt-bintray to version 0.5.6 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 47ae1f3..7a85042 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ -addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.4") +addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6") addSbtPlugin("com.dwijnand" % "sbt-dynver" % "3.0.0") From 57e957fda3ddd6eb8ab0dd2b4dd790a8367c66b8 Mon Sep 17 00:00:00 2001 From: Claudio Bley Date: Fri, 16 Oct 2020 21:24:19 +0200 Subject: [PATCH 4/4] Fix `NoSuchMethodError` due to internal API breakage in sbt >= 1.4 Using runtime reflection, we can avoid having the concrete prototype of the `defaultScreen` and `withScreenLogger` methods encoded in byte code. --- .../scala/sbthyperlink/HyperlinkPlugin.scala | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/scala/sbthyperlink/HyperlinkPlugin.scala b/src/main/scala/sbthyperlink/HyperlinkPlugin.scala index 79c1a02..a00df11 100644 --- a/src/main/scala/sbthyperlink/HyperlinkPlugin.scala +++ b/src/main/scala/sbthyperlink/HyperlinkPlugin.scala @@ -6,7 +6,7 @@ import sbt.{ Def, _ } import sbt.Keys._ import sbt.plugins.CorePlugin import sbt.internal._ -import sbt.internal.util.MainAppender._ +import sbt.internal.util.MainAppender import sbt.internal.util.ConsoleAppender import scala.util.matching.Regex @@ -84,10 +84,30 @@ object HyperlinkPlugin extends AutoPlugin { hyperlinkRegex := Default.regex(baseDirectory.value), hyperlinkAction := FileAction, logManager := { - LogManager.withScreenLogger { + // we use internal sbt APIs, which are incompatible between < 1.4 and >= 1.4 + // see https://github.com/sbt/sbt/issues/5931 and https://github.com/sbt/sbt/pull/5731 + // work-around using reflection + import scala.reflect.runtime.{ universe => ru } + + val mirror = ru.runtimeMirror(getClass.getClassLoader) + val mainAppenderType = mirror.typeOf[MainAppender.type] + val mainAppenderModuleSymbol = mainAppenderType.termSymbol.asModule + val mainAppender = mirror.reflect(mirror.reflectModule(mainAppenderModuleSymbol).instance) + val defaultScreenMethodSymbol = + mainAppenderType.decl(ru.TermName("defaultScreen")).asTerm.alternatives.collectFirst { + case m if m.asMethod.paramLists.foldLeft(0)(_ + _.size) == 1 => m.asMethod + } + val defaultScreen = mainAppender.reflectMethod(defaultScreenMethodSymbol.get) + + val logManagerType = mirror.typeOf[LogManager.type] + val logManagerModuleSymbol = logManagerType.termSymbol.asModule + val logManager = mirror.reflect(mirror.reflectModule(logManagerModuleSymbol).instance) + val withScreenLoggerMethodSymbol = logManagerType.decl(ru.TermName("withScreenLogger")).asMethod + val withScreenLogger = logManager.reflectMethod(withScreenLoggerMethodSymbol) + + withScreenLogger({ (_: ScopedKey[_], state: State) ⇒ val extracted = Project.extract(state) - val basedir = extracted.get(baseDirectory) val action: HyperlinkAction = extracted.get(hyperlinkAction) val regex: Regex = extracted.get(hyperlinkRegex) @@ -100,7 +120,7 @@ object HyperlinkPlugin extends AutoPlugin { override def print(s: String): Unit = super.print(filter(s)) })) - } + }).asInstanceOf[LogManager] } ) }