From 2be631ea4d17f53ea11c251f494bda69b8dfeb53 Mon Sep 17 00:00:00 2001 From: Roman Karpenko Date: Thu, 21 Oct 2021 03:43:32 -0700 Subject: [PATCH] Fix Flipper lints #18 Summary: Fixed several lint errors mainly related to Warning/node/no-sync. Reviewed By: passy Differential Revision: D31795894 fbshipit-source-id: 020597d93232a8e84b25ea11a87d9481a6d2616f --- desktop/static/launcher.ts | 25 +++---- desktop/static/main.ts | 138 +++++++++++++++++++++---------------- desktop/static/setup.ts | 46 +++++++++---- 3 files changed, 122 insertions(+), 87 deletions(-) diff --git a/desktop/static/launcher.ts b/desktop/static/launcher.ts index 5dfdb976a..6eb9712e3 100644 --- a/desktop/static/launcher.ts +++ b/desktop/static/launcher.ts @@ -10,7 +10,6 @@ import os from 'os'; import fs from 'fs'; import path from 'path'; -import {promisify} from 'util'; import {spawn} from 'child_process'; import xdg from 'xdg-basedir'; import mkdirp from 'mkdirp'; @@ -18,14 +17,19 @@ import mkdirp from 'mkdirp'; const isProduction = () => !/node_modules[\\/]electron[\\/]/.test(process.execPath); -const isLauncherInstalled = () => { +const isLauncherInstalled = async () => { if (os.type() == 'Darwin') { const receipt = 'com.facebook.flipper.launcher'; const plistLocation = '/Applications/Flipper.app/Contents/Info.plist'; - return ( - fs.existsSync(plistLocation) && - fs.readFileSync(plistLocation).indexOf(receipt) > 0 - ); + try { + return ( + (await fs.promises.stat(plistLocation)) && + (await fs.promises.readFile(plistLocation)).indexOf(receipt) > 0 + ); + } catch (e) { + console.error('Error while reading Info.plist', e); + return false; + } } return false; @@ -54,17 +58,14 @@ const checkIsCycle = async () => { let backThen; try { - backThen = parseInt( - (await promisify(fs.readFile)(filePath)).toString(), - 10, - ); + backThen = parseInt((await fs.promises.readFile(filePath)).toString(), 10); } catch (e) { backThen = 0; } const delta = rightNow - backThen; await mkdirp(dir); - await promisify(fs.writeFile)(filePath, '' + rightNow); + await fs.promises.writeFile(filePath, '' + rightNow); // If the last startup was less than 5s ago, something's not okay. return Math.abs(delta) < 5000; @@ -79,7 +80,7 @@ export default async function delegateToLauncher(argv: { file?: string; url?: string; }) { - if (argv.launcher && isProduction() && isLauncherInstalled()) { + if (argv.launcher && isProduction() && (await isLauncherInstalled())) { if (await checkIsCycle()) { console.error( 'Launcher cycle detected. Not delegating even though I usually would.', diff --git a/desktop/static/main.ts b/desktop/static/main.ts index 7567df88b..659109f98 100644 --- a/desktop/static/main.ts +++ b/desktop/static/main.ts @@ -26,7 +26,7 @@ import url from 'url'; import fs from 'fs'; import fixPath from 'fix-path'; import {exec} from 'child_process'; -import setup from './setup'; +import setup, {Config, configPath} from './setup'; import isFB from './fb-stubs/isFB'; import delegateToLauncher from './launcher'; import yargs from 'yargs'; @@ -99,8 +99,6 @@ const argv = yargs .help() .parse(process.argv.slice(1)); -const {config, configPath} = setup(argv); - if (isFB && process.env.FLIPPER_FB === undefined) { process.env.FLIPPER_FB = 'true'; } @@ -110,11 +108,6 @@ if (argv['disable-gpu'] || process.env.FLIPPER_DISABLE_GPU === '1') { app.disableHardwareAcceleration(); } -process.env.CONFIG = JSON.stringify(config); -nativeTheme.themeSource = validThemes.includes(config.darkMode) - ? config.darkMode - : 'light'; - // possible reference to main app window let win: BrowserWindow; let appReady = false; @@ -178,61 +171,71 @@ app.on('will-finish-launching', () => { }); }); -app.on('ready', () => { +app.on('ready', async () => { + const config = await setup(argv); + processConfig(config); + // If we delegate to the launcher, shut down this instance of the app. - delegateToLauncher(argv).then(async (hasLauncherInvoked: boolean) => { - if (hasLauncherInvoked) { - app.quit(); - return; - } - appReady = true; - app.commandLine.appendSwitch('scroll-bounce'); - configureSession(); - createWindow(); - // if in development install the react devtools extension - if (process.env.NODE_ENV === 'development') { - const { - default: installExtension, - REACT_DEVELOPER_TOOLS, - REDUX_DEVTOOLS, - } = require('electron-devtools-installer'); - // if set, try to download a newever version of the dev tools - const forceDownload = process.env.FLIPPER_UPDATE_DEV_TOOLS === 'true'; - if (forceDownload) { - console.log('Force updating DevTools'); + delegateToLauncher(argv) + .then(async (hasLauncherInvoked: boolean) => { + if (hasLauncherInvoked) { + app.quit(); + return; } - // Redux - await installExtension(REDUX_DEVTOOLS.id, { - loadExtensionOptions: {allowFileAccess: true, forceDownload}, - }).catch((e: any) => { - console.error('Failed to install Redux devtools extension', e); - }); - // React - // Fix for extension loading (see D27685981) - // Work around per https://github.com/electron/electron/issues/23662#issuecomment-787420799 - const reactDevToolsPath = `${os.homedir()}/Library/Application Support/Electron/extensions/${ - REACT_DEVELOPER_TOOLS.id - }`; - if (await promisify(fs.exists)(reactDevToolsPath)) { - console.log('Loading React devtools from disk ' + reactDevToolsPath); - await session.defaultSession - .loadExtension( - reactDevToolsPath, - // @ts-ignore only supported (and needed) in Electron 12 - {allowFileAccess: true}, - ) - .catch((e) => { - console.error('Failed to loa React devtools from disk: ', e); + appReady = true; + app.commandLine.appendSwitch('scroll-bounce'); + configureSession(); + createWindow(config); + + // if in development install the react devtools extension + if (process.env.NODE_ENV === 'development') { + const { + default: installExtension, + REACT_DEVELOPER_TOOLS, + REDUX_DEVTOOLS, + } = require('electron-devtools-installer'); + // if set, try to download a newever version of the dev tools + const forceDownload = process.env.FLIPPER_UPDATE_DEV_TOOLS === 'true'; + if (forceDownload) { + console.log('Force updating DevTools'); + } + // Redux + try { + await installExtension(REDUX_DEVTOOLS.id, { + loadExtensionOptions: {allowFileAccess: true, forceDownload}, }); - } else { - await installExtension(REACT_DEVELOPER_TOOLS.id, { - loadExtensionOptions: {allowFileAccess: true, forceDownload}, - }).catch((e: any) => { - console.error('Failed to install React devtools extension', e); - }); + } catch (e) { + console.error('Failed to install Redux devtools extension', e); + } + // React + // Fix for extension loading (see D27685981) + // Work around per https://github.com/electron/electron/issues/23662#issuecomment-787420799 + const reactDevToolsPath = `${os.homedir()}/Library/Application Support/Electron/extensions/${ + REACT_DEVELOPER_TOOLS.id + }`; + if (await promisify(fs.exists)(reactDevToolsPath)) { + console.log('Loading React devtools from disk ' + reactDevToolsPath); + try { + await session.defaultSession.loadExtension( + reactDevToolsPath, + // @ts-ignore only supported (and needed) in Electron 12 + {allowFileAccess: true}, + ); + } catch (e) { + console.error('Failed to loa React devtools from disk: ', e); + } + } else { + try { + await installExtension(REACT_DEVELOPER_TOOLS.id, { + loadExtensionOptions: {allowFileAccess: true, forceDownload}, + }); + } catch (e) { + console.error('Failed to install React devtools extension', e); + } + } } - } - }); + }) + .catch((e: any) => console.error('Error while delegating app launch', e)); }); app.on('web-contents-created', (_event, contents) => { @@ -340,7 +343,7 @@ app.setAsDefaultProtocolClient('flipper'); // is workaround suggested in the issue app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors'); -function createWindow() { +function createWindow(config: Config) { win = new BrowserWindow({ show: false, title: 'Flipper', @@ -384,7 +387,8 @@ function createWindow() { const [x, y] = win.getPosition(); const [width, height] = win.getSize(); // save window position and size - fs.writeFileSync( + + fs.writeFile( configPath, JSON.stringify({ ...config, @@ -396,6 +400,11 @@ function createWindow() { height, }, }), + (err) => { + if (err) { + console.error('Error while saving window position/size', err); + } + }, ); }); if ( @@ -414,3 +423,10 @@ function createWindow() { }); win.loadURL(entryUrl); } + +function processConfig(config: Config) { + process.env.CONFIG = JSON.stringify(config); + nativeTheme.themeSource = validThemes.includes(config.darkMode) + ? config.darkMode + : 'light'; +} diff --git a/desktop/static/setup.ts b/desktop/static/setup.ts index bd2f90e6a..fc6f6586c 100644 --- a/desktop/static/setup.ts +++ b/desktop/static/setup.ts @@ -11,6 +11,14 @@ import path from 'path'; import os from 'os'; import fs from 'fs'; +const flipperHomeDir = path.join(os.homedir(), '.flipper'); +export const configPath = path.join(flipperHomeDir, 'config.json'); +export const defaultConfig: Config = { + pluginPaths: [], + disabledPlugins: [], + darkMode: 'light', +}; + export type Config = { pluginPaths?: string[]; disabledPlugins?: string[]; @@ -27,31 +35,41 @@ export type Config = { darkMode: 'system' | 'light' | 'dark'; }; -export default function setup(argv: any) { - // ensure .flipper folder and config exist - const flipperDir = path.join(os.homedir(), '.flipper'); - if (!fs.existsSync(flipperDir)) { - fs.mkdirSync(flipperDir); +const ensureConfigDirExists = async (path: fs.PathLike) => { + try { + await fs.promises.access(path); + } catch (e) { + console.warn('Config directory not found, creating config directory.'); + try { + await fs.promises.mkdir(path); + } catch (e) { + console.error('Failed to create config directory', e); + } } +}; - const configPath = path.join(flipperDir, 'config.json'); - let config: Config = { - pluginPaths: [], - disabledPlugins: [], - darkMode: 'light', - }; +const readConfigFile = async (configPath: fs.PathLike) => { + let config = defaultConfig; try { config = { ...config, - ...JSON.parse(fs.readFileSync(configPath).toString()), + ...JSON.parse((await fs.promises.readFile(configPath)).toString()), }; } catch (e) { // file not readable or not parsable, overwrite it with the new config console.warn(`Failed to read ${configPath}: ${e}`); console.info('Writing new default config.'); - fs.writeFileSync(configPath, JSON.stringify(config)); + await fs.promises.writeFile(configPath, JSON.stringify(config)); } + return config; +}; + +export default async function setup(argv: any) { + // ensure .flipper folder and config exist + await ensureConfigDirExists(flipperHomeDir); + + let config = await readConfigFile(configPath); // Non-persistent CLI arguments. config = { @@ -67,5 +85,5 @@ export default function setup(argv: any) { launcherMsg: argv.launcherMsg, }; - return {config, configPath}; + return config; }