Fix file retention after updates on macOS #417

This fixes issue #417 where autoupdate installer files were not deleted
on macOS, leading to accumulation of old installers.

Key changes:

- Store update files in application-specific directory
- Clear update files directory on every app launch

Other supporting changes:

- Refactor file system operations to be more testable and reusable
- Improve separation of concerns in directory management
- Enhance dependency injection for auto-update logic
- Fix async completion to support `await` operations
- Add additional logging and revise some log messages during updates
This commit is contained in:
undergroundwires
2024-10-07 17:33:47 +02:00
parent 4e06d543b3
commit 2f31bc7b06
44 changed files with 1484 additions and 590 deletions

View File

@@ -1,57 +1,13 @@
import { join } from 'node:path';
import { chmod, mkdir } from 'node:fs/promises';
import { exec } from 'node:child_process';
import { app } from 'electron/main';
import type {
CommandOps, FileSystemOps, LocationOps, OperatingSystemOps, SystemOperations,
} from './SystemOperations';
import { NodeElectronFileSystemOperations } from '@/infrastructure/FileSystem/NodeElectronFileSystemOperations';
import type { SystemOperations } from './SystemOperations';
/**
* Thin wrapper for Node and Electron APIs.
*/
export class NodeElectronSystemOperations implements SystemOperations {
public readonly operatingSystem: OperatingSystemOps = {
/*
This method returns the directory for storing app's configuration files.
It appends your app's name to the default appData directory.
Conventionally, you should store user data files in this directory.
However, avoid writing large files here as some environments might back up this directory
to cloud storage, potentially causing issues with file size.
Based on tests it returns:
- Windows: `%APPDATA%\privacy.sexy`
- Linux: `$HOME/.config/privacy.sexy/runs`
- macOS: `$HOME/Library/Application Support/privacy.sexy/runs`
For more details, refer to the Electron documentation: https://web.archive.org/web/20240104154857/https://www.electronjs.org/docs/latest/api/app#appgetpathname
*/
getUserDataDirectory: () => {
return app.getPath('userData');
},
};
public readonly location: LocationOps = {
combinePaths: (...pathSegments) => join(...pathSegments),
};
public readonly fileSystem: FileSystemOps = {
setFilePermissions: (
filePath: string,
mode: string | number,
) => chmod(filePath, mode),
createDirectory: async (
directoryPath: string,
isRecursive?: boolean,
) => {
await mkdir(directoryPath, { recursive: isRecursive });
// Ignoring the return value from `mkdir`, which is the first directory created
// when `recursive` is true, or empty return value.
// See https://github.com/nodejs/node/pull/31530
},
};
public readonly command: CommandOps = {
export const NodeElectronSystemOperations: SystemOperations = {
fileSystem: NodeElectronFileSystemOperations,
command: {
exec,
};
}
},
};