@tmsfe/tmskit 0.0.7 → 0.0.9-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +27 -27
  2. package/dist/index.cjs.js +1284 -983
  3. package/main.js +3 -3
  4. package/package.json +73 -75
  5. package/src/{gulp → compile}/build.js +5 -5
  6. package/src/{gulp → compile}/compile.js +90 -81
  7. package/src/{gulp → compile}/dev.js +129 -102
  8. package/src/{gulp → compile}/plugins/less.js +116 -116
  9. package/src/{gulp → compile}/plugins/mpCommonDep.js +131 -131
  10. package/src/{gulp → compile}/plugins/mpJsonDep.js +112 -108
  11. package/src/{gulp → compile}/plugins/mpWxmlDep.js +194 -194
  12. package/src/{gulp → compile}/plugins/postcss-font-base64.js +72 -72
  13. package/src/{gulp → compile}/plugins/replaceEnv.js +29 -29
  14. package/src/{gulp → compile}/plugins/utils/pluginError.js +25 -25
  15. package/src/config/constant.js +69 -71
  16. package/src/config/defaultTmsConfig.js +16 -16
  17. package/src/{utils → core}/buildAppJson.js +166 -221
  18. package/src/{utils → core}/checkDependencies.js +77 -77
  19. package/src/core/cloneModules.js +203 -0
  20. package/src/{utils → core}/handleError.js +18 -16
  21. package/src/core/isInIt.js +69 -0
  22. package/src/{utils/mpCiUtils.js → core/mpCi.js} +73 -73
  23. package/src/core/npm.js +218 -0
  24. package/src/core/symbolicLink.js +24 -0
  25. package/src/{utils/tkitUtils.js → core/tmsMpconfig.js} +234 -158
  26. package/src/entry.js +62 -60
  27. package/src/index.js +63 -62
  28. package/src/init.js +33 -33
  29. package/src/scripts/create/ask.js +63 -63
  30. package/src/scripts/create/generator.js +25 -25
  31. package/src/scripts/create/ignoreFiles.js +7 -7
  32. package/src/scripts/create/index.js +72 -72
  33. package/src/scripts/create/render.js +19 -19
  34. package/src/scripts/run/build/index.js +16 -17
  35. package/src/scripts/run/dev/index.js +42 -84
  36. package/src/scripts/run/index.js +97 -68
  37. package/src/scripts/run/init/index.js +95 -87
  38. package/src/scripts/run/install/index.js +31 -29
  39. package/src/utils/findCssImport.js +30 -30
  40. package/src/utils/global.js +22 -36
  41. package/src/utils/io.js +107 -106
  42. package/src/utils/log.js +47 -44
  43. package/src/utils/widgets.js +178 -167
  44. package/src/utils/cliUtils.js +0 -35
  45. package/src/utils/cloneModules.js +0 -116
  46. package/src/utils/npmUtils.js +0 -166
@@ -1,158 +1,234 @@
1
- const loadash = require('lodash');
2
- const fs = require('fs');
3
- const { TMS_NAME, TMS_CONFIG_FILENAME, MODULE_CONFIG_FILENAME, TMS_PRIVATE_FILENAME } = require('../config/constant');
4
- const { resolve, isObject } = require('./widgets');
5
- const { setModuleConfig, getValidModules } = require('./buildAppJson');
6
- const defaultTmsConfig = require('../config/defaultTmsConfig');
7
- const { fail } = require('./log');
8
- const path = require('path');
9
-
10
- /**
11
- * 读取tms.config.js
12
- * @param env {string} 环境变量
13
- */
14
- const readTmsConfig = function (env) {
15
- const tmsConfigPath = resolve(TMS_CONFIG_FILENAME);
16
- if (!fs.existsSync(tmsConfigPath)) {
17
- fail('当前执行目录没有tms.config.js的配置项,请进行配置');
18
- process.exit(1);
19
- }
20
- const tmsConfigFn = require(tmsConfigPath);
21
- const tmsConfig = tmsConfigFn({
22
- env,
23
- });
24
- // 合并默认值
25
- loadash.mergeWith(tmsConfig, defaultTmsConfig);
26
- // modules兼容处理
27
- tmsConfig.modules = convertModules(tmsConfig.modules);
28
- return tmsConfig;
29
- };
30
-
31
- // convertModules 处理默认值
32
- const convertModules = (modules) => {
33
- const newModules = [];
34
- modules.forEach((module, index) => {
35
- const newModule = {};
36
- if (typeof module === 'string') {
37
- // 路径字符串
38
- Object.assign(newModule, {
39
- name: path.basename(module),
40
- path: module,
41
- });
42
- } else if (typeof module === 'object') {
43
- Object.assign(newModule, module);
44
- if (module.name === undefined) {
45
- newModule.name = path.basename(module.path);
46
- }
47
- }
48
- newModules.push(newModule);
49
- });
50
- return newModules;
51
- };
52
-
53
- /**
54
- * 读取tms.private.js
55
- */
56
- const readTmsPrivateCf = function () {
57
- let tmsPrivateCg;
58
- const tmsPrivatePath = resolve(TMS_PRIVATE_FILENAME);
59
- if (fs.existsSync(tmsPrivatePath)) {
60
- tmsPrivateCg = require(tmsPrivatePath);
61
- }
62
- return tmsPrivateCg;
63
- };
64
-
65
- /**
66
- * 从tms.config.json中检索用户传入的有效modules
67
- * @param { object } tmsConfig
68
- * @param { array } modules
69
- * @returns
70
- */
71
- const checkModules = function (tmsConfig, modules) {
72
- const targetModules = [];
73
- modules.forEach((moduleName) => {
74
- const module = tmsConfig.modules.find(module => module.name === moduleName);
75
- module && targetModules.push(module);
76
- });
77
- if (targetModules.length === 0) {
78
- fail(`你启动的模块无效,尝试 ${TMS_NAME} -m moduleName`);
79
- process.exit(1);
80
- }
81
- return targetModules;
82
- };
83
-
84
- /**
85
- * tms.config.js的modules 合并 module.config.json的配置项
86
- * @param {array} modules
87
- * @param {string} appName
88
- * @param {string} moduleDir
89
- * @returns
90
- */
91
- const tmsModulesMergeLocalModuleCfg = (modules, appName) => {
92
- const newModules = [];
93
- modules.forEach(({ path: relativePath, name: moduleName }, moduleIndex) => {
94
- const moduleConfigPath = resolve(relativePath, MODULE_CONFIG_FILENAME);
95
- if (fs.existsSync(moduleConfigPath)) {
96
- try {
97
- let moduleConfigContent = fs.readFileSync(moduleConfigPath, 'utf-8');
98
- moduleConfigContent = setModuleConfig(moduleConfigContent, appName);
99
- const moduleContentArr = isObject(moduleConfigContent) ? [moduleConfigContent] : moduleConfigContent;
100
- getValidModules(moduleContentArr).forEach(({ name }, moduleContentArrIndex) => {
101
- if (name === moduleName) {
102
- newModules.push({
103
- ...modules[moduleIndex],
104
- ...moduleContentArr[moduleContentArrIndex],
105
- });
106
- }
107
- });
108
- } catch (e) {
109
- fail(`${moduleConfigPath}配置错误: ${e}`);
110
- newModules.push({
111
- ...modules[moduleIndex],
112
- });
113
- }
114
- } else {
115
- newModules.push({
116
- ...modules[moduleIndex],
117
- });
118
- }
119
- });
120
- return newModules;
121
- };
122
-
123
- /**
124
- * 分包依赖了分包的模块 合并所依赖的modules
125
- * @param { object } tmsConfig
126
- * @param {array} modules
127
- * @param {string} moduleDir
128
- * @returns
129
- */
130
- const subModulesMergeDepModules = (tmsConfig, modules) => {
131
- const moduleNames = [];
132
- modules.forEach(({ name: moduleName }) => {
133
- moduleNames.push(moduleName);
134
- });
135
- let mergeModules = modules;
136
- let isOver = true;
137
- modules.forEach(({ dependencies: dependencyModules }) => {
138
- dependencyModules?.forEach((item) => {
139
- // 如果所有模块的dep都在moduleNames内,则所有依赖都齐了
140
- // 否则递归处理,根据name找到相关配置加到modules里
141
- if (moduleNames.indexOf(item) === -1) {
142
- isOver = false;
143
- const tmpModules = checkModules(tmsConfig, [...new Set([item])]);
144
- mergeModules = [...mergeModules, ...tmpModules];
145
- mergeModules = tmsModulesMergeLocalModuleCfg(mergeModules, tmsConfig.appName);
146
- }
147
- });
148
- });
149
- return isOver ? mergeModules : subModulesMergeDepModules(tmsConfig, mergeModules);
150
- };
151
-
152
- module.exports = {
153
- readTmsConfig,
154
- readTmsPrivateCf,
155
- checkModules,
156
- tmsModulesMergeLocalModuleCfg,
157
- subModulesMergeDepModules,
158
- };
1
+ /**
2
+ * 用来读取处理tms.config.js与module.config.json字段
3
+ */
4
+ const loadash = require('lodash');
5
+ const fs = require('fs');
6
+ const { TMS_NAME, TMS_CONFIG_FILENAME, MODULE_CONFIG_FILENAME, TMS_PRIVATE_FILENAME } = require('../config/constant');
7
+ const { resolve, isObject, isArray } = require('../utils/widgets');
8
+ const defaultTmsConfig = require('../config/defaultTmsConfig');
9
+ const { fail } = require('../utils/log');
10
+ const path = require('path');
11
+
12
+ /**
13
+ * 读取tms.config.js
14
+ * @param env {string} 环境变量
15
+ */
16
+ const readTmsConfig = function (env) {
17
+ const tmsConfigPath = resolve(TMS_CONFIG_FILENAME);
18
+ if (!fs.existsSync(tmsConfigPath)) {
19
+ fail('当前执行目录没有tms.config.js的配置项,请进行配置');
20
+ process.exit(1);
21
+ }
22
+ const tmsConfigFn = require(tmsConfigPath);
23
+ const tmsConfig = tmsConfigFn({
24
+ env,
25
+ });
26
+ // 合并默认值
27
+ loadash.mergeWith(tmsConfig, defaultTmsConfig);
28
+
29
+ // modules兼容处理
30
+ tmsConfig.modules = convertModules(tmsConfig.modules);
31
+ return tmsConfig;
32
+ };
33
+
34
+ // convertModules 处理默认值
35
+ const convertModules = (modules) => {
36
+ const newModules = [];
37
+ modules.forEach((module) => {
38
+ const newModule = {};
39
+ if (typeof module === 'string') {
40
+ // 路径字符串
41
+ Object.assign(newModule, {
42
+ name: path.basename(module),
43
+ path: module,
44
+ });
45
+ } else if (typeof module === 'object') {
46
+ Object.assign(newModule, module);
47
+ if (module.name === undefined) {
48
+ newModule.name = path.basename(module.path);
49
+ }
50
+ }
51
+ newModules.push(newModule);
52
+ });
53
+ return newModules;
54
+ };
55
+
56
+ /**
57
+ * 读取tms.private.config.js
58
+ */
59
+ const readTmsPrivateCf = function () {
60
+ let tmsPrivateCf = {};
61
+ const tmsPrivatePath = resolve(TMS_PRIVATE_FILENAME);
62
+ if (fs.existsSync(tmsPrivatePath)) {
63
+ tmsPrivateCf = require(tmsPrivatePath);
64
+ }
65
+ // 处理modules字段
66
+ if (tmsPrivateCf.modules instanceof Array) {
67
+ Object.assign(tmsPrivateCf.modules, {
68
+ include: tmsPrivateCf.modules,
69
+ });
70
+ }
71
+ return tmsPrivateCf;
72
+ };
73
+
74
+ /**
75
+ * 从tms.config.json中检索用户传入的有效modules
76
+ * @param { object } tmsConfig
77
+ * @param { array } modules
78
+ * @returns
79
+ */
80
+ const checkModules = function (tmsConfig, modules) {
81
+ const targetModules = [];
82
+ modules.forEach((moduleName) => {
83
+ const module = tmsConfig.modules.find(module => module.name === moduleName);
84
+ module && targetModules.push(module);
85
+ });
86
+ if (targetModules.length === 0) {
87
+ fail(`你启动的模块无效,尝试 ${TMS_NAME} -m moduleName`);
88
+ process.exit(1);
89
+ }
90
+ return targetModules;
91
+ };
92
+
93
+ /**
94
+ * 过滤页面为空的分包
95
+ * @param {Array} moduleCfg 模块配置内容
96
+ * @returns pages不为空的分包
97
+ */
98
+ const getValidModules = (moduleCfg) => {
99
+ // 过滤 pages 为空的情况
100
+ const validModules = moduleCfg.filter(item => item.pages.length > 0);
101
+ return validModules;
102
+ };
103
+
104
+ /**
105
+ * 适配处理module.config.json的字段
106
+ * @param { object } fileContent module.config.json的内容
107
+ * @param { string } appName 小程序的名称
108
+ */
109
+ function adaptMpCgContent(fileContent, appName) {
110
+ const content = fileContent.contents ? JSON.parse(fileContent.contents.toString()) : JSON.parse(fileContent);
111
+
112
+ if (isArray(content)) {
113
+ let i = content.length - 1;
114
+ while (i >= 0) {
115
+ let current = content[i];
116
+
117
+ if (appName && current.mpConfig && current.mpConfig[appName]) {
118
+ current = { ...current, ...current.mpConfig[appName] };
119
+ }
120
+
121
+ delete current.mpConfig;
122
+ delete current.isSubpackages;
123
+
124
+ content[i] = current;
125
+ i--; // eslint-disable-line
126
+ }
127
+ }
128
+ return content;
129
+ }
130
+
131
+ /**
132
+ * 递归获取本地所有模块的配置信息
133
+ * @param {array} modules 用户要编译的模块列表
134
+ * @param { string } appName 小程序的名称
135
+ * @param { string } moduleConfigFilename moduleConfig的文件名
136
+ */
137
+ function getModuleConfig(modules = [], appName, moduleConfigFilename) {
138
+ const modulesConfig = {};
139
+
140
+ modules.forEach(({ path }) => {
141
+ const moduleConfigPath = resolve(path, moduleConfigFilename);
142
+ if (fs.existsSync(moduleConfigPath)) {
143
+ const content = fs.readFileSync(moduleConfigPath, 'utf-8');
144
+ modulesConfig[moduleConfigPath] = adaptMpCgContent(content, appName);
145
+ }
146
+ });
147
+
148
+ return modulesConfig;
149
+ }
150
+
151
+ /**
152
+ * tms.config.js的modules 合并 module.config.json的配置项
153
+ * @param {array} modules
154
+ * @param {string} appName
155
+ * @param {string} moduleDir
156
+ * @returns
157
+ */
158
+ const tmsModulesMergeLocalModuleCfg = (modules, appName) => {
159
+ const newModules = [];
160
+ modules.forEach(({ path: relativePath, name: moduleName }, moduleIndex) => {
161
+ const moduleConfigPath = resolve(relativePath, MODULE_CONFIG_FILENAME);
162
+ if (fs.existsSync(moduleConfigPath)) {
163
+ try {
164
+ let findModule = false;
165
+ let moduleConfigContent = fs.readFileSync(moduleConfigPath, 'utf-8');
166
+ moduleConfigContent = adaptMpCgContent(moduleConfigContent, appName);
167
+ const moduleContentArr = isObject(moduleConfigContent) ? [moduleConfigContent] : moduleConfigContent;
168
+ getValidModules(moduleContentArr).forEach(({ name }, moduleContentArrIndex) => {
169
+ if (name === moduleName) {
170
+ findModule = true;
171
+ newModules.push({
172
+ ...modules[moduleIndex],
173
+ ...moduleContentArr[moduleContentArrIndex],
174
+ });
175
+ }
176
+ });
177
+ if (!findModule) {
178
+ fail(`启动模块${moduleName}在${moduleConfigPath}没有找到,请检查配置`);
179
+ process.exit(1);
180
+ }
181
+ } catch (e) {
182
+ fail(`${moduleConfigPath}配置错误: ${e}`);
183
+ newModules.push({
184
+ ...modules[moduleIndex],
185
+ });
186
+ }
187
+ } else {
188
+ newModules.push({
189
+ ...modules[moduleIndex],
190
+ });
191
+ }
192
+ });
193
+ return newModules;
194
+ };
195
+
196
+ /**
197
+ * 分包依赖了分包的模块 合并所依赖的modules
198
+ * @param { object } tmsConfig
199
+ * @param {array} modules
200
+ * @param {string} moduleDir
201
+ * @returns
202
+ */
203
+ const subModulesMergeDepModules = (tmsConfig, modules) => {
204
+ const moduleNames = [];
205
+ modules.forEach(({ name: moduleName }) => {
206
+ moduleNames.push(moduleName);
207
+ });
208
+ let mergeModules = modules;
209
+ let isOver = true;
210
+
211
+ modules.forEach(({ dependencies: dependencyModules }) => {
212
+ dependencyModules?.forEach((item) => {
213
+ // 如果所有模块的dep都在moduleNames内,则所有依赖都齐了
214
+ // 否则递归处理,根据name找到相关配置加到modules里
215
+ if (moduleNames.indexOf(item) === -1) {
216
+ isOver = false;
217
+ const tmpModules = checkModules(tmsConfig, [...new Set([item])]);
218
+ mergeModules = [...mergeModules, ...tmpModules];
219
+ mergeModules = tmsModulesMergeLocalModuleCfg(mergeModules, tmsConfig.appName);
220
+ }
221
+ });
222
+ });
223
+ return isOver ? mergeModules : subModulesMergeDepModules(tmsConfig, mergeModules);
224
+ };
225
+
226
+ module.exports = {
227
+ readTmsConfig,
228
+ readTmsPrivateCf,
229
+ getModuleConfig,
230
+ getValidModules,
231
+ checkModules,
232
+ tmsModulesMergeLocalModuleCfg,
233
+ subModulesMergeDepModules,
234
+ };
package/src/entry.js CHANGED
@@ -1,60 +1,62 @@
1
- module.exports = [
2
- {
3
- command: 'create <app-name>',
4
- description: '创建新的应用',
5
- action: (appName, cmd) => {
6
- require('./scripts/create')(appName, cmd);
7
- },
8
- },
9
- {
10
- name: 'run',
11
- type: 'child',
12
- description: '项目开发使用的命令',
13
- commands: [
14
- {
15
- command: 'install',
16
- description: '安装依赖',
17
- options: [
18
- ['-m, --module [moduleName]', '模块名称'],
19
- ['-e, --env [env]', '环境变量'],
20
- ],
21
- action: (cmd) => {
22
- require('./scripts/run/index')('install', cmd);
23
- },
24
- },
25
- {
26
- command: 'dev',
27
- description: 'dev 打包编译',
28
- options: [
29
- ['-m, --module [moduleName]', '模块名称'],
30
- ['-e, --env [env]', '环境变量'],
31
- ],
32
- action: (cmd) => {
33
- require('./scripts/run/index')('dev', cmd);
34
- },
35
- },
36
- {
37
- command: 'build',
38
- description: 'prod 打包编译',
39
- options: [
40
- ['-m, --module [moduleName]', '模块名称'],
41
- ['-e, --env [env]', '环境变量'],
42
- ],
43
- action: (cmd) => {
44
- require('./scripts/run/index')('build', cmd);
45
- },
46
- },
47
- {
48
- command: 'init',
49
- description: '根据模块配置初始化项目(eg: 动态拷贝模块、下载依赖、生成app.json等)',
50
- options: [
51
- ['-m, --module [moduleName]', '模块名称'],
52
- ['-e, --env [env]', '环境变量'],
53
- ],
54
- action: (cmd) => {
55
- require('./scripts/run/index')('init', cmd);
56
- },
57
- },
58
- ],
59
- },
60
- ];
1
+ module.exports = [
2
+ {
3
+ command: 'create <app-name>',
4
+ description: '创建新的应用',
5
+ action: (appName, cmd) => {
6
+ require('./scripts/create')(appName, cmd);
7
+ },
8
+ },
9
+ {
10
+ name: 'run',
11
+ type: 'child',
12
+ description: '项目开发使用的命令',
13
+ commands: [
14
+ {
15
+ command: 'install',
16
+ description: '安装依赖',
17
+ options: [
18
+ ['-m, --module [moduleName]', '模块名称'],
19
+ ['-e, --env [env]', '环境变量'],
20
+ ],
21
+ action: (cmd) => {
22
+ require('./scripts/run/index')('install', cmd);
23
+ },
24
+ },
25
+ {
26
+ command: 'dev',
27
+ description: 'dev 打包编译',
28
+ options: [
29
+ ['-m, --module [moduleName]', '模块名称'],
30
+ ['-e, --env [env]', '环境变量'],
31
+ ['-latest, --latest', '下载最新第三方模块代码、安装最新依赖'],
32
+ ],
33
+ action: (cmd) => {
34
+ require('./scripts/run/index')('dev', cmd);
35
+ },
36
+ },
37
+ {
38
+ command: 'build',
39
+ description: 'prod 打包编译',
40
+ options: [
41
+ ['-m, --module [moduleName]', '模块名称'],
42
+ ['-e, --env [env]', '环境变量'],
43
+ ],
44
+ action: (cmd) => {
45
+ require('./scripts/run/index')('build', cmd);
46
+ },
47
+ },
48
+ // 对外暂不暴露该命令
49
+ // {
50
+ // command: 'init',
51
+ // description: '模块配置初始化项目(eg: 下载第三方模块代码、安装依赖、生成app.json等)',
52
+ // options: [
53
+ // ['-m, --module [moduleName]', '模块名称'],
54
+ // ['-e, --env [env]', '环境变量'],
55
+ // ],
56
+ // action: (cmd) => {
57
+ // require('./scripts/run/index')('init', cmd);
58
+ // },
59
+ // },
60
+ ],
61
+ },
62
+ ];
package/src/index.js CHANGED
@@ -1,62 +1,63 @@
1
- const chalk = require('chalk');
2
- const commander = require('commander');
3
- const { log, suggestCommands } = require('./utils/widgets');
4
- const { TMS_NAME } = require('./config/constant.js');
5
- const commands = require('./entry');
6
- const init = require('./init');
7
-
8
- init();
9
-
10
- const program = new commander.Command(TMS_NAME);
11
-
12
- program
13
- .version(`${TMS_NAME} ${require('../package.json').version}`, '-v, -V, --version');
14
-
15
- function registerCommand(program, commands) {
16
- commands.forEach((cmd) => {
17
- if (cmd.type === 'child') {
18
- const childProgram = new commander.Command(cmd.name);
19
- cmd.usage && childProgram.usage(cmd.usage);
20
- cmd.description && childProgram.description(cmd.description);
21
- registerCommand(childProgram, cmd.commands);
22
-
23
- program.addCommand(childProgram);
24
- } else {
25
- const command = program.command(cmd.command);
26
-
27
- cmd.usage && command.usage(cmd.usage);
28
-
29
- cmd.description && command.description(cmd.description);
30
-
31
- cmd.options?.forEach(opt => command.option(...opt));
32
-
33
- command.action(cmd.action);
34
- }
35
- });
36
- }
37
-
38
- registerCommand(program, commands);
39
-
40
- program.on('--help', () => {
41
- log();
42
- log(` Run ${chalk.cyan(`${TMS_NAME} <command> --help`)} for detailed usage of given command.`);
43
- log();
44
- });
45
-
46
- // 捕获未注册的命令
47
- program
48
- .arguments('<command>')
49
- .action((cmd) => {
50
- program.outputHelp();
51
- log(` ${chalk.red(`Unknown command ${chalk.yellow(cmd)}.`)}`);
52
- log();
53
- suggestCommands(cmd);
54
- process.exitCode = 1;
55
- });
56
-
57
- if (!process.argv.slice(2).length) {
58
- program.outputHelp();
59
- process.exit(-1);
60
- }
61
-
62
- program.parse(process.argv);
1
+ const chalk = require('chalk');
2
+ const commander = require('commander');
3
+ const { suggestCommands } = require('./utils/widgets');
4
+ const { info } = require('./utils/log');
5
+ const { TMS_NAME } = require('./config/constant.js');
6
+ const commands = require('./entry');
7
+ const init = require('./init');
8
+
9
+ init();
10
+
11
+ const program = new commander.Command(TMS_NAME);
12
+
13
+ program
14
+ .version(`${TMS_NAME} ${require('../package.json').version}`, '-v, -V, --version');
15
+
16
+ function registerCommand(program, commands) {
17
+ commands.forEach((cmd) => {
18
+ if (cmd.type === 'child') {
19
+ const childProgram = new commander.Command(cmd.name);
20
+ cmd.usage && childProgram.usage(cmd.usage);
21
+ cmd.description && childProgram.description(cmd.description);
22
+ registerCommand(childProgram, cmd.commands);
23
+
24
+ program.addCommand(childProgram);
25
+ } else {
26
+ const command = program.command(cmd.command);
27
+
28
+ cmd.usage && command.usage(cmd.usage);
29
+
30
+ cmd.description && command.description(cmd.description);
31
+
32
+ cmd.options?.forEach(opt => command.option(...opt));
33
+
34
+ command.action(cmd.action);
35
+ }
36
+ });
37
+ }
38
+
39
+ registerCommand(program, commands);
40
+
41
+ program.on('--help', () => {
42
+ info();
43
+ info(` Run ${chalk.cyan(`${TMS_NAME} <command> --help`)} for detailed usage of given command.`);
44
+ info();
45
+ });
46
+
47
+ // 捕获未注册的命令
48
+ program
49
+ .arguments('<command>')
50
+ .action((cmd) => {
51
+ program.outputHelp();
52
+ info(` ${chalk.red(`Unknown command ${chalk.yellow(cmd)}.`)}`);
53
+ info();
54
+ suggestCommands(cmd);
55
+ process.exitCode = 1;
56
+ });
57
+
58
+ if (!process.argv.slice(2).length) {
59
+ program.outputHelp();
60
+ process.exit(-1);
61
+ }
62
+
63
+ program.parse(process.argv);