1 | import { BaseCLI, installNpm } from '@midwayjs/fcli-command-core';
|
2 | import { saveYaml } from '@midwayjs/serverless-spec-builder';
|
3 | import { plugins } from './plugins';
|
4 | import { resolve } from 'path';
|
5 | import { existsSync } from 'fs';
|
6 | import { execSync } from 'child_process';
|
7 | import Spin from 'light-spinner';
|
8 |
|
9 | const { Select } = require('enquirer');
|
10 | export class CLI extends BaseCLI {
|
11 | async loadDefaultPlugin() {
|
12 | const command = this.commands && this.commands[0];
|
13 |
|
14 | if (this.argv.v || this.argv.version) {
|
15 | return;
|
16 | }
|
17 | let needLoad = [];
|
18 | if (!this.argv.h && command) {
|
19 | if (plugins[command]) {
|
20 | needLoad = needLoad.concat(plugins[command]);
|
21 | }
|
22 | } else {
|
23 |
|
24 | Object.keys(plugins).forEach((cmd: string) => {
|
25 | needLoad = needLoad.concat(plugins[cmd]);
|
26 | });
|
27 | }
|
28 | const platform = this.spec.provider.name;
|
29 | const requiredMap = {};
|
30 | for (let pluginIndex = 0; pluginIndex < needLoad.length; pluginIndex++) {
|
31 | const pluginInfo = needLoad[pluginIndex];
|
32 | const key = `${pluginInfo.mod}:${pluginInfo.name}`;
|
33 |
|
34 | if (
|
35 | requiredMap[key] ||
|
36 | (pluginInfo.platform && platform !== pluginInfo.platform)
|
37 | ) {
|
38 | continue;
|
39 | }
|
40 | requiredMap[key] = true;
|
41 | let mod;
|
42 | try {
|
43 | mod = require(pluginInfo.mod);
|
44 | } catch (e) {
|
45 | const userModPath = resolve(this.cwd, 'node_modules', pluginInfo.mod);
|
46 |
|
47 | if (!existsSync(userModPath)) {
|
48 | await this.autoInstallMod(pluginInfo.mod);
|
49 | }
|
50 | try {
|
51 | mod = require(userModPath);
|
52 | } catch (e) {
|
53 |
|
54 | }
|
55 | }
|
56 | if (mod && mod[pluginInfo.name]) {
|
57 | this.core.addPlugin(mod[pluginInfo.name]);
|
58 | }
|
59 | }
|
60 | }
|
61 |
|
62 | async loadPlugins() {
|
63 | await this.checkProvider();
|
64 | await this.loadDefaultOptions();
|
65 | await super.loadPlugins();
|
66 | }
|
67 |
|
68 | async loadDefaultOptions() {
|
69 | if (this.commands.length) {
|
70 | return;
|
71 | }
|
72 |
|
73 | if (this.argv.v || this.argv.version) {
|
74 | this.displayVersion();
|
75 | } else {
|
76 |
|
77 | this.argv.h = true;
|
78 | }
|
79 | }
|
80 |
|
81 | displayVersion() {
|
82 | const log = this.loadLog();
|
83 | try {
|
84 | const nodeVersion = execSync('node -v').toString().replace('\n', '');
|
85 | log.log('Node.js'.padEnd(20) + nodeVersion);
|
86 | } catch (E) {
|
87 |
|
88 | }
|
89 |
|
90 | try {
|
91 |
|
92 | const cliVersion = require('../package.json').version;
|
93 | log.log('@midwayjs/faas-cli'.padEnd(20) + `v${cliVersion}`);
|
94 | } catch (E) {
|
95 |
|
96 | }
|
97 | }
|
98 |
|
99 | displayUsage(commandsArray, usage, coreInstance) {
|
100 | this.displayVersion();
|
101 | super.displayUsage(commandsArray, usage, coreInstance);
|
102 | }
|
103 |
|
104 | async checkProvider() {
|
105 |
|
106 | if (!this.commands.length || this.argv.h) {
|
107 | return;
|
108 | }
|
109 | const skipCommands = ['create', 'test'];
|
110 | if (skipCommands.indexOf(this.commands[0]) !== -1) {
|
111 | return;
|
112 | }
|
113 | if (!this.spec.provider) {
|
114 | this.spec.provider = { name: '', runtime: '' };
|
115 | }
|
116 | if (!this.spec.provider.name || this.argv.platform) {
|
117 | let platform = this.argv.platform;
|
118 | let needSelectPlatform = false;
|
119 | if (!this.spec.provider.name) {
|
120 |
|
121 | needSelectPlatform = true;
|
122 | } else if (this.argv.platform === true) {
|
123 |
|
124 | needSelectPlatform = true;
|
125 | }
|
126 | if (needSelectPlatform) {
|
127 | const prompt = new Select({
|
128 | name: 'provider',
|
129 | message: 'Which platform do you want to use?',
|
130 | choices: [
|
131 | '阿里云函数计算 aliyun fc',
|
132 | '腾讯云函数 tencent scf',
|
133 | '亚马逊 aws lambda',
|
134 | ],
|
135 | });
|
136 | const answers = await prompt.run();
|
137 | platform = answers.split(' ')[1];
|
138 | }
|
139 | if (typeof platform === 'string') {
|
140 | this.spec.provider.name = platform;
|
141 | saveYaml(this.specFile.path, this.spec);
|
142 | }
|
143 | }
|
144 | }
|
145 |
|
146 | async autoInstallMod(modName) {
|
147 | const log = this.loadLog();
|
148 | log.log(
|
149 | `[ midway ] CLI plugin '${modName}' was not installed, and will be installed automatically`
|
150 | );
|
151 | if (!this.argv.npm) {
|
152 | log.log(
|
153 | '[ midway ] You could use the `--npm` parameter to speed up the installation process'
|
154 | );
|
155 | }
|
156 | const spin = new Spin({ text: 'installing' });
|
157 | spin.start();
|
158 | try {
|
159 | await installNpm({
|
160 | npmName: modName,
|
161 | register: this.argv.npm,
|
162 | baseDir: this.cwd,
|
163 | slience: true,
|
164 | });
|
165 | } catch (e) {
|
166 | log.error(
|
167 | `[ midway ] cli plugin '${modName}' install error: ${e?.message}`
|
168 | );
|
169 | log.log(`[ midway ] please manual install '${modName}'`);
|
170 | }
|
171 | spin.stop();
|
172 | }
|
173 | }
|