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

Commit cf9fe20

Browse files
committed
feat: added init and prerun hooks
1 parent 8140e6e commit cf9fe20

File tree

8 files changed

+33
-24
lines changed

8 files changed

+33
-24
lines changed

src/config.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as os from 'os'
33
import * as path from 'path'
44
import * as readPkg from 'read-pkg'
55

6+
import {Hooks} from './hooks'
67
import {PJSON} from './pjson'
78
import * as Plugin from './plugin'
89

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

150-
async runHook<T extends {}>(event: string, opts?: T) {
151+
async runHook<T extends Hooks, K extends keyof T>(event: K, opts: T[K]) {
151152
debug('start %s hook', event)
152-
await super.runHook(event, {...opts || {}, config: this})
153+
await super.runHook<T, K>(event, {...opts || {} as any, config: this})
153154
debug('done %s hook', event)
154155
}
155156

156157
async runCommand(id: string, argv: string[] = []) {
158+
await this.runHook('init', {id})
157159
debug('runCommand %s %o', id, argv)
158160
const cmd = this.findCommand(id, {must: true}).load()
161+
await this.runHook('prerun', {Command: cmd, argv})
159162
await cmd.run(argv, this)
160163
}
161164

src/hooks.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import * as Config from '.'
22

33
export interface Hooks {
44
init: {id: string}
5+
prerun: {
6+
Command: Config.Command.Class
7+
argv: string[]
8+
}
59
update: {}
610
'command_not_found': {id: string},
711
'plugins:parse': {
812
pjson: Config.IPlugin
913
}
10-
prerun: {
11-
Command: Config.Command.Class
12-
argv: string[]
13-
}
1414
}
1515

1616
export type Hook<K extends keyof Hooks> = (options: Hooks[K] & {config: Config.IConfig}) => any

src/plugin.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import * as readPkg from 'read-pkg'
77
import {inspect} from 'util'
88

99
import {Command} from './command'
10+
import {Hooks} from './hooks'
1011
import {Manifest} from './manifest'
1112
import {PJSON} from './pjson'
1213
import {Topic} from './topic'
1314
import {tsPath} from './ts_node'
14-
import {undefault} from './util'
1515

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

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

192-
async runHook<T extends {}>(event: string, opts?: T) {
193+
async runHook<T extends Hooks, K extends keyof T>(event: K, opts: T[K]) {
193194
const promises = (this.hooks[event] || [])
194195
.map(async hook => {
195196
try {
196197
const p = tsPath(this.root, hook)
197198
debug('hook', event, p)
198-
await undefault(require(p))(opts)
199+
const search = (m: any) => {
200+
if (_.isFunction(m)) return m
201+
if (m.default && _.isFunction(m.default)) return m.default
202+
return Object.values(m).find((m: any) => _.isFunction(m))
203+
}
204+
205+
await search(require(p))(opts)
199206
} catch (err) {
200207
if (err.code === 'EEXIT') throw err
201208
cli.warn(err)

src/util.ts

-9
This file was deleted.

test/fixtures/typescript/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"anycli": {
55
"commands": "./lib/commands",
66
"hooks": {
7-
"init": "./lib/hooks/init"
7+
"init": "./lib/hooks/init",
8+
"prerun": ["./lib/hooks/prerun"]
89
}
910
}
1011
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function init() {
2+
console.log('running ts init hook')
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function prerun() {
2+
console.log('running ts prerun hook')
3+
}

test/typescript.test.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import {expect, fancy} from 'fancy-test'
21
import * as path from 'path'
32

43
import * as Config from '../src'
54

5+
import {expect, fancy} from './test'
6+
67
const root = path.resolve(__dirname, 'fixtures/typescript')
78
const p = (p: string) => path.join(root, p)
89

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

2021
withConfig
2122
.stdout()
22-
.it('runs ts command', async ctx => {
23-
ctx.config.runCommand('foo:bar:baz')
24-
expect(ctx.stdout).to.equal('it works!\n')
23+
.it('runs ts command init, and prerun hooks', async ctx => {
24+
await ctx.config.runCommand('foo:bar:baz')
25+
expect(ctx.stdout).to.equal('running ts init hook\nrunning ts prerun hook\nit works!\n')
2526
})
2627
})

0 commit comments

Comments
 (0)