UNPKG

3.73 kBPlain TextView Raw
1import { existsSync } from 'fs';
2import { join } from 'path';
3import chalk from 'chalk';
4import { get } from 'lodash';
5
6import Feflow from '../core';
7import { Config } from '../shared/file';
8import CommandPicker, { COMMAND_TYPE } from '../core/command-picker';
9
10type PrintError = {
11 error: any | Error;
12 msg: string;
13 pluginPath?: string;
14 hideError?: boolean;
15};
16
17// 不用强制中断流程
18export class FefError {
19 context: Feflow;
20 picker: CommandPicker | null;
21
22 defaultDocs = 'https://github.com/Tencent/feflow/issues';
23 docsPathList = ['docs', 'doc', 'bugs.url', 'repository.url'];
24 pluginFile = 'package.json';
25 unversalpluginFile = ['plugin.yaml', 'plugin.yml'];
26
27 constructor(context: Feflow) {
28 this.context = context;
29 // 区分npm插件和多语言插件
30 // npm插件 => package.json
31 // 多语言插件 => plugin.yaml
32 if (this.context.commandPick) {
33 this.picker = context.commandPick as CommandPicker;
34 } else {
35 this.picker = null;
36 // throw new Error('command pick is not inital');
37 context.logger.debug('command pick is not inital');
38 }
39 }
40
41 checkPick() {
42 if (this.picker) return true;
43 if (this.context.commandPick) {
44 this.picker = this.context.commandPick as CommandPicker;
45 }
46 return !!this.picker;
47 }
48
49 printError(obj: PrintError) {
50 const { pluginPath } = obj;
51 console.log(999999, obj);
52 if (!pluginPath) {
53 if (!this.checkPick()) {
54 this.context.logger.debug('无法找到命令路径');
55 } else {
56 this.context.logger.debug('FefError command pick 初始化成功');
57 }
58 }
59
60 const docs = this.getDocPath(pluginPath);
61 if (docs) {
62 this.printErrorWithDocs(obj, docs);
63 } else {
64 let { error, msg } = obj;
65 if (!obj.hideError) {
66 msg = `${msg || error}`;
67 this.context.logger.error({ err: error }, msg, chalk.magenta(error));
68 } else {
69 // 兼容多语言插件
70 this.context.logger.info(`${msg}`);
71 }
72 }
73 }
74
75 printErrorWithDocs(obj: PrintError, docs: string) {
76 let { error, msg } = obj;
77 if (!obj.hideError) {
78 msg = `${msg || error}
79 插件执行发生异常,请查看文档获取更多内容:${chalk.green(docs)}`;
80 this.context.logger.error({ err: error }, msg, chalk.magenta(error));
81 } else {
82 // 兼容多语言插件
83 msg = `${msg} 请查看文档获取更多内容:${chalk.green(docs)}`;
84 this.context.logger.info(msg);
85 }
86 }
87
88 getDocPath(pluginPath?: string) {
89 let docs = '';
90 let configPath = '';
91 let type = COMMAND_TYPE.PLUGIN_TYPE;
92 if (!pluginPath) {
93 if (this.picker != null) {
94 const { path, type: cmdType } = this.picker.getCmdInfo();
95 pluginPath = path;
96 type = cmdType;
97 } else {
98 return docs;
99 }
100 }
101
102 if (!existsSync(pluginPath)) {
103 return docs;
104 }
105 if (type === COMMAND_TYPE.PLUGIN_TYPE) {
106 configPath = join(pluginPath, this.pluginFile);
107 } else if (type === COMMAND_TYPE.UNIVERSAL_PLUGIN_TYPE) {
108 this.unversalpluginFile.forEach((ext) => {
109 const tmpPath = join(pluginPath as string, ext);
110 if (existsSync(tmpPath)) configPath = tmpPath;
111 });
112 } else if (type === COMMAND_TYPE.NATIVE_TYPE) {
113 return this.defaultDocs;
114 }
115
116 if (existsSync(configPath)) {
117 const config = this.parseConfig(configPath);
118 this.docsPathList.forEach((docsPath) => {
119 if (docs) return;
120 docs = get(config, docsPath);
121 });
122 } else {
123 this.context.logger.info(`未找到插件配置文件: ${pluginPath}`);
124 }
125
126 return docs;
127 }
128
129 parseConfig(filePath: string) {
130 return Config.loadConfigFile(filePath);
131 }
132}