Skip to content

Commit

Permalink
feat(generic): Support setting the Electron app path in start()
Browse files Browse the repository at this point in the history
The start command allows the caller to specify the directory for the Electron forge project, and then assumes that its main module is the Electron application. However, some projects may contain multiple Electron applications, or may want to specify an html file or a URL as the Electron application (see https://github.com/electron/electron/blob/cf694ef32b78f0904219c6c8ba554d3d5cbea037/default_app/main.js#L338).

So, this adds an optional 'appPath' API option (and corresponding '-p'/'--app-path' CLI option) that is the path to the Electron application relative to the electron forge project (the 'dir' option).

This also fixes the start command-line options parsing, which was passing all arguments through to the Electron application instead of parsing out the start command options.
  • Loading branch information
Ben Demboski authored and MarshallOfSound committed Mar 5, 2017
1 parent fddb40e commit 47c5572
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 9 deletions.
10 changes: 6 additions & 4 deletions src/api/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import resolveDir from '../util/resolve-dir';

/**
* @typedef {Object} StartOptions
* @property {string} [dir=process.cwd()] The path to the app to be run
* @property {string} [dir=process.cwd()] The path to the electron forge project to run
* @property {string} [appPath='.'] The path (relative to dir) to the electron app to run relative to the project directory
* @property {boolean} [interactive=false] Whether to use sensible defaults or prompt the user visually
* @property {boolean} [enableLogging=false] Enables advanced internal Electron debug calls
* @property {Array<string>} [args] Arguments to pass through to the launched Electron application
Expand All @@ -23,8 +24,9 @@ import resolveDir from '../util/resolve-dir';
*/
export default async (providedOptions = {}) => {
// eslint-disable-next-line prefer-const, no-unused-vars
let { dir, interactive, enableLogging, args } = Object.assign({
let { dir, interactive, enableLogging, appPath, args } = Object.assign({
dir: process.cwd(),
appPath: '.',
interactive: false,
enableLogging: false,
args: [],
Expand Down Expand Up @@ -56,9 +58,9 @@ export default async (providedOptions = {}) => {
await asyncOra('Launching Application', async () => {
/* istanbul ignore if */
if (process.platform === 'win32') {
spawned = spawn(path.resolve(dir, 'node_modules/.bin/electron.cmd'), ['.'].concat(args), spawnOpts);
spawned = spawn(path.resolve(dir, 'node_modules/.bin/electron.cmd'), [appPath].concat(args), spawnOpts);
} else {
spawned = spawn(path.resolve(dir, 'node_modules/.bin/electron'), ['.'].concat(args), spawnOpts);
spawned = spawn(path.resolve(dir, 'node_modules/.bin/electron'), [appPath].concat(args), spawnOpts);
}
});

Expand Down
39 changes: 34 additions & 5 deletions src/electron-forge-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,21 @@ import './util/terminate';
import { start } from './api';

(async () => {
let commandArgs;
let appArgs;
const tripleDashIndex = process.argv.indexOf('---');
if (tripleDashIndex === -1) {
commandArgs = process.argv;
} else {
commandArgs = process.argv.slice(0, tripleDashIndex);
appArgs = process.argv.slice(tripleDashIndex + 1);
}

let dir = process.cwd();
program
.version(require('../package.json').version)
.arguments('[cwd]')
.option('-p, --app-path <path>', "Override the path to the Electron app to launch (defaults to '.')")
.option('-l, --enable-logging', 'Enable advanced logging. This will log internal Electron things')
.action((cwd) => {
if (!cwd) return;
Expand All @@ -19,12 +30,30 @@ import { start } from './api';
dir = path.resolve(dir, cwd);
}
})
.parse(process.argv.slice(0, 2));
.parse(commandArgs);

program.on('--help', () => {
console.log(" Any arguments found after '---' will be passed to the Electron app, e.g.");
console.log('');
console.log(' $ electron-forge /path/to/project -l --- -d -f foo.txt');
console.log('');
console.log(" will pass the arguments '-d -f foo.txt' to the Electron app");
});

await start({
const opts = {
dir,
interactive: true,
enableLogging: program.enableLogging,
args: process.argv.slice(2),
});
};

if (program.appPath) {
opts.appPath = program.appPath;
}
if (program.enableLogging) {
opts.enableLogging = program.enableLogging;
}
if (appArgs) {
opts.args = appArgs;
}

await start(opts);
})();
89 changes: 89 additions & 0 deletions test/fast/electron_forge_start_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import chai, { expect } from 'chai';
import chaiAsPromised from 'chai-as-promised';
import proxyquire from 'proxyquire';
import sinon from 'sinon';
import { Command } from 'commander';
import path from 'path';

chai.use(chaiAsPromised);

describe('electron-forge start', () => {
let argv;
let startStub;
let runCommand;

beforeEach(() => {
({ argv } = process);

startStub = sinon.stub();
runCommand = async (args = []) => {
process.argv = ['node', 'electron-forge-start'].concat(args);
return proxyquire.noCallThru().load('../../src/electron-forge-start', {
commander: new Command(),
'./api': { start: async opts => startStub(opts) },
});
};
});

afterEach(() => {
process.argv = argv;
});

it('should pass through correct defaults', async () => {
await runCommand();
expect(startStub.callCount).to.equal(1);
expect(startStub.firstCall.args[0]).to.deep.equal({
dir: process.cwd(),
interactive: true,
});
});

it('should handle an absolute project directory', async () => {
await runCommand([path.join(process.cwd(), 'test', 'fixture', 'dummy_app')]);
expect(startStub.callCount).to.equal(1);
expect(startStub.firstCall.args[0]).to.deep.equal({
dir: path.join(process.cwd(), 'test', 'fixture', 'dummy_app'),
interactive: true,
});
});

it('should handle a relative project directory', async () => {
await runCommand([path.join('test', 'fixture', 'dummy_app')]);
expect(startStub.callCount).to.equal(1);
expect(startStub.firstCall.args[0]).to.deep.equal({
dir: path.join(process.cwd(), 'test', 'fixture', 'dummy_app'),
interactive: true,
});
});

it('should handle an app path', async () => {
await runCommand(['-p', path.join('foo', 'electron.js')]);
expect(startStub.callCount).to.equal(1);
expect(startStub.firstCall.args[0]).to.deep.equal({
dir: process.cwd(),
appPath: path.join('foo', 'electron.js'),
interactive: true,
});
});

it('should be able to enable logging', async () => {
await runCommand(['-l']);
expect(startStub.callCount).to.equal(1);
expect(startStub.firstCall.args[0]).to.deep.equal({
dir: process.cwd(),
enableLogging: true,
interactive: true,
});
});

it('should handle app args', async () => {
await runCommand(['-l', '---', '-a', 'foo', '-l']);
expect(startStub.callCount).to.equal(1);
expect(startStub.firstCall.args[0]).to.deep.equal({
dir: process.cwd(),
enableLogging: true,
interactive: true,
args: ['-a', 'foo', '-l'],
});
});
});
21 changes: 21 additions & 0 deletions test/fast/start_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ describe('start', () => {
expect(spawnStub.firstCall.args[2].env).to.not.have.property('ELECTRON_ENABLE_LOGGING');
});

it("should pass electron '.' as the app path if not specified", async () => {
resolveStub.returnsArg(0);
await start({
dir: __dirname,
});
expect(spawnStub.callCount).to.equal(1);
expect(spawnStub.firstCall.args[0]).to.contain('electron');
expect(spawnStub.firstCall.args[1][0]).to.equal('.');
});

it('should pass electron the app path if specified', async () => {
resolveStub.returnsArg(0);
await start({
dir: __dirname,
appPath: '/path/to/app.js',
});
expect(spawnStub.callCount).to.equal(1);
expect(spawnStub.firstCall.args[0]).to.contain('electron');
expect(spawnStub.firstCall.args[1][0]).to.equal('/path/to/app.js');
});

it('should enable electron logging if enableLogging=true', async () => {
resolveStub.returnsArg(0);
await start({
Expand Down

0 comments on commit 47c5572

Please sign in to comment.