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