All files ReactNativeCli.js

0% Statements 0/33
0% Branches 0/25
0% Functions 0/12
0% Lines 0/33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128                                                                                                                                                                                                                                                               
// @flow
 
import * as fileUtils from './fileUtil'
import fs from 'fs'
import path from 'path'
import shell from './shell'
import spin from './spin'
import tmp from 'tmp'
import {
  execp,
  spawnp
} from './childProcess'
const fetch = require('node-fetch')
 
export default class ReactNativeCli {
  _binaryPath: ?string
 
  constructor (binaryPath?: string) {
    this._binaryPath = binaryPath
  }
 
  get binaryPath () : string {
    return this._binaryPath ? this._binaryPath : 'react-native'
  }
 
  async init (appName: string, rnVersion: string) {
    const dir = path.join(process.cwd(), appName)
 
    if (fs.existsSync(dir)) {
      throw new Error(`Path already exists will not override ${dir}`)
    }
 
    return execp(`${this.binaryPath} init ${appName} --version react-native@${rnVersion} --skip-jest`)
  }
 
  async bundle ({
    entryFile,
    dev,
    bundleOutput,
    assetsDest,
    platform
  } : {
    entryFile: string,
    dev: boolean,
    bundleOutput: string,
    assetsDest: string,
    platform: 'android' | 'ios'
  }) {
    const bundleCommand =
    `${this.binaryPath} bundle \
${entryFile ? `--entry-file=${entryFile}` : ''} \
${dev ? '--dev=true' : '--dev=false'} \
${platform ? `--platform=${platform}` : ''} \
${bundleOutput ? `--bundle-output=${bundleOutput}` : ''} \
${assetsDest ? `--assets-dest=${assetsDest}` : ''}`
 
    return execp(bundleCommand)
  }
 
  startPackager (cwd: string) {
    spawnp(this.binaryPath, [ 'start' ], { cwd })
  }
 
  async startPackagerInNewWindow (cwd: string, args: Array<string> = []) {
    const isPackagerRunning = await this.isPackagerRunning()
 
    if (!isPackagerRunning) {
      await spin('Starting React Native packager', Promise.resolve())
      if (process.platform === 'darwin') {
        return this.darwinStartPackagerInNewWindow({ cwd, args })
      } else if (/^win/.test(process.platform)) {
        return this.windowsStartPackagerInNewWindow({ cwd, args })
      } else {
        throw new Error(`${process.platform} is not supported yet`)
      }
    } else {
      log.warn('A React Native Packager is already running in a different process')
    }
  }
 
  async darwinStartPackagerInNewWindow ({
    cwd = process.cwd(),
    args = []
  } : {
    cwd?: string,
    args?: Array<string>
  }) {
    const tmpDir = tmp.dirSync({ unsafeCleanup: true }).name
    const tmpScriptPath = path.join(tmpDir, 'packager.sh')
    await fileUtils.writeFile(tmpScriptPath,
`
cd "${cwd}"; 
echo "Running ${this.binaryPath} start ${args.join(' ')}";
${this.binaryPath} start ${args.join(' ')};
`)
    shell.chmod('+x', tmpScriptPath)
    spawnp('open', ['-a', 'Terminal', tmpScriptPath])
  }
 
  async windowsStartPackagerInNewWindow ({
    cwd = process.cwd(),
    args = []
  }: {
      cwd?: string,
      args?: Array<string>
    }) {
    const tmpDir = tmp.dirSync({ unsafeCleanup: true }).name
    const tmpScriptPath = path.join(tmpDir, 'packager.bat')
    await fileUtils.writeFile(tmpScriptPath,
`
cd "${cwd}"; 
echo "Running ${this.binaryPath} start ${args.join(' ')}";
${this.binaryPath} start ${args.join(' ')};
`)
    shell.chmod('+x', tmpScriptPath)
    spawnp('cmd.exe', ['/C', tmpScriptPath], { detached: true })
  }
 
  async isPackagerRunning () {
    return fetch('http://localhost:8081/status').then(
      res => res.text().then(body =>
        body === 'packager-status:running'
      ),
      () => false
    )
  }
}