Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: You can now use web-ext programatically, e.g. webExt.cmd.run() #1028

Merged
merged 3 commits into from
Aug 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion bin/web-ext
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/usr/bin/env node

var webExt = require('../dist/web-ext').default;
var path = require('path');
var absolutePackageDir = path.join(path.resolve(__dirname), '..');
require('../dist/web-ext').main(absolutePackageDir);

webExt.main(absolutePackageDir);
2 changes: 2 additions & 0 deletions src/cmd/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ export type BuildCmdParams = {|
sourceDir: string,
artifactsDir: string,
asNeeded?: boolean,
noInput?: boolean,
overwriteDest?: boolean,
ignoreFiles?: Array<string>,
|};
Expand All @@ -196,6 +197,7 @@ export default async function build(
asNeeded = false,
overwriteDest = false,
ignoreFiles = [],
noInput = false,
}: BuildCmdParams,
{
manifestData,
Expand Down
8 changes: 6 additions & 2 deletions src/cmd/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ import {createLogger} from '../util/logger';

const log = createLogger(__filename);

type DocsParams = {
noInput?: boolean,
shouldExitProgram?: boolean,
}

type DocsOptions = {
openUrl?: typeof defaultUrlOpener,
shouldExitProgram?: boolean,
}

export const url = 'https://developer.mozilla.org/en-US/Add-ons' +
'/WebExtensions/Getting_started_with_web-ext';

export default function docs(
params: Object, {openUrl = defaultUrlOpener}: DocsOptions = {}
params: DocsParams, {openUrl = defaultUrlOpener}: DocsOptions = {}
) {
return new Promise((resolve, reject) => {
openUrl(url, (error) => {
Expand Down
1 change: 0 additions & 1 deletion src/cmd/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ import sign from './sign';
import docs from './docs';

export default {build, lint, run, sign, docs};

26 changes: 18 additions & 8 deletions src/cmd/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ export type LinterCreatorFn = (params: LinterCreatorParams) => Linter;
// Lint command types and implementation.

export type LintCmdParams = {|
sourceDir: string,
verbose?: boolean,
selfHosted?: boolean,
artifactsDir?: string,
boring?: boolean,
output?: LinterOutputType,
ignoreFiles?: Array<string>,
metadata?: boolean,
noInput?: boolean,
output?: LinterOutputType,
pretty?: boolean,
selfHosted?: boolean,
sourceDir: string,
verbose?: boolean,
warningsAsErrors?: boolean,
ignoreFiles?: Array<string>,
artifactsDir?: string,
|};

export type LintCmdOptions = {|
Expand All @@ -61,8 +62,17 @@ export type LintCmdOptions = {|

export default function lint(
{
verbose, sourceDir, selfHosted, boring, output,
metadata, pretty, warningsAsErrors, ignoreFiles, artifactsDir,
artifactsDir,
boring,
ignoreFiles,
metadata,
noInput = false,
output,
pretty,
sourceDir,
selfHosted,
verbose,
warningsAsErrors,
}: LintCmdParams,
{
createLinter = defaultLinterCreator,
Expand Down
27 changes: 19 additions & 8 deletions src/cmd/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ const log = createLogger(__filename);
// Run command types and implementation.

export type CmdRunParams = {|
sourceDir: string,
artifactsDir: string,
browserConsole: boolean,
customPrefs?: FirefoxPreferences,
firefox: string,
firefoxProfile?: string,
ignoreFiles?: Array<string>,
keepProfileChanges: boolean,
preInstall: boolean,
noInput?: boolean,
noReload: boolean,
browserConsole: boolean,
customPrefs?: FirefoxPreferences,
preInstall: boolean,
sourceDir: string,
startUrl?: string | Array<string>,
ignoreFiles?: Array<string>,
|};

export type CmdRunOptions = {|
Expand All @@ -48,9 +49,18 @@ export type CmdRunOptions = {|

export default async function run(
{
sourceDir, artifactsDir, firefox, firefoxProfile,
keepProfileChanges = false, preInstall = false, noReload = false,
browserConsole = false, customPrefs, startUrl, ignoreFiles,
artifactsDir,
browserConsole = false,
customPrefs,
firefox,
firefoxProfile,
keepProfileChanges = false,
ignoreFiles,
noInput = false,
noReload = false,
preInstall = false,
sourceDir,
startUrl,
}: CmdRunParams,
{
desktopNotifications = defaultDesktopNotifications,
Expand Down Expand Up @@ -111,6 +121,7 @@ export default async function run(
sourceDir,
artifactsDir,
ignoreFiles,
noInput,
});
}

Expand Down
29 changes: 20 additions & 9 deletions src/cmd/sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ export const extensionIdFile = '.web-extension-id';
// Sign command types and implementation.

export type SignParams = {|
id?: string,
verbose?: boolean,
sourceDir: string,
artifactsDir: string,
ignoreFiles?: Array<string>,
apiKey: string,
apiProxy: string,
apiSecret: string,
apiUrlPrefix: string,
apiProxy: string,
artifactsDir: string,
id?: string,
ignoreFiles?: Array<string>,
noInput?: boolean,
sourceDir: string,
timeout: number,
verbose?: boolean,
|};

export type SignOptions = {
Expand All @@ -47,12 +48,22 @@ export type SignResult = {|

export default function sign(
{
verbose, sourceDir, artifactsDir, ignoreFiles = [],
apiKey, apiSecret, apiUrlPrefix, apiProxy, id, timeout,
apiKey,
apiProxy,
apiSecret,
apiUrlPrefix,
artifactsDir,
id,
ignoreFiles = [],
noInput = false,
sourceDir,
timeout,
verbose,
}: SignParams,
{
build = defaultBuilder, signAddon = defaultAddonSigner,
build = defaultBuilder,
preValidatedManifest,
signAddon = defaultAddonSigner,
}: SignOptions = {}
): Promise<SignResult> {
return withTempDir(
Expand Down
17 changes: 14 additions & 3 deletions src/extension-runners/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ export type ReloadStrategyParams = {|
sourceDir: string,
artifactsDir: string,
ignoreFiles?: Array<string>,
noInput?: boolean,
|};

export type ReloadStrategyOptions = {|
Expand All @@ -246,15 +247,23 @@ export type ReloadStrategyOptions = {|

export function defaultReloadStrategy(
{
artifactsDir,
extensionRunner,
sourceDir, artifactsDir, ignoreFiles,
ignoreFiles,
noInput = false,
sourceDir,
}: ReloadStrategyParams,
{
createWatcher = defaultWatcherCreator,
stdin = process.stdin,
kill = process.kill,
}: ReloadStrategyOptions = {}
): void {
const allowInput = !noInput;
if (!allowInput) {
log.debug('Input has been disabled because of noInput==true');
}

const watcher: Watchpack = createWatcher({
reloadExtension: (watchedSourceDir) => {
extensionRunner.reloadExtensionBySourceDir(watchedSourceDir);
Expand All @@ -266,10 +275,12 @@ export function defaultReloadStrategy(

extensionRunner.registerCleanup(() => {
watcher.close();
stdin.pause();
if (allowInput) {
stdin.pause();
}
});

if (stdin.isTTY && stdin instanceof tty.ReadStream) {
if (allowInput && stdin.isTTY && stdin instanceof tty.ReadStream) {
readline.emitKeypressEvents(stdin);
stdin.setRawMode(true);

Expand Down
8 changes: 7 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
/* @flow */
import {main} from './program';
import cmd from './cmd';
import * as logger from './util/logger';

export {main};
// This only exposes util/logger so far.
// Do we need anything else?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kumar303 👍 Nice! This is pretty neat!

The change seems ok to me, but I'm wondering if we should make some tweak to the defaultReloadStrategy, mostly to make the caller of the API able to disable or customize the "interactive" behavior (e.g. reading from stdin when used as a library doesn't seem a great idea, it is probably something that the caller may want to easily disable and maybe manage with an API object which allow it to know when a change has been detected, trigger the addon reload and exit the runner).

What do you think?

const util = {logger};

export default {main, cmd, util};
8 changes: 8 additions & 0 deletions tests/unit/test-cmd/test.run.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ describe('run', () => {
assert.equal(args.artifactsDir, artifactsDir);
});

it('can disable input in the reload strategy', async () => {
const cmd = prepareRun();
const {reloadStrategy} = cmd.options;

await cmd.run({noInput: true, noReload: false});
sinon.assert.calledWithMatch(reloadStrategy, {noInput: true});
});

it('will not reload when using --pre-install', async () => {
const cmd = prepareRun();
const {reloadStrategy} = cmd.options;
Expand Down
21 changes: 21 additions & 0 deletions tests/unit/test-extension-runners/test.extension-runners.js
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,27 @@ describe('util/extension-runners', () => {
}
});

it('allows you to disable input', async () => {
const {extensionRunner, reloadStrategy} = prepare();
sinon.spy(extensionRunner, 'registerCleanup');

const fakeStdin = new tty.ReadStream();
sinon.spy(fakeStdin, 'pause');
sinon.spy(fakeStdin, 'setRawMode');

try {
await reloadStrategy({noInput: true}, {stdin: fakeStdin});
// This is meant to test that all input is ignored.
sinon.assert.notCalled(fakeStdin.setRawMode);
} finally {
exitKeypressLoop(fakeStdin);
}

const cleanupCb = extensionRunner.registerCleanup.firstCall.args[0];
cleanupCb();
sinon.assert.notCalled(fakeStdin.pause);
});

it('can still reload when user presses R after a reload error',
async () => {
const {extensionRunner, reloadStrategy} = prepare({
Expand Down
26 changes: 26 additions & 0 deletions tests/unit/test.web-ext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* @flow */
import {describe, it} from 'mocha';
import {assert} from 'chai';

import webExt from '../../src/main';
import build from '../../src/cmd/build';
import run from '../../src/cmd/run';
import {main} from '../../src/program';
import {consoleStream} from '../../src/util/logger';


describe('webExt', () => {
it('exposes main', () => {
assert.equal(webExt.main, main);
});

it('exposes commands', () => {
// This just checks a sample of commands.
assert.equal(webExt.cmd.run, run);
assert.equal(webExt.cmd.build, build);
});

it('gives you access to the log stream', () => {
assert.equal(webExt.util.logger.consoleStream, consoleStream);
});
});