mirror of
https://github.com/sbt/sbt.git
synced 2026-09-03 16:39:24 +02:00
[2.x] Minimalist console (#8722)
**Problem** Forked console currently pulls in full Zinc, which includes JLine. **Solution** This implements a lighter-weight, full Java ForkConsoleMain, which no longer depends on JLine.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.net.URI;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ConsoleInfo implements Serializable {
|
||||
public ArrayList<URI> toolsJars;
|
||||
public ArrayList<URI> bridgeJars;
|
||||
public ArrayList<URI> products;
|
||||
public ArrayList<URI> classpathJars;
|
||||
public ArrayList<String> scalacOptions;
|
||||
public String initialCommands;
|
||||
public String cleanupCommands;
|
||||
|
||||
public ConsoleInfo(
|
||||
ArrayList<URI> toolsJars,
|
||||
ArrayList<URI> bridgeJars,
|
||||
ArrayList<URI> products,
|
||||
ArrayList<URI> classpathJars,
|
||||
ArrayList<String> scalacOptions,
|
||||
String initialCommands,
|
||||
String cleanupCommands) {
|
||||
this.toolsJars = toolsJars;
|
||||
this.bridgeJars = bridgeJars;
|
||||
this.products = products;
|
||||
this.classpathJars = classpathJars;
|
||||
this.scalacOptions = scalacOptions;
|
||||
this.initialCommands = initialCommands;
|
||||
this.cleanupCommands = cleanupCommands;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package sbt.internal.worker1;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Paths;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import xsbti.compile.ConsoleInterface1;
|
||||
|
||||
public final class ForkConsoleMain {
|
||||
public void run(long id, ConsoleInfo info) throws Exception {
|
||||
try {
|
||||
Class cls = ConsoleInterface1.class;
|
||||
Iterator iter = ServiceLoader.load(cls, ForkConsoleMain.class.getClassLoader()).iterator();
|
||||
List<ConsoleInterface1> list = new ArrayList<>();
|
||||
while (iter.hasNext()) {
|
||||
list.add((ConsoleInterface1) iter.next());
|
||||
}
|
||||
if (list.size() > 0) {
|
||||
runInterface1(list.get(0), info);
|
||||
} else {
|
||||
runOldInterface(info);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void runInterface1(ConsoleInterface1 intf, ConsoleInfo info) throws Exception {
|
||||
String toolsJars =
|
||||
info.toolsJars
|
||||
.stream()
|
||||
.map(u -> Paths.get(u).toString())
|
||||
.collect(Collectors.joining(File.pathSeparator));
|
||||
String classpathJars =
|
||||
Stream.concat(info.products.stream(), info.classpathJars.stream())
|
||||
.map(u -> Paths.get(u).toString())
|
||||
.collect(Collectors.joining(File.pathSeparator));
|
||||
intf.run(
|
||||
info.scalacOptions.toArray(new String[0]),
|
||||
toolsJars,
|
||||
classpathJars,
|
||||
info.initialCommands,
|
||||
info.cleanupCommands,
|
||||
createClassLoader(info, ForkConsoleMain.class.getClassLoader()),
|
||||
new String[] {},
|
||||
new Object[] {},
|
||||
new ZeroLogger());
|
||||
}
|
||||
|
||||
private void runOldInterface(ConsoleInfo info) throws Exception {
|
||||
Class concrete = Class.forName("xsbt.ConsoleInterface");
|
||||
Object instance = concrete.getDeclaredConstructor().newInstance();
|
||||
Method m =
|
||||
concrete.getMethod(
|
||||
"run",
|
||||
String[].class,
|
||||
String.class,
|
||||
String.class,
|
||||
String.class,
|
||||
String.class,
|
||||
ClassLoader.class,
|
||||
String[].class,
|
||||
Object[].class,
|
||||
xsbti.Logger.class);
|
||||
String toolsJars =
|
||||
info.toolsJars
|
||||
.stream()
|
||||
.map(u -> Paths.get(u).toString())
|
||||
.collect(Collectors.joining(File.pathSeparator));
|
||||
String classpathJars =
|
||||
Stream.concat(info.products.stream(), info.classpathJars.stream())
|
||||
.map(u -> Paths.get(u).toString())
|
||||
.collect(Collectors.joining(File.pathSeparator));
|
||||
m.invoke(
|
||||
instance,
|
||||
info.scalacOptions.toArray(new String[0]),
|
||||
toolsJars,
|
||||
classpathJars,
|
||||
info.initialCommands,
|
||||
info.cleanupCommands,
|
||||
createClassLoader(info, concrete.getClassLoader()),
|
||||
new String[] {},
|
||||
new Object[] {},
|
||||
new ZeroLogger());
|
||||
}
|
||||
|
||||
private URLClassLoader createClassLoader(ConsoleInfo info, ClassLoader parent) {
|
||||
URL[] urls =
|
||||
Stream.concat(info.products.stream(), info.classpathJars.stream())
|
||||
.map(
|
||||
u -> {
|
||||
try {
|
||||
return u.toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
})
|
||||
.toArray(URL[]::new);
|
||||
return new URLClassLoader(urls, parent);
|
||||
}
|
||||
|
||||
public static void main(long id, ConsoleInfo info) throws Exception {
|
||||
new ForkConsoleMain().run(id, info);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,9 @@ import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
@@ -67,6 +70,10 @@ public final class WorkerMain {
|
||||
WorkerMain app = new WorkerMain();
|
||||
app.consoleWork();
|
||||
System.exit(0);
|
||||
} else if (args.length == 1 && args[0].startsWith("@")) {
|
||||
WorkerMain app = new WorkerMain();
|
||||
app.argFileWork(Paths.get(args[0].substring(1)));
|
||||
System.exit(0);
|
||||
} else if (args.length == 2 && args[0].equals("--tcp")) {
|
||||
WorkerMain app = new WorkerMain();
|
||||
int serverPort = Integer.parseInt(args[1]);
|
||||
@@ -99,6 +106,13 @@ public final class WorkerMain {
|
||||
}
|
||||
}
|
||||
|
||||
void argFileWork(Path arg) throws Exception {
|
||||
this.jsonOut = this.originalOut;
|
||||
byte[] encoded = Files.readAllBytes(arg);
|
||||
String line = new String(encoded, "UTF-8");
|
||||
process(line);
|
||||
}
|
||||
|
||||
void socketWork(int serverPort) throws Exception {
|
||||
InetAddress loopback = InetAddress.getByName(null);
|
||||
Socket client = new Socket(loopback, serverPort);
|
||||
@@ -132,6 +146,10 @@ public final class WorkerMain {
|
||||
TestInfo testInfo = g.fromJson(params, TestInfo.class);
|
||||
test(id, testInfo);
|
||||
break;
|
||||
case "console":
|
||||
ConsoleInfo consoleInfo = g.fromJson(params, ConsoleInfo.class);
|
||||
console(id, consoleInfo);
|
||||
return;
|
||||
case "bye":
|
||||
break;
|
||||
}
|
||||
@@ -178,6 +196,11 @@ public final class WorkerMain {
|
||||
}
|
||||
}
|
||||
|
||||
void console(long id, ConsoleInfo info) throws Exception {
|
||||
ForkConsoleMain.main(id, info);
|
||||
return;
|
||||
}
|
||||
|
||||
private URLClassLoader createClassLoader(RunInfo.JvmRunInfo info, ClassLoader parent) {
|
||||
URL[] urls =
|
||||
info.classpath
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.function.Supplier;
|
||||
import xsbti.Logger;
|
||||
|
||||
public class ZeroLogger implements Logger {
|
||||
public void error(Supplier<String> msg) {}
|
||||
|
||||
public void warn(Supplier<String> msg) {}
|
||||
|
||||
public void info(Supplier<String> msg) {}
|
||||
|
||||
public void debug(Supplier<String> msg) {}
|
||||
|
||||
public void trace(Supplier<Throwable> exception) {}
|
||||
}
|
||||
Reference in New Issue
Block a user