mirror of https://github.com/sbt/sbt.git
parent
c3baa55668
commit
eb74554ec1
37
build.sbt
37
build.sbt
|
|
@ -530,6 +530,27 @@ lazy val testAgentProj = (project in file("testing") / "agent")
|
|||
mimaSettings,
|
||||
)
|
||||
|
||||
lazy val workerProj = (project in file("worker"))
|
||||
.dependsOn(exampleWorkProj % Test)
|
||||
.settings(
|
||||
name := "worker",
|
||||
testedBaseSettings,
|
||||
Compile / doc / javacOptions := Nil,
|
||||
autoScalaLibrary := false,
|
||||
libraryDependencies += gson,
|
||||
libraryDependencies += "org.scala-lang" %% "scala3-library" % scalaVersion.value % Test,
|
||||
// run / fork := false,
|
||||
Test / fork := true,
|
||||
)
|
||||
.configure(addSbtIOForTest)
|
||||
|
||||
lazy val exampleWorkProj = (project in file("internal") / "example-work")
|
||||
.settings(
|
||||
minimalSettings,
|
||||
name := "example work",
|
||||
publish / skip := true,
|
||||
)
|
||||
|
||||
// Basic task engine
|
||||
lazy val taskProj = (project in file("tasks"))
|
||||
.dependsOn(collectionProj, utilControl)
|
||||
|
|
@ -656,6 +677,8 @@ lazy val actionsProj = (project in file("main-actions"))
|
|||
utilLogging,
|
||||
utilRelation,
|
||||
utilTracking,
|
||||
workerProj,
|
||||
protocolProj,
|
||||
)
|
||||
.settings(
|
||||
testedBaseSettings,
|
||||
|
|
@ -666,18 +689,9 @@ lazy val actionsProj = (project in file("main-actions"))
|
|||
baseDirectory.value / "src" / "main" / "contraband-scala",
|
||||
Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala",
|
||||
Compile / generateContrabands / contrabandFormatsForType := ContrabandConfig.getFormats,
|
||||
// Test / fork := true,
|
||||
Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat,
|
||||
mimaSettings,
|
||||
mimaBinaryIssueFilters ++= Seq(
|
||||
// Removed unused private[sbt] nested class
|
||||
exclude[MissingClassProblem]("sbt.Doc$Scaladoc"),
|
||||
// Removed no longer used private[sbt] method
|
||||
exclude[DirectMissingMethodProblem]("sbt.Doc.generate"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.compiler.Eval.filesModifiedBytes"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.compiler.Eval.fileModifiedBytes"),
|
||||
exclude[DirectMissingMethodProblem]("sbt.Doc.$init$"),
|
||||
// Added field in nested private[this] class
|
||||
exclude[ReversedMissingMethodProblem]("sbt.compiler.Eval#EvalType.sourceName"),
|
||||
),
|
||||
)
|
||||
.dependsOn(lmCore)
|
||||
.configure(
|
||||
|
|
@ -1231,6 +1245,7 @@ def allProjects =
|
|||
lmCoursier,
|
||||
lmCoursierShaded,
|
||||
lmCoursierShadedPublishing,
|
||||
workerProj,
|
||||
) ++ lowerUtilProjects
|
||||
|
||||
// These need to be cross published to 2.12 and 2.13 for Zinc
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
package example
|
||||
|
||||
class Hello
|
||||
|
||||
object Hello:
|
||||
def main(args: Array[String]): Unit =
|
||||
if args.toList == List("boom") then sys.error("boom")
|
||||
else println(s"${args.mkString}")
|
||||
end Hello
|
||||
|
|
@ -58,6 +58,7 @@ object Dependencies {
|
|||
}
|
||||
|
||||
def addSbtIO = addSbtModule(sbtIoPath, "io", sbtIO)
|
||||
def addSbtIOForTest = addSbtModule(sbtIoPath, "io", sbtIO, Some(Test))
|
||||
|
||||
def addSbtCompilerInterface = addSbtModule(sbtZincPath, "compilerInterface", compilerInterface)
|
||||
def addSbtCompilerClasspath = addSbtModule(sbtZincPath, "zincClasspath", compilerClasspath)
|
||||
|
|
@ -91,6 +92,7 @@ object Dependencies {
|
|||
val templateResolverApi = "org.scala-sbt" % "template-resolver" % "0.1"
|
||||
val remoteapis =
|
||||
"com.eed3si9n.remoteapis.shaded" % "shaded-remoteapis-java" % "2.3.0-M1-52317e00d8d4c37fa778c628485d220fb68a8d08"
|
||||
val gson = "com.google.code.gson" % "gson" % "2.13.1"
|
||||
|
||||
val scalaCompiler = "org.scala-lang" %% "scala3-compiler" % scala3
|
||||
val scala3Library = "org.scala-lang" %% "scala3-library" % scala3
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package sbt.internal.worker1;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
public class FilePath {
|
||||
public URI path;
|
||||
public String digest;
|
||||
|
||||
public FilePath(URI path, String digest) {
|
||||
this.path = path;
|
||||
this.digest = digest;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2023, Scala center
|
||||
* Copyright 2011 - 2022, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal.worker1;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RunInfo {
|
||||
public class JvmRunInfo {
|
||||
public ArrayList<String> args;
|
||||
public ArrayList<FilePath> classpath;
|
||||
public String mainClass;
|
||||
public boolean connectInput;
|
||||
|
||||
public JvmRunInfo(
|
||||
ArrayList<String> args,
|
||||
ArrayList<FilePath> classpath,
|
||||
String mainClass,
|
||||
boolean connectInput) {
|
||||
this.args = args;
|
||||
this.classpath = classpath;
|
||||
this.mainClass = mainClass;
|
||||
this.connectInput = connectInput;
|
||||
}
|
||||
}
|
||||
|
||||
public class NativeRunInfo {}
|
||||
|
||||
public boolean jvm;
|
||||
public JvmRunInfo jvmRunInfo;
|
||||
public NativeRunInfo nativeRunInfo;
|
||||
|
||||
public RunInfo(boolean jvm, JvmRunInfo jvmRunInfo, NativeRunInfo nativeRunInfo) {
|
||||
this.jvm = jvm;
|
||||
this.jvmRunInfo = jvmRunInfo;
|
||||
this.nativeRunInfo = nativeRunInfo;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* sbt
|
||||
* Copyright 2023, Scala center
|
||||
* Copyright 2011 - 2022, Lightbend, Inc.
|
||||
* Copyright 2008 - 2010, Mark Harrah
|
||||
* Licensed under Apache License 2.0 (see LICENSE)
|
||||
*/
|
||||
|
||||
package sbt.internal.worker1;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
public final class WorkerMain {
|
||||
private PrintStream originalOut;
|
||||
|
||||
public static void main(final String[] args) throws Exception {
|
||||
try {
|
||||
if (args.length == 0) {
|
||||
WorkerMain app = new WorkerMain();
|
||||
app.consoleWork();
|
||||
} else {
|
||||
System.err.println("missing args");
|
||||
System.exit(1);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
WorkerMain() {
|
||||
this.originalOut = System.out;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
System.setOut(new PrintStream(baos));
|
||||
}
|
||||
|
||||
void consoleWork() throws Exception {
|
||||
Scanner input = new Scanner(System.in);
|
||||
if (input.hasNextLine()) {
|
||||
String line = input.nextLine();
|
||||
process(line);
|
||||
}
|
||||
}
|
||||
|
||||
void process(String json) throws Exception {
|
||||
JsonElement elem = JsonParser.parseString(json);
|
||||
JsonObject o = elem.getAsJsonObject();
|
||||
if (!o.has("jsonrpc")) {
|
||||
throw new RuntimeException("missing jsonprc element");
|
||||
}
|
||||
long id = o.getAsJsonPrimitive("id").getAsLong();
|
||||
String method = o.getAsJsonPrimitive("method").getAsString();
|
||||
JsonObject params = o.getAsJsonObject("params");
|
||||
switch (method) {
|
||||
case "run":
|
||||
Gson g = new Gson();
|
||||
RunInfo info = g.fromJson(params, RunInfo.class);
|
||||
run(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void run(RunInfo info) throws Exception {
|
||||
if (info.jvm) {
|
||||
if (info.jvmRunInfo == null) {
|
||||
throw new RuntimeException("missing jvmRunInfo element");
|
||||
}
|
||||
RunInfo.JvmRunInfo jvmRunInfo = info.jvmRunInfo;
|
||||
URL[] urls =
|
||||
jvmRunInfo
|
||||
.classpath
|
||||
.stream()
|
||||
.map(
|
||||
filePath -> {
|
||||
try {
|
||||
return filePath.path.toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})
|
||||
.toArray(URL[]::new);
|
||||
URLClassLoader cl = new URLClassLoader(urls, ClassLoader.getSystemClassLoader());
|
||||
try {
|
||||
Class<?> mainClass = cl.loadClass(jvmRunInfo.mainClass);
|
||||
Method mainMethod = mainClass.getMethod("main", String[].class);
|
||||
String[] mainArgs = jvmRunInfo.args.stream().toArray(String[]::new);
|
||||
mainMethod.invoke(null, (Object) mainArgs);
|
||||
} finally {
|
||||
cl.close();
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("only jvm is supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package sbt.internal.worker1
|
||||
|
||||
import sbt.io.IO
|
||||
|
||||
object WorkerTest extends verify.BasicTestSuite:
|
||||
val main = WorkerMain()
|
||||
|
||||
test("process") {
|
||||
val u0 = IO.classLocationPath(classOf[example.Hello]).toUri()
|
||||
val u1 = IO.classLocationPath(classOf[scala.quoted.Quotes]).toUri()
|
||||
val u2 = IO.classLocationPath(classOf[scala.AnyVal]).toUri()
|
||||
val cp =
|
||||
s"""[{ "path": "${u0}", "digest": "" }, { "path": "${u1}", "digest": "" }, { "path": "${u2}", "digest": "" }]"""
|
||||
val runInfo =
|
||||
s"""{ "jvm": true, "jvmRunInfo": { "args": ["hi"], "classpath": $cp, "mainClass": "example.Hello" } }"""
|
||||
val json = s"""{ "jsonrpc": "2.0", "id": 1, "method": "run", "params": $runInfo }"""
|
||||
main.process(json)
|
||||
}
|
||||
end WorkerTest
|
||||
Loading…
Reference in New Issue