This commit is contained in:
crschnick
2025-03-04 17:41:01 +00:00
parent 117dfdd10c
commit 73bb8cf76e
8 changed files with 45 additions and 57 deletions
@@ -19,42 +19,21 @@ import java.util.regex.Matcher;
@Value
public class ContextualFileReference {
private static String lastDataDir;
private static FilePath lastDataDir;
@NonNull
String path;
private static String getDataDir() {
private static FilePath getDataDir() {
if (DataStorage.get() == null) {
return lastDataDir != null ? lastDataDir : normalized(AppPrefs.DEFAULT_STORAGE_DIR.resolve("data"));
return lastDataDir != null ? lastDataDir : new FilePath(AppPrefs.DEFAULT_STORAGE_DIR.resolve("data")).toUnix();
}
return lastDataDir = normalized(DataStorage.get().getDataDir());
return lastDataDir = new FilePath(DataStorage.get().getDataDir()).toUnix();
}
private static String normalized(Path p) {
return p.normalize().toString().replaceAll("\\\\", "/");
}
private static String normalized(String s) {
try {
return Path.of(s).normalize().toString().replaceAll("\\\\", "/");
} catch (InvalidPathException ex) {
return s;
}
}
public static Optional<ContextualFileReference> parseIfInDataDirectory(String s) {
var cf = of(s);
if (cf.serialize().contains("<DATA>")) {
return Optional.of(cf);
} else {
return Optional.empty();
}
}
public static Optional<String> resolveIfInDataDirectory(ShellControl shellControl, String s) {
if (s.contains("<DATA>")) {
public static Optional<FilePath> resolveIfInDataDirectory(ShellControl shellControl, String s) {
if (s.startsWith("<DATA>")) {
var cf = of(s);
return Optional.of(cf.toAbsoluteFilePath(shellControl));
} else {
@@ -63,30 +42,30 @@ public class ContextualFileReference {
}
public static ContextualFileReference of(FilePath p) {
return of(p != null ? p.toString() : null);
}
public static ContextualFileReference of(String s) {
if (s == null) {
if (p == null) {
return null;
}
var ns = normalized(s.trim());
var ns = p.normalize().toUnix();
var home = new FilePath(System.getProperty("user.home")).normalize().toUnix();
String replaced;
var withHomeResolved = ns.replace("~", normalized(System.getProperty("user.home")));
var withHomeResolved = ns.toString().replace("~", home.toString());
// Only replace ~ if it is part of data dir, otherwise keep it raw
if (withHomeResolved.startsWith(getDataDir())) {
replaced = withHomeResolved.replace("<DATA>", getDataDir());
if (withHomeResolved.startsWith(getDataDir().toString())) {
replaced = withHomeResolved.replace("<DATA>", getDataDir().toString());
} else {
replaced = ns.replace("<DATA>", getDataDir());
replaced = ns.toString().replace("<DATA>", getDataDir().toString());
}
return new ContextualFileReference(normalized(replaced));
return new ContextualFileReference(replaced);
}
public String toAbsoluteFilePath(ShellControl sc) {
return path.replaceAll(
"/", Matcher.quoteReplacement(sc != null ? sc.getOsType().getFileSystemSeparator() : "/"));
public static ContextualFileReference of(String s) {
return of(s != null ? new FilePath(s) : null);
}
public FilePath toAbsoluteFilePath(ShellControl sc) {
return new FilePath(path.replaceAll("/", Matcher.quoteReplacement(sc != null ? sc.getOsType().getFileSystemSeparator() : "/")));
}
public boolean isInDataDirectory() {
@@ -95,9 +74,9 @@ public class ContextualFileReference {
public String serialize() {
var start = getDataDir();
var normalizedPath = normalized(path);
var normalizedPath = new FilePath(path).normalize().toUnix();
if (normalizedPath.startsWith(start) && !normalizedPath.equals(start)) {
return "<DATA>" + "/" + FileNames.relativize(start, normalizedPath);
return "<DATA>" + "/" + start.relativize(normalizedPath);
}
return path;
}
@@ -59,7 +59,7 @@ public interface WindowsTerminalType extends ExternalTerminalType, TrackableTerm
var script = ScriptHelper.createExecScript(
shellControl,
configuration.getDialectLaunchCommand().buildFull(shellControl));
return script.toString();
return script;
});
}
} else {
@@ -1,6 +1,7 @@
package io.xpipe.app.util;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.core.store.FilePath;
import io.xpipe.core.util.StreamCharset;
import lombok.Value;
@@ -20,9 +21,9 @@ public class RdpConfig {
Map<String, TypedValue> content;
public static RdpConfig parseFile(String file) throws Exception {
public static RdpConfig parseFile(FilePath file) throws Exception {
try (var in = new BufferedReader(
StreamCharset.detectedReader(new BufferedInputStream(Files.newInputStream(Path.of(file)))))) {
StreamCharset.detectedReader(new BufferedInputStream(Files.newInputStream(Path.of(file.toString())))))) {
var content = in.lines().collect(Collectors.joining("\n"));
return parseContent(content);
} catch (NoSuchFileException e) {
@@ -181,7 +181,7 @@ public class CommandBuilder {
return prepend("\"" + s + "\"");
}
public CommandBuilder addFile(FailableFunction<ShellControl, String, Exception> f) {
public CommandBuilder addFile(FailableFunction<ShellControl, FilePath, Exception> f) {
elements.add(sc -> {
if (f == null) {
return null;
@@ -174,6 +174,10 @@ public final class FilePath {
return new FilePath(value.substring(0, value.length() - getFileName().length() - 1));
}
public boolean startsWith(String start) {
return startsWith(new FilePath(start));
}
public boolean startsWith(FilePath start) {
return normalize().startsWith(start.normalize());
}
@@ -189,6 +193,10 @@ public final class FilePath {
return backslash ? toWindows() : toUnix();
}
public FilePath resolveTildeHome(String dir) {
return value.startsWith("~") ? new FilePath(value.replace("~", dir)) : this;
}
private List<String> split() {
var split = value.split("[\\\\/]");
return Arrays.stream(split).filter(s -> !s.isEmpty()).toList();
@@ -170,11 +170,11 @@ public interface SshIdentityStrategy {
var s = file.toAbsoluteFilePath(parent);
// The ~ is supported on all platforms, so manually replace it here for Windows
if (s.contains("~")) {
s = s.replace("~", parent.getOsType().getUserHomeDirectory(parent));
if (s.startsWith("~")) {
s = s.resolveTildeHome(parent.getOsType().getUserHomeDirectory(parent));
}
var resolved =
parent.getShellDialect().evaluateExpression(parent, s).readStdoutOrThrow();
parent.getShellDialect().evaluateExpression(parent, s.toString()).readStdoutOrThrow();
if (!parent.getShellDialect()
.createFileExistsCommand(parent, resolved)
.executeAndCheck()) {
@@ -213,11 +213,11 @@ public interface SshIdentityStrategy {
var s = file.toAbsoluteFilePath(sc);
// The ~ is supported on all platforms, so manually replace it here for Windows
if (s.contains("~")) {
s = s.replace("~", sc.getOsType().getUserHomeDirectory(sc));
if (s.startsWith("~")) {
s = s.resolveTildeHome(sc.getOsType().getUserHomeDirectory(sc));
}
var resolved =
sc.getShellDialect().evaluateExpression(sc, s).readStdoutOrThrow();
sc.getShellDialect().evaluateExpression(sc, s.toString()).readStdoutOrThrow();
return sc.getShellDialect().fileArgument(resolved);
})
.add("-oIdentitiesOnly=yes");
@@ -95,7 +95,7 @@ public class SshIdentityStrategyHelper {
boolean allowSync) {
var keyPath = new SimpleObjectProperty<FilePath>(
fileProperty.getValue() != null && fileProperty.getValue().getFile() != null
? new FilePath(fileProperty.getValue().getFile().toAbsoluteFilePath(null))
? fileProperty.getValue().getFile().toAbsoluteFilePath(null)
: null);
fileProperty.addListener((observable, oldValue, newValue) -> {
if (keyPath.get() != null
@@ -106,7 +106,7 @@ public class SshIdentityStrategyHelper {
keyPath.setValue(
newValue != null && newValue.getFile() != null
? new FilePath(newValue.getFile().toAbsoluteFilePath(null))
? newValue.getFile().toAbsoluteFilePath(null)
: null);
});
var keyPasswordProperty = new SimpleObjectProperty<>(
@@ -47,8 +47,8 @@ public class SyncedIdentityStoreProvider extends IdentityStoreProvider {
return;
}
var source = Path.of(f.getFile().toAbsoluteFilePath(null));
var target = Path.of("keys", FileNames.getFileName(f.getFile().toAbsoluteFilePath(null)));
var source = Path.of(f.getFile().toAbsoluteFilePath(null).toString());
var target = Path.of("keys", f.getFile().toAbsoluteFilePath(null).getFileName());
DataStorageSyncHandler.getInstance().addDataFile(source, target, newValue);
});