Skip to content
Permalink
Browse files

feat(plugin-local-electron): add plugin-local-electron

used to run a local version of electron instead of the version the electron module downloads
  • Loading branch information
MarshallOfSound committed May 2, 2018
1 parent fef9bcd commit 8af9268232c0e9dc2613af041d5b150b874432f0
@@ -9,7 +9,8 @@
"packages/installer/*",
"packages/maker/*",
"packages/publisher/*",
"packages/utils/*"
"packages/utils/*",
"packages/plugin/*"
]
},
"config": {
@@ -17,6 +17,7 @@ import requireSearch from '../util/require-search';
import resolveDir from '../util/resolve-dir';
import getCurrentOutDir from '../util/out-dir';
import getElectronVersion from '../util/electron-version';
import electronVersion from '../util/electron-version';

const { hostArch }: { hostArch: () => ForgeArch | 'all'} = require('electron-packager/targets');

@@ -154,12 +155,18 @@ export default async ({
done();
}) as ElectronPackagerAfterCopyHook);

const afterExtractHooks = [(async (buildPath, electronVersion, pPlatform, pArch, done) => {
await runHook(forgeConfig, 'packageAfterExtract', buildPath, electronVersion, pPlatform, pArch);
done();
}) as ElectronPackagerAfterCopyHook];
afterExtractHooks.push(...resolveHooks(forgeConfig.packagerConfig.afterExtract, dir));

const packageOpts: packager.Options = Object.assign({
asar: false,
overwrite: true,
}, forgeConfig.packagerConfig, {
afterCopy: sequentialHooks(afterCopyHooks),
afterExtract: sequentialHooks(resolveHooks(forgeConfig.packagerConfig.afterExtract, dir)),
afterExtract: sequentialHooks(afterExtractHooks),
afterPrune: sequentialHooks(afterPruneHooks),
dir,
arch,
@@ -1,5 +1,6 @@
import 'colors';
import { asyncOra } from '@electron-forge/async-ora';
import { StartOptions } from '@electron-forge/shared-types';
import { spawn, ChildProcess } from 'child_process';
import path from 'path';

@@ -11,36 +12,7 @@ import runHook from '../util/hook';
import getElectronVersion from '../util/electron-version';
import { ForgePlatform, ForgeArch } from '@electron-forge/shared-types';

export interface StartOptions {
/**
* The path to the electron forge project to run
*/
dir?: string;
/**
* The path (relative to dir) to the electron app to run relative to the project directory
*/
appPath?: string;
/**
* Whether to use sensible defaults or prompt the user visually
*/
interactive?: boolean;
/**
* Enables advanced internal Electron debug calls
*/
enableLogging?: boolean;
/**
* Arguments to pass through to the launched Electron application
*/
args?: (string | number)[];
/**
* Runs the Electron process as if it were node, disables all Electron API's
*/
runAsNode?: boolean;
/**
* Enables the node inspector, you can connect to this from chrome://inspect
*/
inspect?: boolean;
}
export { StartOptions };

export default async ({
dir = process.cwd(),
@@ -79,6 +51,8 @@ export default async ({

await runHook(forgeConfig, 'generateAssets');

let electronExecPath = path.resolve(dir, 'node_modules/electron/cli');

// If a plugin has taken over the start command let's stop here
const spawnedPluginChild = await forgeConfig.pluginInterface.overrideStartLogic({
dir,
@@ -89,7 +63,11 @@ export default async ({
runAsNode,
inspect,
});
if (spawnedPluginChild) return spawnedPluginChild;
if (typeof spawnedPluginChild === 'string') {
electronExecPath = spawnedPluginChild;
} else if (spawnedPluginChild) {
return spawnedPluginChild;
}

const spawnOpts = {
cwd: dir,
@@ -113,7 +91,7 @@ export default async ({
let spawned!: ChildProcess;

await asyncOra('Launching Application', async () => {
spawned = spawn(process.execPath, [path.resolve(dir, 'node_modules/electron/cli'), appPath].concat(args as string[]), spawnOpts);
spawned = spawn(process.execPath, [electronExecPath, appPath].concat(args as string[]), spawnOpts);
});

return spawned;
@@ -52,7 +52,6 @@ export default class PluginInterface implements IForgePluginInterface {
}
}

// FIXME: any
async overrideStartLogic(opts: StartOptions) {
let newStartFn;
const claimed = [];
@@ -0,0 +1,23 @@
{
"name": "@electron-forge/plugin-base",
"version": "6.0.0-beta.5",
"description": "Base plugin for Electron Forge",
"repository": "https://github.com/electron-userland/electron-forge",
"author": "Samuel Attard",
"license": "MIT",
"main": "dist/Plugin.js",
"typings": "dist/Plugin.d.ts",
"scripts": {
"test": "exit 0"
},
"devDependencies": {
"chai": "^4.0.0",
"mocha": "^5.0.0"
},
"engines": {
"node": ">= 6.0"
},
"dependencies": {
"@electron-forge/shared-types": "6.0.0-beta.5"
}
}
@@ -0,0 +1,25 @@
import { ForgeHookFn, StartOptions } from '@electron-forge/shared-types';
import { ChildProcess } from 'child_process';

export { StartOptions };

export default abstract class Plugin<C> {
public abstract name: string;
__isElectronForgePlugin!: true;

constructor(public config: C) {
Object.defineProperty(this, '__isElectronForgePlugin', {
value: true,
enumerable: false,
configurable: false,
});
}

getHook(hookName: string): ForgeHookFn | null {
return null;
}

async startLogic(startOpts: StartOptions): Promise<ChildProcess | string | false> {
return false;
}
}
@@ -0,0 +1,24 @@
{
"name": "@electron-forge/plugin-local-electron",
"version": "6.0.0-beta.5",
"description": "Local Electron plugin for Electron Forge, let's you use a local build of Electron",
"repository": "https://github.com/electron-userland/electron-forge",
"author": "Samuel Attard",
"license": "MIT",
"main": "dist/LocalElectronPlugin.js",
"typings": "dist/LocalElectronPlugin.d.ts",
"scripts": {
"test": "exit 0"
},
"devDependencies": {
"chai": "^4.0.0",
"mocha": "^5.0.0"
},
"engines": {
"node": ">= 6.0"
},
"dependencies": {
"@electron-forge/plugin-base": "6.0.0-beta.5",
"fs-extra": "^5.0.0"
}
}
@@ -0,0 +1,6 @@
export interface LocalElectronPluginConfig {
enabled: boolean;
electronPath: string;
electronPlatform?: string;
electronArch?: string;
}
@@ -0,0 +1,47 @@
import PluginBase, { StartOptions } from '@electron-forge/plugin-base';
import { spawn } from 'child_process';
import fs from 'fs-extra';

import { LocalElectronPluginConfig } from './Config';

export default class LocalElectronPlugin extends PluginBase<LocalElectronPluginConfig> {
name = 'local-electron';

async startLogic(startOpts: StartOptions) {
if (this.config.enabled) {
this.checkPlatform(process.platform);
process.env.ELECTRON_OVERRIDE_DIST_PATH = this.config.electronPath;
}
return false as any;
}

getHook(hookName: string) {
if (hookName === 'packageAfterExtract') {
return this.afterExtract;
}
return null;
}

private checkPlatform = (platform: string) => {
if ((this.config.electronPlatform || process.platform) !== platform) {
throw `Can not use local Electron version, required platform "${platform}" but local platform is "${this.config.electronPlatform || process.platform}"`
}
}

private checkArch = (arch: string) => {
if ((this.config.electronArch || process.arch) !== arch) {
throw `Can not use local Electron version, required arch "${arch}" but local arch is "${this.config.electronArch || process.arch}"`
}
}

private afterExtract = async (_: any, buildPath: string, __: any, platform: string, arch: string) => {
if (!this.config.enabled) return;

this.checkPlatform(platform);
this.checkArch(arch);

await fs.remove(buildPath);

await fs.copy(this.config.electronPath, buildPath);
}
}
@@ -59,8 +59,7 @@ import { RebuildOptions } from "electron-rebuild/lib/src/rebuild";

init(dir: string, forgeConfig: ForgeConfig): void;
getHook?(hookName: string): ForgeHookFn | null;
/* FIXME: MarshallOfSound - Having any here is depressing */
startLogic?(opts: any): Promise<ChildProcess | false>;
startLogic?(opts: StartOptions): Promise<ChildProcess | false>;
}

export interface IForgeResolvableMaker {
@@ -84,4 +83,35 @@ import { RebuildOptions } from "electron-rebuild/lib/src/rebuild";
__isElectronForgePublisher: boolean;
platforms?: undefined;
}

export interface StartOptions {
/**
* The path to the electron forge project to run
*/
dir?: string;
/**
* The path (relative to dir) to the electron app to run relative to the project directory
*/
appPath?: string;
/**
* Whether to use sensible defaults or prompt the user visually
*/
interactive?: boolean;
/**
* Enables advanced internal Electron debug calls
*/
enableLogging?: boolean;
/**
* Arguments to pass through to the launched Electron application
*/
args?: (string | number)[];
/**
* Runs the Electron process as if it were node, disables all Electron API's
*/
runAsNode?: boolean;
/**
* Enables the node inspector, you can connect to this from chrome://inspect
*/
inspect?: boolean;
}
// }

0 comments on commit 8af9268

Please sign in to comment.
You can’t perform that action at this time.