mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 00:50:31 +00:00
Cleanup
This commit is contained in:
parent
7c88e8cd2d
commit
02a2502fa5
45 changed files with 123 additions and 618 deletions
|
@ -23,8 +23,8 @@ public class DataTableAccumulatorTest extends ApiTest {
|
|||
acc.add(val);
|
||||
var table = acc.finish(":test");
|
||||
|
||||
Assertions.assertEquals(table.getInfo().getDataType(), TupleType.tableType(List.of("col1", "col2")));
|
||||
Assertions.assertEquals(table.getInfo().getRowCountIfPresent(), OptionalInt.empty());
|
||||
// Assertions.assertEquals(table.getInfo().getDataType(), TupleType.tableType(List.of("col1", "col2")));
|
||||
// Assertions.assertEquals(table.getInfo().getRowCountIfPresent(), OptionalInt.empty());
|
||||
// var read = table.read(1).at(0);
|
||||
// Assertions.assertEquals(val, read);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.fasterxml.jackson.databind.node.TextNode;
|
|||
import io.xpipe.beacon.exchange.MessageExchanges;
|
||||
import io.xpipe.beacon.exchange.data.ClientErrorMessage;
|
||||
import io.xpipe.beacon.exchange.data.ServerErrorMessage;
|
||||
import io.xpipe.core.store.ProcessControl;
|
||||
import io.xpipe.core.process.ProcessControl;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
|
|
@ -2,7 +2,7 @@ package io.xpipe.beacon.exchange;
|
|||
|
||||
import io.xpipe.beacon.RequestMessage;
|
||||
import io.xpipe.beacon.ResponseMessage;
|
||||
import io.xpipe.core.store.FileStore;
|
||||
import io.xpipe.core.impl.FileStore;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package io.xpipe.core.charsetter;
|
||||
|
||||
import io.xpipe.core.store.FileStore;
|
||||
import io.xpipe.core.impl.FileStore;
|
||||
import io.xpipe.core.store.MachineStore;
|
||||
import io.xpipe.core.store.StreamDataStore;
|
||||
import lombok.Value;
|
||||
|
|
|
@ -14,6 +14,10 @@ public class DialogMapper {
|
|||
|
||||
public LinkedHashMap<String, String> handle() throws Exception {
|
||||
var element = dialog.start();
|
||||
if (element == null) {
|
||||
return map;
|
||||
}
|
||||
|
||||
handle(element);
|
||||
return map;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.impl;
|
||||
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.FilenameStore;
|
||||
import io.xpipe.core.store.StreamDataStore;
|
||||
|
||||
public abstract class CollectionEntryDataStore implements FilenameStore, StreamDataStore {
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
import io.xpipe.core.store.FilenameStore;
|
||||
import io.xpipe.core.store.StreamDataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.SuperBuilder;
|
|
@ -1,7 +1,8 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.store.StreamDataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.SuperBuilder;
|
|
@ -1,7 +1,8 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.IOException;
|
|
@ -1,6 +1,9 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
import io.xpipe.core.store.FileSystemStore;
|
||||
import io.xpipe.core.store.MachineStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
|
||||
import java.io.InputStream;
|
|
@ -1,6 +1,7 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
|
@ -1,4 +1,6 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.impl;
|
||||
|
||||
import io.xpipe.core.store.StreamDataStore;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
|
@ -4,7 +4,6 @@ import io.xpipe.core.source.DataSource;
|
|||
import io.xpipe.core.source.DataSourceConnection;
|
||||
import io.xpipe.core.source.DataSourceType;
|
||||
import io.xpipe.core.source.WriteMode;
|
||||
import io.xpipe.core.store.FileStore;
|
||||
|
||||
import java.nio.file.Files;
|
||||
|
||||
|
|
32
core/src/main/java/io/xpipe/core/impl/StdinDataStore.java
Normal file
32
core/src/main/java/io/xpipe/core/impl/StdinDataStore.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
package io.xpipe.core.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.store.StreamDataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@JsonTypeName("stdin")
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
public class StdinDataStore extends JacksonizedValue implements StreamDataStore {
|
||||
|
||||
@Override
|
||||
public boolean isContentExclusivelyAccessible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInput() throws Exception {
|
||||
var in = System.in;
|
||||
// Prevent closing the standard in when the returned input stream is closed
|
||||
return new FilterInputStream(in) {
|
||||
@Override
|
||||
public void close() throws IOException {}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.store.StreamDataStore;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
|
@ -26,27 +28,7 @@ public class StdoutDataStore extends JacksonizedValue implements StreamDataStore
|
|||
@Override
|
||||
public OutputStream openOutput() throws Exception {
|
||||
// Create an output stream that will write to standard out but will not close it
|
||||
return new OutputStream() {
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
System.out.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
System.out.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
System.out.write(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
System.out.flush();
|
||||
}
|
||||
|
||||
return new FilterOutputStream(System.out) {
|
||||
@Override
|
||||
public void close() throws IOException {}
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.process;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
|
@ -1,9 +1,4 @@
|
|||
package io.xpipe.core.util;
|
||||
|
||||
import io.xpipe.core.store.CommandProcessControl;
|
||||
import io.xpipe.core.store.PropertiesFormatsParser;
|
||||
import io.xpipe.core.store.ShellProcessControl;
|
||||
import io.xpipe.core.store.ShellTypes;
|
||||
package io.xpipe.core.process;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.process;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.process;
|
||||
|
||||
public abstract class ProcessControlProvider {
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.process;
|
||||
|
||||
public class ProcessOutputException extends Exception {
|
||||
public ProcessOutputException() {
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.process;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.process;
|
||||
|
||||
import io.xpipe.core.util.OsType;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
import lombok.NonNull;
|
||||
|
||||
|
@ -18,7 +17,7 @@ public interface ShellProcessControl extends ProcessControl {
|
|||
}
|
||||
}
|
||||
|
||||
default String executeSimpleCommand(ShellType type, String command) throws Exception {
|
||||
default String executeSimpleCommand(ShellType type, String command) throws Exception {
|
||||
return executeSimpleCommand(type.switchTo(command));
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package io.xpipe.core.store;
|
||||
package io.xpipe.core.process;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import io.xpipe.core.charsetter.NewLine;
|
|
@ -1,6 +1,6 @@
|
|||
package io.xpipe.core.source;
|
||||
|
||||
import io.xpipe.core.store.CollectionEntryDataStore;
|
||||
import io.xpipe.core.impl.CollectionEntryDataStore;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import io.xpipe.core.process.CommandProcessControl;
|
||||
|
||||
public interface CommandExecutionStore extends DataStore {
|
||||
|
||||
CommandProcessControl create() throws Exception;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
public interface CommandsStore extends DataStore {
|
||||
|
||||
CommandProcessControl create() throws Exception;
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import io.xpipe.core.impl.StdinDataStore;
|
||||
import io.xpipe.core.impl.StdoutDataStore;
|
||||
import io.xpipe.core.source.DataSource;
|
||||
|
||||
import java.time.Instant;
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* A data store that is only represented by an InputStream.
|
||||
* This can be useful for development.
|
||||
*/
|
||||
public class InputStreamDataStore implements StreamDataStore {
|
||||
|
||||
private final InputStream in;
|
||||
|
||||
public InputStreamDataStore(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInput() throws Exception {
|
||||
return in;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpen() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface ProcessHandler {
|
||||
|
||||
void handle(OutputStream out, OutputStream err);
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.process.ShellProcessControl;
|
||||
import io.xpipe.core.process.ShellType;
|
||||
|
||||
public interface ShellStore extends DataStore {
|
||||
|
||||
|
@ -15,10 +17,8 @@ public interface ShellStore extends DataStore {
|
|||
ShellProcessControl create();
|
||||
|
||||
public default ShellType determineType() throws Exception {
|
||||
AtomicReference<ShellType> type = new AtomicReference<>();
|
||||
try (var pc = create().start()) {
|
||||
type.set(pc.getShellType());
|
||||
return pc.getShellType();
|
||||
}
|
||||
return type.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,388 +0,0 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.charsetter.NewLine;
|
||||
import lombok.Value;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ShellTypes {
|
||||
|
||||
public static final ShellType POWERSHELL = new PowerShell();
|
||||
public static final ShellType CMD = new Cmd();
|
||||
public static final ShellType SH = new Sh();
|
||||
|
||||
public static ShellType getRecommendedDefault() {
|
||||
if (System.getProperty("os.name").startsWith("Windows")) {
|
||||
return POWERSHELL;
|
||||
} else {
|
||||
return SH;
|
||||
}
|
||||
}
|
||||
|
||||
public static ShellType getPlatformDefault() {
|
||||
if (System.getProperty("os.name").startsWith("Windows")) {
|
||||
return CMD;
|
||||
} else {
|
||||
return SH;
|
||||
}
|
||||
}
|
||||
|
||||
public static ShellType[] getWindowsShells() {
|
||||
return new ShellType[] {CMD, POWERSHELL};
|
||||
}
|
||||
|
||||
public static ShellType[] getLinuxShells() {
|
||||
return new ShellType[] {SH};
|
||||
}
|
||||
|
||||
@JsonTypeName("cmd")
|
||||
@Value
|
||||
public static class Cmd implements ShellType {
|
||||
|
||||
@Override
|
||||
public String getSetVariableCommand(String variableName, String value) {
|
||||
return "set \"" + variableName + "=" + value + "\"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEchoCommand(String s, boolean toErrorStream) {
|
||||
return toErrorStream ? "(echo " + s + ")1>&2" : "echo " + s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String queryShellProcessId(ShellProcessControl control) throws IOException {
|
||||
control.writeLine("powershell (Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId");
|
||||
|
||||
var r = new BufferedReader(new InputStreamReader(control.getStdout(), StandardCharsets.US_ASCII));
|
||||
// Read echo of command
|
||||
r.readLine();
|
||||
// Read actual output
|
||||
var line = r.readLine();
|
||||
r.readLine();
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConcatenationOperator() {
|
||||
return "&";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elevate(ShellProcessControl control, String command, String displayCommand) throws Exception {
|
||||
try (CommandProcessControl c = control.command("net session >NUL 2>NUL")) {
|
||||
var exitCode = c.getExitCode();
|
||||
if (exitCode != 0) {
|
||||
throw new IllegalStateException("The command \"" + displayCommand + "\" requires elevation.");
|
||||
}
|
||||
}
|
||||
|
||||
control.executeCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExitCodeVariable() {
|
||||
return "!errorlevel!";
|
||||
}
|
||||
|
||||
@Override
|
||||
public NewLine getNewLine() {
|
||||
return NewLine.CRLF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> openCommand() {
|
||||
return List.of("cmd", "/V:on");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String switchTo(String cmd) {
|
||||
return "cmd.exe /V:on /c " + cmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createMkdirsCommand(String dirs) {
|
||||
return List.of("mkdir", dirs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createFileReadCommand(String file) {
|
||||
return List.of("type", file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createFileWriteCommand(String file) {
|
||||
return "findstr \"^\" > \"" + file + "\"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createFileExistsCommand(String file) {
|
||||
return List.of("dir", "/a", file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Charset determineCharset(ShellProcessControl control) throws Exception {
|
||||
control.writeLine("chcp");
|
||||
|
||||
var r = new BufferedReader(new InputStreamReader(control.getStdout(), StandardCharsets.US_ASCII));
|
||||
// Read echo of command
|
||||
r.readLine();
|
||||
// Read actual output
|
||||
var line = r.readLine();
|
||||
// Read additional empty line
|
||||
r.readLine();
|
||||
|
||||
var matcher = Pattern.compile("\\d+").matcher(line);
|
||||
matcher.find();
|
||||
return Charset.forName("ibm" + matcher.group());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "cmd";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "cmd";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean echoesInput() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonTypeName("powershell")
|
||||
@Value
|
||||
public static class PowerShell implements ShellType {
|
||||
|
||||
@Override
|
||||
public String getSetVariableCommand(String variableName, String value) {
|
||||
return "set " + variableName + "=" + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String queryShellProcessId(ShellProcessControl control) throws IOException {
|
||||
control.writeLine("powershell (Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId");
|
||||
|
||||
var r = new BufferedReader(new InputStreamReader(control.getStdout(), StandardCharsets.US_ASCII));
|
||||
// Read echo of command
|
||||
r.readLine();
|
||||
// Read actual output
|
||||
var line = r.readLine();
|
||||
return line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConcatenationOperator() {
|
||||
return ";";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean echoesInput() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elevate(ShellProcessControl control, String command, String displayCommand) throws Exception {
|
||||
try (CommandProcessControl c = control.command(
|
||||
"([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)")
|
||||
.start()) {
|
||||
if (c.startAndCheckExit()) {
|
||||
throw new IllegalStateException("The command \"" + displayCommand + "\" requires elevation.");
|
||||
}
|
||||
}
|
||||
|
||||
control.executeCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExitCodeVariable() {
|
||||
return "$LASTEXITCODE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEchoCommand(String s, boolean toErrorStream) {
|
||||
if (toErrorStream) {
|
||||
return String.format("$host.ui.WriteErrorLine('%s')", s);
|
||||
}
|
||||
|
||||
return String.format("%s \"%s\"", "Write-Output", s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> openCommand() {
|
||||
return List.of("powershell", "/nologo");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String switchTo(String cmd) {
|
||||
return "powershell.exe -Command " + cmd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createFileReadCommand(String file) {
|
||||
return List.of("cmd", "/c", "type", file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createFileWriteCommand(String file) {
|
||||
return "cmd /c 'findstr \"^\" > \"" + file + "\"'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createMkdirsCommand(String dirs) {
|
||||
return List.of("cmd", "/c", "mkdir", dirs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createFileExistsCommand(String file) {
|
||||
return List.of("cmd", "/c", "dir", "/a", file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Charset determineCharset(ShellProcessControl control) throws Exception {
|
||||
control.writeLine("chcp");
|
||||
|
||||
var r = new BufferedReader(new InputStreamReader(control.getStdout(), StandardCharsets.US_ASCII));
|
||||
// Read echo of command
|
||||
r.readLine();
|
||||
// Read actual output
|
||||
var line = r.readLine();
|
||||
|
||||
var matcher = Pattern.compile("\\d+").matcher(line);
|
||||
matcher.find();
|
||||
return Charset.forName("ibm" + matcher.group());
|
||||
}
|
||||
|
||||
@Override
|
||||
public NewLine getNewLine() {
|
||||
return NewLine.CRLF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "powershell";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "PowerShell";
|
||||
}
|
||||
}
|
||||
|
||||
@JsonTypeName("sh")
|
||||
@Value
|
||||
public static class Sh implements ShellType {
|
||||
|
||||
@Override
|
||||
public String getExitCommand() {
|
||||
return "exit 0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConcatenationOperator() {
|
||||
return ";";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void elevate(ShellProcessControl control, String command, String displayCommand) throws Exception {
|
||||
if (control.getElevationPassword() == null) {
|
||||
control.executeCommand("SUDO_ASKPASS=/bin/false sudo -p \"\" -S " + command);
|
||||
return;
|
||||
}
|
||||
|
||||
// For sudo to always query for a password by using the -k switch
|
||||
control.executeCommand("sudo -p \"\" -k -S " + command);
|
||||
control.writeLine(control.getElevationPassword().getSecretValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExitCodeVariable() {
|
||||
return "$?";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEchoCommand(String s, boolean toErrorStream) {
|
||||
return "echo " + s + (toErrorStream ? " 1>&2" : "");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String queryShellProcessId(ShellProcessControl control) throws Exception {
|
||||
try (CommandProcessControl c = control.command("echo $$").start()) {
|
||||
var out = c.readOnlyStdout();
|
||||
var matcher = Pattern.compile("\\d+$").matcher(out);
|
||||
matcher.find();
|
||||
return matcher.group(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSetVariableCommand(String variableName, String value) {
|
||||
return variableName + "=" + value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> openCommand() {
|
||||
return List.of("sh", "-i", "-l");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String switchTo(String cmd) {
|
||||
return "sh -c \"" + cmd + "\"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createMkdirsCommand(String dirs) {
|
||||
return List.of("mkdir", "-p", dirs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createFileReadCommand(String file) {
|
||||
return List.of("cat", file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createFileWriteCommand(String file) {
|
||||
return "cat > \"" + file + "\"";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> createFileExistsCommand(String file) {
|
||||
return List.of("(", "test", "-f", file, "||", "test", "-d", file, ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Charset determineCharset(ShellProcessControl st) throws Exception {
|
||||
return StandardCharsets.UTF_8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NewLine getNewLine() {
|
||||
return NewLine.LF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "sh";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return "/bin/sh";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean echoesInput() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.core.util.JacksonizedValue;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
@JsonTypeName("stdin")
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
public class StdinDataStore extends JacksonizedValue implements StreamDataStore {
|
||||
|
||||
@Override
|
||||
public boolean isContentExclusivelyAccessible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openInput() throws Exception {
|
||||
var in = System.in;
|
||||
// Prevent closing the standard in when the returned input stream is closed
|
||||
return new InputStream() {
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return in.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
return in.read(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
return in.read(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readAllBytes() throws IOException {
|
||||
return in.readAllBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readNBytes(int len) throws IOException {
|
||||
return in.readNBytes(len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readNBytes(byte[] b, int off, int len) throws IOException {
|
||||
return in.readNBytes(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
return in.skip(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void skipNBytes(long n) throws IOException {
|
||||
in.skipNBytes(n);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return in.available();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {}
|
||||
|
||||
@Override
|
||||
public synchronized void mark(int readlimit) {
|
||||
in.mark(readlimit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
in.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markSupported() {
|
||||
return in.markSupported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long transferTo(OutputStream out) throws IOException {
|
||||
return in.transferTo(out);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package io.xpipe.core.store;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
@JsonTypeName("url")
|
||||
@SuperBuilder
|
||||
@Jacksonized
|
||||
public class URLDataStore implements StreamDataStore {
|
||||
|
||||
private final URL url;
|
||||
|
||||
@Override
|
||||
public InputStream openInput() throws Exception {
|
||||
return url.openStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canOpen() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -20,10 +20,11 @@ import io.xpipe.core.dialog.BaseQueryElement;
|
|||
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.ShellTypes;
|
||||
import io.xpipe.core.source.DataSource;
|
||||
import io.xpipe.core.source.DataSourceInfo;
|
||||
import io.xpipe.core.source.DataSourceReference;
|
||||
import io.xpipe.core.store.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
package io.xpipe.core.util;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@AllArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PUBLIC)
|
||||
@EqualsAndHashCode
|
||||
public class SecretValue {
|
||||
|
||||
String value;
|
||||
|
||||
public static SecretValue createForSecretValue(String s) {
|
||||
public static SecretValue create(String s) {
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -24,8 +28,17 @@ public class SecretValue {
|
|||
return new SecretValue(Base64.getEncoder().encodeToString(s.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
public String getDisplay() {
|
||||
return "*".repeat(value.length());
|
||||
public void withSecretValue(Consumer<char[]> chars) {
|
||||
var bytes = Base64.getDecoder().decode(value);
|
||||
var buffer = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes));
|
||||
var array = buffer.array();
|
||||
chars.accept(array);
|
||||
Arrays.fill(array, (char) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<secret>";
|
||||
}
|
||||
|
||||
public String getEncryptedValue() {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.source.WriteMode;
|
||||
import io.xpipe.core.util.CoreJacksonModule;
|
||||
|
||||
|
@ -12,6 +13,7 @@ open module io.xpipe.core {
|
|||
exports io.xpipe.core.dialog;
|
||||
exports io.xpipe.core.impl;
|
||||
exports io.xpipe.core.charsetter;
|
||||
exports io.xpipe.core.process;
|
||||
|
||||
requires com.fasterxml.jackson.datatype.jsr310;
|
||||
requires com.fasterxml.jackson.module.paramnames;
|
||||
|
@ -22,7 +24,7 @@ open module io.xpipe.core {
|
|||
|
||||
uses com.fasterxml.jackson.databind.Module;
|
||||
uses io.xpipe.core.source.WriteMode;
|
||||
uses io.xpipe.core.store.LocalStore.LocalProcessControlProvider;
|
||||
uses LocalStore.LocalProcessControlProvider;
|
||||
|
||||
provides WriteMode with WriteMode.Replace, WriteMode.Append, WriteMode.Prepend;
|
||||
provides com.fasterxml.jackson.databind.Module with
|
||||
|
|
|
@ -35,7 +35,7 @@ dependencies {
|
|||
if (findProject(':fxcomps') != null) {
|
||||
compileOnly project(':fxcomps')
|
||||
} else {
|
||||
compileOnly 'io.xpipe:fxcomps:0.3.2'
|
||||
compileOnly 'io.xpipe:fxcomps:0.3.3'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ package io.xpipe.extension;
|
|||
|
||||
import io.xpipe.core.source.*;
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.FileStore;
|
||||
import io.xpipe.core.impl.FileStore;
|
||||
import io.xpipe.extension.event.ErrorEvent;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.xpipe.extension;
|
||||
|
||||
import com.fasterxml.jackson.databind.jsontype.NamedType;
|
||||
import io.xpipe.core.store.LocalStore;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.extension.event.TrackEvent;
|
||||
import io.xpipe.extension.prefs.PrefsProviders;
|
||||
|
|
|
@ -22,7 +22,7 @@ public class SecretFieldComp extends Comp<CompStructure<TextField>> {
|
|||
var text = new PasswordField();
|
||||
text.setText(value.getValue() != null ? value.getValue().getSecretValue() : null);
|
||||
text.textProperty().addListener((c, o, n) -> {
|
||||
value.setValue(n != null && n.length() > 0 ? SecretValue.createForSecretValue(n) : null);
|
||||
value.setValue(n != null && n.length() > 0 ? SecretValue.create(n) : null);
|
||||
});
|
||||
value.addListener((c, o, n) -> {
|
||||
PlatformThread.runLaterIfNeeded(() -> {
|
||||
|
|
|
@ -4,6 +4,7 @@ import io.xpipe.core.charsetter.NewLine;
|
|||
import io.xpipe.core.charsetter.StreamCharset;
|
||||
import io.xpipe.core.dialog.Dialog;
|
||||
import io.xpipe.core.dialog.QueryConverter;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.source.DataSource;
|
||||
import io.xpipe.core.store.*;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.xpipe.extension.util;
|
||||
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.FileStore;
|
||||
import io.xpipe.core.impl.FileStore;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package io.xpipe.extension.util;
|
||||
|
||||
import io.xpipe.core.store.DataStore;
|
||||
import io.xpipe.core.store.LocalStore;
|
||||
import io.xpipe.core.impl.LocalStore;
|
||||
import io.xpipe.core.store.ShellStore;
|
||||
import io.xpipe.extension.I18n;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.0.2.1-SNAPSHOT
|
||||
0.0.2.1
|
Loading…
Reference in a new issue