Rework updater

This commit is contained in:
crschnick 2024-07-24 11:03:51 +00:00
parent 2f4d72c63f
commit d8d62c0eff
5 changed files with 85 additions and 59 deletions

View file

@ -223,7 +223,7 @@ public abstract class OperationMode {
CURRENT = null; CURRENT = null;
r.run(); r.run();
} catch (Throwable ex) { } catch (Throwable ex) {
ErrorEvent.fromThrowable(ex).build().handle(); ErrorEvent.fromThrowable(ex).handle();
OperationMode.halt(1); OperationMode.halt(1);
} }

View file

@ -1,19 +1,22 @@
package io.xpipe.app.update; package io.xpipe.app.update;
import io.xpipe.app.core.AppLogs;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.util.LocalShell;
import io.xpipe.app.util.ScriptHelper;
import io.xpipe.app.util.TerminalLauncher;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.FileNames;
import io.xpipe.core.store.LocalStore;
import io.xpipe.core.util.XPipeInstallation;
import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonTypeName;
import io.xpipe.app.core.AppLogs;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.LocalShell;
import io.xpipe.app.util.ScriptHelper;
import io.xpipe.app.util.TerminalLauncher;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellDialects;
import io.xpipe.core.store.FileNames;
import io.xpipe.core.store.LocalStore;
import io.xpipe.core.util.FailableRunnable;
import io.xpipe.core.util.XPipeInstallation;
import lombok.Getter; import lombok.Getter;
import java.nio.file.Files; import java.nio.file.Files;
@ -21,10 +24,6 @@ import java.nio.file.Path;
public class AppInstaller { public class AppInstaller {
public static void installFileLocal(InstallerAssetType asset, Path localFile) throws Exception {
asset.installLocal(localFile.toString());
}
public static InstallerAssetType getSuitablePlatformAsset() { public static InstallerAssetType getSuitablePlatformAsset() {
if (OsType.getLocal().equals(OsType.WINDOWS)) { if (OsType.getLocal().equals(OsType.WINDOWS)) {
return new InstallerAssetType.Msi(); return new InstallerAssetType.Msi();
@ -53,7 +52,18 @@ public class AppInstaller {
}) })
public abstract static class InstallerAssetType { public abstract static class InstallerAssetType {
public abstract void installLocal(String file) throws Exception; protected void runAndClose(FailableRunnable<Exception> r) {
OperationMode.executeAfterShutdown(() -> {
r.run();
// In case we perform any operations such as opening a terminal
// give it some time to open while this process is still alive
// Otherwise it might quit because the parent process is dead already
ThreadHelper.sleep(100);
});
}
public abstract void installLocal(Path file) throws Exception;
public boolean isCorrectAsset(String name) { public boolean isCorrectAsset(String name) {
return name.endsWith(getExtension()) return name.endsWith(getExtension())
@ -66,7 +76,7 @@ public class AppInstaller {
public static final class Msi extends InstallerAssetType { public static final class Msi extends InstallerAssetType {
@Override @Override
public void installLocal(String file) throws Exception { public void installLocal(Path file) throws Exception {
var shellProcessControl = new LocalStore().control().start(); var shellProcessControl = new LocalStore().control().start();
var exec = (AppProperties.get().isDevelopmentEnvironment() var exec = (AppProperties.get().isDevelopmentEnvironment()
? Path.of(XPipeInstallation.getLocalDefaultInstallationBasePath()) ? Path.of(XPipeInstallation.getLocalDefaultInstallationBasePath())
@ -75,15 +85,18 @@ public class AppInstaller {
.toString(); .toString();
var logsDir = var logsDir =
AppLogs.get().getSessionLogsDirectory().getParent().toString(); AppLogs.get().getSessionLogsDirectory().getParent().toString();
var logFile = FileNames.join(logsDir, "installer_" + FileNames.getFileName(file) + ".log"); var logFile = FileNames.join(logsDir, "installer_" + file.getFileName().toString() + ".log");
var command = LocalShell.getShell().getShellDialect().equals(ShellDialects.CMD) var command = LocalShell.getShell().getShellDialect().equals(ShellDialects.CMD)
? getCmdCommand(file, logFile, exec) ? getCmdCommand(file.toString(), logFile, exec)
: getPowershellCommand(file, logFile, exec); : getPowershellCommand(file.toString(), logFile, exec);
var toRun = LocalShell.getShell().getShellDialect().equals(ShellDialects.CMD) var toRun = LocalShell.getShell().getShellDialect().equals(ShellDialects.CMD)
? "start \"XPipe Updater\" /min cmd /c \"" + ScriptHelper.createLocalExecScript(command) + "\"" ? "start \"XPipe Updater\" /min cmd /c \"" + ScriptHelper.createLocalExecScript(command) + "\""
: "Start-Process -WindowStyle Minimized -FilePath powershell -ArgumentList \"-ExecutionPolicy\", \"Bypass\", \"-File\", \"`\"" : "Start-Process -WindowStyle Minimized -FilePath powershell -ArgumentList \"-ExecutionPolicy\", \"Bypass\", \"-File\", \"`\""
+ ScriptHelper.createLocalExecScript(command) + "`\"\""; + ScriptHelper.createLocalExecScript(command) + "`\"\"";
runAndClose(() -> {
shellProcessControl.executeSimpleCommand(toRun); shellProcessControl.executeSimpleCommand(toRun);
});
} }
@Override @Override
@ -124,7 +137,12 @@ public class AppInstaller {
public static final class Debian extends InstallerAssetType { public static final class Debian extends InstallerAssetType {
@Override @Override
public void installLocal(String file) throws Exception { public void installLocal(Path file) throws Exception {
var start = AppPrefs.get() != null && AppPrefs.get().terminalType().getValue() != null && AppPrefs.get().terminalType().getValue().isAvailable();
if (!start) {
return;
}
var name = AppProperties.get().isStaging() ? "xpipe-ptb" : "xpipe"; var name = AppProperties.get().isStaging() ? "xpipe-ptb" : "xpipe";
var command = String.format( var command = String.format(
""" """
@ -139,7 +157,10 @@ public class AppInstaller {
exec || read -rsp "Update failed ..."$'\\n' -n 1 key exec || read -rsp "Update failed ..."$'\\n' -n 1 key
""", """,
file, file, name); file, file, name);
runAndClose(() -> {
TerminalLauncher.openDirect("XPipe Updater", sc -> command); TerminalLauncher.openDirect("XPipe Updater", sc -> command);
});
} }
@Override @Override
@ -150,8 +171,14 @@ public class AppInstaller {
@JsonTypeName("rpm") @JsonTypeName("rpm")
public static final class Rpm extends InstallerAssetType { public static final class Rpm extends InstallerAssetType {
@Override @Override
public void installLocal(String file) throws Exception { public void installLocal(Path file) throws Exception {
var start = AppPrefs.get() != null && AppPrefs.get().terminalType().getValue() != null && AppPrefs.get().terminalType().getValue().isAvailable();
if (!start) {
return;
}
var name = AppProperties.get().isStaging() ? "xpipe-ptb" : "xpipe"; var name = AppProperties.get().isStaging() ? "xpipe-ptb" : "xpipe";
var command = String.format( var command = String.format(
""" """
@ -166,7 +193,10 @@ public class AppInstaller {
exec || read -rsp "Update failed ..."$'\\n' -n 1 key exec || read -rsp "Update failed ..."$'\\n' -n 1 key
""", """,
file, file, name); file, file, name);
runAndClose(() -> {
TerminalLauncher.openDirect("XPipe Updater", sc -> command); TerminalLauncher.openDirect("XPipe Updater", sc -> command);
});
} }
@Override @Override
@ -177,8 +207,14 @@ public class AppInstaller {
@JsonTypeName("pkg") @JsonTypeName("pkg")
public static final class Pkg extends InstallerAssetType { public static final class Pkg extends InstallerAssetType {
@Override @Override
public void installLocal(String file) throws Exception { public void installLocal(Path file) throws Exception {
var start = AppPrefs.get() != null && AppPrefs.get().terminalType().getValue() != null && AppPrefs.get().terminalType().getValue().isAvailable();
if (!start) {
return;
}
var name = AppProperties.get().isStaging() ? "xpipe-ptb" : "xpipe"; var name = AppProperties.get().isStaging() ? "xpipe-ptb" : "xpipe";
var command = String.format( var command = String.format(
""" """
@ -193,7 +229,10 @@ public class AppInstaller {
exec || echo "Update failed ..." && read -rs -k 1 key exec || echo "Update failed ..." && read -rs -k 1 key
""", """,
file, file, name); file, file, name);
runAndClose(() -> {
TerminalLauncher.openDirect("XPipe Updater", sc -> command); TerminalLauncher.openDirect("XPipe Updater", sc -> command);
});
} }
@Override @Override

View file

@ -1,9 +1,9 @@
package io.xpipe.app.update; package io.xpipe.app.update;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.AppProperties;
import io.xpipe.app.issue.ErrorEvent;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import org.kohsuke.github.GHRelease; import org.kohsuke.github.GHRelease;
import java.nio.file.Files; import java.nio.file.Files;
@ -43,13 +43,24 @@ public class GitHubUpdater extends UpdateHandler {
preparedUpdate.setValue(rel); preparedUpdate.setValue(rel);
} }
public void executeUpdateOnCloseImpl() throws Exception { public void executeUpdate() {
var downloadFile = preparedUpdate.getValue().getFile(); var p = preparedUpdate.getValue();
var downloadFile = p.getFile();
if (!Files.exists(downloadFile)) { if (!Files.exists(downloadFile)) {
event("Prepared update file does not exist");
return; return;
} }
AppInstaller.installFileLocal(preparedUpdate.getValue().getAssetType(), downloadFile); try {
var performedUpdate = new PerformedUpdate(p.getVersion(), p.getBody(), p.getVersion());
AppCache.update("performedUpdate", performedUpdate);
var a = p.getAssetType();
a.installLocal(downloadFile);
} catch (Throwable t) {
ErrorEvent.fromThrowable(t).handle();
preparedUpdate.setValue(null);
}
} }
public synchronized AvailableRelease refreshUpdateCheckImpl() throws Exception { public synchronized AvailableRelease refreshUpdateCheckImpl() throws Exception {

View file

@ -29,10 +29,6 @@ public class PortableUpdater extends UpdateHandler {
.createRegion(); .createRegion();
} }
public void executeUpdateOnCloseImpl() {
throw new UnsupportedOperationException();
}
public synchronized AvailableRelease refreshUpdateCheckImpl() throws Exception { public synchronized AvailableRelease refreshUpdateCheckImpl() throws Exception {
var rel = AppDownloads.getLatestSuitableRelease(); var rel = AppDownloads.getLatestSuitableRelease();
event("Determined latest suitable release " event("Determined latest suitable release "

View file

@ -2,19 +2,16 @@ package io.xpipe.app.update;
import io.xpipe.app.core.AppCache; import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppProperties; import io.xpipe.app.core.AppProperties;
import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent; import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.util.BooleanScope; import io.xpipe.app.util.BooleanScope;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property; import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Value; import lombok.Value;
@ -225,27 +222,10 @@ public abstract class UpdateHandler {
} }
event("Executing update ..."); event("Executing update ...");
OperationMode.executeAfterShutdown(() -> { executeUpdate();
try {
var performedUpdate = new PerformedUpdate(
preparedUpdate.getValue().getVersion(),
preparedUpdate.getValue().getBody(),
preparedUpdate.getValue().getVersion());
AppCache.update("performedUpdate", performedUpdate);
executeUpdateOnCloseImpl();
// In case we perform any operations such as opening a terminal
// give it some time to open while this process is still alive
// Otherwise it might quit because the parent process is dead already
ThreadHelper.sleep(100);
} catch (Throwable ex) {
ex.printStackTrace();
}
});
} }
public void executeUpdateOnCloseImpl() throws Exception { public void executeUpdate() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }