UNPKG

@the-goat/core

Version:

![npm version](https://badgen.net/npm/v/@the-goat/goat?icon=npm) ![npm downloads](https://badgen.net/npm/dt/@the-goat/goat?icon=npm) ![npm weekly downloads](https://badgen.net/npm/dw/@the-goat/goat?icon=npm) ![npm licence](https://badgen.net/npm/license/@

171 lines (146 loc) 4.32 kB
import commander, { Command } from 'commander'; import { JSONSchema6 } from 'json-schema'; import Notifier from './notifier'; import GoatEvents from './events/GoatEvents'; import writeConfig from './schemas/writeConfig'; import { getConfig, validateConfig } from './config/config'; import checkSchema from './validators/schema'; import { IGoatExternalProjectConfig } from './config'; import watchFiles from './events/watch'; interface IGoatTaskOption { allowOnOnce?: boolean; allowOnWatch?: boolean; flags: string; label: string; } export type TGoatTaskMethodConfig = GoatTask & { options: Command }; interface IGoatTaskConfig { name: string; description: string; schema: JSONSchema6; init?: { files?: () => { files: { destination: string; name: string; data: string | Uint8Array }[] }; }; command: string; method: (command: TGoatTaskMethodConfig) => Promise<void>; watch?: (command: TGoatTaskMethodConfig) => void; options?: IGoatTaskOption[]; } /** * Class defining all Goat tasks */ export default class GoatTask { public name: string; private key: string; public description: string; public schema: JSONSchema6; public path: string; public init?: { files?: () => { files: { destination: string; name: string; data: string | Uint8Array }[] }; }; public configuration: IGoatExternalProjectConfig; private readonly command: Command; public readonly method: (command: TGoatTaskMethodConfig) => Promise<void>; public readonly watch?: (command: TGoatTaskMethodConfig) => void; public events: GoatEvents; public options: IGoatTaskOption[]; constructor(build: IGoatTaskConfig) { this.name = build.name; this.key = build.command; this.description = build.description; this.schema = build.schema; this.method = build.method; this.watch = build.watch; this.path = process.cwd(); this.init = build.init; this.events = new GoatEvents(); this.options = build.options || []; this.configuration = this.getConfiguration(); this.command = this.buildCommand(); } /** * Build the commander command object */ private buildCommand(): Command { const command = new commander.Command(this.key) .allowUnknownOption(true) .command(this.key) .description(this.description) // DO NOT SIMPLIFY: this-binding required .action((config: any) => this.action(config)); if (this.watch) { command.option('-w, --watch', 'Watch for file changes'); } if (this.options) { this.options.forEach((option) => { if (!option.allowOnOnce) { return; } command.option(option.flags, option.label); }); } return command as Command; } /** * Method to be executed by running Goat command. */ action(config: any) { if (config.watch) { watchFiles(this.events); return this.watchBase(config, this.events); } return this.actionBase(config); } /** * Goat configuration object of the current project */ private getConfiguration(): IGoatExternalProjectConfig { const configuration = getConfig(); if (!configuration) { throw new Error('Missing Goat configuraton'); } const isValid = validateConfig(configuration); // Validate used config if (!isValid || (this.schema && !checkSchema(configuration, this.schema))) { Notifier.error('The configuration is not correct'); writeConfig(this.schema); } return configuration; } /** * Forms the base of all Goat actions, */ public actionBase(config: Command): Promise<void> { Notifier.log(`${Notifier.emoji('goat')} Running ${this.name || 'task'} in ${process.cwd()}\n`); // const result = ; // result.then((callback) => { // if (typeof callback === 'function') { // callback(); // } // }); return this.method({ ...this, options: config, }); } /** * Base function for watch tasks */ watchBase(config: Command, events: GoatEvents) { this.events = events; if (!this.watch) { Notifier.log('This command has no watch option'); return; } this.watch({ ...this, options: config, }); } /** * Build command */ getCommand() { return this.command; } }