UNPKG

electron-forge

Version:

A complete tool for building modern Electron applications

415 lines (308 loc) 14.4 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _keys = require('babel-runtime/core-js/object/keys'); var _keys2 = _interopRequireDefault(_keys); var _promise = require('babel-runtime/core-js/promise'); var _promise2 = _interopRequireDefault(_promise); var _regenerator = require('babel-runtime/regenerator'); var _regenerator2 = _interopRequireDefault(_regenerator); var _getIterator2 = require('babel-runtime/core-js/get-iterator'); var _getIterator3 = _interopRequireDefault(_getIterator2); var _assign = require('babel-runtime/core-js/object/assign'); var _assign2 = _interopRequireDefault(_assign); var _bluebird = require('bluebird'); require('colors'); var _debug = require('debug'); var _debug2 = _interopRequireDefault(_debug); var _nodeFetch = require('node-fetch'); var _nodeFetch2 = _interopRequireDefault(_nodeFetch); var _fsExtra = require('fs-extra'); var _fsExtra2 = _interopRequireDefault(_fsExtra); var _inquirer = require('inquirer'); var _inquirer2 = _interopRequireDefault(_inquirer); var _nugget = require('nugget'); var _nugget2 = _interopRequireDefault(_nugget); var _os = require('os'); var _os2 = _interopRequireDefault(_os); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _pify = require('pify'); var _pify2 = _interopRequireDefault(_pify); var _semver = require('semver'); var _semver2 = _interopRequireDefault(_semver); var _oraHandler = require('../util/ora-handler'); var _oraHandler2 = _interopRequireDefault(_oraHandler); var _messages = require('../util/messages'); var _dmg = require('../installers/darwin/dmg'); var _dmg2 = _interopRequireDefault(_dmg); var _zip = require('../installers/darwin/zip'); var _zip2 = _interopRequireDefault(_zip); var _deb = require('../installers/linux/deb'); var _deb2 = _interopRequireDefault(_deb); var _rpm = require('../installers/linux/rpm'); var _rpm2 = _interopRequireDefault(_rpm); var _exe = require('../installers/win32/exe'); var _exe2 = _interopRequireDefault(_exe); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var d = (0, _debug2.default)('electron-forge:install'); var GITHUB_API = 'https://api.github.com'; /** * @typedef {Object} InstallOptions * @property {boolean} [interactive=false] Whether to use sensible defaults or prompt the user visually * @property {boolean} [prerelease=false] Whether to install prerelease versions * @property {string} repo The GitHub repository to install from, in the format owner/name * @property {function} chooseAsset A function that must return the asset to use/install from a provided array of compatible GitHub assets */ /** * Install an Electron application from GitHub. If you leave interactive as `false`, you MUST provide a `chooseAsset` function. * * @param {InstallOptions} providedOptions - Options for the install method * @return {Promise} Will resolve when the install process is complete */ exports.default = function () { var _ref = (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee3() { var providedOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var _Object$assign, interactive, prerelease, repo, chooseAsset, latestRelease, possibleAssets, targetAsset, choices, _ref3, assetID, tmpdir, pathSafeRepo, filename, fullFilePath, nuggetOpts; return _regenerator2.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: // eslint-disable-next-line prefer-const, no-unused-vars _Object$assign = (0, _assign2.default)({ interactive: false, prerelease: false }, providedOptions), interactive = _Object$assign.interactive, prerelease = _Object$assign.prerelease, repo = _Object$assign.repo, chooseAsset = _Object$assign.chooseAsset; _oraHandler2.default.interactive = interactive; latestRelease = void 0; possibleAssets = []; _context3.next = 6; return (0, _oraHandler2.default)('Searching for Application', function () { var _ref2 = (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee(searchSpinner) { var releases, sortedReleases, assets, installTargets; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: if (!(!repo || repo.indexOf('/') === -1)) { _context.next = 2; break; } throw 'Invalid repository name, must be in the format owner/name'; case 2: d('searching for repo:', repo); releases = void 0; _context.prev = 4; _context.next = 7; return (0, _nodeFetch2.default)(GITHUB_API + '/repos/' + repo + '/releases'); case 7: _context.next = 9; return _context.sent.json(); case 9: releases = _context.sent; _context.next = 14; break; case 12: _context.prev = 12; _context.t0 = _context['catch'](4); case 14: if (!(!releases || releases.message === 'Not Found' || !Array.isArray(releases))) { _context.next = 16; break; } throw 'Failed to find releases for repository "' + repo + '". Please check the name and try again.'; case 16: releases = releases.filter(function (release) { return !release.prerelease || prerelease; }); sortedReleases = releases.sort(function (releaseA, releaseB) { var tagA = releaseA.tag_name; if (tagA.substr(0, 1) === 'v') tagA = tagA.substr(1); var tagB = releaseB.tag_name; if (tagB.substr(0, 1) === 'v') tagB = tagB.substr(1); return _semver2.default.gt(tagB, tagA) ? 1 : -1; }); latestRelease = sortedReleases[0]; searchSpinner.text = 'Searching for Releases'; // eslint-disable-line assets = latestRelease.assets; if (!(!assets || !Array.isArray(assets))) { _context.next = 23; break; } throw 'Could not find any assets for the latest release'; case 23: installTargets = { win32: [/\.exe$/], darwin: [/OSX.*\.zip$/, /darwin.*\.zip$/, /macOS.*\.zip$/, /mac.*\.zip$/, /\.dmg$/], linux: [/\.rpm$/, /\.deb$/] }; possibleAssets = assets.filter(function (asset) { var targetSuffixes = installTargets[process.platform]; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = (0, _getIterator3.default)(targetSuffixes), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var suffix = _step.value; if (suffix.test(asset.name)) return true; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return false; }); if (!(possibleAssets.length === 0)) { _context.next = 27; break; } throw 'Failed to find any installable assets for target platform: ' + ('' + process.platform).cyan; case 27: case 'end': return _context.stop(); } } }, _callee, undefined, [[4, 12]]); })); return function (_x2) { return _ref2.apply(this, arguments); }; }()); case 6: (0, _messages.info)(interactive, 'Found latest release' + (prerelease ? ' (including prereleases)' : '') + ': ' + latestRelease.tag_name.cyan); targetAsset = possibleAssets[0]; if (!(possibleAssets.length > 1)) { _context3.next = 26; break; } if (!chooseAsset) { _context3.next = 15; break; } _context3.next = 12; return _promise2.default.resolve(chooseAsset(possibleAssets)); case 12: targetAsset = _context3.sent; _context3.next = 26; break; case 15: if (!interactive) { _context3.next = 25; break; } choices = []; possibleAssets.forEach(function (asset) { choices.push({ name: asset.name, value: asset.id }); }); _context3.next = 20; return _inquirer2.default.createPromptModule()({ type: 'list', name: 'assetID', message: 'Multiple potential assets found, please choose one from the list below:'.cyan, choices: choices }); case 20: _ref3 = _context3.sent; assetID = _ref3.assetID; targetAsset = possibleAssets.find(function (asset) { return asset.id === assetID; }); _context3.next = 26; break; case 25: throw 'expected a chooseAsset function to be provided but it was not'; case 26: tmpdir = _path2.default.resolve(_os2.default.tmpdir(), 'forge-install'); pathSafeRepo = repo.replace(/[/\\]/g, '-'); filename = pathSafeRepo + '-' + latestRelease.tag_name + '-' + targetAsset.name; fullFilePath = _path2.default.resolve(tmpdir, filename); _context3.next = 32; return _fsExtra2.default.pathExists(fullFilePath); case 32: _context3.t0 = !_context3.sent; if (_context3.t0) { _context3.next = 39; break; } _context3.next = 36; return _fsExtra2.default.stat(fullFilePath); case 36: _context3.t1 = _context3.sent.size; _context3.t2 = targetAsset.size; _context3.t0 = _context3.t1 !== _context3.t2; case 39: if (!_context3.t0) { _context3.next = 45; break; } _context3.next = 42; return _fsExtra2.default.mkdirs(tmpdir); case 42: nuggetOpts = { target: filename, dir: tmpdir, resume: true, strictSSL: true }; _context3.next = 45; return (0, _pify2.default)(_nugget2.default)(targetAsset.browser_download_url, nuggetOpts); case 45: _context3.next = 47; return (0, _oraHandler2.default)('Installing Application', function () { var _ref4 = (0, _bluebird.coroutine)(_regenerator2.default.mark(function _callee2(installSpinner) { var installActions, suffixFnIdent; return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: installActions = { win32: { '.exe': _exe2.default }, darwin: { '.zip': _zip2.default, '.dmg': _dmg2.default }, linux: { '.deb': _deb2.default, '.rpm': _rpm2.default } }; suffixFnIdent = (0, _keys2.default)(installActions[process.platform]).find(function (suffix) { return targetAsset.name.endsWith(suffix); }); _context2.next = 4; return installActions[process.platform][suffixFnIdent](fullFilePath, installSpinner); case 4: case 'end': return _context2.stop(); } } }, _callee2, undefined); })); return function (_x3) { return _ref4.apply(this, arguments); }; }()); case 47: case 'end': return _context3.stop(); } } }, _callee3, undefined); })); return function () { return _ref.apply(this, arguments); }; }();