Rework [stage]

This commit is contained in:
crschnick 2025-04-13 15:54:42 +00:00
parent ce48444da6
commit 14a4c1b046
5 changed files with 84 additions and 65 deletions

View file

@ -1,15 +1,12 @@
package io.xpipe.app.core;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.update.*;
import io.xpipe.app.util.LocalExec;
import io.xpipe.app.util.LocalShell;
import io.xpipe.app.util.Translatable;
import io.xpipe.core.process.CommandBuilder;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.process.ShellScript;
import io.xpipe.core.util.XPipeInstallation;
@ -31,8 +28,7 @@ public enum AppDistributionType implements Translatable {
var pkg = AppProperties.get().isStaging() ? "xpipe-ptb" : "xpipe";
return new CommandUpdater(ShellScript.lines(
"brew upgrade --cask xpipe-io/tap/" + pkg,
AppRestart.getRestartCommand(),
LocalShell.getDialect().getPauseCommand()
AppRestart.getTerminalRestartCommand()
));
}),
APT_REPO("apt", true, () -> {
@ -41,8 +37,7 @@ public enum AppDistributionType implements Translatable {
"echo \"+ sudo apt update && sudo apt install -y " + pkg + "\"",
"sudo apt update",
"sudo apt install -y " + pkg,
AppRestart.getRestartCommand(),
LocalShell.getDialect().getPauseCommand()
AppRestart.getTerminalRestartCommand()
));
}),
RPM_REPO("rpm", true, () -> {
@ -50,8 +45,7 @@ public enum AppDistributionType implements Translatable {
return new CommandUpdater(ShellScript.lines(
"echo \"+ sudo yum upgrade " + pkg + " --refresh -y\"",
"sudo yum upgrade " + pkg + " --refresh -y",
AppRestart.getRestartCommand(),
LocalShell.getDialect().getPauseCommand()
AppRestart.getTerminalRestartCommand()
));
}),
WEBTOP("webtop", true, () -> new WebtopUpdater()),
@ -61,14 +55,12 @@ public enum AppDistributionType implements Translatable {
if (systemWide) {
return new CommandUpdater(ShellScript.lines(
"powershell -Command \"Start-Process -Verb runAs -FilePath choco -ArgumentList upgrade, " + pkg + "\"",
AppRestart.getRestartCommand(),
LocalShell.getDialect().getPauseCommand()
AppRestart.getTerminalRestartCommand()
));
} else {
return new CommandUpdater(ShellScript.lines(
"choco upgrade " + pkg,
AppRestart.getRestartCommand(),
LocalShell.getDialect().getPauseCommand()
AppRestart.getTerminalRestartCommand()
));
}
});

View file

@ -6,52 +6,65 @@ import io.xpipe.app.util.LocalShell;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellDialect;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.FileNames;
import io.xpipe.core.util.XPipeDaemonMode;
import io.xpipe.core.util.XPipeInstallation;
import java.util.ArrayList;
import java.util.List;
public class AppRestart {
private static String createExternalAsyncLaunchCommand(XPipeDaemonMode mode, List<String> arguments, ShellDialect dialect) {
private static String createTerminalLaunchCommand(List<String> arguments, ShellDialect dialect) {
var loc = AppProperties.get().isDevelopmentEnvironment()
? XPipeInstallation.getLocalDefaultInstallationBasePath()
: XPipeInstallation.getCurrentInstallationBasePath().toString();
var suffix = (arguments != null ? " " + String.join(" ", arguments) : "");
var modeOption = mode != null ? " --mode " + mode.getDisplayName() : "";
: XPipeInstallation.getCurrentInstallationBasePath();
var suffix = (arguments.size() > 0 ? " " + String.join(" ", arguments) : "");
if (OsType.getLocal().equals(OsType.LINUX)) {
return "nohup \"" + loc + "/bin/xpiped\"" + modeOption + suffix + " & disown";
var exec = loc.resolve(XPipeInstallation.getRelativeCliExecutablePath(OsType.getLocal()));
return "\"" + exec + "\" open" + suffix;
} else if (OsType.getLocal().equals(OsType.MACOS)) {
return "(sleep 1;open \"" + loc + "\" --args" + modeOption + suffix
+ "</dev/null &>/dev/null) & disown";
var exec = loc.resolve(XPipeInstallation.getRelativeCliExecutablePath(OsType.getLocal()));
return "\"" + exec + "\" open" + suffix;
} else {
var exe = FileNames.join(loc, XPipeInstallation.getDaemonExecutablePath(OsType.getLocal()));
var exe = loc.resolve(XPipeInstallation.getDaemonExecutablePath(OsType.getLocal()));
if (ShellDialects.isPowershell(dialect)) {
var list = new ArrayList<String>();
if (mode != null) {
list.add("--mode");
list.add(mode.getDisplayName());
}
list.addAll(arguments);
var escapedList = list.stream().map(s -> s.replaceAll("\"", "`\"")).toList();
var escapedList = arguments.stream().map(s -> s.replaceAll("\"", "`\"")).toList();
var argumentList = String.join(" ", escapedList);
return "Start-Process -FilePath \"" + exe + "\" -ArgumentList \"" + argumentList + "\"";
} else {
var base = "\"" + FileNames.join(loc, XPipeInstallation.getDaemonExecutablePath(OsType.getLocal()))
+ "\"" + modeOption + suffix;
var base = "\"" + exe + "\"" + suffix;
return "start \"\" " + base;
}
}
}
public static String getRestartCommand(ShellDialect dialect) {
private static String createBackgroundLaunchCommand(List<String> arguments, ShellDialect dialect) {
var loc = AppProperties.get().isDevelopmentEnvironment()
? XPipeInstallation.getLocalDefaultInstallationBasePath()
: XPipeInstallation.getCurrentInstallationBasePath();
var suffix = (arguments.size() > 0 ? " " + String.join(" ", arguments) : "");
if (OsType.getLocal().equals(OsType.LINUX)) {
return "nohup \"" + loc + "/bin/xpiped\"" + suffix + "</dev/null >/dev/null 2>&1 & disown";
} else if (OsType.getLocal().equals(OsType.MACOS)) {
return "(sleep 1;open \"" + loc + "\" --args" + suffix
+ "</dev/null &>/dev/null) & disown";
} else {
var exe = loc.resolve(XPipeInstallation.getDaemonExecutablePath(OsType.getLocal()));
if (ShellDialects.isPowershell(dialect)) {
var escapedList = arguments.stream().map(s -> s.replaceAll("\"", "`\"")).toList();
var argumentList = String.join(" ", escapedList);
return "Start-Process -FilePath \"" + exe + "\" -ArgumentList \"" + argumentList + "\"";
} else {
var base = "\"" + exe + "\"" + suffix;
return "start \"\" " + base;
}
}
}
public static String getBackgroundRestartCommand(ShellDialect dialect) {
var dataDir = AppProperties.get().getDataDir();
// We have to quote the arguments like this to make it work in PowerShell as well
var exec = createExternalAsyncLaunchCommand(
XPipeDaemonMode.GUI,
var exec = createBackgroundLaunchCommand(
List.of(
"--mode",
"gui",
"-Dio.xpipe.app.acceptEula=true",
"-Dio.xpipe.app.dataDir=\"" + dataDir + "\"",
"-Dio.xpipe.app.restarted=true"),
@ -59,14 +72,31 @@ public class AppRestart {
return exec;
}
public static String getRestartCommand() {
return getRestartCommand(ProcessControlProvider.get().getEffectiveLocalDialect());
public static String getBackgroundRestartCommand() {
return getBackgroundRestartCommand(ProcessControlProvider.get().getEffectiveLocalDialect());
}
public static String getTerminalRestartCommand(ShellDialect dialect) {
var dataDir = AppProperties.get().getDataDir();
var exec = createTerminalLaunchCommand(
List.of(
"--mode",
"gui",
"-Dio.xpipe.app.acceptEula=true",
"-Dio.xpipe.app.dataDir=\"" + dataDir + "\"",
"-Dio.xpipe.app.restarted=true"),
dialect);
return exec;
}
public static String getTerminalRestartCommand() {
return getTerminalRestartCommand(ProcessControlProvider.get().getEffectiveLocalDialect());
}
public static void restart() {
OperationMode.executeAfterShutdown(() -> {
try (var sc = LocalShell.getShell().start()) {
sc.command(getRestartCommand()).execute();
sc.command(getBackgroundRestartCommand()).execute();
}
});
}

View file

@ -5,8 +5,6 @@ import io.xpipe.app.core.AppProperties;
import io.xpipe.app.core.AppRestart;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.ext.ProcessControlProvider;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.terminal.ExternalTerminalType;
import io.xpipe.app.terminal.TerminalLauncher;
import io.xpipe.app.util.LocalShell;
import io.xpipe.app.util.ScriptHelper;
@ -135,7 +133,7 @@ public class AppInstaller {
file,
logFile,
args,
AppRestart.getRestartCommand(ShellDialects.CMD)
AppRestart.getBackgroundRestartCommand(ShellDialects.CMD)
);
}
@ -159,7 +157,7 @@ public class AppInstaller {
file,
logFile,
startProcessProperty,
AppRestart.getRestartCommand(ShellDialects.POWERSHELL)
AppRestart.getBackgroundRestartCommand(ShellDialects.POWERSHELL)
);
}
}
@ -169,20 +167,19 @@ public class AppInstaller {
@Override
public void installLocal(Path file) {
var name = AppProperties.get().isStaging() ? "xpipe-ptb" : "xpipe";
var command = new ShellScript(String.format(
"""
runinstaller() {
echo "Installing downloaded .deb installer ..."
echo "+ sudo apt install \\"%s\\""
DEBIAN_FRONTEND=noninteractive sudo apt-get install -qy "%s" || return 1
%s open -d "%s" || return 1
DEBIAN_FRONTEND=noninteractive sudo apt install -y "%s" || return 1
%s || return 1
}
cd ~
runinstaller || echo "Update failed ..." && read key
""",
file, file, name, AppProperties.get().getDataDir()));
file, file, AppRestart.getTerminalRestartCommand()));
runAndClose(() -> {
TerminalLauncher.openDirectFallback("XPipe Updater", sc -> command);
});
@ -212,7 +209,7 @@ public class AppInstaller {
runinstaller || read -rsp "Update failed ..."$'\\n' -n 1 key
""",
file, file,
AppRestart.getRestartCommand()));
AppRestart.getTerminalRestartCommand()));
runAndClose(() -> {
TerminalLauncher.openDirectFallback("XPipe Updater", sc -> command);
@ -243,7 +240,7 @@ public class AppInstaller {
runinstaller || echo "Update failed ..." && read -rs -k 1 key
""",
file, file,
AppRestart.getRestartCommand()));
AppRestart.getTerminalRestartCommand()));
runAndClose(() -> {
TerminalLauncher.openDirectFallback("XPipe Updater", sc -> command);

View file

@ -35,7 +35,7 @@ public class XPipeInstallation {
var suffix = (arguments != null ? " " + arguments : "");
var modeOption = mode != null ? " --mode " + mode.getDisplayName() : "";
if (OsType.getLocal().equals(OsType.LINUX)) {
return "nohup \"" + installationBase + "/bin/xpiped\"" + modeOption + suffix + " & disown";
return "nohup \"" + installationBase + "/bin/xpiped\"" + modeOption + suffix + "</dev/null >/dev/null 2>&1 & disown";
} else if (OsType.getLocal().equals(OsType.MACOS)) {
if (restart) {
return "(sleep 1;open \"" + installationBase + "\" --args" + modeOption + suffix
@ -141,7 +141,7 @@ public class XPipeInstallation {
}
}
public static String getLocalInstallationBasePathForCLI(String cliExecutable) {
public static Path getLocalInstallationBasePathForCLI(String cliExecutable) {
var defaultInstallation = getLocalDefaultInstallationBasePath();
// Can be empty in development mode
@ -155,11 +155,11 @@ public class XPipeInstallation {
var path = Path.of(cliExecutable);
if (OsType.getLocal().equals(OsType.MACOS)) {
return path.getParent().getParent().getParent().toString();
return path.getParent().getParent().getParent();
} else if (OsType.getLocal().equals(OsType.LINUX)) {
return path.getParent().getParent().toString();
return path.getParent().getParent();
} else {
return path.getParent().getParent().toString();
return path.getParent().getParent();
}
}
@ -173,7 +173,7 @@ public class XPipeInstallation {
}
public static String getLocalDefaultCliExecutable() {
Path path = isImage() ? getCurrentInstallationBasePath() : Path.of(getLocalDefaultInstallationBasePath());
Path path = isImage() ? getCurrentInstallationBasePath() : getLocalDefaultInstallationBasePath();
return path.resolve(getRelativeCliExecutablePath(OsType.getLocal())).toString();
}
@ -200,25 +200,25 @@ public class XPipeInstallation {
}
}
public static String getLocalDefaultInstallationBasePath() {
public static Path getLocalDefaultInstallationBasePath() {
return getLocalDefaultInstallationBasePath(staging);
}
public static String getLocalDefaultInstallationBasePath(boolean stage) {
String path;
public static Path getLocalDefaultInstallationBasePath(boolean stage) {
Path path;
if (OsType.getLocal().equals(OsType.WINDOWS)) {
var pg = System.getenv("ProgramFiles");
var systemPath = Path.of(pg, stage ? "XPipe PTB" : "XPipe");
if (Files.exists(systemPath)) {
return systemPath.toString();
return systemPath;
}
var base = System.getenv("LOCALAPPDATA");
path = FileNames.join(base, stage ? "XPipe PTB" : "XPipe");
var base = Path.of(System.getenv("LOCALAPPDATA"));
path = base.resolve(stage ? "XPipe PTB" : "XPipe");
} else if (OsType.getLocal().equals(OsType.LINUX)) {
path = stage ? "/opt/xpipe-ptb" : "/opt/xpipe";
path = Path.of(stage ? "/opt/xpipe-ptb" : "/opt/xpipe");
} else {
path = stage ? "/Applications/XPipe PTB.app" : "/Applications/XPipe.app";
path = Path.of(stage ? "/Applications/XPipe PTB.app" : "/Applications/XPipe.app");
}
return path;

View file

@ -1 +1 @@
16.0-37
16.0-38