Don't mkdir restore dir in updater
This commit is contained in:
parent
effe5aae6f
commit
df7cdfacc7
5 changed files with 96 additions and 21 deletions
|
@ -5,14 +5,14 @@ import { ipcRenderer } from 'electron';
|
|||
import type { DialogType } from '../types/Dialogs';
|
||||
import type {
|
||||
UpdateDialogOptionsType,
|
||||
ShowUpdateDialogAction,
|
||||
ShowUpdateDialogActionType,
|
||||
} from '../state/ducks/updates';
|
||||
|
||||
type UpdatesActions = {
|
||||
showUpdateDialog: (
|
||||
x: DialogType,
|
||||
options: UpdateDialogOptionsType
|
||||
) => ShowUpdateDialogAction;
|
||||
) => ShowUpdateDialogActionType;
|
||||
};
|
||||
|
||||
export function initializeUpdateListener(updatesActions: UpdatesActions): void {
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
import { ipcRenderer } from 'electron';
|
||||
|
||||
export function startUpdate(): void {
|
||||
ipcRenderer.invoke('start-update');
|
||||
export function startUpdate(): Promise<void> {
|
||||
return ipcRenderer.invoke('start-update');
|
||||
}
|
||||
|
|
|
@ -32,11 +32,11 @@ export type UpdateDialogOptionsType = {
|
|||
version?: string;
|
||||
};
|
||||
|
||||
type DismissDialogAction = {
|
||||
type DismissDialogActionType = {
|
||||
type: typeof DISMISS_DIALOG;
|
||||
};
|
||||
|
||||
export type ShowUpdateDialogAction = {
|
||||
export type ShowUpdateDialogActionType = {
|
||||
type: typeof SHOW_UPDATE_DIALOG;
|
||||
payload: {
|
||||
dialogType: DialogType;
|
||||
|
@ -48,7 +48,7 @@ type SnoozeUpdateActionType = {
|
|||
type: typeof SNOOZE_UPDATE;
|
||||
};
|
||||
|
||||
type StartUpdateAction = {
|
||||
type StartUpdateActionType = {
|
||||
type: typeof START_UPDATE;
|
||||
};
|
||||
|
||||
|
@ -58,15 +58,15 @@ type UnsnoozeUpdateActionType = {
|
|||
};
|
||||
|
||||
export type UpdatesActionType =
|
||||
| DismissDialogAction
|
||||
| ShowUpdateDialogAction
|
||||
| DismissDialogActionType
|
||||
| ShowUpdateDialogActionType
|
||||
| SnoozeUpdateActionType
|
||||
| StartUpdateAction
|
||||
| StartUpdateActionType
|
||||
| UnsnoozeUpdateActionType;
|
||||
|
||||
// Action Creators
|
||||
|
||||
function dismissDialog(): DismissDialogAction {
|
||||
function dismissDialog(): DismissDialogActionType {
|
||||
return {
|
||||
type: DISMISS_DIALOG,
|
||||
};
|
||||
|
@ -75,7 +75,7 @@ function dismissDialog(): DismissDialogAction {
|
|||
function showUpdateDialog(
|
||||
dialogType: DialogType,
|
||||
updateDialogOptions: UpdateDialogOptionsType = {}
|
||||
): ShowUpdateDialogAction {
|
||||
): ShowUpdateDialogActionType {
|
||||
return {
|
||||
type: SHOW_UPDATE_DIALOG,
|
||||
payload: {
|
||||
|
@ -106,11 +106,28 @@ function snoozeUpdate(): ThunkAction<
|
|||
};
|
||||
}
|
||||
|
||||
function startUpdate(): StartUpdateAction {
|
||||
updateIpc.startUpdate();
|
||||
function startUpdate(): ThunkAction<
|
||||
void,
|
||||
RootStateType,
|
||||
unknown,
|
||||
StartUpdateActionType | ShowUpdateDialogActionType
|
||||
> {
|
||||
return async dispatch => {
|
||||
dispatch({
|
||||
type: START_UPDATE,
|
||||
});
|
||||
|
||||
return {
|
||||
type: START_UPDATE,
|
||||
try {
|
||||
await updateIpc.startUpdate();
|
||||
} catch (_) {
|
||||
dispatch({
|
||||
type: SHOW_UPDATE_DIALOG,
|
||||
payload: {
|
||||
dialogType: DialogType.Cannot_Update,
|
||||
otherState: {},
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { pathExists } from 'fs-extra';
|
||||
import { stat, mkdir } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
|
||||
import {
|
||||
createUpdateCacheDirIfNeeded,
|
||||
|
@ -10,6 +13,9 @@ import {
|
|||
isUpdateFileNameValid,
|
||||
validatePath,
|
||||
parseYaml,
|
||||
createTempDir,
|
||||
getTempDir,
|
||||
deleteTempDir,
|
||||
} from '../../updater/common';
|
||||
|
||||
describe('updater/signatures', () => {
|
||||
|
@ -152,4 +158,32 @@ releaseDate: '2021-12-03T19:00:23.754Z'
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('createTempDir', () => {
|
||||
it('creates a temporary directory', async () => {
|
||||
const dir = await createTempDir();
|
||||
assert.isTrue((await stat(dir)).isDirectory());
|
||||
|
||||
await deleteTempDir(dir);
|
||||
|
||||
assert.isFalse(await pathExists(dir), 'Directory should be deleted');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTempDir', () => {
|
||||
it('reserves a temporary directory', async () => {
|
||||
const dir = await getTempDir();
|
||||
assert.isTrue(
|
||||
(await stat(join(dir, '..'))).isDirectory(),
|
||||
'Parent folder should exist'
|
||||
);
|
||||
assert.isFalse(await pathExists(dir), 'Reserved folder should not exist');
|
||||
|
||||
await mkdir(dir);
|
||||
|
||||
await deleteTempDir(dir);
|
||||
|
||||
assert.isFalse(await pathExists(dir), 'Directory should be deleted');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -446,7 +446,6 @@ export abstract class Updater {
|
|||
const targetUpdatePath = join(cacheDir, fileName);
|
||||
|
||||
const tempDir = await createTempDir();
|
||||
const restoreDir = await createTempDir();
|
||||
|
||||
const tempUpdatePath = join(tempDir, fileName);
|
||||
const tempBlockMapPath = join(tempDir, blockMapFileName);
|
||||
|
@ -556,7 +555,12 @@ export abstract class Updater {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
this.logger.info(
|
||||
'downloadUpdate: Downloaded update, moving into cache dir'
|
||||
);
|
||||
|
||||
// Backup old files
|
||||
const restoreDir = await getTempDir();
|
||||
await rename(cacheDir, restoreDir);
|
||||
|
||||
// Move the files into the final position
|
||||
|
@ -569,9 +573,18 @@ export abstract class Updater {
|
|||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
await deleteTempDir(restoreDir);
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
'downloadUpdate: Failed to remove backup folder, ignoring',
|
||||
Errors.toLogFormat(error)
|
||||
);
|
||||
}
|
||||
|
||||
return { updateFilePath: targetUpdatePath, signature };
|
||||
} finally {
|
||||
await Promise.all([deleteTempDir(tempDir), deleteTempDir(restoreDir)]);
|
||||
await deleteTempDir(tempDir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,14 +794,25 @@ function getBaseTempDir() {
|
|||
}
|
||||
|
||||
export async function createTempDir(): Promise<string> {
|
||||
const baseTempDir = getBaseTempDir();
|
||||
const uniqueName = getGuid();
|
||||
const targetDir = join(baseTempDir, uniqueName);
|
||||
const targetDir = await getTempDir();
|
||||
|
||||
await mkdirpPromise(targetDir);
|
||||
|
||||
return targetDir;
|
||||
}
|
||||
|
||||
export async function getTempDir(): Promise<string> {
|
||||
const baseTempDir = getBaseTempDir();
|
||||
const uniqueName = getGuid();
|
||||
|
||||
// Create parent folder if not already present
|
||||
if (!(await pathExists(baseTempDir))) {
|
||||
await mkdirpPromise(baseTempDir);
|
||||
}
|
||||
|
||||
return join(baseTempDir, uniqueName);
|
||||
}
|
||||
|
||||
function getUpdateCacheDir() {
|
||||
// We only use tmpdir() when this code is run outside of an Electron app (as in: tests)
|
||||
return app ? getUpdateCachePath(app.getPath('userData')) : tmpdir();
|
||||
|
|
Loading…
Reference in a new issue