Skip to content

Commit

Permalink
feat(hook): add feflow hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
cpselvis committed Mar 2, 2020
1 parent f5c706e commit a8076ec
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 5 deletions.
18 changes: 14 additions & 4 deletions packages/feflow-cli/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import figlet from 'figlet';
import minimist from 'minimist';
import semver from 'semver';
import Report from '@feflow/report';
import {
HOOK_TYPE_BEFORE,
HOOK_TYPE_AFTER,
EVENT_COMMAND_BEGIN
} from '../shared/constant';
const pkg = require('../../package.json');

const checkNodeVersion = (wanted: any, id: string) => {
Expand Down Expand Up @@ -78,10 +83,15 @@ export default function entry() {

report.report(cmd, args);

return feflow.call(cmd, feflow).then(() => {
logger.debug(`call ${cmd} success`);
}).catch((err) => {
handleError(err);
feflow.hook.emit(HOOK_TYPE_BEFORE);

feflow.hook.on(EVENT_COMMAND_BEGIN, () => {
return feflow.call(cmd, feflow).then(() => {
feflow.hook.emit(HOOK_TYPE_AFTER);
logger.debug(`call ${cmd} success`);
}).catch((err) => {
handleError(err);
});
});
});
}
95 changes: 95 additions & 0 deletions packages/feflow-cli/src/core/hook/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
HOOK_TYPE_BEFORE,
HOOK_TYPE_AFTER,
EVENT_COMMAND_BEGIN,
EVENT_DONE
} from '../../shared/constant';

export default class Hook {
private listeners: any;
private maxListener: any;
constructor() {
this.listeners = [];
this.maxListener = 100;
}

on(type: any, listener: any) {
const listeners = this.listeners;
if (listeners[type] && listeners[type].length >= this.maxListener) {
throw new Error(`Listener's maxCount is ${ this.maxListener }, has exceed`);
}
if (listeners[type] instanceof Array) {
if (listeners[type].indexOf(listener) === -1) {
listeners[type].push(listener);
}
} else {
listeners[type] = [].concat(listener);
}
}

emit(type: any) {
const args = Array.prototype.slice.call(arguments);
args.shift();
switch (type) {
case HOOK_TYPE_BEFORE:
this.hook(HOOK_TYPE_BEFORE, () => {
this.emit(EVENT_COMMAND_BEGIN);
});
break;
case HOOK_TYPE_AFTER:
this.hook(HOOK_TYPE_AFTER, () => {
this.emit(EVENT_DONE);
});
break;
default:
const listeners = this.listeners[type];
if (!listeners) {
return;
}
this.listeners[type].forEach((listener: any) => {
listener.apply(null, args);
});
break;
}
}

/**
* Run hook `type` callbacks and then invoke `fn()`.
*
* @private
* @param {string} type
* @param {Function} fn
*/
hook(type: any, fn: any) {
const hooks = this.listeners[type];

const next = (i: any) => {
const hook = hooks[i];
if (!hook) {
return fn();
}

const result = hook.call();
if (result && typeof result.then === 'function') {
result.then(
() => {
next(++i);
},
() => {
throw new Error('Promise rejected with no or falsy reason');
}
);
} else {
next(++i);
}
}

process.nextTick(() => {
if (!hooks) {
return fn();
} else {
next(0);
}
});
}
}
3 changes: 3 additions & 0 deletions packages/feflow-cli/src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Commander from './commander';
import Hook from './hook';
import fs from 'fs';
import inquirer from 'inquirer';
import logger from './logger';
Expand All @@ -24,6 +25,7 @@ export default class Feflow {
public version: string;
public logger: any;
public commander: any;
public hook: any;
public root: any;
public rootPkg: any;
public config: any;
Expand All @@ -40,6 +42,7 @@ export default class Feflow {
this.config = parseYaml(configPath);
this.configPath = configPath;
this.commander = new Commander();
this.hook = new Hook();
this.logger = logger({
debug: Boolean(args.debug),
silent: Boolean(args.silent)
Expand Down
22 changes: 21 additions & 1 deletion packages/feflow-cli/src/shared/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,24 @@ export const DEVKIT_CONFIG = [
'.feflowrc.json',
'.feflowrc',
'package.json'
];
];

/**
* Namespace for collection of "before" hooks
*/
export const HOOK_TYPE_BEFORE = 'before';

/**
* Namespace for collection of "after" hooks
*/
export const HOOK_TYPE_AFTER = 'after';

/**
* Emitted when command execution begins
*/
export const EVENT_COMMAND_BEGIN = 'command begin';

/**
* Emitted when totally finished
*/
export const EVENT_DONE = 'done';

0 comments on commit a8076ec

Please sign in to comment.