mirror of
https://github.com/Llewellynvdm/nativefier.git
synced 2024-06-03 05:10:47 +00:00
6fb3b92eb8
* Update deps except eslint * Update eslint and lint:fix (WIP, needs manual fixing for remaining 44 problems) * Manually fix remaining eslint errors * Document deprecation of `version-string` as of electron-packager 9.0.0 * Upgrade to Electron 1.7.9 (chrome-58, node-7.9.0, v8-5.8) * npm: Disable generation of package-lock.json and gitignore it --Trying this, package-lock is a pain in PRs. May not be a good idea (obviously we lose deps pinning), will revert if necessary.-- * npm tasks: add dev-up-win for Windows developers, and e2e for end-to-end tests. Update docs. * Move normalizeUrl test to a jest unit test, makes no sense to be in the mocha e2e tests * Switch from babel-preset-es2015 to babel-preset-env, with target.node=4.0. Seem like it's today's most convenient way to support the latest ES and let babel transpile to what makes sense for our currently minimal node version
233 lines
6.5 KiB
JavaScript
233 lines
6.5 KiB
JavaScript
import path from 'path';
|
|
import packager from 'electron-packager';
|
|
import tmp from 'tmp';
|
|
import ncp from 'ncp';
|
|
import async from 'async';
|
|
import hasBinary from 'hasbin';
|
|
import log from 'loglevel';
|
|
import DishonestProgress from './../helpers/dishonestProgress';
|
|
import optionsFactory from './../options/optionsMain';
|
|
import iconBuild from './iconBuild';
|
|
import helpers from './../helpers/helpers';
|
|
import PackagerConsole from './../helpers/packagerConsole';
|
|
import buildApp from './buildApp';
|
|
|
|
const copy = ncp.ncp;
|
|
const { isWindows } = helpers;
|
|
|
|
/**
|
|
* Checks the app path array to determine if the packaging was completed successfully
|
|
* @param appPathArray Result from electron-packager
|
|
* @returns {*}
|
|
*/
|
|
function getAppPath(appPathArray) {
|
|
if (appPathArray.length === 0) {
|
|
// directory already exists, --overwrite is not set
|
|
// exit here
|
|
return null;
|
|
}
|
|
|
|
if (appPathArray.length > 1) {
|
|
log.warn('Warning: This should not be happening, packaged app path contains more than one element:', appPathArray);
|
|
}
|
|
|
|
return appPathArray[0];
|
|
}
|
|
|
|
/**
|
|
* Removes the `icon` parameter from options if building for Windows while not on Windows
|
|
* and Wine is not installed
|
|
* @param options
|
|
*/
|
|
function maybeNoIconOption(options) {
|
|
const packageOptions = JSON.parse(JSON.stringify(options));
|
|
if (options.platform === 'win32' && !isWindows()) {
|
|
if (!hasBinary.sync('wine')) {
|
|
log.warn('Wine is required to set the icon for a Windows app when packaging on non-windows platforms');
|
|
packageOptions.icon = null;
|
|
}
|
|
}
|
|
return packageOptions;
|
|
}
|
|
|
|
/**
|
|
* For windows and linux, we have to copy over the icon to the resources/app folder, which the
|
|
* BrowserWindow is hard coded to read the icon from
|
|
* @param {{}} options
|
|
* @param {string} appPath
|
|
* @param callback
|
|
*/
|
|
function maybeCopyIcons(options, appPath, callback) {
|
|
if (!options.icon) {
|
|
callback();
|
|
return;
|
|
}
|
|
|
|
if (options.platform === 'darwin') {
|
|
callback();
|
|
return;
|
|
}
|
|
|
|
// windows & linux
|
|
// put the icon file into the app
|
|
const destIconPath = path.join(appPath, 'resources/app');
|
|
const destFileName = `icon${path.extname(options.icon)}`;
|
|
copy(options.icon, path.join(destIconPath, destFileName), (error) => {
|
|
callback(error);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Removes invalid parameters from options if building for Windows while not on Windows
|
|
* and Wine is not installed
|
|
* @param options
|
|
*/
|
|
function removeInvalidOptions(options, param) {
|
|
const packageOptions = JSON.parse(JSON.stringify(options));
|
|
if (options.platform === 'win32' && !isWindows()) {
|
|
if (!hasBinary.sync('wine')) {
|
|
log.warn(`Wine is required to use "${param}" option for a Windows app when packaging on non-windows platforms`);
|
|
packageOptions[param] = null;
|
|
}
|
|
}
|
|
return packageOptions;
|
|
}
|
|
|
|
/**
|
|
* Removes the `appCopyright` parameter from options if building for Windows while not on Windows
|
|
* and Wine is not installed
|
|
* @param options
|
|
*/
|
|
function maybeNoAppCopyrightOption(options) {
|
|
return removeInvalidOptions(options, 'appCopyright');
|
|
}
|
|
|
|
/**
|
|
* Removes the `buildVersion` parameter from options if building for Windows while not on Windows
|
|
* and Wine is not installed
|
|
* @param options
|
|
*/
|
|
function maybeNoBuildVersionOption(options) {
|
|
return removeInvalidOptions(options, 'buildVersion');
|
|
}
|
|
|
|
/**
|
|
* Removes the `appVersion` parameter from options if building for Windows while not on Windows
|
|
* and Wine is not installed
|
|
* @param options
|
|
*/
|
|
function maybeNoAppVersionOption(options) {
|
|
return removeInvalidOptions(options, 'appVersion');
|
|
}
|
|
|
|
/**
|
|
* Removes the `versionString` parameter from options if building for Windows while not on Windows
|
|
* and Wine is not installed
|
|
* @param options
|
|
*/
|
|
function maybeNoVersionStringOption(options) {
|
|
return removeInvalidOptions(options, 'versionString');
|
|
}
|
|
|
|
/**
|
|
* Removes the `win32metadata` parameter from options if building for Windows while not on Windows
|
|
* and Wine is not installed
|
|
* @param options
|
|
*/
|
|
function maybeNoWin32metadataOption(options) {
|
|
return removeInvalidOptions(options, 'win32metadata');
|
|
}
|
|
|
|
/**
|
|
* @callback buildAppCallback
|
|
* @param error
|
|
* @param {string} appPath
|
|
*/
|
|
|
|
/**
|
|
*
|
|
* @param {{}} inpOptions
|
|
* @param {buildAppCallback} callback
|
|
*/
|
|
function buildMain(inpOptions, callback) {
|
|
const options = Object.assign({}, inpOptions);
|
|
|
|
// pre process app
|
|
const tmpObj = tmp.dirSync({ unsafeCleanup: true });
|
|
const tmpPath = tmpObj.name;
|
|
|
|
// todo check if this is still needed on later version of packager
|
|
const packagerConsole = new PackagerConsole();
|
|
|
|
const progress = new DishonestProgress(5);
|
|
|
|
async.waterfall([
|
|
(cb) => {
|
|
progress.tick('inferring');
|
|
optionsFactory(options)
|
|
.then((result) => {
|
|
cb(null, result);
|
|
}).catch((error) => {
|
|
cb(error);
|
|
});
|
|
},
|
|
(opts, cb) => {
|
|
progress.tick('copying');
|
|
buildApp(opts.dir, tmpPath, opts, (error) => {
|
|
if (error) {
|
|
cb(error);
|
|
return;
|
|
}
|
|
// Change the reference file for the Electron app to be the temporary path
|
|
const newOptions = Object.assign({}, opts, { dir: tmpPath });
|
|
cb(null, newOptions);
|
|
});
|
|
},
|
|
(opts, cb) => {
|
|
progress.tick('icons');
|
|
iconBuild(opts, (error, optionsWithIcon) => {
|
|
cb(null, optionsWithIcon);
|
|
});
|
|
},
|
|
(opts, cb) => {
|
|
progress.tick('packaging');
|
|
// maybe skip passing icon parameter to electron packager
|
|
let packageOptions = maybeNoIconOption(opts);
|
|
// maybe skip passing other parameters to electron packager
|
|
packageOptions = maybeNoAppCopyrightOption(packageOptions);
|
|
packageOptions = maybeNoAppVersionOption(packageOptions);
|
|
packageOptions = maybeNoBuildVersionOption(packageOptions);
|
|
packageOptions = maybeNoVersionStringOption(packageOptions);
|
|
packageOptions = maybeNoWin32metadataOption(packageOptions);
|
|
|
|
packagerConsole.override();
|
|
|
|
packager(packageOptions, (error, appPathArray) => {
|
|
// restore console.error
|
|
packagerConsole.restore();
|
|
|
|
// pass options which still contains the icon to waterfall
|
|
cb(error, opts, appPathArray);
|
|
});
|
|
},
|
|
(opts, appPathArray, cb) => {
|
|
progress.tick('finalizing');
|
|
// somehow appPathArray is a 1 element array
|
|
const appPath = getAppPath(appPathArray);
|
|
if (!appPath) {
|
|
cb();
|
|
return;
|
|
}
|
|
|
|
maybeCopyIcons(opts, appPath, (error) => {
|
|
cb(error, appPath);
|
|
});
|
|
},
|
|
], (error, appPath) => {
|
|
packagerConsole.playback();
|
|
callback(error, appPath);
|
|
});
|
|
}
|
|
|
|
export default buildMain;
|