-
-
Notifications
You must be signed in to change notification settings - Fork 6.3k
/
Copy pathinvoke.js
163 lines (139 loc) · 4.32 KB
/
invoke.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
const inquirer = require('inquirer')
const {
chalk,
log,
error,
logWithSpinner,
stopSpinner,
resolvePluginId,
loadModule
} = require('@vue/cli-shared-utils')
const Generator = require('./Generator')
const confirmIfGitDirty = require('./util/confirmIfGitDirty')
const readFiles = require('./util/readFiles')
const getPkg = require('./util/getPkg')
const getChangedFiles = require('./util/getChangedFiles')
const PackageManager = require('./util/ProjectPackageManager')
async function invoke (pluginName, options = {}, context = process.cwd()) {
if (!(await confirmIfGitDirty(context))) {
return
}
delete options._
const pkg = getPkg(context)
// attempt to locate the plugin in package.json
const findPlugin = deps => {
if (!deps) return
let name
// official
if (deps[(name = `@vue/cli-plugin-${pluginName}`)]) {
return name
}
// full id, scoped short, or default short
if (deps[(name = resolvePluginId(pluginName))]) {
return name
}
}
const id = findPlugin(pkg.devDependencies) || findPlugin(pkg.dependencies)
if (!id) {
throw new Error(
`Cannot resolve plugin ${chalk.yellow(pluginName)} from package.json. ` +
`Did you forget to install it?`
)
}
const pluginGenerator = loadModule(`${id}/generator`, context)
if (!pluginGenerator) {
throw new Error(`Plugin ${id} does not have a generator.`)
}
// resolve options if no command line options (other than --registry) are passed,
// and the plugin contains a prompt module.
// eslint-disable-next-line prefer-const
let { registry, $inlineOptions, ...pluginOptions } = options
if ($inlineOptions) {
try {
pluginOptions = JSON.parse($inlineOptions)
} catch (e) {
throw new Error(`Couldn't parse inline options JSON: ${e.message}`)
}
} else if (!Object.keys(pluginOptions).length) {
let pluginPrompts = loadModule(`${id}/prompts`, context)
if (pluginPrompts) {
const prompt = inquirer.createPromptModule()
if (typeof pluginPrompts === 'function') {
pluginPrompts = pluginPrompts(pkg, prompt)
}
if (typeof pluginPrompts.getPrompts === 'function') {
pluginPrompts = pluginPrompts.getPrompts(pkg, prompt)
}
pluginOptions = await prompt(pluginPrompts)
}
}
const plugin = {
id,
apply: pluginGenerator,
options: {
registry,
...pluginOptions
}
}
await runGenerator(context, plugin, pkg)
}
async function runGenerator (context, plugin, pkg = getPkg(context)) {
const isTestOrDebug = process.env.VUE_CLI_TEST || process.env.VUE_CLI_DEBUG
const afterInvokeCbs = []
const afterAnyInvokeCbs = []
const generator = new Generator(context, {
pkg,
plugins: [plugin],
files: await readFiles(context),
afterInvokeCbs,
afterAnyInvokeCbs,
invoking: true
})
log()
log(`🚀 Invoking generator for ${plugin.id}...`)
await generator.generate({
extractConfigFiles: true,
checkExisting: true
})
const newDeps = generator.pkg.dependencies
const newDevDeps = generator.pkg.devDependencies
const depsChanged =
JSON.stringify(newDeps) !== JSON.stringify(pkg.dependencies) ||
JSON.stringify(newDevDeps) !== JSON.stringify(pkg.devDependencies)
if (!isTestOrDebug && depsChanged) {
log(`📦 Installing additional dependencies...`)
log()
const pm = new PackageManager({ context })
await pm.install()
}
if (afterInvokeCbs.length || afterAnyInvokeCbs.length) {
logWithSpinner('⚓', `Running completion hooks...`)
await Promise.all(afterInvokeCbs.map((cb) => cb()))
await Promise.all(afterAnyInvokeCbs.map((cb) => cb()))
stopSpinner()
log()
}
log(`${chalk.green('✔')} Successfully invoked generator for plugin: ${chalk.cyan(plugin.id)}`)
const changedFiles = getChangedFiles(context)
if (changedFiles.length) {
log(` The following files have been updated / added:\n`)
log(chalk.red(changedFiles.map(line => ` ${line}`).join('\n')))
log()
log(
` You should review these changes with ${chalk.cyan(
'git diff'
)} and commit them.`
)
log()
}
generator.printExitLogs()
}
module.exports = (...args) => {
return invoke(...args).catch(err => {
error(err)
if (!process.env.VUE_CLI_TEST) {
process.exit(1)
}
})
}
module.exports.runGenerator = runGenerator