2018-10-25 07:43:42 +00:00
|
|
|
import parseArgs from 'minimist'
|
|
|
|
import { name, version } from '../package.json'
|
2018-11-01 03:53:06 +00:00
|
|
|
import { loadNuxtConfig } from './utils'
|
2018-11-08 09:15:56 +00:00
|
|
|
import { indent, foldLines, startSpaces, optionSpaces, colorize } from './utils/formatting'
|
2018-11-02 04:35:32 +00:00
|
|
|
import * as commands from './commands'
|
2018-10-25 07:43:42 +00:00
|
|
|
import * as imports from './imports'
|
|
|
|
|
|
|
|
export default class NuxtCommand {
|
2018-10-29 22:16:16 +00:00
|
|
|
constructor({ name, description, usage, options, run } = {}) {
|
|
|
|
this.name = name || ''
|
2018-10-25 07:43:42 +00:00
|
|
|
this.description = description || ''
|
|
|
|
this.usage = usage || ''
|
2018-10-29 22:16:16 +00:00
|
|
|
this.options = Object.assign({}, options)
|
|
|
|
this._run = run
|
|
|
|
}
|
|
|
|
|
2018-11-02 04:35:32 +00:00
|
|
|
static async load(name) {
|
2018-11-08 09:15:56 +00:00
|
|
|
if (name in commands) {
|
|
|
|
const cmd = await commands[name]() // eslint-disable-line import/namespace
|
|
|
|
.then(m => m.default)
|
2018-11-02 04:35:32 +00:00
|
|
|
return NuxtCommand.from(cmd)
|
|
|
|
} else {
|
|
|
|
// TODO dynamic module loading
|
2018-11-08 09:15:56 +00:00
|
|
|
throw new Error('Command ' + name + ' could not be loaded!')
|
2018-11-02 04:35:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-29 22:16:16 +00:00
|
|
|
static from(options) {
|
|
|
|
if (options instanceof NuxtCommand) {
|
|
|
|
return options
|
|
|
|
}
|
|
|
|
return new NuxtCommand(options)
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
|
|
|
|
2018-11-08 09:15:56 +00:00
|
|
|
run() {
|
|
|
|
return this._run(this)
|
|
|
|
}
|
2018-10-25 07:43:42 +00:00
|
|
|
|
2018-11-08 09:15:56 +00:00
|
|
|
showVersion() {
|
|
|
|
process.stdout.write(`${name} v${version}\n`)
|
|
|
|
process.exit(0)
|
|
|
|
}
|
2018-10-25 07:43:42 +00:00
|
|
|
|
2018-11-08 09:15:56 +00:00
|
|
|
showHelp() {
|
|
|
|
process.stdout.write(this._getHelp())
|
|
|
|
process.exit(0)
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getArgv(args) {
|
|
|
|
const minimistOptions = this._getMinimistOptions()
|
|
|
|
const argv = parseArgs(args || process.argv.slice(2), minimistOptions)
|
|
|
|
|
|
|
|
if (argv.version) {
|
|
|
|
this.showVersion()
|
|
|
|
} else if (argv.help) {
|
|
|
|
this.showHelp()
|
|
|
|
}
|
|
|
|
|
|
|
|
return argv
|
|
|
|
}
|
|
|
|
|
|
|
|
async getNuxtConfig(argv, extraOptions) {
|
|
|
|
const config = await loadNuxtConfig(argv)
|
|
|
|
const options = Object.assign(config, extraOptions || {})
|
|
|
|
|
2018-10-29 22:16:16 +00:00
|
|
|
for (const name of Object.keys(this.options)) {
|
2018-11-08 09:15:56 +00:00
|
|
|
this.options[name].prepare && this.options[name].prepare(this, options, argv)
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return options
|
|
|
|
}
|
|
|
|
|
|
|
|
async getNuxt(options) {
|
2018-10-25 15:40:55 +00:00
|
|
|
const { Nuxt } = await imports.core()
|
2018-12-01 10:13:28 +00:00
|
|
|
const nuxt = new Nuxt(options)
|
|
|
|
await nuxt.ready()
|
|
|
|
return nuxt
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async getBuilder(nuxt) {
|
2018-10-25 15:40:55 +00:00
|
|
|
const { Builder } = await imports.builder()
|
|
|
|
const { BundleBuilder } = await imports.webpack()
|
2018-10-25 11:22:31 +00:00
|
|
|
return new Builder(nuxt, BundleBuilder)
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async getGenerator(nuxt) {
|
2018-10-25 15:40:55 +00:00
|
|
|
const { Generator } = await imports.generator()
|
2018-10-25 11:22:31 +00:00
|
|
|
const builder = await this.getBuilder(nuxt)
|
|
|
|
return new Generator(nuxt, builder)
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
|
|
|
|
2018-11-08 09:15:56 +00:00
|
|
|
_getMinimistOptions() {
|
|
|
|
const minimistOptions = {
|
|
|
|
alias: {},
|
|
|
|
boolean: [],
|
|
|
|
string: [],
|
|
|
|
default: {}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const name of Object.keys(this.options)) {
|
|
|
|
const option = this.options[name]
|
|
|
|
|
|
|
|
if (option.alias) {
|
|
|
|
minimistOptions.alias[option.alias] = name
|
|
|
|
}
|
|
|
|
if (option.type) {
|
|
|
|
minimistOptions[option.type].push(option.alias || name)
|
|
|
|
}
|
|
|
|
if (option.default) {
|
|
|
|
minimistOptions.default[option.alias || name] = option.default
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return minimistOptions
|
|
|
|
}
|
|
|
|
|
2018-10-25 07:43:42 +00:00
|
|
|
_getHelp() {
|
|
|
|
const options = []
|
|
|
|
let maxOptionLength = 0
|
2018-10-29 22:16:16 +00:00
|
|
|
|
|
|
|
for (const name in this.options) {
|
|
|
|
const option = this.options[name]
|
|
|
|
|
|
|
|
let optionHelp = '--'
|
|
|
|
optionHelp += option.type === 'boolean' && option.default ? 'no-' : ''
|
|
|
|
optionHelp += name
|
|
|
|
if (option.alias) {
|
|
|
|
optionHelp += `, -${option.alias}`
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
2018-10-29 22:16:16 +00:00
|
|
|
|
|
|
|
maxOptionLength = Math.max(maxOptionLength, optionHelp.length)
|
|
|
|
options.push([ optionHelp, option.description ])
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
|
|
|
|
2018-10-29 22:16:16 +00:00
|
|
|
const _opts = options.map(([option, description]) => {
|
|
|
|
const i = indent(maxOptionLength + optionSpaces - option.length)
|
|
|
|
return foldLines(
|
|
|
|
option + i + description,
|
|
|
|
startSpaces + maxOptionLength + optionSpaces * 2,
|
|
|
|
startSpaces + optionSpaces
|
|
|
|
)
|
2018-10-25 07:43:42 +00:00
|
|
|
}).join('\n')
|
|
|
|
|
2018-11-01 03:53:06 +00:00
|
|
|
const usage = foldLines(`Usage: nuxt ${this.usage} [options]`, startSpaces)
|
|
|
|
const description = foldLines(this.description, startSpaces)
|
|
|
|
const opts = foldLines(`Options:`, startSpaces) + '\n\n' + _opts
|
2018-10-25 07:43:42 +00:00
|
|
|
|
2018-11-08 09:15:56 +00:00
|
|
|
let helpText = colorize(`${usage}\n\n`)
|
|
|
|
if (this.description) helpText += colorize(`${description}\n\n`)
|
|
|
|
if (options.length) helpText += colorize(`${opts}\n\n`)
|
2018-10-25 07:43:42 +00:00
|
|
|
|
2018-11-08 09:15:56 +00:00
|
|
|
return helpText
|
2018-10-25 07:43:42 +00:00
|
|
|
}
|
|
|
|
}
|