1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import commander from 'commander';
17import envConfig from './config/env';
18import { getToolConfiguration, ToolConfigType } from './bin/index';
19import { CommandType, OptionObjType, PluginType, PluginOptionsType, toolNameType, toolNameSet } from './bin/config';
20import { LogUtil } from './utils/logUtil';
21import { FileUtils } from './utils/FileUtils';
22
23class ToolBoxCommander {
24  program: commander.Command = new commander.Command();
25  constructor() { }
26  addPluginCommand(plugin: PluginType): void {
27    const pluginOption: PluginOptionsType = plugin.pluginOptions;
28    if (!pluginOption) {
29      return;
30    }
31    const pluginCommand: commander.Command = this.program
32      .name(pluginOption.name)
33      .description(pluginOption.description)
34      .version(pluginOption.version)
35      .action((opts: OptionObjType) => {
36        this.judgeOpts(opts);
37        plugin.start(opts);
38        plugin.stop();
39      });
40    pluginOption.commands.forEach((command: CommandType) => {
41      if (command.isRequiredOption) {
42        pluginCommand.requiredOption(...command.options);
43      } else {
44        pluginCommand.option(...command.options);
45      }
46    });
47  }
48  buildCommands(): void {
49    this.program.parse();
50  }
51  /**
52   * 判断传入命令是否满足工具允许条件,满足正常允许,不满足的时候通过stopRun停止命令行执行
53   *
54   * @param {OptionObjType} opts
55   */
56  judgeOpts(opts: OptionObjType): void {
57    const toolName: string = opts.toolName;
58    if (!toolNameSet.has(toolName)) {
59      this.stopRun(`error toolName "${toolName}",toolName not in \[${[...toolNameSet]}\] `);
60    }
61    switch (toolName) {
62      case toolNameType.COLLECT:
63        const collectPath: string = opts.collectPath;
64        if (collectPath === '' || !FileUtils.isExists(collectPath)) {
65          this.stopRun(`error collectPath "${collectPath}",collectPath need a exist file path`);
66        }
67        break;
68      case toolNameType.LABELDETECTION:
69        const checkLabels: string = opts.checkLabels;
70        if (checkLabels === '') {
71          this.stopRun(`error checkLabels "${checkLabels}",detection tools need checkLabels`);
72        }
73    }
74  }
75  /**
76   * 停止命令行执行,输出错误信息
77   *
78   * @param {string} text
79   */
80  stopRun(text: string): void {
81    LogUtil.e('commander', text);
82    this.program.help({ error: true });
83  }
84}
85class ToolboxEntry {
86  commandBuilder: ToolBoxCommander;
87  constructor() {
88    this.commandBuilder = new ToolBoxCommander();
89  }
90  runPlugins(): void {
91    const configuration: ToolConfigType = getToolConfiguration();
92    configuration.plugins.forEach((plugin: PluginType) => {
93      this.commandBuilder.addPluginCommand(plugin);
94    });
95    this.commandBuilder.buildCommands();
96  }
97}
98
99function main(): void {
100  Object.assign(process.env, envConfig);
101  const entry = new ToolboxEntry();
102  entry.runPlugins();
103}
104
105main();
106