mirror of https://github.com/sbt/sbt.git
Merge pull request #6246 from eed3si9n/wip/2.13-pre1
Port XMainConfiguration to Java
This commit is contained in:
commit
cb4c1e7100
|
|
@ -17,6 +17,7 @@ ThisBuild / Test / scalafmtOnCompile := !(Global / insideCI).value
|
|||
ThisBuild / turbo := true
|
||||
ThisBuild / usePipelining := false // !(Global / insideCI).value
|
||||
|
||||
Global / semanticdbEnabled := !(Global / insideCI).value
|
||||
val excludeLint = SettingKey[Set[Def.KeyedInitialize[_]]]("excludeLintKeys")
|
||||
Global / excludeLint := (Global / excludeLint).?.value.getOrElse(Set.empty)
|
||||
Global / excludeLint += componentID
|
||||
|
|
@ -1029,7 +1030,11 @@ lazy val mainProj = (project in file("main"))
|
|||
// internal logging apis,
|
||||
exclude[IncompatibleSignatureProblem]("sbt.internal.LogManager*"),
|
||||
exclude[MissingTypesProblem]("sbt.internal.RelayAppender"),
|
||||
exclude[MissingClassProblem]("sbt.internal.TaskProgress$ProgressThread")
|
||||
exclude[MissingClassProblem]("sbt.internal.TaskProgress$ProgressThread"),
|
||||
// internal implementation
|
||||
exclude[MissingClassProblem](
|
||||
"sbt.internal.XMainConfiguration$ModifiedConfiguration$ModifiedAppProvider$ModifiedScalaProvider$"
|
||||
),
|
||||
)
|
||||
)
|
||||
.configure(
|
||||
|
|
@ -1317,6 +1322,7 @@ def runNpm(command: String, base: File, log: sbt.internal.util.ManagedLogger) =
|
|||
|
||||
lazy val vscodePlugin = (project in file("vscode-sbt-scala"))
|
||||
.settings(
|
||||
bspEnabled := false,
|
||||
crossPaths := false,
|
||||
crossScalaVersions := Seq(baseScalaVersion),
|
||||
skip in publish := true,
|
||||
|
|
|
|||
|
|
@ -33,32 +33,32 @@ object InputWrapper {
|
|||
@compileTimeOnly(
|
||||
"`value` can only be called on a task within a task definition macro, such as :=, +=, ++=, or Def.task."
|
||||
)
|
||||
def wrapTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
def `wrapTask_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be used within a task or setting macro, such as :=, +=, ++=, Def.task, or Def.setting."
|
||||
)
|
||||
def wrapInit_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
def `wrapInit_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be called on a task within a task definition macro, such as :=, +=, ++=, or Def.task."
|
||||
)
|
||||
def wrapInitTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
def `wrapInitTask_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be called on an input task within a task definition macro, such as := or Def.inputTask."
|
||||
)
|
||||
def wrapInputTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
def `wrapInputTask_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`value` can only be called on an input task within a task definition macro, such as := or Def.inputTask."
|
||||
)
|
||||
def wrapInitInputTask_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
def `wrapInitInputTask_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
@compileTimeOnly(
|
||||
"`previous` can only be called on a task within a task or input task definition macro, such as :=, +=, ++=, Def.task, or Def.inputTask."
|
||||
)
|
||||
def wrapPrevious_\u2603\u2603[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
def `wrapPrevious_\u2603\u2603`[T](@deprecated("unused", "") in: Any): T = implDetailError
|
||||
|
||||
private[this] def implDetailError =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
|
@ -240,13 +240,13 @@ object ParserInput {
|
|||
@compileTimeOnly(
|
||||
"`parsed` can only be used within an input task macro, such as := or Def.inputTask."
|
||||
)
|
||||
def parser_\u2603\u2603[T](@deprecated("unused", "") i: Any): T =
|
||||
def `parser_\u2603\u2603`[T](@deprecated("unused", "") i: Any): T =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
||||
@compileTimeOnly(
|
||||
"`parsed` can only be used within an input task macro, such as := or Def.inputTask."
|
||||
)
|
||||
def initParser_\u2603\u2603[T](@deprecated("unused", "") i: Any): T =
|
||||
def `initParser_\u2603\u2603`[T](@deprecated("unused", "") i: Any): T =
|
||||
sys.error("This method is an implementation detail and should not be referenced.")
|
||||
|
||||
private[std] def wrap[T: c.WeakTypeTag](
|
||||
|
|
|
|||
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2018, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import xsbti.*;
|
||||
|
||||
/**
|
||||
* Generates a new app configuration and invokes xMainImpl.run. For AppConfigurations generated by
|
||||
* recent launchers, it is unnecessary to modify the original configuration, but configurations
|
||||
* generated by older launchers need to be modified to place the test interface jar higher in the
|
||||
* class hierarchy. The methods this object are implemented without using the scala library so that
|
||||
* we can avoid loading any classes from the old scala provider.
|
||||
*/
|
||||
public class XMainConfiguration {
|
||||
public xsbti.MainResult run(String moduleName, xsbti.AppConfiguration configuration) {
|
||||
try {
|
||||
ClassLoader topLoader = configuration.provider().scalaProvider().launcher().topLoader();
|
||||
xsbti.AppConfiguration updatedConfiguration = null;
|
||||
try {
|
||||
Method method = topLoader.getClass().getMethod("getJLineJars");
|
||||
URL[] jars = (URL[]) method.invoke(topLoader);
|
||||
boolean canReuseConfiguration = jars.length == 3;
|
||||
int j = 0;
|
||||
while (j < jars.length && canReuseConfiguration) {
|
||||
String s = jars[j].toString();
|
||||
canReuseConfiguration = s.contains("jline") || s.contains("jansi");
|
||||
j += 1;
|
||||
}
|
||||
if (canReuseConfiguration && j == 3) {
|
||||
updatedConfiguration = configuration;
|
||||
} else {
|
||||
updatedConfiguration = makeConfiguration(configuration);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
updatedConfiguration = makeConfiguration(configuration);
|
||||
}
|
||||
|
||||
ClassLoader loader = updatedConfiguration.provider().loader();
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
Class<?> clazz = loader.loadClass("sbt." + moduleName + "$");
|
||||
Object instance = clazz.getField("MODULE$").get(null);
|
||||
Method runMethod = clazz.getMethod("run", xsbti.AppConfiguration.class);
|
||||
try {
|
||||
Class<?> clw = loader.loadClass("sbt.internal.ClassLoaderWarmup$");
|
||||
clw.getMethod("warmup").invoke(clw.getField("MODULE$").get(null));
|
||||
return (xsbti.MainResult) runMethod.invoke(instance, updatedConfiguration);
|
||||
} catch (InvocationTargetException e) {
|
||||
// This propogates xsbti.FullReload to the launcher
|
||||
throw (xsbti.FullReload) e.getCause();
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private xsbti.AppConfiguration makeConfiguration(xsbti.AppConfiguration configuration) {
|
||||
try {
|
||||
ClassLoader baseLoader = XMainConfiguration.class.getClassLoader();
|
||||
String className = "sbt/internal/XMainConfiguration.class";
|
||||
URL url = baseLoader.getResource(className);
|
||||
String path = url.toString().replaceAll(className.concat("$"), "");
|
||||
URL[] urlArray = new URL[1];
|
||||
urlArray[0] = new URL(path);
|
||||
ClassLoader topLoader = configuration.provider().scalaProvider().launcher().topLoader();
|
||||
// This loader doesn't have the scala library in it so it's critical that none of the code
|
||||
// in this file use the scala library.
|
||||
ClassLoader modifiedLoader = new XMainClassLoader(urlArray, topLoader);
|
||||
Class<?> xMainConfigurationClass =
|
||||
modifiedLoader.loadClass("sbt.internal.XMainConfiguration");
|
||||
Object instance = (Object) xMainConfigurationClass.getConstructor().newInstance();
|
||||
Class<?> metaBuildLoaderClass = modifiedLoader.loadClass("sbt.internal.MetaBuildLoader");
|
||||
Method method = metaBuildLoaderClass.getMethod("makeLoader", AppProvider.class);
|
||||
|
||||
ClassLoader loader = (ClassLoader) method.invoke(null, configuration.provider());
|
||||
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
Class<?> modifiedConfigurationClass =
|
||||
modifiedLoader.loadClass("sbt.internal.XMainConfiguration$ModifiedConfiguration");
|
||||
Constructor<?> cons = modifiedConfigurationClass.getConstructors()[0];
|
||||
ClassLoaderClose.close(configuration.provider().loader());
|
||||
ScalaProvider scalaProvider = configuration.provider().scalaProvider();
|
||||
Class<? extends ScalaProvider> providerClass = scalaProvider.getClass();
|
||||
try {
|
||||
Method method2 = providerClass.getMethod("loaderLibraryOnly");
|
||||
ClassLoaderClose.close((ClassLoader) method2.invoke(scalaProvider));
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
ClassLoaderClose.close(scalaProvider.loader());
|
||||
ClassLoaderClose.close(configuration.provider().loader());
|
||||
return (xsbti.AppConfiguration) cons.newInstance(instance, configuration, loader);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Replaces the AppProvider.loader method with a new loader that puts the sbt test interface
|
||||
* jar ahead of the rest of the sbt classpath in the classloading hierarchy.
|
||||
*/
|
||||
public class ModifiedConfiguration implements xsbti.AppConfiguration {
|
||||
private xsbti.AppConfiguration configuration;
|
||||
private ClassLoader metaLoader;
|
||||
|
||||
public ModifiedConfiguration(xsbti.AppConfiguration configuration, ClassLoader metaLoader) {
|
||||
this.configuration = configuration;
|
||||
this.metaLoader = metaLoader;
|
||||
}
|
||||
|
||||
public class ModifiedAppProvider implements AppProvider {
|
||||
private AppProvider appProvider;
|
||||
private ScalaProvider instance;
|
||||
|
||||
public ModifiedAppProvider(AppProvider appProvider) throws ClassNotFoundException {
|
||||
this.appProvider = appProvider;
|
||||
ScalaProvider delegate = configuration.provider().scalaProvider();
|
||||
this.instance =
|
||||
new ScalaProvider() {
|
||||
public Launcher _launcher =
|
||||
new Launcher() {
|
||||
private Launcher delegateLauncher = delegate.launcher();
|
||||
private ClassLoader interfaceLoader =
|
||||
metaLoader.loadClass("sbt.testing.Framework").getClassLoader();
|
||||
|
||||
@Override
|
||||
public ScalaProvider getScala(String version) {
|
||||
return getScala(version, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScalaProvider getScala(String version, String reason) {
|
||||
return getScala(version, reason, "org.scala-lang");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScalaProvider getScala(String version, String reason, String scalaOrg) {
|
||||
return delegateLauncher.getScala(version, reason, scalaOrg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppProvider app(xsbti.ApplicationID id, String version) {
|
||||
return delegateLauncher.app(id, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader topLoader() {
|
||||
return interfaceLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalLock globalLock() {
|
||||
return delegateLauncher.globalLock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File bootDirectory() {
|
||||
return delegateLauncher.bootDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public xsbti.Repository[] ivyRepositories() {
|
||||
return delegateLauncher.ivyRepositories();
|
||||
}
|
||||
|
||||
@Override
|
||||
public xsbti.Repository[] appRepositories() {
|
||||
return delegateLauncher.appRepositories();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideRepositories() {
|
||||
return delegateLauncher.isOverrideRepositories();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File ivyHome() {
|
||||
return delegateLauncher.ivyHome();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] checksums() {
|
||||
return delegateLauncher.checksums();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public Launcher launcher() {
|
||||
return this._launcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String version() {
|
||||
return delegate.version();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader loader() {
|
||||
return metaLoader.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File[] jars() {
|
||||
return delegate.jars();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated()
|
||||
public File libraryJar() {
|
||||
return delegate.libraryJar();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated()
|
||||
public File compilerJar() {
|
||||
return delegate.compilerJar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppProvider app(xsbti.ApplicationID id) {
|
||||
return delegate.app(id);
|
||||
}
|
||||
|
||||
private ClassLoader loaderLibraryOnly() {
|
||||
return metaLoader.getParent().getParent();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScalaProvider scalaProvider() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public xsbti.ApplicationID id() {
|
||||
return appProvider.id();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoader loader() {
|
||||
return metaLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated()
|
||||
public Class<? extends AppMain> mainClass() {
|
||||
return appProvider.mainClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> entryPoint() {
|
||||
return appProvider.entryPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppMain newMain() {
|
||||
return appProvider.newMain();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File[] mainClasspath() {
|
||||
return appProvider.mainClasspath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentProvider components() {
|
||||
return appProvider.components();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] arguments() {
|
||||
return configuration.arguments();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File baseDirectory() {
|
||||
return configuration.baseDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppProvider provider() {
|
||||
try {
|
||||
return new ModifiedAppProvider(configuration.provider());
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2018, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal
|
||||
|
||||
import java.util.concurrent.{ ExecutorService, Executors }
|
||||
import sbt.plugins.{ CorePlugin, IvyPlugin, JvmPlugin }
|
||||
|
||||
private[internal] object ClassLoaderWarmup {
|
||||
def warmup(): Unit = {
|
||||
if (Runtime.getRuntime.availableProcessors > 1) {
|
||||
val executorService: ExecutorService =
|
||||
Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors - 1)
|
||||
def submit[R](f: => R): Unit = {
|
||||
executorService.submit(new Runnable {
|
||||
override def run(): Unit = { f; () }
|
||||
})
|
||||
()
|
||||
}
|
||||
|
||||
submit(Class.forName("sbt.internal.parser.SbtParserInit").getConstructor().newInstance())
|
||||
submit(CorePlugin.projectSettings)
|
||||
submit(IvyPlugin.projectSettings)
|
||||
submit(JvmPlugin.projectSettings)
|
||||
submit(() => {
|
||||
try {
|
||||
val clazz = Class.forName("scala.reflect.runtime.package$")
|
||||
clazz.getMethod("universe").invoke(clazz.getField("MODULE$").get(null))
|
||||
} catch {
|
||||
case _: Exception =>
|
||||
}
|
||||
executorService.shutdown()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2011 - 2018, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal
|
||||
|
||||
import java.io.File
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.net.URL
|
||||
import java.util.concurrent.{ ExecutorService, Executors }
|
||||
import ClassLoaderClose.close
|
||||
|
||||
import sbt.plugins.{ CorePlugin, IvyPlugin, JvmPlugin }
|
||||
import xsbti._
|
||||
|
||||
private[internal] object ClassLoaderWarmup {
|
||||
def warmup(): Unit = {
|
||||
if (Runtime.getRuntime.availableProcessors > 1) {
|
||||
val executorService: ExecutorService =
|
||||
Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors - 1)
|
||||
def submit[R](f: => R): Unit = {
|
||||
executorService.submit(new Runnable {
|
||||
override def run(): Unit = { f; () }
|
||||
})
|
||||
()
|
||||
}
|
||||
|
||||
submit(Class.forName("sbt.internal.parser.SbtParserInit").getConstructor().newInstance())
|
||||
submit(CorePlugin.projectSettings)
|
||||
submit(IvyPlugin.projectSettings)
|
||||
submit(JvmPlugin.projectSettings)
|
||||
submit(() => {
|
||||
try {
|
||||
val clazz = Class.forName("scala.reflect.runtime.package$")
|
||||
clazz.getMethod("universe").invoke(clazz.getField("MODULE$").get(null))
|
||||
} catch {
|
||||
case _: Exception =>
|
||||
}
|
||||
executorService.shutdown()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a new app configuration and invokes xMainImpl.run. For AppConfigurations generated
|
||||
* by recent launchers, it is unnecessary to modify the original configuration, but configurations
|
||||
* generated by older launchers need to be modified to place the test interface jar higher in
|
||||
* the class hierarchy. The methods this object are implemented without using the scala library
|
||||
* so that we can avoid loading any classes from the old scala provider. Verified as of
|
||||
* sbt 1.3.0 that there are no references to the scala standard library in any of the methods
|
||||
* in this file.
|
||||
*/
|
||||
private[sbt] class XMainConfiguration {
|
||||
def run(moduleName: String, configuration: xsbti.AppConfiguration): xsbti.MainResult = {
|
||||
val topLoader = configuration.provider.scalaProvider.launcher.topLoader
|
||||
val updatedConfiguration =
|
||||
try {
|
||||
val method = topLoader.getClass.getMethod("getJLineJars")
|
||||
val jars = method.invoke(topLoader).asInstanceOf[Array[URL]]
|
||||
var canReuseConfiguration = jars.length == 3
|
||||
var j = 0
|
||||
while (j < jars.length && canReuseConfiguration) {
|
||||
val s = jars(j).toString
|
||||
canReuseConfiguration = s.contains("jline") || s.contains("jansi")
|
||||
j += 1
|
||||
}
|
||||
if (canReuseConfiguration && j == 3) configuration else makeConfiguration(configuration)
|
||||
} catch {
|
||||
case _: NoSuchMethodException => makeConfiguration(configuration)
|
||||
}
|
||||
val loader = updatedConfiguration.provider.loader
|
||||
Thread.currentThread.setContextClassLoader(loader)
|
||||
val clazz = loader.loadClass(s"sbt.$moduleName$$")
|
||||
val instance = clazz.getField("MODULE$").get(null)
|
||||
val runMethod = clazz.getMethod("run", classOf[xsbti.AppConfiguration])
|
||||
try {
|
||||
val clw = loader.loadClass("sbt.internal.ClassLoaderWarmup$")
|
||||
clw.getMethod("warmup").invoke(clw.getField("MODULE$").get(null))
|
||||
runMethod.invoke(instance, updatedConfiguration).asInstanceOf[xsbti.MainResult]
|
||||
} catch {
|
||||
case e: InvocationTargetException =>
|
||||
// This propogates xsbti.FullReload to the launcher
|
||||
throw e.getCause
|
||||
}
|
||||
}
|
||||
|
||||
private def makeConfiguration(configuration: xsbti.AppConfiguration): xsbti.AppConfiguration = {
|
||||
val baseLoader = classOf[XMainConfiguration].getClassLoader
|
||||
val className = "sbt/internal/XMainConfiguration.class"
|
||||
val url = baseLoader.getResource(className)
|
||||
val path = url.toString.replaceAll(s"$className$$", "")
|
||||
val urlArray = new Array[URL](1)
|
||||
urlArray(0) = new URL(path)
|
||||
val topLoader = configuration.provider.scalaProvider.launcher.topLoader
|
||||
// This loader doesn't have the scala library in it so it's critical that none of the code
|
||||
// in this file use the scala library.
|
||||
val modifiedLoader = new XMainClassLoader(urlArray, topLoader)
|
||||
val xMainConfigurationClass = modifiedLoader.loadClass("sbt.internal.XMainConfiguration")
|
||||
val instance: AnyRef =
|
||||
xMainConfigurationClass.getConstructor().newInstance().asInstanceOf[AnyRef]
|
||||
|
||||
val metaBuildLoaderClass = modifiedLoader.loadClass("sbt.internal.MetaBuildLoader")
|
||||
val method = metaBuildLoaderClass.getMethod("makeLoader", classOf[AppProvider])
|
||||
|
||||
val loader = method.invoke(null, configuration.provider).asInstanceOf[ClassLoader]
|
||||
|
||||
Thread.currentThread.setContextClassLoader(loader)
|
||||
val modifiedConfigurationClass =
|
||||
modifiedLoader.loadClass("sbt.internal.XMainConfiguration$ModifiedConfiguration")
|
||||
val cons = modifiedConfigurationClass.getConstructors()(0)
|
||||
close(configuration.provider.loader)
|
||||
val scalaProvider = configuration.provider.scalaProvider
|
||||
val providerClass = scalaProvider.getClass
|
||||
val _ = try {
|
||||
val method = providerClass.getMethod("loaderLibraryOnly")
|
||||
close(method.invoke(scalaProvider).asInstanceOf[ClassLoader])
|
||||
1
|
||||
} catch { case _: NoSuchMethodException => 1 }
|
||||
close(scalaProvider.loader)
|
||||
close(configuration.provider.loader)
|
||||
cons.newInstance(instance, configuration, loader).asInstanceOf[xsbti.AppConfiguration]
|
||||
}
|
||||
|
||||
/*
|
||||
* Replaces the AppProvider.loader method with a new loader that puts the sbt test interface
|
||||
* jar ahead of the rest of the sbt classpath in the classloading hierarchy.
|
||||
*/
|
||||
private[sbt] class ModifiedConfiguration(
|
||||
val configuration: xsbti.AppConfiguration,
|
||||
val metaLoader: ClassLoader
|
||||
) extends xsbti.AppConfiguration {
|
||||
|
||||
private class ModifiedAppProvider(val appProvider: AppProvider) extends AppProvider {
|
||||
private val delegate = configuration.provider.scalaProvider
|
||||
object ModifiedScalaProvider extends ScalaProvider {
|
||||
override def launcher(): Launcher = new Launcher {
|
||||
private val delegateLauncher = delegate.launcher
|
||||
private val interfaceLoader = metaLoader.loadClass("sbt.testing.Framework").getClassLoader
|
||||
override def getScala(version: String): ScalaProvider = getScala(version, "")
|
||||
override def getScala(version: String, reason: String): ScalaProvider =
|
||||
getScala(version, reason, "org.scala-lang")
|
||||
override def getScala(version: String, reason: String, scalaOrg: String): ScalaProvider =
|
||||
delegateLauncher.getScala(version, reason, scalaOrg)
|
||||
override def app(id: xsbti.ApplicationID, version: String): AppProvider =
|
||||
delegateLauncher.app(id, version)
|
||||
override def topLoader(): ClassLoader = interfaceLoader
|
||||
override def globalLock(): GlobalLock = delegateLauncher.globalLock()
|
||||
override def bootDirectory(): File = delegateLauncher.bootDirectory()
|
||||
override def ivyRepositories(): Array[xsbti.Repository] =
|
||||
delegateLauncher.ivyRepositories()
|
||||
override def appRepositories(): Array[xsbti.Repository] =
|
||||
delegateLauncher.appRepositories()
|
||||
override def isOverrideRepositories: Boolean = delegateLauncher.isOverrideRepositories
|
||||
override def ivyHome(): File = delegateLauncher.ivyHome()
|
||||
override def checksums(): Array[String] = delegateLauncher.checksums()
|
||||
}
|
||||
override def version(): String = delegate.version
|
||||
override def loader(): ClassLoader = metaLoader.getParent
|
||||
override def jars(): Array[File] = delegate.jars
|
||||
@deprecated("Implements deprecated api", "1.3.0")
|
||||
override def libraryJar(): File = delegate.libraryJar
|
||||
@deprecated("Implements deprecated api", "1.3.0")
|
||||
override def compilerJar(): File = delegate.compilerJar
|
||||
override def app(id: xsbti.ApplicationID): AppProvider = delegate.app(id)
|
||||
def loaderLibraryOnly(): ClassLoader = metaLoader.getParent.getParent
|
||||
}
|
||||
override def scalaProvider(): ModifiedScalaProvider.type = ModifiedScalaProvider
|
||||
override def id(): xsbti.ApplicationID = appProvider.id()
|
||||
override def loader(): ClassLoader = metaLoader
|
||||
@deprecated("Implements deprecated api", "1.3.0")
|
||||
override def mainClass(): Class[_ <: AppMain] = appProvider.mainClass()
|
||||
override def entryPoint(): Class[_] = appProvider.entryPoint()
|
||||
override def newMain(): AppMain = appProvider.newMain()
|
||||
override def mainClasspath(): Array[File] = appProvider.mainClasspath()
|
||||
override def components(): ComponentProvider = appProvider.components()
|
||||
}
|
||||
override def arguments(): Array[String] = configuration.arguments
|
||||
override def baseDirectory(): File = configuration.baseDirectory
|
||||
override def provider(): AppProvider = new ModifiedAppProvider(configuration.provider)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,13 +20,13 @@ object IvyReport {
|
|||
def fromReportXML(doc: Document): ModuleGraph = {
|
||||
def edgesForModule(id: GraphModuleId, revision: NodeSeq): Seq[Edge] =
|
||||
for {
|
||||
caller ← revision \ "caller"
|
||||
caller <- revision \ "caller"
|
||||
callerModule = moduleIdFromElement(caller, caller.attribute("callerrev").get.text)
|
||||
} yield (moduleIdFromElement(caller, caller.attribute("callerrev").get.text), id)
|
||||
|
||||
val moduleEdges: Seq[(Module, Seq[Edge])] = for {
|
||||
mod ← doc \ "dependencies" \ "module"
|
||||
revision ← mod \ "revision"
|
||||
mod <- doc \ "dependencies" \ "module"
|
||||
revision <- mod \ "revision"
|
||||
rev = revision.attribute("name").get.text
|
||||
moduleId = moduleIdFromElement(mod, rev)
|
||||
module = Module(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ object DOT {
|
|||
labelRendering: HTMLLabelRendering
|
||||
): String = {
|
||||
val nodes = {
|
||||
for (n ← graph.nodes) yield {
|
||||
for (n <- graph.nodes) yield {
|
||||
val style = if (n.isEvicted) EvictedStyle else ""
|
||||
val label = nodeFormation(n.id.organization, n.id.name, n.id.version)
|
||||
""" "%s"[%s style="%s"]""".format(
|
||||
|
|
@ -56,7 +56,7 @@ object DOT {
|
|||
.filterNot(e => originWasEvicted(e) || evictionTargetEdges(e)) ++ evictedByEdges
|
||||
|
||||
val edges = {
|
||||
for (e ← filteredEdges) yield {
|
||||
for (e <- filteredEdges) yield {
|
||||
val extra =
|
||||
if (graph.module(e._1).isEvicted)
|
||||
s""" [label="Evicted By" style="$EvictedStyle"]"""
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import scala.xml.XML
|
|||
object GraphML {
|
||||
def saveAsGraphML(graph: ModuleGraph, outputFile: String): Unit = {
|
||||
val nodesXml =
|
||||
for (n ← graph.nodes)
|
||||
for (n <- graph.nodes)
|
||||
yield <node id={n.id.idString}><data key="d0">
|
||||
<y:ShapeNode>
|
||||
<y:NodeLabel>{n.id.idString}</y:NodeLabel>
|
||||
|
|
@ -23,7 +23,7 @@ object GraphML {
|
|||
</data></node>
|
||||
|
||||
val edgesXml =
|
||||
for (e ← graph.edges)
|
||||
for (e <- graph.edges)
|
||||
yield <edge source={e._1.idString} target={e._2.idString}/>
|
||||
|
||||
val xml =
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
sbt.version=1.4.4
|
||||
sbt.version=1.4.6
|
||||
|
|
|
|||
Loading…
Reference in New Issue