From 759ced341742e934424714c461565ada00b00af3 Mon Sep 17 00:00:00 2001 From: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com> Date: Wed, 30 Jun 2021 14:27:18 -0700 Subject: [PATCH] Updater debug utility --- _locales/en/messages.json | 4 + app/menu.ts | 10 ++ main.js | 13 ++ ...linux-setup.json => menu-linux-setup.json} | 0 ...enu-windows-linux.json => menu-linux.json} | 0 test/app/fixtures/menu-mac-os-setup.json | 4 + test/app/fixtures/menu-mac-os.json | 4 + test/app/fixtures/menu-windows-setup.json | 164 ++++++++++++++++++ test/app/fixtures/menu-windows.json | 157 +++++++++++++++++ test/app/menu_test.js | 9 +- ts/updater/common.ts | 14 +- ts/updater/index.ts | 17 +- ts/updater/macos.ts | 14 +- ts/updater/windows.ts | 14 +- 14 files changed, 409 insertions(+), 15 deletions(-) rename test/app/fixtures/{menu-windows-linux-setup.json => menu-linux-setup.json} (100%) rename test/app/fixtures/{menu-windows-linux.json => menu-linux.json} (100%) create mode 100644 test/app/fixtures/menu-windows-setup.json create mode 100644 test/app/fixtures/menu-windows.json diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 7df3e400f..2534ef47e 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -663,6 +663,10 @@ "message": "Debug Log", "description": "View menu item to open the debug log (title case)" }, + "forceUpdate": { + "message": "Force Update", + "description": "View menu item to force the app to update download and install" + }, "helpMenuShowKeyboardShortcuts": { "message": "Show Keyboard Shortcuts", "description": "Item under the help menu, pops up a screen showing the application's keyboard shortcuts" diff --git a/app/menu.ts b/app/menu.ts index 3c6ece28d..63815a07e 100644 --- a/app/menu.ts +++ b/app/menu.ts @@ -24,6 +24,7 @@ type OptionsType = { openSupportPage: () => unknown; setupAsNewDevice: () => unknown; setupAsStandalone: () => unknown; + forceUpdate: () => unknown; showAbout: () => unknown; showDebugLog: () => unknown; showKeyboardShortcuts: () => unknown; @@ -52,6 +53,7 @@ export const createTemplate = ( platform, setupAsNewDevice, setupAsStandalone, + forceUpdate, showAbout, showDebugLog, showKeyboardShortcuts, @@ -162,6 +164,14 @@ export const createTemplate = ( }, ] : []), + ...(devTools && platform !== 'linux' + ? [ + { + label: messages.forceUpdate.message, + click: forceUpdate, + }, + ] + : []), ], }, { diff --git a/main.js b/main.js index 701ce170a..587ca0228 100644 --- a/main.js +++ b/main.js @@ -666,6 +666,18 @@ async function readyForUpdates() { } } +async function forceUpdate() { + try { + logger.info('starting force update'); + await updater.force(); + } catch (error) { + logger.error( + 'Error during force update:', + error && error.stack ? error.stack : error + ); + } +} + ipc.once('ready-for-updates', readyForUpdates); const TEN_MINUTES = 10 * 60 * 1000; @@ -1404,6 +1416,7 @@ function setupMenu(options) { platform, setupAsNewDevice, setupAsStandalone, + forceUpdate, }; const template = createTemplate(menuOptions, locale.messages); const menu = Menu.buildFromTemplate(template); diff --git a/test/app/fixtures/menu-windows-linux-setup.json b/test/app/fixtures/menu-linux-setup.json similarity index 100% rename from test/app/fixtures/menu-windows-linux-setup.json rename to test/app/fixtures/menu-linux-setup.json diff --git a/test/app/fixtures/menu-windows-linux.json b/test/app/fixtures/menu-linux.json similarity index 100% rename from test/app/fixtures/menu-windows-linux.json rename to test/app/fixtures/menu-linux.json diff --git a/test/app/fixtures/menu-mac-os-setup.json b/test/app/fixtures/menu-mac-os-setup.json index f09d3765f..c933942f7 100644 --- a/test/app/fixtures/menu-mac-os-setup.json +++ b/test/app/fixtures/menu-mac-os-setup.json @@ -161,6 +161,10 @@ { "label": "Toggle Developer Tools", "role": "toggleDevTools" + }, + { + "label": "Force Update", + "click": null } ] }, diff --git a/test/app/fixtures/menu-mac-os.json b/test/app/fixtures/menu-mac-os.json index 25acc070f..db0cf28fa 100644 --- a/test/app/fixtures/menu-mac-os.json +++ b/test/app/fixtures/menu-mac-os.json @@ -154,6 +154,10 @@ { "label": "Toggle Developer Tools", "role": "toggleDevTools" + }, + { + "label": "Force Update", + "click": null } ] }, diff --git a/test/app/fixtures/menu-windows-setup.json b/test/app/fixtures/menu-windows-setup.json new file mode 100644 index 000000000..ab089f796 --- /dev/null +++ b/test/app/fixtures/menu-windows-setup.json @@ -0,0 +1,164 @@ +[ + { + "label": "&File", + "submenu": [ + { + "label": "Set Up as New Device", + "click": null + }, + { + "type": "separator" + }, + { + "label": "Create/upload sticker pack", + "click": null + }, + { + "accelerator": "CommandOrControl+,", + "label": "Preferences…", + "click": null + }, + { + "type": "separator" + }, + { + "label": "Quit Signal", + "role": "quit" + } + ] + }, + { + "label": "&Edit", + "submenu": [ + { + "label": "Undo", + "role": "undo" + }, + { + "label": "Redo", + "role": "redo" + }, + { + "type": "separator" + }, + { + "label": "Cut", + "role": "cut" + }, + { + "label": "Copy", + "role": "copy" + }, + { + "label": "Paste", + "role": "paste" + }, + { + "label": "Paste and Match Style", + "role": "pasteAndMatchStyle" + }, + { + "label": "Delete", + "role": "delete" + }, + { + "label": "Select All", + "role": "selectAll" + } + ] + }, + { + "label": "&View", + "submenu": [ + { + "label": "Actual Size", + "role": "resetZoom" + }, + { + "accelerator": "Control+=", + "label": "Zoom In", + "role": "zoomIn" + }, + { + "label": "Zoom Out", + "role": "zoomOut" + }, + { + "type": "separator" + }, + { + "label": "Toggle Full Screen", + "role": "togglefullscreen" + }, + { + "type": "separator" + }, + { + "label": "Debug Log", + "click": null + }, + { + "type": "separator" + }, + { + "label": "Toggle Developer Tools", + "role": "toggleDevTools" + }, + { + "label": "Force Update", + "click": null + } + ] + }, + { + "label": "&Window", + "role": "window", + "submenu": [ + { + "label": "Minimize", + "role": "minimize" + } + ] + }, + { + "label": "&Help", + "role": "help", + "submenu": [ + { + "label": "Show Keyboard Shortcuts", + "accelerator": "CmdOrCtrl+/", + "click": null + }, + { + "type": "separator" + }, + { + "label": "Contact Us", + "click": null + }, + { + "label": "Go to Release Notes", + "click": null + }, + { + "label": "Go to Forums", + "click": null + }, + { + "label": "Go to Support Page", + "click": null + }, + { + "label": "Join the Beta", + "click": null + }, + { + "type": "separator" + }, + { + "label": "About Signal Desktop", + "click": null + } + ] + } +] diff --git a/test/app/fixtures/menu-windows.json b/test/app/fixtures/menu-windows.json new file mode 100644 index 000000000..4ea55bc04 --- /dev/null +++ b/test/app/fixtures/menu-windows.json @@ -0,0 +1,157 @@ +[ + { + "label": "&File", + "submenu": [ + { + "label": "Create/upload sticker pack", + "click": null + }, + { + "accelerator": "CommandOrControl+,", + "label": "Preferences…", + "click": null + }, + { + "type": "separator" + }, + { + "label": "Quit Signal", + "role": "quit" + } + ] + }, + { + "label": "&Edit", + "submenu": [ + { + "label": "Undo", + "role": "undo" + }, + { + "label": "Redo", + "role": "redo" + }, + { + "type": "separator" + }, + { + "label": "Cut", + "role": "cut" + }, + { + "label": "Copy", + "role": "copy" + }, + { + "label": "Paste", + "role": "paste" + }, + { + "label": "Paste and Match Style", + "role": "pasteAndMatchStyle" + }, + { + "label": "Delete", + "role": "delete" + }, + { + "label": "Select All", + "role": "selectAll" + } + ] + }, + { + "label": "&View", + "submenu": [ + { + "label": "Actual Size", + "role": "resetZoom" + }, + { + "accelerator": "Control+=", + "label": "Zoom In", + "role": "zoomIn" + }, + { + "label": "Zoom Out", + "role": "zoomOut" + }, + { + "type": "separator" + }, + { + "label": "Toggle Full Screen", + "role": "togglefullscreen" + }, + { + "type": "separator" + }, + { + "label": "Debug Log", + "click": null + }, + { + "type": "separator" + }, + { + "label": "Toggle Developer Tools", + "role": "toggleDevTools" + }, + { + "label": "Force Update", + "click": null + } + ] + }, + { + "label": "&Window", + "role": "window", + "submenu": [ + { + "label": "Minimize", + "role": "minimize" + } + ] + }, + { + "label": "&Help", + "role": "help", + "submenu": [ + { + "label": "Show Keyboard Shortcuts", + "accelerator": "CmdOrCtrl+/", + "click": null + }, + { + "type": "separator" + }, + { + "label": "Contact Us", + "click": null + }, + { + "label": "Go to Release Notes", + "click": null + }, + { + "label": "Go to Forums", + "click": null + }, + { + "label": "Go to Support Page", + "click": null + }, + { + "label": "Join the Beta", + "click": null + }, + { + "type": "separator" + }, + { + "label": "About Signal Desktop", + "click": null + } + ] + } +] diff --git a/test/app/menu_test.js b/test/app/menu_test.js index 4e3feb7a3..c4fe6b8c4 100644 --- a/test/app/menu_test.js +++ b/test/app/menu_test.js @@ -19,16 +19,16 @@ const PLATFORMS = [ label: 'Windows', platform: 'win32', fixtures: { - default: './fixtures/menu-windows-linux', - setup: './fixtures/menu-windows-linux-setup', + default: './fixtures/menu-windows', + setup: './fixtures/menu-windows-setup', }, }, { label: 'Linux', platform: 'linux', fixtures: { - default: './fixtures/menu-windows-linux', - setup: './fixtures/menu-windows-linux-setup', + default: './fixtures/menu-linux', + setup: './fixtures/menu-linux-setup', }, }, ]; @@ -60,6 +60,7 @@ describe('SignalMenu', () => { includeSetup, setupAsNewDevice: null, setupAsStandalone: null, + forceUpdate: null, showAbout: null, showDebugLog: null, showKeyboardShortcuts: null, diff --git a/ts/updater/common.ts b/ts/updater/common.ts index 8e06cddef..71bfa18a9 100644 --- a/ts/updater/common.ts +++ b/ts/updater/common.ts @@ -40,8 +40,13 @@ const { platform } = process; export const ACK_RENDER_TIMEOUT = 10000; +export type UpdaterInterface = { + force(): Promise; +}; + export async function checkForUpdates( - logger: LoggerType + logger: LoggerType, + forceUpdate = false ): Promise<{ fileName: string; version: string; @@ -55,8 +60,11 @@ export async function checkForUpdates( return null; } - if (isVersionNewer(version)) { - logger.info(`checkForUpdates: found newer version ${version}`); + if (forceUpdate || isVersionNewer(version)) { + logger.info( + `checkForUpdates: found newer version ${version} ` + + `forceUpdate=${forceUpdate}` + ); return { fileName: getUpdateFileName(yaml), diff --git a/ts/updater/index.ts b/ts/updater/index.ts index 5ea4281bf..1ab3005ae 100644 --- a/ts/updater/index.ts +++ b/ts/updater/index.ts @@ -4,6 +4,7 @@ import { get as getFromConfig } from 'config'; import { BrowserWindow } from 'electron'; +import { UpdaterInterface } from './common'; import { start as startMacOS } from './macos'; import { start as startWindows } from './windows'; import { LocaleType } from '../types/I18N'; @@ -11,6 +12,8 @@ import { LoggerType } from '../types/Logging'; let initialized = false; +let updater: UpdaterInterface | undefined; + export async function start( getMainWindow: () => BrowserWindow, locale?: LocaleType, @@ -39,14 +42,24 @@ export async function start( } if (platform === 'win32') { - await startWindows(getMainWindow, locale, logger); + updater = await startWindows(getMainWindow, locale, logger); } else if (platform === 'darwin') { - await startMacOS(getMainWindow, locale, logger); + updater = await startMacOS(getMainWindow, locale, logger); } else { throw new Error('updater/start: Unsupported platform'); } } +export async function force(): Promise { + if (!initialized) { + throw new Error("updater/force: Updates haven't been initialized!"); + } + + if (updater) { + await updater.force(); + } +} + function autoUpdateDisabled() { return ( process.platform === 'linux' || diff --git a/ts/updater/macos.ts b/ts/updater/macos.ts index a3834aea0..fec772ffd 100644 --- a/ts/updater/macos.ts +++ b/ts/updater/macos.ts @@ -21,6 +21,7 @@ import { setUpdateListener, showCannotUpdateDialog, showUpdateDialog, + UpdaterInterface, } from './common'; import { LocaleType } from '../types/I18N'; import { LoggerType } from '../types/Logging'; @@ -36,7 +37,7 @@ export async function start( getMainWindow: () => BrowserWindow, locale: LocaleType, logger: LoggerType -): Promise { +): Promise { logger.info('macos/start: starting checks...'); loggerForQuitHandler = logger; @@ -53,6 +54,12 @@ export async function start( setUpdateListener(createUpdater(logger)); await checkDownloadAndInstall(getMainWindow, locale, logger); + + return { + async force(): Promise { + return checkDownloadAndInstall(getMainWindow, locale, logger, true); + }, + }; } let fileName: string; @@ -63,11 +70,12 @@ let loggerForQuitHandler: LoggerType; async function checkDownloadAndInstall( getMainWindow: () => BrowserWindow, locale: LocaleType, - logger: LoggerType + logger: LoggerType, + force = false ) { logger.info('checkDownloadAndInstall: checking for update...'); try { - const result = await checkForUpdates(logger); + const result = await checkForUpdates(logger, force); if (!result) { return; } diff --git a/ts/updater/windows.ts b/ts/updater/windows.ts index ac56dd39f..2e5136d23 100644 --- a/ts/updater/windows.ts +++ b/ts/updater/windows.ts @@ -18,6 +18,7 @@ import { setUpdateListener, showCannotUpdateDialog, showUpdateDialog, + UpdaterInterface, } from './common'; import { LocaleType } from '../types/I18N'; import { LoggerType } from '../types/Logging'; @@ -41,7 +42,7 @@ export async function start( getMainWindow: () => BrowserWindow, locale: LocaleType, logger: LoggerType -): Promise { +): Promise { logger.info('windows/start: starting checks...'); loggerForQuitHandler = logger; @@ -59,16 +60,23 @@ export async function start( await deletePreviousInstallers(logger); await checkDownloadAndInstall(getMainWindow, locale, logger); + + return { + async force(): Promise { + return checkDownloadAndInstall(getMainWindow, locale, logger, true); + }, + }; } async function checkDownloadAndInstall( getMainWindow: () => BrowserWindow, locale: LocaleType, - logger: LoggerType + logger: LoggerType, + force = false ) { try { logger.info('checkDownloadAndInstall: checking for update...'); - const result = await checkForUpdates(logger); + const result = await checkForUpdates(logger, force); if (!result) { return; }