All files / api make.js

61.7% Statements 29/47
40% Branches 12/30
100% Functions 3/3
61.7% Lines 29/47
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 129 130 131 132 133 134 135 136                                                              2x             2x     2x 2x 2x         2x     2x         2x                 2x     2x 2x   2x 2x       2x   2x 2x                             2x 2x 2x   2x 2x 2x       2x   2x 2x         2x       2x 2x                               2x    
import 'colors';
import fs from 'fs-promise';
import path from 'path';
 
import asyncOra from '../util/ora-handler';
import electronHostArch from '../util/electron-host-arch';
import getForgeConfig from '../util/forge-config';
import readPackageJSON from '../util/read-package-json';
import requireSearch from '../util/require-search';
import resolveDir from '../util/resolve-dir';
 
import packager from './package';
 
/**
 * @typedef {Object} MakeOptions
 * @property {string} [dir=process.cwd()] The path to the app from which distributables are generated
 * @property {boolean} [interactive=false] Whether to use sensible defaults or prompt the user visually
 * @property {boolean} [skipPackage=false] Whether to skip the pre-make packaging step
 * @property {Array<string>} [overrideTargets] An array of make targets to override your forge config
 * @property {string} [arch=host architecture] The target architecture
 * @property {string} [platform=process.platform] The target platform. NOTE: This is limited to be the current platform at the moment
 */
 
/**
 * Make distributables for an Electron application.
 *
 * @param {MakeOptions} providedOptions - Options for the make method
 * @return {Promise} Will resolve when the make process is complete
 */
export default async (providedOptions = {}) => {
  // eslint-disable-next-line prefer-const, no-unused-vars
  let { dir, interactive, skipPackage, overrideTargets, arch, platform } = Object.assign({
    dir: process.cwd(),
    interactive: false,
    skipPackage: false,
    arch: electronHostArch(),
    platform: process.platform,
  }, providedOptions);
  asyncOra.interactive = interactive;
 
  let forgeConfig;
  await asyncOra('Resolving Forge Config', async () => {
    dir = await resolveDir(dir);
    Iif (!dir) {
      // eslint-disable-next-line no-throw-literal
      throw 'Failed to locate makeable Electron application';
    }
 
    forgeConfig = await getForgeConfig(dir);
  });
 
  Iif (platform && platform !== process.platform && !(process.platform === 'darwin' && platform === 'mas')) {
    console.error('You can not "make" for a platform other than your systems platform'.red);
    process.exit(1);
  }
 
  Iif (!skipPackage) {
    console.info('We need to package your application before we can make it'.green);
    await packager({
      dir,
      interactive,
      arch,
      platform,
    });
  } else {
    console.warn('WARNING: Skipping the packaging step, this could result in an out of date build'.red);
  }
 
  const declaredArch = arch;
  const declaredPlatform = platform;
 
  let targets = forgeConfig.make_targets[declaredPlatform];
  Iif (overrideTargets) {
    targets = overrideTargets;
  }
 
  console.info('Making for the following targets:', `${targets.join(', ')}`.cyan);
 
  let targetArchs = [declaredArch];
  Iif (declaredArch === 'all') {
    switch (process.platform) {
      case 'darwin':
        targetArchs = ['x64'];
        break;
      case 'linux':
        targetArchs = ['ia32', 'x64', 'armv7l'];
        break;
      case 'win32':
      default:
        targetArchs = ['ia32', 'x64'];
        break;
    }
  }
 
  const packageJSON = await readPackageJSON(dir);
  const appName = packageJSON.productName || packageJSON.name;
  const outputs = [];
 
  for (const targetArch of targetArchs) {
    const packageDir = path.resolve(dir, `out/${appName}-${declaredPlatform}-${targetArch}`);
    Iif (!(await fs.exists(packageDir))) {
      throw new Error(`Couldn't find packaged app at: ${packageDir}`);
    }
 
    for (const target of targets) {
      // eslint-disable-next-line no-loop-func
      await asyncOra(`Making for target: ${target.cyan} - On platform: ${declaredPlatform.cyan} - For arch: ${targetArch.cyan}`, async () => {
        const maker = requireSearch(__dirname, [
          `../makers/${process.platform}/${target}.js`,
          `../makers/generic/${target}.js`,
          `electron-forge-maker-${target}`,
        ]);
        Iif (!maker) {
          // eslint-disable-next-line no-throw-literal
          throw `Could not find a build target with the name: ${target} for the platform: ${declaredPlatform}`;
        }
        try {
          outputs.push(await (maker.default || maker)(packageDir, appName, targetArch, forgeConfig, packageJSON));
        } catch (err) {
          if (err) {
            // eslint-disable-next-line no-throw-literal
            throw {
              message: `An error occured while making for target: ${target}`,
              stack: `${err.message}\n${err.stack}`,
            };
          } else {
            throw new Error(`An unknown error occured while making for target: ${target}`);
          }
        }
      });
    }
  }
 
  return outputs;
};