Skip to content

Commit

Permalink
馃懛 Refactors Builder to accept options in any order
Browse files Browse the repository at this point in the history
  • Loading branch information
jamonholmgren committed Feb 24, 2018
1 parent da04d74 commit 1e558f6
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 19 deletions.
3 changes: 0 additions & 3 deletions src/domain/builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ test('the gauntlet', t => {
.plugin(`${__dirname}/../fixtures/good-plugins/simplest`)
.plugins(`${__dirname}/../fixtures/good-plugins`, { hidden: true })

// test the builder
t.is(builder.runtime.brand, 'test')

const runtime = builder.create()
t.truthy(runtime)

Expand Down
75 changes: 59 additions & 16 deletions src/domain/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,35 @@ import coreCommandVersion from '../core-commands/version'
import { GluegunCommand } from './command'
import { GluegunLoadOptions, GluegunMultiLoadOptions } from './options'

interface BuilderItem {
value: string
options: GluegunLoadOptions
}

/**
* Provides a cleaner way to build a runtime.
*
* @class Builder
*/
export class Builder {
public readonly runtime: Runtime
public excludes: string[]
private data: {
defaultCommand?: GluegunCommand
brand?: string
excludes: string[]
defaultPlugin?: BuilderItem
commands: GluegunCommand[]
plugins: BuilderItem[]
multiPlugins: { value: string; options: GluegunLoadOptions & GluegunMultiLoadOptions }[]
}

constructor() {
this.runtime = new Runtime()
this.excludes = []
constructor(brand?: string) {
this.data = {
brand: brand,
excludes: [],
commands: [],
plugins: [],
multiPlugins: [],
}
}

/**
Expand All @@ -26,15 +43,15 @@ export class Builder {
* @param name The name should be all lowercase and contains only numbers, letters, and dashes.
*/
public brand(value: string): Builder {
this.runtime.brand = value
this.data.brand = value
return this
}

/**
* Excludes core libraries if they're not needed, for performance reasons.
*/
public exclude(excludes: string[]) {
this.excludes = excludes
this.data.excludes = excludes
return this
}

Expand All @@ -46,8 +63,7 @@ export class Builder {
* @return self.
*/
public src(value: string, options: GluegunLoadOptions = {}): Builder {
this.runtime.addCoreExtensions(this.excludes)
this.runtime.addDefaultPlugin(value, options)
this.data.defaultPlugin = { value, options }
return this
}

Expand All @@ -59,7 +75,8 @@ export class Builder {
* @return self.
*/
public plugin(value: string, options: GluegunLoadOptions = {}): Builder {
this.runtime.addPlugin(value, options)
// this.runtime.addPlugin(value, options)
this.data.plugins.push({ value, options })
return this
}

Expand All @@ -71,7 +88,7 @@ export class Builder {
* @return self.
*/
public plugins(value: string, options: GluegunLoadOptions & GluegunMultiLoadOptions = {}): Builder {
this.runtime.addPlugins(value, options)
this.data.multiPlugins.push({ value, options })
return this
}

Expand Down Expand Up @@ -111,7 +128,7 @@ export class Builder {
if (typeof command === 'function') {
command = { run: command }
}
command.name = this.runtime.brand
command.name = this.data.brand
return this.command(command)
}

Expand All @@ -121,21 +138,47 @@ export class Builder {
* @return self.
*/
public command(command: GluegunCommand): Builder {
this.runtime.addCommand(command)
// this.data.addCommand(command)
this.data.commands.push(command)
return this
}

/**
* Hand over the runtime.
*/
public create(): Runtime {
return this.runtime
// create a runtime
const runtime = new Runtime()

// extract the data the builder has collected
const { brand, excludes, defaultCommand, defaultPlugin, plugins, multiPlugins, commands } = this.data

// set the brand
runtime.brand = brand

// load the core extensions, minus excludes
runtime.addCoreExtensions(excludes)

// add a default command first
if (defaultCommand) runtime.addCommand(defaultCommand)

// add a default plugin
if (defaultPlugin) runtime.addDefaultPlugin(defaultPlugin.value, defaultPlugin.options)

// add other plugins, both singular and multiple
plugins.forEach(p => runtime.addPlugin(p.value, p.options))
multiPlugins.forEach(mp => runtime.addPlugins(mp.value, mp.options))

// add other commands
commands.forEach(c => runtime.addCommand(c))

return runtime
}
}

/**
* Export it as a factory function.
*/
export function build(): Builder {
return new Builder()
export function build(brand?: string): Builder {
return new Builder(brand)
}

0 comments on commit 1e558f6

Please sign in to comment.