From a40440cc7d85b131f22ba548a4838483798b4f4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Roy?= Date: Mon, 15 Aug 2022 13:39:58 -0400 Subject: [PATCH] Add installer config state --- package.json | 3 +- src/electron/InstallerConfig.ts | 74 +++++++++++++++++++++++++++++++++ src/electron/preload.ts | 7 ++++ src/electron/renderer.d.ts | 9 +++- src/react/App.tsx | 8 ++-- yarn.lock | 8 ++++ 6 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 src/electron/InstallerConfig.ts diff --git a/package.json b/package.json index daf44ff..92a661c 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,8 @@ "react-router-dom": "^6.2.2", "shebang-loader": "^0.0.1", "sudo-prompt": "^9.2.1", - "tmp-promise": "^3.0.3" + "tmp-promise": "^3.0.3", + "yaml": "^2.1.1" }, "build": { "appId": "gg.wagyu.installer", diff --git a/src/electron/InstallerConfig.ts b/src/electron/InstallerConfig.ts new file mode 100644 index 0000000..d3f9f64 --- /dev/null +++ b/src/electron/InstallerConfig.ts @@ -0,0 +1,74 @@ +import { open, mkdir, FileHandle } from 'fs/promises'; + +import path from 'path'; +import os from 'os'; +import { parse, Document, parseDocument } from 'yaml'; + +import { doesFileExist } from './BashUtils'; + +const configDirectoryPath = path.join(os.homedir(), '.config', 'wagyu-installer'); +const configFilePath = path.join(configDirectoryPath, 'wagyu-installer.yml') + +interface Configuration { + rootDirectory: string; +} + +async function getConfigFileContent(): Promise { + if (!await doesFileExist(configFilePath)) { + return undefined; + } + + // Open config file and read the content. + let configFile: FileHandle | undefined = undefined; + let configFileContent: string | undefined = undefined; + try { + configFile = await open(configFilePath, 'r'); + configFileContent = await configFile.readFile({ encoding: 'utf8' }); + } finally { + await configFile?.close(); + } + + return configFileContent; +} + +export async function initInstallerConfig() { + await mkdir(configDirectoryPath, { recursive: true }); +} + +export async function setInstallPath(installPath: string) { + const configFileContent = await getConfigFileContent(); + + let configDocument: Document | undefined = undefined; + if (configFileContent === undefined) { + configDocument = new Document({ + rootDirectory: installPath + }); + } else { + const yamlContent = parseDocument(configFileContent as string); + yamlContent.set('rootDirectory', installPath); + configDocument = yamlContent; + } + + if (configDocument !== undefined) { + const newFileContent = configDocument?.toString(); + + let configFile: FileHandle | undefined = undefined; + try { + configFile = await open(configFilePath, 'w'); + await configFile.write(newFileContent); + } finally { + await configFile?.close(); + } + } +} + +export async function getInstallPath(): Promise { + const configFileContent = await getConfigFileContent(); + if (configFileContent === undefined) { + return undefined; + } + + const yamlContent = parse(configFileContent as string) as Configuration; + + return yamlContent.rootDirectory; +} \ No newline at end of file diff --git a/src/electron/preload.ts b/src/electron/preload.ts index 1ca5883..25cc464 100644 --- a/src/electron/preload.ts +++ b/src/electron/preload.ts @@ -17,6 +17,7 @@ import { doesDirectoryExist, findFirstFile } from './BashUtils'; import { EthDockerInstaller } from './EthDockerInstaller'; import { InstallDetails, OutputLogs } from "./IMultiClientInstaller"; +import { initInstallerConfig, getInstallPath, setInstallPath } from "./InstallerConfig"; import { Writable } from 'stream'; @@ -71,4 +72,10 @@ contextBridge.exposeInMainWorld('ethDocker', { 'postInstall': ethDockerPostInstall, 'startNodes': ethDockerStartNodes, 'stopNodes': ethDockerStopNodes +}); + +contextBridge.exposeInMainWorld('installerConfig', { + 'initInstallerConfig': initInstallerConfig, + 'getInstallPath': getInstallPath, + 'setInstallPath': setInstallPath }); \ No newline at end of file diff --git a/src/electron/renderer.d.ts b/src/electron/renderer.d.ts index b0674ef..9a398a1 100644 --- a/src/electron/renderer.d.ts +++ b/src/electron/renderer.d.ts @@ -55,10 +55,17 @@ export interface IEthDockerAPI { stopNodes: (network: Network) => Promise, } +export interface IInstallerConfigAPI { + initInstallerConfig: () => Promise, + setInstallPath: (installPath: string) => Promise, + getInstallPath: () => Promise +} + declare global { interface Window { electronAPI: IElectronAPI, bashUtils: IBashUtilsAPI, - ethDocker: IEthDockerAPI + ethDocker: IEthDockerAPI, + installerConfig: IInstallerConfigAPI } } \ No newline at end of file diff --git a/src/react/App.tsx b/src/react/App.tsx index 37aa8ab..f1edcbf 100644 --- a/src/react/App.tsx +++ b/src/react/App.tsx @@ -24,11 +24,13 @@ const Container = styled.main` const App: FC = (): ReactElement => { // const [network, setNetwork] = useState(Network.PRATER); const [installationDetails, setInstallationDetails] = useState({ - consensusClient: ConsensusClient.PRYSM, - executionClient: ExecutionClient.GETH, - network: Network.PRATER + consensusClient: ConsensusClient.PRYSM, + executionClient: ExecutionClient.GETH, + network: Network.PRATER }) + window.installerConfig.initInstallerConfig(); + return ( diff --git a/yarn.lock b/yarn.lock index c087d5b..a4dbaed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5172,6 +5172,7 @@ __metadata: typescript: ^4.3.5 webpack: ^5.64.3 webpack-cli: ^4.9.1 + yaml: ^2.1.1 languageName: unknown linkType: soft @@ -5398,6 +5399,13 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.1.1": + version: 2.1.1 + resolution: "yaml@npm:2.1.1" + checksum: f48bb209918aa57cfaf78ef6448d1a1f8187f45c746f933268b7023dc59e5456004611879126c9bb5ea55b0a2b1c2b392dfde436931ece0c703a3d754562bb96 + languageName: node + linkType: hard + "yargs-parser@npm:^21.0.0": version: 21.0.1 resolution: "yargs-parser@npm:21.0.1"