Rework updater to fix some bugs [release]

This commit is contained in:
crschnick 2023-04-01 12:04:01 +00:00
parent 5444bc785f
commit b1f2272fc2
9 changed files with 104 additions and 113 deletions

View file

@ -38,6 +38,7 @@ public class FileBrowserComp extends SimpleComp {
@Override
protected Region createSimple() {
var bookmarksList = new BookmarkList(model).createRegion();
VBox.setVgrow(bookmarksList, Priority.ALWAYS);
var localDownloadStage = new LocalFileTransferComp(model.getLocalTransfersStage()).hide(Bindings.createBooleanBinding(() -> {
if (model.getOpenFileSystems().size() == 0) {
return true;

View file

@ -40,20 +40,16 @@ public class UpdateCheckComp extends SimpleComp {
}
private void restart() {
// Check if we're still on latest
if (!AppUpdater.get().isDownloadedUpdateStillLatest()) {
return;
}
AppUpdater.get().refreshUpdateCheckSilent();
AppUpdater.get().executeUpdateAndClose();
}
private void update() {
private void download() {
AppUpdater.get().downloadUpdateAsync();
}
private void refresh() {
AppUpdater.get().checkForUpdateAsync(true);
AppUpdater.get().checkForUpdateAsync();
}
private ObservableValue<String> descriptionText() {
@ -131,8 +127,6 @@ public class UpdateCheckComp extends SimpleComp {
updateReady));
button.getStyleClass().add("button-comp");
button.setOnAction(e -> {
AppUpdater.get().refreshUpdateState();
if (updateReady.getValue()) {
restart();
return;
@ -142,7 +136,7 @@ public class UpdateCheckComp extends SimpleComp {
Hyperlinks.open(
AppUpdater.get().getLastUpdateCheckResult().getValue().getReleaseUrl());
} else if (updateAvailable.getValue()) {
update();
download();
} else {
refresh();
}

View file

@ -88,7 +88,7 @@ public class TerminalErrorHandler implements ErrorHandler {
private static void handleProbableUpdate() {
try {
AppUpdater.init();
var rel = AppUpdater.get().checkForUpdate(true);
var rel = AppUpdater.get().refreshUpdateCheck();
if (rel != null && rel.isUpdate()) {
var update = AppWindowHelper.showBlockingAlert(alert -> {
alert.setAlertType(Alert.AlertType.INFORMATION);

View file

@ -1,5 +1,6 @@
package io.xpipe.app.update;
import io.xpipe.app.core.AppProperties;
import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.prefs.AppPrefs;
@ -96,26 +97,41 @@ public class AppDownloads {
}
}
public static String getLatestVersion(boolean omitErrors) {
return getLatestSuitableRelease(omitErrors)
public static String getLatestVersion() throws IOException {
return getLatestSuitableRelease()
.map(ghRelease -> ghRelease.getTagName())
.orElse("?");
}
public static Optional<GHRelease> getLatestSuitableRelease(boolean omitErrors) {
try {
var repo = getRepository();
// Always choose most up-to-date release as we assume that there are only full releases and prereleases
if (AppPrefs.get() != null && AppPrefs.get().updateToPrereleases().get()) {
return Optional.ofNullable(repo.listReleases().iterator().next());
}
public static Optional<GHRelease> getLatestIncludingPreRelease() throws IOException {
var repo = getRepository();
return Optional.ofNullable(repo.listReleases().iterator().next());
}
return Optional.ofNullable(repo.getLatestRelease());
} catch (IOException e) {
ErrorEvent.fromThrowable("Unable to fetch latest release information", e).omitted(omitErrors).handle();
return Optional.empty();
public static Optional<GHRelease> getLatestRelease() throws IOException {
var repo = getRepository();
return Optional.ofNullable(repo.getLatestRelease());
}
public static Optional<GHRelease> getLatestSuitableRelease() throws IOException {
var preIncluding = getLatestIncludingPreRelease();
if (AppPrefs.get() != null && AppPrefs.get().updateToPrereleases().get()) {
return preIncluding;
}
// If we are currently running a prerelease, always return this as the suitable release!
if (preIncluding.isPresent() && AppProperties.get().getVersion().equals(preIncluding.get().getTagName())) {
return preIncluding;
}
// If this release is not a prerelease, just return it to prevent querying another release
if (preIncluding.isPresent() && !preIncluding.get().isPrerelease()) {
return preIncluding;
}
return getLatestRelease();
}
public static Optional<GHRelease> getRelease(String version, boolean omitErrors) {

View file

@ -20,6 +20,7 @@ import lombok.With;
import lombok.extern.jackson.Jacksonized;
import org.kohsuke.github.GHRelease;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
@ -50,6 +51,8 @@ public class AppUpdater {
}
downloadedUpdate.setValue(AppCache.get("downloadedUpdate", DownloadedUpdate.class, () -> null));
// Check if the original version this was downloaded from is still the same
if (downloadedUpdate.getValue() != null
&& !downloadedUpdate
.getValue()
@ -57,6 +60,16 @@ public class AppUpdater {
.equals(AppProperties.get().getVersion())) {
downloadedUpdate.setValue(null);
}
// Check if somehow the downloaded version is equal to the current one
if (downloadedUpdate.getValue() != null
&& downloadedUpdate
.getValue()
.getVersion()
.equals(AppProperties.get().getVersion())) {
downloadedUpdate.setValue(null);
}
if (!XPipeDistributionType.get().supportsUpdate()) {
downloadedUpdate.setValue(null);
}
@ -64,20 +77,10 @@ public class AppUpdater {
downloadedUpdate.addListener((c, o, n) -> {
AppCache.update("downloadedUpdate", n);
});
lastUpdateCheckResult.setValue(AppCache.get("lastUpdateCheckResult", AvailableRelease.class, () -> null));
if (lastUpdateCheckResult.getValue() != null
&& lastUpdateCheckResult.getValue().getSourceVersion() != null
&& !lastUpdateCheckResult
.getValue()
.getSourceVersion()
.equals(AppProperties.get().getVersion())) {
lastUpdateCheckResult.setValue(null);
}
event("Last update check result was " + lastUpdateCheckResult.getValue());
lastUpdateCheckResult.addListener((c, o, n) -> {
AppCache.update("lastUpdateCheckResult", n);
downloadedUpdate.setValue(null);
});
refreshUpdateCheckSilent();
}
private static void event(String msg) {
@ -94,14 +97,17 @@ public class AppUpdater {
}
INSTANCE = new AppUpdater();
startBackgroundUpdater();
}
private static void startBackgroundUpdater() {
if (XPipeDistributionType.get().supportsUpdate()
&& XPipeDistributionType.get() != XPipeDistributionType.DEVELOPMENT) {
ThreadHelper.create("updater", true, () -> {
ThreadHelper.sleep(Duration.ofMinutes(10).toMillis());
event("Starting background updater thread");
while (true) {
var rel = INSTANCE.checkForUpdate(false);
var rel = INSTANCE.refreshUpdateCheckSilent();
if (rel != null
&& AppPrefs.get().automaticallyUpdate().get() && rel.isUpdate()) {
event("Performing background update");
@ -115,7 +121,7 @@ public class AppUpdater {
}
}
private static boolean isUpdate(String currentVersion) {
private static boolean isUpdate(String releaseVersion) {
if (AppPrefs.get() != null
&& AppPrefs.get().developerMode().getValue()
&& AppPrefs.get().developerDisableUpdateVersionCheck().get()) {
@ -123,10 +129,7 @@ public class AppUpdater {
return true;
}
if (
// true
// ||
!AppProperties.get().getVersion().equals(currentVersion)) {
if (!AppProperties.get().getVersion().equals(releaseVersion)) {
event("Release has a different version");
return true;
}
@ -134,13 +137,6 @@ public class AppUpdater {
return false;
}
public void refreshUpdateState() {
if (lastUpdateCheckResult.getValue() != null
&& !isUpdate(lastUpdateCheckResult.getValue().getVersion())) {
lastUpdateCheckResult.setValue(lastUpdateCheckResult.getValue().withUpdate(false));
}
}
public void downloadUpdateAsync() {
ThreadHelper.runAsync(() -> downloadUpdate());
}
@ -158,6 +154,10 @@ public class AppUpdater {
return;
}
if (!lastUpdateCheckResult.getValue().isUpdate()) {
return;
}
try (var ignored = new BusyProperty(busy)) {
event("Performing update download ...");
try {
@ -184,20 +184,12 @@ public class AppUpdater {
}
}
private boolean shouldPerformUpdate() {
public void executeUpdateAndClose() {
if (busy.getValue()) {
return false;
return;
}
if (downloadedUpdate.getValue() == null) {
return false;
}
return true;
}
public void executeUpdateAndClose() {
if (!shouldPerformUpdate()) {
return;
}
@ -222,69 +214,57 @@ public class AppUpdater {
});
}
public void checkForUpdateAsync(boolean forceCheck) {
ThreadHelper.runAsync(() -> checkForUpdate(forceCheck));
public void checkForUpdateAsync() {
ThreadHelper.runAsync(() -> refreshUpdateCheckSilent());
}
public synchronized boolean isDownloadedUpdateStillLatest() {
if (downloadedUpdate.getValue() == null) {
return false;
public synchronized AvailableRelease refreshUpdateCheckSilent() {
try {
return refreshUpdateCheck();
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).omit().handle();
return null;
}
var available = checkForUpdate(true);
if (available == null) {
return true;
}
return downloadedUpdate.getValue() != null
&& available.getVersion().equals(downloadedUpdate.getValue().getVersion());
}
public synchronized AvailableRelease checkForUpdate(boolean forceCheck) {
public synchronized AvailableRelease refreshUpdateCheck() throws IOException {
if (busy.getValue()) {
return lastUpdateCheckResult.getValue();
}
if (!forceCheck
&& lastUpdateCheckResult.getValue() != null
&& Duration.between(lastUpdateCheckResult.getValue().getCheckTime(), Instant.now())
.compareTo(Duration.ofHours(1))
<= 0) {
return lastUpdateCheckResult.getValue();
}
try (var ignored = new BusyProperty(busy)) {
var rel = AppDownloads.getLatestSuitableRelease(!forceCheck);
var rel = AppDownloads.getLatestSuitableRelease();
event("Determined latest suitable release "
+ rel.map(GHRelease::getName).orElse(null));
lastUpdateCheckResult.setValue(null);
if (rel.isEmpty()) {
lastUpdateCheckResult.setValue(null);
return null;
}
var isUpdate = isUpdate(rel.get().getTagName());
try {
var assetType = AppInstaller.getSuitablePlatformAsset();
var ghAsset = rel.orElseThrow().listAssets().toList().stream()
.filter(g -> assetType.isCorrectAsset(g.getName()))
.findAny();
if (ghAsset.isEmpty()) {
return null;
}
event("Selected asset " + ghAsset.get().getName());
lastUpdateCheckResult.setValue(new AvailableRelease(
AppProperties.get().getVersion(),
rel.get().getTagName(),
rel.get().getHtmlUrl().toString(),
ghAsset.get().getBrowserDownloadUrl(),
assetType,
Instant.now(),
isUpdate));
} catch (Exception ex) {
ErrorEvent.fromThrowable(ex).omit().handle();
// Don't update value if result is the same
if (lastUpdateCheckResult.getValue() != null && lastUpdateCheckResult.getValue().getVersion().equals(rel.get().getTagName())) {
return lastUpdateCheckResult.getValue();
}
var isUpdate = isUpdate(rel.get().getTagName());
var assetType = AppInstaller.getSuitablePlatformAsset();
var ghAsset = rel.orElseThrow().listAssets().toList().stream()
.filter(g -> assetType.isCorrectAsset(g.getName()))
.findAny();
if (ghAsset.isEmpty()) {
return null;
}
event("Selected asset " + ghAsset.get().getName());
lastUpdateCheckResult.setValue(new AvailableRelease(
AppProperties.get().getVersion(),
rel.get().getTagName(),
rel.get().getHtmlUrl().toString(),
ghAsset.get().getBrowserDownloadUrl(),
assetType,
Instant.now(),
isUpdate));
}
return lastUpdateCheckResult.getValue();

View file

@ -18,11 +18,6 @@ public class UpdateAvailableAlert {
return;
}
if (AppUpdater.get().getDownloadedUpdate().getValue() != null && !AppUpdater.get().isDownloadedUpdateStillLatest()) {
AppUpdater.get().getDownloadedUpdate().setValue(null);
return;
}
var update = AppWindowHelper.showBlockingAlert(alert -> {
alert.setTitle(AppI18n.get("updateReadyAlertTitle"));
alert.setHeaderText(AppI18n.get("updateReadyAlertHeader", AppUpdater.get().getDownloadedUpdate().getValue().getVersion()));

View file

@ -32,7 +32,7 @@ public class ProxyManagerProviderImpl extends ProxyManagerProvider {
@Override
public Optional<String> checkCompatibility(ShellControl s) throws Exception {
var version = ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion(true);
var version = ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion();
if (AppPrefs.get().developerDisableConnectorInstallationVersionCheck().get()) {
return Optional.of(AppI18n.get("versionCheckOverride"));
@ -59,7 +59,7 @@ public class ProxyManagerProviderImpl extends ProxyManagerProvider {
if (message.isPresent()) {
if (showAlert()) {
var version =
ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion(true);
ModuleHelper.isImage() ? AppProperties.get().getVersion() : AppDownloads.getLatestVersion();
AppInstaller.installOnRemoteMachine(s, version);
return true;
}

5
dist/changelogs/0.5.29.md vendored Normal file
View file

@ -0,0 +1,5 @@
- Introduce new download functionality in the file browser
- Allow for the creation of desktop shortcuts on portable distributions as well
- Fix file sizes sometimes being incorrectly displayed
- Fix background updater downloading the same version
- Fix various small bugs

View file

@ -1 +1 @@
0.5.28
0.5.29