Skip to content

Commit

Permalink
feat(packager): rebuild native modules automatically in all the right…
Browse files Browse the repository at this point in the history
… places
  • Loading branch information
MarshallOfSound authored and malept committed Dec 11, 2016
1 parent 12e5d99 commit 1d1ff74
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 2 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"inquirer": "^1.2.1",
"log-symbols": "^1.0.2",
"mkdirp": "^0.5.1",
"node-gyp": "^3.4.0",
"ora": "^0.3.0",
"pify": "^2.3.0",
"rimraf": "^2.5.4",
Expand Down
5 changes: 3 additions & 2 deletions src/electron-forge-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import rimraf from 'rimraf';
import './util/terminate';
import getForgeConfig from './util/forge-config';
import packagerCompileHook from './util/compile-hook';
import rebuildHook from './util/rebuild';
import resolveDir from './util/resolve-dir';

const main = async () => {
Expand Down Expand Up @@ -60,8 +61,8 @@ const main = async () => {
}, async (...args) => {
prepareSpinner.succeed();
await packagerCompileHook(dir, ...args);
packagerSpinner = ora.ora('Packaging Application').start();
}].concat(forgeConfig.electronPackagerConfig.afterCopy ? forgeConfig.electronPackagerConfig.afterCopy.map(item => require(item)) : []),
packagerSpinner = ora.ora('Packaging Application');
}, rebuildHook].concat(forgeConfig.electronPackagerConfig.afterCopy ? forgeConfig.electronPackagerConfig.afterCopy.map(item => require(item)) : []),
afterExtract: forgeConfig.electronPackagerConfig.afterExtract ? forgeConfig.electronPackagerConfig.afterExtract.map(item => require(item)) : [],
dir,
arch,
Expand Down
5 changes: 5 additions & 0 deletions src/electron-forge-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import fs from 'fs-promise';
import path from 'path';
import program from 'commander';
import ora from 'ora';
import pify from 'pify';

import './util/terminate';
import rebuild from './util/rebuild';
import resolveDir from './util/resolve-dir';

const main = async () => {
Expand Down Expand Up @@ -33,6 +35,9 @@ const main = async () => {
process.exit(1);
}

const packageJSON = JSON.parse(await fs.readFile(path.resolve(dir, 'package.json'), 'utf8'));

await pify(rebuild)(dir, packageJSON.devDependencies['electron-prebuilt-compile'], process.platform, process.arch);
spawn(process.execPath, [path.resolve(dir, 'node_modules/.bin/electron'), '.'].concat(process.argv.slice(2)), {
cwd: dir,
stdio: 'inherit',
Expand Down
64 changes: 64 additions & 0 deletions src/util/rebuild.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { spawn } from 'child_process';
import debug from 'debug';
import fs from 'fs-promise';
import mkdirp from 'mkdirp';
import os from 'os';
import path from 'path';
import pify from 'pify';

const d = debug('electron-forge:rebuild');

export default async (buildPath, electronVersion, pPlatform, pArch, done) => {
const rebuilds = [];
const rebuildModuleAt = async (modulePath) => {
if (await fs.exists(path.resolve(modulePath, 'binding.gyp'))) {
const metaPath = path.resolve(modulePath, 'build', 'Release', '.forge-meta');
if (await fs.exists(metaPath)) {
const meta = await fs.readFile(metaPath, 'utf8');
if (meta === pArch) {
d(`skipping: ${path.basename(modulePath)} as it is already built`);
return;
}
}
d('rebuilding:', path.basename(modulePath));
const rebuildArgs = [
'rebuild',
`--target=${electronVersion}`,
`--arch=${pArch}`,
'--dist-url=https://atom.io/download/electron',
];
await new Promise((resolve, reject) => {
const child = spawn(process.execPath, [path.resolve(__dirname, '../../node_modules/.bin/node-gyp')].concat(rebuildArgs), {
cwd: modulePath,
// stdio: 'inherit',
env: Object.assign({}, process.env, {
HOME: path.resolve(os.homedir(), '.electron-gyp'),
USERPROFILE: path.resolve(os.homedir(), '.electron-gyp'),
npm_config_disturl: 'https://atom.io/download/electron',
npm_config_runtime: 'electron',
npm_config_arch: pArch,
npm_config_target_arch: pArch,
}),
});
child.on('exit', async (code) => {
d('built:', path.basename(modulePath));
if (code !== 0) return reject(new Error(`Failed to rebuild: ${modulePath}`));
await pify(mkdirp)(path.dirname(metaPath));
await fs.writeFile(metaPath, pArch);
resolve();
});
});
}
};
const rebuildAllModulesIn = (nodeModulesPath) => {
for (const modulePath of fs.readdirSync(nodeModulesPath)) {
rebuilds.push(rebuildModuleAt(path.resolve(nodeModulesPath, modulePath)));
if (fs.existsSync(path.resolve(nodeModulesPath, modulePath, 'node_modules'))) {
rebuildAllModulesIn(path.resolve(nodeModulesPath, modulePath, 'node_modules'));
}
}
};
rebuildAllModulesIn(path.resolve(buildPath, 'node_modules'));
await Promise.all(rebuilds);
done();
};

0 comments on commit 1d1ff74

Please sign in to comment.