Shell refactoring

This commit is contained in:
crschnick 2023-02-20 09:49:10 +00:00
parent 211b516b7b
commit f304b66055
34 changed files with 165 additions and 66 deletions

View file

@ -76,15 +76,12 @@ https://user-images.githubusercontent.com/72509152/218265431-27bf34ad-03f8-43b7-
The following for modules make up the X-Pipe API and a licensed under the MIT license:
- [core](core) - Shared core classes of the X-Pipe Java API, X-Pipe extensions, and the X-Pipe daemon implementation
- [API](api) - The API that can be used to interact with X-Pipe from any JVM-based language.
For setup instructions, see the [X-Pipe Java API Usage](https://xpipe-io.readthedocs.io/en/latest/dev/api/java.html) section.
- [beacon](beacon) - The X-Pipe beacon component is responsible for handling all communications between the X-Pipe daemon
and the client applications, for example the various programming language APIs and the CLI
- [extension](extension) - An API to create all different kinds of extensions for the X-Pipe platform
For setup instructions, see the [X-Pipe extension development](https://xpipe-io.readthedocs.io/en/latest/dev/extensions/index.html) section.
The other modules make up the X-Pipe implementation and are licensed under GPL:
- [app](app) - Contains the X-Pipe daemon implementation and the X-Pipe desktop application code
- [app](app) - Contains the X-Pipe daemon implementation, the X-Pipe desktop application, and an
API to create all different kinds of extensions for the X-Pipe platform
- [dist](dist) - Tools to create a distributable package of X-Pipe
- [ext](ext) - Available X-Pipe extensions. Essentially every feature is implemented as an extension
@ -92,7 +89,7 @@ The other modules make up the X-Pipe implementation and are licensed under GPL:
X-Pipe utilizes an open core model, which essentially means that
the main application core is open source while certain other components are not.
In this case these non open source components are planned to be future parts of a potential commercialization.
In this case these non open source components are planned to be future parts of a potential commercialization (got to make a living somehow).
Furthermore, some tests and especially test environments and that run on private servers
are also not included in this repository (Don't want to leak server information).
Finally, scripts and workflows to create signed executables and installers
@ -119,6 +116,14 @@ many IDEs still have problems building this project properly.
For example, you can't build this project in eclipse or vscode as it will complain about missing modules.
The tested and recommended IDE is intellij.
### Setup
You need to have an up-to-date version of X-Pipe installed on your local system in order to properly
run X-Pipe in a development environment.
This is due to the fact that some components are only included in the release version and not in this repository.
X-pipe is able to automatically detect your installation and fetch the required
components from it when it is run in a development environment.
### Building and Running
You can use the gradle wrapper to build and run the project:

View file

@ -132,7 +132,7 @@ application {
run {
systemProperty 'io.xpipe.app.mode', 'gui'
systemProperty 'io.xpipe.app.dataDir', "$projectDir/local_stage/"
systemProperty 'io.xpipe.app.dataDir', "$projectDir/local8/"
systemProperty 'io.xpipe.app.writeLogs', "true"
systemProperty 'io.xpipe.app.writeSysOut', "true"
systemProperty 'io.xpipe.app.developerMode', "true"

View file

@ -72,7 +72,12 @@ public class AppExtensionManager {
if (!AppProperties.get().isFullVersion()) {
var localInstallation = XPipeInstallation.getLocalDefaultInstallationBasePath(true);
var extensions = XPipeInstallation.getLocalExtensionsDirectory(Path.of(localInstallation));
Path p = Path.of(localInstallation);
if (!Files.exists(p)) {
throw new IllegalStateException("Required local X-Pipe installation not found");
}
var extensions = XPipeInstallation.getLocalExtensionsDirectory(p);
extensionBaseDirectories.add(extensions);
}

View file

@ -66,6 +66,10 @@ public class AppGreetings {
}
public static void showIfNeeded() {
if (!AppProperties.get().isImage()) {
return;
}
boolean set = AppCache.get("legalAccepted", Boolean.class, () -> false);
if (set) {
return;
@ -95,8 +99,11 @@ public class AppGreetings {
.createRegion();
var layout = new BorderPane();
layout.getStyleClass().add("window-content");
layout.setCenter(accordion);
layout.setBottom(acceptanceBox);
layout.setPrefWidth(700);
layout.setPrefHeight(600);
alert.getDialogPane().setContent(layout);

View file

@ -1,7 +1,7 @@
package io.xpipe.app.ext;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.util.ModuleLayerLoader;
import io.xpipe.core.util.ModuleLayerLoader;
import io.xpipe.core.source.DataSource;
import io.xpipe.core.store.DataStore;
import javafx.beans.value.ObservableValue;

View file

@ -1,6 +1,6 @@
package io.xpipe.app.ext;
import io.xpipe.app.util.ModuleLayerLoader;
import io.xpipe.core.util.ModuleLayerLoader;
import io.xpipe.app.util.Validator;
import io.xpipe.core.source.DataSource;
import io.xpipe.core.source.DataSourceId;

View file

@ -1,7 +1,7 @@
package io.xpipe.app.ext;
import com.dlsc.formsfx.model.structure.Field;
import io.xpipe.app.util.ModuleLayerLoader;
import io.xpipe.core.util.ModuleLayerLoader;
import javafx.beans.value.ObservableBooleanValue;
import java.util.ServiceLoader;

View file

@ -1,8 +1,9 @@
package io.xpipe.app.ext;
import com.fasterxml.jackson.databind.jsontype.NamedType;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.util.ModuleLayerLoader;
import io.xpipe.core.util.ModuleLayerLoader;
import io.xpipe.app.util.XPipeDaemon;
import io.xpipe.core.process.ProcessControlProvider;
import io.xpipe.core.util.JacksonMapper;
@ -12,7 +13,9 @@ public class XPipeServiceProviders {
public static void load(ModuleLayer layer) {
var hasDaemon = XPipeDaemon.getInstanceIfPresent().isPresent();
ModuleLayerLoader.loadAll(layer, hasDaemon, true);
ModuleLayerLoader.loadAll(layer, hasDaemon, true, t -> {
ErrorEvent.fromThrowable(t).handle();
});
ProcessControlProvider.init(layer);
TrackEvent.info("Loading extension providers ...");
@ -34,7 +37,9 @@ public class XPipeServiceProviders {
});
}
ModuleLayerLoader.loadAll(layer, hasDaemon, false);
ModuleLayerLoader.loadAll(layer, hasDaemon, false, t -> {
ErrorEvent.fromThrowable(t).handle();
});
if (hasDaemon) {
ProxyFunction.init(layer);

View file

@ -4,7 +4,7 @@ import io.xpipe.app.ext.PrefsChoiceValue;
import io.xpipe.app.util.ApplicationHelper;
import io.xpipe.app.util.WindowsRegistry;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellTypes;
import io.xpipe.core.process.ShellDialects;
import java.io.IOException;
import java.nio.file.Path;
@ -112,7 +112,7 @@ public interface ExternalEditorType extends PrefsChoiceValue {
@Override
public void launch(Path file) throws IOException {
var list = ShellTypes.getPlatformDefault().executeCommandListWithShell(executable + " \"" + file + "\"");
var list = ShellDialects.getPlatformDefault().executeCommandListWithShell(executable + " \"" + file + "\"");
new ProcessBuilder(list).start();
}

View file

@ -9,7 +9,7 @@ import io.xpipe.core.impl.FileNames;
import io.xpipe.core.process.CommandProcessControl;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellProcessControl;
import io.xpipe.core.process.ShellTypes;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.ShellStore;
import io.xpipe.core.util.XPipeInstallation;
import lombok.Getter;
@ -151,7 +151,7 @@ public class AppInstaller {
shellProcessControl,
XPipeInstallation.getDefaultInstallationBasePath(shellProcessControl, false));
var logsDir = FileNames.join(XPipeInstallation.getDataBasePath(shellProcessControl), "logs");
var installer = ShellTypes.getPlatformDefault()
var installer = ShellDialects.getPlatformDefault()
.flatten(List.of(
"start",
"/wait",
@ -161,7 +161,7 @@ public class AppInstaller {
"/l*",
FileNames.join(logsDir.toString(), "installer_" + FileNames.getFileName(file) + ".log"),
"/qb"));
var start = ShellTypes.getPlatformDefault().flatten(List.of("start", "\"\"", exec));
var start = ShellDialects.getPlatformDefault().flatten(List.of("start", "\"\"", exec));
var command = installer + "\r\n" + start;
var script = ScriptHelper.createExecScript(shellProcessControl, command);
shellProcessControl.executeSimpleCommand("start /min " + script);
@ -178,7 +178,7 @@ public class AppInstaller {
@Override
public void installRemote(ShellProcessControl shellProcessControl, String file) throws Exception {
try (var pc = shellProcessControl.subShell(ShellTypes.BASH).start()) {
try (var pc = shellProcessControl.subShell(ShellDialects.BASH).start()) {
try (CommandProcessControl c = pc.command("DEBIAN_FRONTEND=noninteractive apt-get remove -qy xpipe")
.elevated()
.start()) {
@ -212,7 +212,7 @@ public class AppInstaller {
@Override
public void installRemote(ShellProcessControl shellProcessControl, String file) throws Exception {
try (var pc = shellProcessControl.subShell(ShellTypes.BASH).start()) {
try (var pc = shellProcessControl.subShell(ShellDialects.BASH).start()) {
try (CommandProcessControl c = pc.command("rpm -U -v --force \"" + file + "\"")
.elevated()
.start()) {
@ -238,7 +238,7 @@ public class AppInstaller {
@Override
public void installRemote(ShellProcessControl shellProcessControl, String file) throws Exception {
try (var pc = shellProcessControl.subShell(ShellTypes.BASH).start()) {
try (var pc = shellProcessControl.subShell(ShellDialects.BASH).start()) {
try (CommandProcessControl c = pc.command(
"installer -verboseR -allowUntrusted -pkg \"" + file + "\" -target /")
.elevated()

View file

@ -2,7 +2,7 @@ package io.xpipe.app.util;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.core.process.ShellProcessControl;
import io.xpipe.core.process.ShellTypes;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.ShellStore;
import java.io.IOException;
@ -11,7 +11,7 @@ import java.util.List;
public class ApplicationHelper {
public static void executeLocalApplication(String s) throws Exception {
var args = ShellTypes.getPlatformDefault().executeCommandListWithShell(s);
var args = ShellDialects.getPlatformDefault().executeCommandListWithShell(s);
TrackEvent.withDebug("proc", "Executing local application")
.elements(args)
.handle();
@ -21,7 +21,7 @@ public class ApplicationHelper {
}
public static void executeLocalApplication(List<String> s) throws Exception {
var args = ShellTypes.getPlatformDefault().executeCommandListWithShell(s);
var args = ShellDialects.getPlatformDefault().executeCommandListWithShell(s);
TrackEvent.withDebug("proc", "Executing local application")
.elements(args)
.handle();

View file

@ -3,13 +3,12 @@ package io.xpipe.app.util;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.core.impl.FileNames;
import io.xpipe.core.process.ShellProcessControl;
import io.xpipe.core.process.ShellType;
import io.xpipe.core.process.ShellTypes;
import io.xpipe.core.process.ShellDialect;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.ShellStore;
import io.xpipe.core.util.SecretValue;
import lombok.SneakyThrows;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
@ -106,7 +105,7 @@ public class ScriptHelper {
public static String constructOpenWithInitScriptCommand(
ShellProcessControl processControl, List<String> init, String toExecuteInShell) {
ShellType t = processControl.getShellType();
ShellDialect t = processControl.getShellType();
if (init.size() == 0 && toExecuteInShell == null) {
return t.getNormalOpenCommand();
}
@ -120,7 +119,7 @@ public class ScriptHelper {
}
// Check for special case of the command being a shell command
if (Arrays.stream(ShellTypes.getAllShellTypes())
if (ShellDialects.ALL.stream()
.anyMatch(shellType -> cmd.equals(shellType.getNormalOpenCommand()))) {
return cmd;
}
@ -129,7 +128,7 @@ public class ScriptHelper {
String nl = t.getNewLine().getNewLineString();
var content = String.join(nl, init) + nl;
if (t.equals(ShellTypes.BASH)) {
if (t.equals(ShellDialects.BASH)) {
content = "if [ -f ~/.bashrc ]; then . ~/.bashrc; fi\n" + content;
}
@ -141,7 +140,7 @@ public class ScriptHelper {
var initFile = createExecScript(processControl, content);
if (t.equals(ShellTypes.ZSH)) {
if (t.equals(ShellDialects.ZSH)) {
var zshiFile = createExecScript(processControl, ZSHI);
return t.getNormalOpenCommand() + " \"" + zshiFile + "\" \"" + initFile + "\"";
}
@ -152,7 +151,7 @@ public class ScriptHelper {
@SneakyThrows
public static String createExecScript(ShellProcessControl processControl, String content) {
var fileName = "exec-" + getScriptId();
ShellType type = processControl.getShellType();
ShellDialect type = processControl.getShellType();
var temp = processControl.getTemporaryDirectory();
var file = FileNames.join(temp, fileName + "." + type.getScriptFileEnding());
return createExecScript(processControl, file, content);
@ -160,7 +159,7 @@ public class ScriptHelper {
@SneakyThrows
private static String createExecScript(ShellProcessControl processControl, String file, String content) {
ShellType type = processControl.getShellType();
ShellDialect type = processControl.getShellType();
content = type.prepareScriptContent(content);
TrackEvent.withTrace("proc", "Writing exec script")
@ -176,7 +175,7 @@ public class ScriptHelper {
}
@SneakyThrows
public static String createAskPassScript(SecretValue pass, ShellProcessControl parent, ShellType type) {
public static String createAskPassScript(SecretValue pass, ShellProcessControl parent, ShellDialect type) {
var content = type.getScriptEchoCommand(pass.getSecretValue());
var temp = parent.getTemporaryDirectory();
var file = FileNames.join(temp, "askpass-" + getScriptId() + "." + type.getScriptFileEnding());

View file

@ -8,6 +8,7 @@ import io.xpipe.app.issue.EventHandlerImpl;
import io.xpipe.app.storage.DataStateProviderImpl;
import io.xpipe.app.util.*;
import io.xpipe.core.util.DataStateProvider;
import io.xpipe.core.util.ModuleLayerLoader;
import io.xpipe.core.util.ProxyFunction;
import io.xpipe.core.util.ProxyManagerProvider;
import org.slf4j.spi.SLF4JServiceProvider;

View file

@ -11,6 +11,10 @@
-fx-border-radius: 2px;
}
.radio-button {
-fx-background-color:transparent;
}
.icon-button-comp {
-fx-padding: 0.05em;
}

View file

@ -3,7 +3,7 @@ package io.xpipe.beacon;
import io.xpipe.beacon.exchange.StopExchange;
import io.xpipe.core.impl.FileNames;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellTypes;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.util.XPipeDaemonMode;
import io.xpipe.core.util.XPipeInstallation;
@ -28,7 +28,7 @@ public class BeaconServer {
public static Process tryStartCustom() throws Exception {
var custom = BeaconConfig.getCustomDaemonCommand();
if (custom != null) {
var command = ShellTypes.getPlatformDefault()
var command = ShellDialects.getPlatformDefault()
.executeCommandListWithShell(custom
+ (BeaconConfig.getDaemonArguments() != null
? " " + BeaconConfig.getDaemonArguments()
@ -50,7 +50,7 @@ public class BeaconServer {
getDaemonDebugExecutable(installationBase), BeaconConfig.getDaemonArguments(), mode);
}
var fullCommand = ShellTypes.getPlatformDefault().executeCommandListWithShell(command);
var fullCommand = ShellDialects.getPlatformDefault().executeCommandListWithShell(command);
Process process = new ProcessBuilder(fullCommand).start();
printDaemonOutput(process, fullCommand);
return process;

View file

@ -143,7 +143,7 @@ public interface OsType {
@Override
public Map<String, String> getProperties(ShellProcessControl pc) throws Exception {
try (CommandProcessControl c =
pc.subShell(ShellTypes.BASH).command("sw_vers").start()) {
pc.subShell(ShellDialects.BASH).command("sw_vers").start()) {
var text = c.readOrThrow();
return PropertiesFormatsParser.parse(text, ":");
}

View file

@ -18,7 +18,7 @@ public interface ProcessControl extends Closeable, AutoCloseable {
boolean isRunning();
ShellType getShellType();
ShellDialect getShellType();
void writeLine(String line) throws IOException;

View file

@ -11,7 +11,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
public interface ShellType {
public interface ShellDialect {
default String getCdCommand(String directory){
return "cd \"" + directory + "\"";
@ -109,7 +109,7 @@ public interface ShellType {
NewLine getNewLine();
String getName();
String getId();
String getDisplayName();

View file

@ -0,0 +1,60 @@
package io.xpipe.core.process;
import io.xpipe.core.util.ModuleLayerLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
public class ShellDialects {
public static final List<ShellDialect> ALL = new ArrayList<>();
public static ShellDialect POWERSHELL;
public static ShellDialect CMD;
public static ShellDialect SH;
public static ShellDialect BASH;
public static ShellDialect ZSH;
public static class Loader implements ModuleLayerLoader {
@Override
public void init(ModuleLayer layer) {
ServiceLoader.load(layer, ShellDialect.class).stream().forEach(moduleLayerLoaderProvider -> {
ALL.add(moduleLayerLoaderProvider.get());
});
CMD = byName("cmd");
POWERSHELL = byName("powershell");
SH = byName("sh");
BASH = byName("bash");
ZSH = byName("zsh");
}
@Override
public boolean requiresFullDaemon() {
return false;
}
@Override
public boolean prioritizeLoading() {
return false;
}
}
private static ShellDialect byName(String name) {
return ALL.stream()
.filter(shellType -> shellType.getId().equals(name))
.findFirst()
.orElseThrow();
}
public static ShellDialect getPlatformDefault() {
if (OsType.getLocal().equals(OsType.WINDOWS)) {
return CMD;
} else if (OsType.getLocal().equals(OsType.LINUX)) {
return BASH;
} else {
return ZSH;
}
}
}

View file

@ -49,7 +49,7 @@ public interface ShellProcessControl extends ProcessControl {
}
}
default String executeStringSimpleCommand(ShellType type, String command) throws Exception {
default String executeStringSimpleCommand(ShellDialect type, String command) throws Exception {
try (var sub = subShell(type).start()) {
return sub.executeStringSimpleCommand(command);
}
@ -69,7 +69,7 @@ public interface ShellProcessControl extends ProcessControl {
SecretValue getElevationPassword();
default ShellProcessControl subShell(@NonNull ShellType type) {
default ShellProcessControl subShell(@NonNull ShellDialect type) {
return subShell(p -> type.getNormalOpenCommand(), (shellProcessControl, s) -> {
return s == null ? type.getNormalOpenCommand() : type.executeCommandWithShell(s);
})

View file

@ -4,7 +4,7 @@ import io.xpipe.core.charsetter.Charsetter;
import io.xpipe.core.impl.LocalStore;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellProcessControl;
import io.xpipe.core.process.ShellType;
import io.xpipe.core.process.ShellDialect;
import java.nio.charset.Charset;
@ -44,8 +44,8 @@ public interface ShellStore extends DataStore, StatefulDataStore, LaunchableStor
return pc;
}
default ShellType getShellType() {
return getState("type", ShellType.class, null);
default ShellDialect getShellType() {
return getState("type", ShellDialect.class, null);
}
default OsType getOsType() {
@ -58,7 +58,7 @@ public interface ShellStore extends DataStore, StatefulDataStore, LaunchableStor
ShellProcessControl createControl();
public default ShellType determineType() throws Exception {
public default ShellDialect determineType() throws Exception {
try (var pc = create().start()) {
return pc.getShellType();
}

View file

@ -23,8 +23,8 @@ import io.xpipe.core.dialog.BusyElement;
import io.xpipe.core.dialog.ChoiceElement;
import io.xpipe.core.dialog.HeaderElement;
import io.xpipe.core.impl.*;
import io.xpipe.core.process.ShellType;
import io.xpipe.core.process.ShellTypes;
import io.xpipe.core.process.ShellDialect;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.source.DataSource;
import io.xpipe.core.source.DataSourceReference;
@ -51,7 +51,7 @@ public class CoreJacksonModule extends SimpleModule {
new NamedType(BusyElement.class),
new NamedType(HeaderElement.class));
for (ShellType t : ShellTypes.getAllShellTypes()) {
for (ShellDialect t : ShellDialects.ALL) {
context.registerSubtypes(new NamedType(t.getClass()));
}

View file

@ -2,7 +2,7 @@ package io.xpipe.core.util;
import io.xpipe.core.charsetter.NewLine;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellTypes;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.ShellStore;
import java.io.PrintWriter;
@ -105,7 +105,7 @@ public class Deobfuscator {
return false;
}
var t = ShellTypes.getPlatformDefault();
var t = ShellDialects.getPlatformDefault();
return ShellStore.local()
.create()
.executeBooleanSimpleCommand(t.getWhichCommand("retrace." + t.getScriptFileEnding()));

View file

@ -1,13 +1,12 @@
package io.xpipe.app.util;
package io.xpipe.core.util;
import io.xpipe.app.issue.ErrorEvent;
import java.util.ServiceLoader;
import java.util.function.Consumer;
public interface ModuleLayerLoader {
public static void loadAll(ModuleLayer layer, boolean hasDaemon, boolean prioritization) {
public static void loadAll(ModuleLayer layer, boolean hasDaemon, boolean prioritization, Consumer<Throwable> errorHandler) {
ServiceLoader.load(layer, ModuleLayerLoader.class).stream().forEach(moduleLayerLoaderProvider -> {
var instance = moduleLayerLoaderProvider.get();
try {
@ -21,7 +20,7 @@ public interface ModuleLayerLoader {
instance.init(layer);
} catch (Throwable t) {
ErrorEvent.fromThrowable(t).handle();
errorHandler.accept(t);
}
});
}

View file

@ -1,6 +1,9 @@
import io.xpipe.core.process.ProcessControlProvider;
import io.xpipe.core.process.ShellDialect;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.source.WriteMode;
import io.xpipe.core.util.CoreJacksonModule;
import io.xpipe.core.util.ModuleLayerLoader;
open module io.xpipe.core {
exports io.xpipe.core.store;
@ -29,6 +32,10 @@ open module io.xpipe.core {
uses io.xpipe.core.util.ProxyManagerProvider;
uses io.xpipe.core.util.DataStateProvider;
uses io.xpipe.core.util.SecretProvider;
uses ModuleLayerLoader;
uses ShellDialect;
provides ModuleLayerLoader with ShellDialects.Loader;
provides WriteMode with
WriteMode.Replace,

View file

@ -1,10 +1,10 @@
module io.xpipe.ext.text.test {
module io.xpipe.ext.base.test {
requires io.xpipe.ext.base;
requires org.junit.jupiter.api;
requires org.junit.jupiter.params;
requires io.xpipe.core;
requires io.xpipe.api;
requires io.xpipe.extension;
requires io.xpipe.app;
exports test;
}

View file

@ -1,11 +1,11 @@
package test;
import io.xpipe.api.DataSource;
import io.xpipe.app.test.DaemonExtensionTest;
import io.xpipe.core.charsetter.NewLine;
import io.xpipe.core.charsetter.StreamCharset;
import io.xpipe.core.impl.FileStore;
import io.xpipe.core.impl.TextSource;
import io.xpipe.extension.test.DaemonExtensionTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

View file

@ -1,11 +1,11 @@
package io.xpipe.ext.csv.test;
import io.xpipe.app.test.DaemonExtensionTest;
import io.xpipe.core.data.node.TupleNode;
import io.xpipe.core.data.node.ValueNode;
import io.xpipe.ext.csv.CsvDelimiter;
import io.xpipe.ext.csv.CsvHeaderState;
import io.xpipe.ext.csv.CsvSource;
import io.xpipe.extension.test.DaemonExtensionTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

View file

@ -7,6 +7,6 @@ module io.xpipe.csv.test {
requires org.junit.jupiter.api;
requires org.junit.jupiter.params;
requires io.xpipe.core;
requires io.xpipe.extension;
requires io.xpipe.app;
requires io.xpipe.api;
}

5
ext/proc/build.gradle Normal file
View file

@ -0,0 +1,5 @@
plugins { id 'java'
id 'org.moditect.gradleplugin' version '1.0.0-rc3'
}
apply from: "$rootDir/gradle/gradle_scripts/java.gradle"
apply from: "$rootDir/gradle/gradle_scripts/extension.gradle"

View file

@ -0,0 +1 @@
module io.xpipe.ext.proc {}

View file

@ -43,6 +43,7 @@ dependencies {
if (project != project(':base')) {
compileOnly project(':base')
testImplementation project(':base')
}
testImplementation project(':app')

View file

@ -2,11 +2,10 @@ import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
apply from: "$buildscript.sourceFile/../junit.gradle"
def useExtension = System.getProperty('excludeExtensionLibrary') == null
dependencies {
testImplementation project(':api')
testImplementation project(':core')
testImplementation project(':app')
testImplementation "org.openjfx:javafx-base:19:win"
testImplementation "org.openjfx:javafx-controls:19:win"
@ -24,6 +23,7 @@ test {
// Daemon properties
systemProperty "io.xpipe.beacon.daemonArgs",
" -Dio.xpipe.beacon.port=21723" +
" -Dio.xpipe.app.mode=tray" +
" -Dio.xpipe.app.dataDir=$projectDir/local/" +
" -Dio.xpipe.storage.persist=false" +
" -Dio.xpipe.app.writeSysOut=true" +

View file

@ -1 +1 @@
0.4.30
0.5.0