diff --git a/static/index.js b/static/index.js index b9d53e418..6b5e387ef 100644 --- a/static/index.js +++ b/static/index.js @@ -159,24 +159,25 @@ app.on('will-finish-launching', () => { app.on('ready', () => { // If we delegate to the launcher, shut down this instance of the app. - if (delegateToLauncher(argv)) { - app.quit(); - return; - } - - appReady = true; - app.commandLine.appendSwitch('scroll-bounce'); - tryCreateWindow(); - // 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'); - installExtension(REACT_DEVELOPER_TOOLS.id); - installExtension(REDUX_DEVTOOLS.id); - } + delegateToLauncher(argv).then(hasLauncherInvoked => { + if (hasLauncherInvoked) { + app.quit(); + return; + } + appReady = true; + app.commandLine.appendSwitch('scroll-bounce'); + tryCreateWindow(); + // 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'); + installExtension(REACT_DEVELOPER_TOOLS.id); + installExtension(REDUX_DEVTOOLS.id); + } + }); }); ipcMain.on('componentDidMount', event => { diff --git a/static/launcher.js b/static/launcher.js index 79980d5c0..512cf6a06 100644 --- a/static/launcher.js +++ b/static/launcher.js @@ -7,7 +7,11 @@ const os = require('os'); const fs = require('fs'); +const path = require('path'); +const promisify = require('util').promisify; const {spawn} = require('child_process'); +const xdg = require('xdg-basedir'); +const mkdirp = require('mkdirp'); const isProduction = () => !/node_modules[\\/]electron[\\/]/.test(process.execPath); @@ -38,12 +42,42 @@ const startLauncher = argv => { } }; +const checkIsCycle = async () => { + const dir = path.join(xdg.cache, 'flipper'); + const filePath = path.join(dir, 'last-launcher-run'); + // This isn't monotonically increasing, so there's a change we get time drift + // between the checks, but the worst case here is that we do two roundtrips + // before this check works. + const rightNow = Date.now(); + + let backThen; + try { + backThen = parseInt(await promisify(fs.readFile)(filePath), 10); + } catch (e) { + backThen = 0; + } + + const delta = rightNow - backThen; + await promisify(mkdirp)(dir); + await promisify(fs.writeFile)(filePath, rightNow); + + // If the last startup was less than 5s ago, something's not okay. + return Math.abs(delta) < 5000; +}; + /** * Runs the launcher if required and returns a boolean based on whether * it has. You should shut down this instance of the app in that case. */ -module.exports = function delegateToLauncher(argv) { +module.exports = async function delegateToLauncher(argv) { if (argv.launcher && isProduction() && isLauncherInstalled()) { + if (await checkIsCycle()) { + console.error( + 'Launcher cycle detected. Not delegating even though I usually would.', + ); + return false; + } + console.warn('Delegating to Flipper Launcher ...'); console.warn( `You can disable this behavior by passing '--no-launcher' at startup.`, diff --git a/static/package.json b/static/package.json index 0ef4d5ef9..1373844f9 100644 --- a/static/package.json +++ b/static/package.json @@ -15,7 +15,9 @@ "@babel/preset-react": "^7.0.0", "expand-tilde": "^2.0.2", "metro": "^0.49.0", - "recursive-readdir": "2.2.2" + "mkdirp": "^0.5.1", + "recursive-readdir": "2.2.2", + "xdg-basedir": "^3.0.0" }, "devDependencies": {}, "resolutions": { diff --git a/static/yarn.lock b/static/yarn.lock index 73eac3959..45b849a01 100644 --- a/static/yarn.lock +++ b/static/yarn.lock @@ -3182,6 +3182,11 @@ ws@^1.1.0: options ">=0.0.5" ultron "1.0.x" +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + xpipe@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" diff --git a/yarn.lock b/yarn.lock index 840b00227..88a0ddff2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7558,6 +7558,7 @@ ws@~3.3.1: xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= xml-name-validator@^3.0.0: version "3.0.0"