mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Reorganize responsibilities for checking updates
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
parent
e2de1449d5
commit
129f9c1953
@ -12,7 +12,8 @@ export type ApplicationUpdateStatusEventId =
|
|||||||
| "download-for-update-started"
|
| "download-for-update-started"
|
||||||
| "download-for-update-failed";
|
| "download-for-update-failed";
|
||||||
|
|
||||||
export type ApplicationUpdateStatusChannel = Channel<{ eventId: ApplicationUpdateStatusEventId; version?: string }>;
|
export interface ApplicationUpdateStatusChannelMessage { eventId: ApplicationUpdateStatusEventId; version?: string }
|
||||||
|
export type ApplicationUpdateStatusChannel = Channel<ApplicationUpdateStatusChannelMessage>;
|
||||||
|
|
||||||
const applicationUpdateStatusChannelInjectable = getInjectable({
|
const applicationUpdateStatusChannelInjectable = getInjectable({
|
||||||
id: "application-update-status-channel",
|
id: "application-update-status-channel",
|
||||||
|
|||||||
@ -20,6 +20,7 @@ const checkForPlatformUpdatesInjectable = getInjectable({
|
|||||||
return async (updateChannel) => {
|
return async (updateChannel) => {
|
||||||
electronUpdater.channel = updateChannel.id;
|
electronUpdater.channel = updateChannel.id;
|
||||||
electronUpdater.autoDownload = false;
|
electronUpdater.autoDownload = false;
|
||||||
|
electronUpdater.allowDowngrade = false;
|
||||||
|
|
||||||
let result: UpdateCheckResult;
|
let result: UpdateCheckResult;
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,7 @@ describe("check-for-platform-updates", () => {
|
|||||||
electronUpdaterFake = {
|
electronUpdaterFake = {
|
||||||
channel: undefined,
|
channel: undefined,
|
||||||
autoDownload: undefined,
|
autoDownload: undefined,
|
||||||
|
allowDowngrade: undefined,
|
||||||
|
|
||||||
checkForUpdates: checkForUpdatesMock,
|
checkForUpdates: checkForUpdatesMock,
|
||||||
} as unknown as AppUpdater;
|
} as unknown as AppUpdater;
|
||||||
@ -58,6 +59,10 @@ describe("check-for-platform-updates", () => {
|
|||||||
expect(electronUpdaterFake.channel).toBe("some-update-channel");
|
expect(electronUpdaterFake.channel).toBe("some-update-channel");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("sets flag for allowing downgrade", () => {
|
||||||
|
expect(electronUpdaterFake.allowDowngrade).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
it("disables auto downloading for being controlled", () => {
|
it("disables auto downloading for being controlled", () => {
|
||||||
expect(electronUpdaterFake.autoDownload).toBe(false);
|
expect(electronUpdaterFake.autoDownload).toBe(false);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,17 +7,12 @@ import { computed } from "mobx";
|
|||||||
import updatingIsEnabledInjectable from "./updating-is-enabled.injectable";
|
import updatingIsEnabledInjectable from "./updating-is-enabled.injectable";
|
||||||
import { trayMenuItemInjectionToken } from "../tray/tray-menu-item/tray-menu-item-injection-token";
|
import { trayMenuItemInjectionToken } from "../tray/tray-menu-item/tray-menu-item-injection-token";
|
||||||
import showApplicationWindowInjectable from "../start-main-application/lens-window/show-application-window.injectable";
|
import showApplicationWindowInjectable from "../start-main-application/lens-window/show-application-window.injectable";
|
||||||
import askBooleanInjectable from "../ask-boolean/ask-boolean.injectable";
|
|
||||||
import quitAndInstallUpdateInjectable from "../electron-app/features/quit-and-install-update.injectable";
|
|
||||||
import discoveredUpdateVersionInjectable from "../../common/application-update/discovered-update-version/discovered-update-version.injectable";
|
import discoveredUpdateVersionInjectable from "../../common/application-update/discovered-update-version/discovered-update-version.injectable";
|
||||||
import updateIsBeingDownloadedInjectable from "../../common/application-update/update-is-being-downloaded/update-is-being-downloaded.injectable";
|
import updateIsBeingDownloadedInjectable from "../../common/application-update/update-is-being-downloaded/update-is-being-downloaded.injectable";
|
||||||
import updatesAreBeingDiscoveredInjectable from "../../common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable";
|
import updatesAreBeingDiscoveredInjectable from "../../common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable";
|
||||||
import checkForUpdatesInjectable from "./check-for-updates/check-for-updates.injectable";
|
|
||||||
import downloadUpdateInjectable from "./download-update/download-update.injectable";
|
|
||||||
import progressOfUpdateDownloadInjectable from "../../common/application-update/progress-of-update-download/progress-of-update-download.injectable";
|
import progressOfUpdateDownloadInjectable from "../../common/application-update/progress-of-update-download/progress-of-update-download.injectable";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import { sendToAgnosticChannelInjectionToken } from "../../common/channel/send-to-agnostic-channel-injection-token";
|
import checkForUpdatesInjectable from "./check-for-updates/check-for-updates.injectable";
|
||||||
import applicationUpdateStatusChannelInjectable from "../../common/application-update/application-update-status-channel.injectable";
|
|
||||||
|
|
||||||
const checkForUpdatesTrayItemInjectable = getInjectable({
|
const checkForUpdatesTrayItemInjectable = getInjectable({
|
||||||
id: "check-for-updates-tray-item",
|
id: "check-for-updates-tray-item",
|
||||||
@ -26,15 +21,10 @@ const checkForUpdatesTrayItemInjectable = getInjectable({
|
|||||||
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
const showApplicationWindow = di.inject(showApplicationWindowInjectable);
|
||||||
const updatingIsEnabled = di.inject(updatingIsEnabledInjectable);
|
const updatingIsEnabled = di.inject(updatingIsEnabledInjectable);
|
||||||
const progressOfUpdateDownload = di.inject(progressOfUpdateDownloadInjectable);
|
const progressOfUpdateDownload = di.inject(progressOfUpdateDownloadInjectable);
|
||||||
const askBoolean = di.inject(askBooleanInjectable);
|
|
||||||
const quitAndInstallUpdate = di.inject(quitAndInstallUpdateInjectable);
|
|
||||||
const discoveredVersionState = di.inject(discoveredUpdateVersionInjectable);
|
const discoveredVersionState = di.inject(discoveredUpdateVersionInjectable);
|
||||||
const downloadingUpdateState = di.inject(updateIsBeingDownloadedInjectable);
|
const downloadingUpdateState = di.inject(updateIsBeingDownloadedInjectable);
|
||||||
const checkingForUpdatesState = di.inject(updatesAreBeingDiscoveredInjectable);
|
const checkingForUpdatesState = di.inject(updatesAreBeingDiscoveredInjectable);
|
||||||
const checkForUpdates = di.inject(checkForUpdatesInjectable);
|
const checkForUpdates = di.inject(checkForUpdatesInjectable);
|
||||||
const downloadUpdate = di.inject(downloadUpdateInjectable);
|
|
||||||
const sendToAgnosticChannel = di.inject(sendToAgnosticChannelInjectionToken);
|
|
||||||
const applicationUpdateStatusChannel = di.inject(applicationUpdateStatusChannelInjectable);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: "check-for-updates",
|
id: "check-for-updates",
|
||||||
@ -62,31 +52,7 @@ const checkForUpdatesTrayItemInjectable = getInjectable({
|
|||||||
visible: computed(() => updatingIsEnabled),
|
visible: computed(() => updatingIsEnabled),
|
||||||
|
|
||||||
click: async () => {
|
click: async () => {
|
||||||
const { updateWasDiscovered, version } = await checkForUpdates();
|
await checkForUpdates();
|
||||||
|
|
||||||
if (updateWasDiscovered) {
|
|
||||||
sendToAgnosticChannel(applicationUpdateStatusChannel, { eventId: "download-for-update-started", version });
|
|
||||||
|
|
||||||
// Note: intentional orphan promise to make download happen in the background
|
|
||||||
downloadUpdate().then(async ({ downloadWasSuccessful }) => {
|
|
||||||
|
|
||||||
if (!downloadWasSuccessful) {
|
|
||||||
sendToAgnosticChannel(applicationUpdateStatusChannel, { eventId: "download-for-update-failed" });
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const userWantsToInstallUpdate = await askBoolean({
|
|
||||||
id: "install-update",
|
|
||||||
title: "Update available",
|
|
||||||
question: `Version ${version} of Lens IDE is available and ready to be installed. Would you like to update now?`,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (userWantsToInstallUpdate) {
|
|
||||||
quitAndInstallUpdate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await showApplicationWindow();
|
await showApplicationWindow();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { ApplicationUpdateStatusChannelMessage } from "../../../common/application-update/application-update-status-channel.injectable";
|
||||||
|
import { sendToAgnosticChannelInjectionToken } from "../../../common/channel/send-to-agnostic-channel-injection-token";
|
||||||
|
import applicationUpdateStatusChannelInjectable from "../../../common/application-update/application-update-status-channel.injectable";
|
||||||
|
|
||||||
|
const broadcastChangeInUpdatingStatusInjectable = getInjectable({
|
||||||
|
id: "broadcast-change-in-updating-status",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const sendToAgnosticChannel = di.inject(sendToAgnosticChannelInjectionToken);
|
||||||
|
const applicationUpdateStatusChannel = di.inject(applicationUpdateStatusChannelInjectable);
|
||||||
|
|
||||||
|
return (data: ApplicationUpdateStatusChannelMessage) => {
|
||||||
|
sendToAgnosticChannel(applicationUpdateStatusChannel, data);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default broadcastChangeInUpdatingStatusInjectable;
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { UpdateChannel } from "../update-channels";
|
||||||
|
import checkForPlatformUpdatesInjectable from "../check-for-platform-updates/check-for-platform-updates.injectable";
|
||||||
|
|
||||||
|
interface CheckForUpdatesFromChannelResult {
|
||||||
|
updateWasDiscovered: boolean;
|
||||||
|
version?: string;
|
||||||
|
actualUpdateChannel?: UpdateChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkForUpdatesStartingFromChannelInjectable = getInjectable({
|
||||||
|
id: "check-for-updates-starting-from-channel",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const checkForPlatformUpdates = di.inject(
|
||||||
|
checkForPlatformUpdatesInjectable,
|
||||||
|
);
|
||||||
|
|
||||||
|
const _recursiveCheck = async (
|
||||||
|
updateChannel: UpdateChannel,
|
||||||
|
): Promise<CheckForUpdatesFromChannelResult> => {
|
||||||
|
const result = await checkForPlatformUpdates(updateChannel);
|
||||||
|
|
||||||
|
if (result.updateWasDiscovered) {
|
||||||
|
return {
|
||||||
|
updateWasDiscovered: true,
|
||||||
|
version: result.version,
|
||||||
|
actualUpdateChannel: updateChannel,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updateChannel.moreStableUpdateChannel) {
|
||||||
|
return await _recursiveCheck(updateChannel.moreStableUpdateChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { updateWasDiscovered: false };
|
||||||
|
};
|
||||||
|
|
||||||
|
return _recursiveCheck;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default checkForUpdatesStartingFromChannelInjectable;
|
||||||
@ -3,103 +3,91 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { CheckForPlatformUpdates } from "../check-for-platform-updates/check-for-platform-updates.injectable";
|
|
||||||
import checkForPlatformUpdatesInjectable from "../check-for-platform-updates/check-for-platform-updates.injectable";
|
|
||||||
import type { UpdateChannel } from "../update-channels";
|
|
||||||
import selectedUpdateChannelInjectable from "../selected-update-channel.injectable";
|
import selectedUpdateChannelInjectable from "../selected-update-channel.injectable";
|
||||||
import updatesAreBeingDiscoveredInjectable from "../../../common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable";
|
import updatesAreBeingDiscoveredInjectable from "../../../common/application-update/updates-are-being-discovered/updates-are-being-discovered.injectable";
|
||||||
import discoveredUpdateVersionInjectable from "../../../common/application-update/discovered-update-version/discovered-update-version.injectable";
|
import discoveredUpdateVersionInjectable from "../../../common/application-update/discovered-update-version/discovered-update-version.injectable";
|
||||||
import { runInAction } from "mobx";
|
import { runInAction } from "mobx";
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import applicationUpdateStatusChannelInjectable from "../../../common/application-update/application-update-status-channel.injectable";
|
import askBooleanInjectable from "../../ask-boolean/ask-boolean.injectable";
|
||||||
import { sendToAgnosticChannelInjectionToken } from "../../../common/channel/send-to-agnostic-channel-injection-token";
|
import quitAndInstallUpdateInjectable from "../../electron-app/features/quit-and-install-update.injectable";
|
||||||
|
import downloadUpdateInjectable from "../download-update/download-update.injectable";
|
||||||
|
import broadcastChangeInUpdatingStatusInjectable from "./broadcast-change-in-updating-status.injectable";
|
||||||
|
import checkForUpdatesStartingFromChannelInjectable from "./check-for-updates-starting-from-channel.injectable";
|
||||||
|
|
||||||
const checkForUpdatesInjectable = getInjectable({
|
const checkForUpdatesInjectable = getInjectable({
|
||||||
id: "check-for-updates",
|
id: "check-for-updates",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
|
const askBoolean = di.inject(askBooleanInjectable);
|
||||||
|
const quitAndInstallUpdate = di.inject(quitAndInstallUpdateInjectable);
|
||||||
|
const downloadUpdate = di.inject(downloadUpdateInjectable);
|
||||||
const selectedUpdateChannel = di.inject(selectedUpdateChannelInjectable);
|
const selectedUpdateChannel = di.inject(selectedUpdateChannelInjectable);
|
||||||
const sendToAgnosticChannel = di.inject(sendToAgnosticChannelInjectionToken);
|
const broadcastChangeInUpdatingStatus = di.inject(broadcastChangeInUpdatingStatusInjectable);
|
||||||
const applicationUpdateStatusChannel = di.inject(applicationUpdateStatusChannelInjectable);
|
const checkingForUpdatesState = di.inject(updatesAreBeingDiscoveredInjectable);
|
||||||
|
|
||||||
const checkForPlatformUpdates = di.inject(
|
|
||||||
checkForPlatformUpdatesInjectable,
|
|
||||||
);
|
|
||||||
|
|
||||||
const checkingForUpdatesState = di.inject(
|
|
||||||
updatesAreBeingDiscoveredInjectable,
|
|
||||||
);
|
|
||||||
|
|
||||||
const discoveredVersionState = di.inject(discoveredUpdateVersionInjectable);
|
const discoveredVersionState = di.inject(discoveredUpdateVersionInjectable);
|
||||||
|
const checkForUpdatesStartingFromChannel = di.inject(checkForUpdatesStartingFromChannelInjectable);
|
||||||
|
|
||||||
return async () => {
|
return async () => {
|
||||||
|
broadcastChangeInUpdatingStatus({ eventId: "checking-for-updates" });
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
checkingForUpdatesState.set(true);
|
checkingForUpdatesState.set(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
const checkForUpdatesStartingFromChannel =
|
|
||||||
checkForUpdatesStartingFromChannelFor(checkForPlatformUpdates);
|
|
||||||
|
|
||||||
sendToAgnosticChannel(applicationUpdateStatusChannel, { eventId: "checking-for-updates" });
|
|
||||||
|
|
||||||
const { updateWasDiscovered, version, actualUpdateChannel } =
|
const { updateWasDiscovered, version, actualUpdateChannel } =
|
||||||
await checkForUpdatesStartingFromChannel(selectedUpdateChannel.value.get());
|
await checkForUpdatesStartingFromChannel(selectedUpdateChannel.value.get());
|
||||||
|
|
||||||
if (!updateWasDiscovered) {
|
if (!updateWasDiscovered) {
|
||||||
sendToAgnosticChannel(applicationUpdateStatusChannel, { eventId: "no-updates-available" });
|
broadcastChangeInUpdatingStatus({ eventId: "no-updates-available" });
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
discoveredVersionState.set(null);
|
||||||
|
checkingForUpdatesState.set(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
broadcastChangeInUpdatingStatus({
|
||||||
|
eventId: "download-for-update-started",
|
||||||
|
version,
|
||||||
|
});
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
if (!updateWasDiscovered) {
|
// TODO: Unacceptable damage caused by strict mode
|
||||||
discoveredVersionState.set(null);
|
assert(version);
|
||||||
} else {
|
assert(actualUpdateChannel);
|
||||||
|
|
||||||
// TODO: Unacceptable damage caused by strict mode
|
discoveredVersionState.set({
|
||||||
assert(version);
|
version,
|
||||||
assert(actualUpdateChannel);
|
updateChannel: actualUpdateChannel,
|
||||||
|
});
|
||||||
discoveredVersionState.set({
|
|
||||||
version,
|
|
||||||
updateChannel: actualUpdateChannel,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
checkingForUpdatesState.set(false);
|
checkingForUpdatesState.set(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
return { updateWasDiscovered, version };
|
// Note: intentional orphan promise to make download happen in the background
|
||||||
|
downloadUpdate().then(async ({ downloadWasSuccessful }) => {
|
||||||
|
if (!downloadWasSuccessful) {
|
||||||
|
broadcastChangeInUpdatingStatus({
|
||||||
|
eventId: "download-for-update-failed",
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userWantsToInstallUpdate = await askBoolean({
|
||||||
|
id: "install-update",
|
||||||
|
title: "Update Available",
|
||||||
|
question: `Version ${version} of Lens IDE is available and ready to be installed. Would you like to update now?`,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (userWantsToInstallUpdate) {
|
||||||
|
quitAndInstallUpdate();
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default checkForUpdatesInjectable;
|
export default checkForUpdatesInjectable;
|
||||||
|
|
||||||
const checkForUpdatesStartingFromChannelFor = (
|
|
||||||
checkForPlatformUpdates: CheckForPlatformUpdates,
|
|
||||||
) => {
|
|
||||||
const _recursiveCheck = async (
|
|
||||||
updateChannel: UpdateChannel,
|
|
||||||
): Promise<{
|
|
||||||
updateWasDiscovered: boolean;
|
|
||||||
version?: string;
|
|
||||||
actualUpdateChannel?: UpdateChannel;
|
|
||||||
}> => {
|
|
||||||
const result = await checkForPlatformUpdates(updateChannel);
|
|
||||||
|
|
||||||
if (result.updateWasDiscovered) {
|
|
||||||
return {
|
|
||||||
updateWasDiscovered: true,
|
|
||||||
version: result.version,
|
|
||||||
actualUpdateChannel: updateChannel,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateChannel.moreStableUpdateChannel) {
|
|
||||||
return await _recursiveCheck(updateChannel.moreStableUpdateChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
return { updateWasDiscovered: false };
|
|
||||||
};
|
|
||||||
|
|
||||||
return _recursiveCheck;
|
|
||||||
};
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user