UNPKG

4.9 kBPlain TextView Raw
1import { BaseCLI, installNpm } from '@midwayjs/fcli-command-core';
2import { saveYaml } from '@midwayjs/serverless-spec-builder';
3import { plugins } from './plugins';
4import { resolve } from 'path';
5import { existsSync } from 'fs';
6import { execSync } from 'child_process';
7import Spin from 'light-spinner';
8
9const { Select } = require('enquirer');
10export class CLI extends BaseCLI {
11 async loadDefaultPlugin() {
12 const command = this.commands && this.commands[0];
13 // version not load plugin
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 // load all
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 // skip unneed plugin
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 // if plugin not exists, auto install
47 if (!existsSync(userModPath)) {
48 await this.autoInstallMod(pluginInfo.mod);
49 }
50 try {
51 mod = require(userModPath);
52 } catch (e) {
53 // no oth doing
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 // 默认没有command的时候展示帮助
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 /** ignore */
88 }
89
90 try {
91 // midway-faas version
92 const cliVersion = require('../package.json').version;
93 log.log('@midwayjs/faas-cli'.padEnd(20) + `v${cliVersion}`);
94 } catch (E) {
95 /** ignore */
96 }
97 }
98
99 displayUsage(commandsArray, usage, coreInstance) {
100 this.displayVersion();
101 super.displayUsage(commandsArray, usage, coreInstance);
102 }
103
104 async checkProvider() {
105 // ignore f -v / f -h / f create
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 // 使用 f xxx --platform
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}