Skip to content
This repository has been archived by the owner on Aug 22, 2023. It is now read-only.

Commit

Permalink
feat: added init and prerun hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Feb 3, 2018
1 parent 8140e6e commit cf9fe20
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 24 deletions.
7 changes: 5 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as os from 'os'
import * as path from 'path'
import * as readPkg from 'read-pkg'

import {Hooks} from './hooks'
import {PJSON} from './pjson'
import * as Plugin from './plugin'

Expand Down Expand Up @@ -147,15 +148,17 @@ export class Config extends Plugin.Plugin implements IConfig {
debug('config done')
}

async runHook<T extends {}>(event: string, opts?: T) {
async runHook<T extends Hooks, K extends keyof T>(event: K, opts: T[K]) {
debug('start %s hook', event)
await super.runHook(event, {...opts || {}, config: this})
await super.runHook<T, K>(event, {...opts || {} as any, config: this})
debug('done %s hook', event)
}

async runCommand(id: string, argv: string[] = []) {
await this.runHook('init', {id})
debug('runCommand %s %o', id, argv)
const cmd = this.findCommand(id, {must: true}).load()
await this.runHook('prerun', {Command: cmd, argv})
await cmd.run(argv, this)
}

Expand Down
8 changes: 4 additions & 4 deletions src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import * as Config from '.'

export interface Hooks {
init: {id: string}
prerun: {
Command: Config.Command.Class
argv: string[]
}
update: {}
'command_not_found': {id: string},
'plugins:parse': {
pjson: Config.IPlugin
}
prerun: {
Command: Config.Command.Class
argv: string[]
}
}

export type Hook<K extends keyof Hooks> = (options: Hooks[K] & {config: Config.IConfig}) => any
15 changes: 11 additions & 4 deletions src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import * as readPkg from 'read-pkg'
import {inspect} from 'util'

import {Command} from './command'
import {Hooks} from './hooks'
import {Manifest} from './manifest'
import {PJSON} from './pjson'
import {Topic} from './topic'
import {tsPath} from './ts_node'
import {undefault} from './util'

export interface Options {
root: string
Expand Down Expand Up @@ -72,7 +72,7 @@ export interface IPlugin {
findCommand(id: string, opts?: {must: boolean}): Command.Plugin | undefined
findTopic(id: string, opts: {must: true}): Topic
findTopic(id: string, opts?: {must: boolean}): Topic | undefined
runHook<T extends {}>(event: string, opts?: T): Promise<void>
runHook<T extends Hooks, K extends keyof T>(event: K, opts: T[K]): Promise<void>
}

const debug = require('debug')('@anycli/config')
Expand Down Expand Up @@ -168,6 +168,7 @@ export class Plugin implements IPlugin {
_findCommand(id: string): Command.Class {
const search = (cmd: any) => {
if (_.isFunction(cmd.run)) return cmd
if (cmd.default && cmd.default.run) return cmd.default
return Object.values(cmd).find((cmd: any) => _.isFunction(cmd.run))
}
const p = require.resolve(path.join(this.commandsDir!, ...id.split(':')))
Expand All @@ -189,13 +190,19 @@ export class Plugin implements IPlugin {
if (opts.must) throw new Error(`topic ${name} not found`)
}

async runHook<T extends {}>(event: string, opts?: T) {
async runHook<T extends Hooks, K extends keyof T>(event: K, opts: T[K]) {
const promises = (this.hooks[event] || [])
.map(async hook => {
try {
const p = tsPath(this.root, hook)
debug('hook', event, p)
await undefault(require(p))(opts)
const search = (m: any) => {
if (_.isFunction(m)) return m
if (m.default && _.isFunction(m.default)) return m.default
return Object.values(m).find((m: any) => _.isFunction(m))
}

await search(require(p))(opts)
} catch (err) {
if (err.code === 'EEXIT') throw err
cli.warn(err)
Expand Down
9 changes: 0 additions & 9 deletions src/util.ts

This file was deleted.

3 changes: 2 additions & 1 deletion test/fixtures/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"anycli": {
"commands": "./lib/commands",
"hooks": {
"init": "./lib/hooks/init"
"init": "./lib/hooks/init",
"prerun": ["./lib/hooks/prerun"]
}
}
}
3 changes: 3 additions & 0 deletions test/fixtures/typescript/src/hooks/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function init() {
console.log('running ts init hook')
}
3 changes: 3 additions & 0 deletions test/fixtures/typescript/src/hooks/prerun.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function prerun() {
console.log('running ts prerun hook')
}
9 changes: 5 additions & 4 deletions test/typescript.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {expect, fancy} from 'fancy-test'
import * as path from 'path'

import * as Config from '../src'

import {expect, fancy} from './test'

const root = path.resolve(__dirname, 'fixtures/typescript')
const p = (p: string) => path.join(root, p)

Expand All @@ -19,8 +20,8 @@ describe('typescript', () => {

withConfig
.stdout()
.it('runs ts command', async ctx => {
ctx.config.runCommand('foo:bar:baz')
expect(ctx.stdout).to.equal('it works!\n')
.it('runs ts command init, and prerun hooks', async ctx => {
await ctx.config.runCommand('foo:bar:baz')
expect(ctx.stdout).to.equal('running ts init hook\nrunning ts prerun hook\nit works!\n')
})
})

0 comments on commit cf9fe20

Please sign in to comment.