@tmsfe/tmskit 0.0.21 → 0.0.24-beta.0

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.
@@ -21,7 +21,8 @@ function replaceGitUrlAccount(httpRepoUrl, moduleName) {
21
21
  const tmsConfig = global.getData('tmsConfig');
22
22
 
23
23
  let gitUrl = httpRepoUrl;
24
- const { username = '', pass = '' } = tmsConfig?.gitAccount?.[moduleName] || {};
24
+
25
+ const { username = '', pass = '' } = tmsConfig?.gitAccount?.[moduleName] || tmsConfig?.gitAccount?.[httpRepoUrl] || {};
25
26
 
26
27
  const urlPrefixReg = /http(s)?:\/\//;
27
28
  if (username && pass && urlPrefixReg.test(gitUrl)) {
@@ -39,6 +40,9 @@ function replaceGitUrlAccount(httpRepoUrl, moduleName) {
39
40
  * @returns { undefined } no return
40
41
  */
41
42
  function moveFile(sourceDir, targetDir, ignore = []) {
43
+ if (fs.existsSync(targetDir)) {
44
+ shelljs.rm('-rf', targetDir);
45
+ }
42
46
  // 删除不是文件夹的文件
43
47
  return new Promise((resolve, reject) => {
44
48
  MetalSmith(__dirname)
@@ -147,7 +151,6 @@ function collectDownLoadTasksMap(sourceDir, targetDir, modules) {
147
151
  ]);
148
152
  },
149
153
  };
150
-
151
154
  if (downloadTasksMap.has(sourcePath)) {
152
155
  const task = downloadTasksMap.get(sourcePath);
153
156
  task.callbacks.push(callback);
@@ -156,7 +159,7 @@ function collectDownLoadTasksMap(sourceDir, targetDir, modules) {
156
159
  let promiseTask;
157
160
  if (fs.existsSync(sourcePath) && fs.existsSync(`${sourcePath}/.git`)) {
158
161
  promiseTask = (gitUrl, sourcePath, branch, httpRepoUrl) => {
159
- info(`git pull:${httpRepoUrl}`);
162
+ info(`git pull:${httpRepoUrl} --branch: ${branch}`);
160
163
  return pullRepoForGit(sourcePath, branch);
161
164
  };
162
165
  } else {
package/src/core/mpCi.js CHANGED
@@ -6,8 +6,8 @@ const path = require('path');
6
6
  * @returns {Object} 小程序ci对象
7
7
  */
8
8
  const getMpCi = ({ appId, projectPath, type = 'miniProgram', privateKey = 'TODO' }) => {
9
- const cfgJsonContent = require(path.join(projectPath, 'project.config.json'));
10
- const ignores = cfgJsonContent?.packOptions?.ignore.map(({ value }) => value) || [];
9
+ const projectCg = require(path.join(projectPath, 'project.config.json'));
10
+ const ignores = projectCg?.packOptions?.ignore?.map(({ value }) => value) || [];
11
11
 
12
12
  return new ci.Project({
13
13
  appid: appId,
@@ -18,14 +18,6 @@ const getMpCi = ({ appId, projectPath, type = 'miniProgram', privateKey = 'TODO'
18
18
  });
19
19
  };
20
20
 
21
-
22
- // 用小程序ci工具构建小程序
23
- const packMpProject = async (project) => {
24
- await ci.packNpm(project, {
25
- ignores: ['cloud/**/*'],
26
- });
27
- };
28
-
29
21
  /**
30
22
  * 格式化构建npm结果信息
31
23
  * @param {Array<String>} warning 构建时的告警信息
@@ -43,21 +35,27 @@ const formatPackNpmWarning = (warning) => {
43
35
  };
44
36
 
45
37
  /**
46
- * 构建miniprogram_npm
47
- * @returns {Object} 小程序ci对象
38
+ * 构建miniprogram_npm https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html#%E6%9E%84%E5%BB%BAnpm
39
+ * * @param {object} {
40
+ * appId,
41
+ * peojectPath,
42
+ * privateKey,
43
+ * }
48
44
  */
49
45
  const buildMpNpm = async ({
50
46
  appId,
51
47
  projectPath,
52
48
  privateKey,
53
49
  }) => {
54
- const mpCi = await getMpCi({
50
+ const mpCi = getMpCi({
55
51
  appId,
56
52
  projectPath,
57
53
  privateKey,
58
54
  });
59
55
 
60
- const packNpmWarning = await packMpProject(mpCi);
56
+ const packNpmWarning = await ci.packNpm(mpCi, {
57
+ ignores: ['cloud/**/*'],
58
+ });
61
59
 
62
60
  const packNpmMsg = formatPackNpmWarning(packNpmWarning);
63
61
  if (packNpmMsg) {
@@ -67,7 +65,57 @@ const buildMpNpm = async ({
67
65
  return Promise.resolve();
68
66
  };
69
67
 
68
+ /**
69
+ * 预览小程序码 https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html#%E9%A2%84%E8%A7%88
70
+ * @param {object} {
71
+ * appId,
72
+ * peojectPath,
73
+ * privateKey,
74
+ * desc
75
+ * robot
76
+ * }
77
+ */
78
+ const previewMp = async (params = {}) => {
79
+ const { appId, projectPath, privateKey, ...resetParams } = params;
80
+ const mpCi = await getMpCi({
81
+ appId,
82
+ projectPath,
83
+ privateKey,
84
+ });
85
+
86
+ return await ci.preview({
87
+ project: mpCi,
88
+ ...resetParams,
89
+ onProgressUpdate: () => {},
90
+ });
91
+ };
92
+
93
+ /**
94
+ * 上传小程序 https://developers.weixin.qq.com/miniprogram/dev/devtools/ci.html#%E4%B8%8A%E4%BC%A0
95
+ * @param {object} {
96
+ * appId,
97
+ * peojectPath,
98
+ * privateKey,
99
+ * version,
100
+ * desc
101
+ * }
102
+ */
103
+ const uploadMp = async (params = {}) => {
104
+ const { appId, projectPath, privateKey, ...resetParams } = params;
105
+ const mpCi = await getMpCi({
106
+ appId,
107
+ projectPath,
108
+ privateKey,
109
+ });
110
+ return await ci.upload({
111
+ project: mpCi,
112
+ ...resetParams,
113
+ onProgressUpdate: () => {},
114
+ });
115
+ };
70
116
 
71
117
  module.exports = {
72
118
  buildMpNpm,
119
+ previewMp,
120
+ uploadMp,
73
121
  };
package/src/core/npm.js CHANGED
@@ -6,10 +6,10 @@ const fsExtra = require('fs-extra');
6
6
  const crypto = require('crypto');
7
7
  const path = require('path');
8
8
  const shell = require('shelljs');
9
- const glob = require('glob-ignore');
10
9
  const log = require('../utils/log');
11
10
  const { npmInstall } = require('../utils/widgets');
12
11
  const { handleError } = require('./handleError');
12
+ const { global } = require('../utils/global');
13
13
 
14
14
  const shellJsOption = { async: false, silent: true };
15
15
  const dirPath = process.cwd(); // 项目根目录
@@ -76,7 +76,8 @@ const collectNpmTasksMap = (packageJsonFiles, cacheDir) => {
76
76
  fsExtra.emptydirSync(cacheNMPath);
77
77
  shell.cp('-f', packageJsonPath, cacheNMPath);
78
78
  log.info(`npm install: ${packageJsonPath}`);
79
- return npmInstall(cacheNMPath).then(() => {
79
+ const tmsConfig = global.getData('tmsConfig');
80
+ return npmInstall(cacheNMPath, tmsConfig.npm).then(() => {
80
81
  const newShellJsOption = {
81
82
  ...shellJsOption,
82
83
  cwd: cacheNMPath,
@@ -198,25 +199,8 @@ const findAllPackageJson = (subRoots = [], contextDir) => {
198
199
  return result;
199
200
  };
200
201
 
201
- function cloudNpmInstall(contextDir) {
202
- return new Promise((resolve, reject) => {
203
- glob(`${contextDir}/**/package.json`, ['node_modules', 'miniprogram_npm'], (err, files) => {
204
- if (err) {
205
- reject(err);
206
- }
207
- files.forEach((file) => {
208
- const dir = path.dirname(file);
209
- shell.cd(dir);
210
- shell.exec('npx npm install --production --registry http://mirrors.tencent.com/npm/', { silent: false });
211
- });
212
- resolve();
213
- });
214
- });
215
- }
216
-
217
202
 
218
203
  module.exports = {
219
- cloudNpmInstall,
220
204
  npmInstallAll,
221
205
  findAllPackageJson,
222
206
  findFilesByFilter,
@@ -0,0 +1,118 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const shelljs = require('shelljs');
4
+ const chalk = require('chalk');
5
+ const request = require('request');
6
+ const inquirer = require('inquirer');
7
+ const { infoNoTime } = require('../utils/log');
8
+ const packageJson = require('../../package.json');
9
+ const { VERSION_CACHE_FILE, VERSION_URL } = require('../config/constant');
10
+ const { ensureDirExist } = require('../utils/io');
11
+ const { versionCompare } = require('../utils/widgets');
12
+
13
+ // 获取推荐的tmskit版本
14
+ function getRecommendVersion() {
15
+ return new Promise((resolve, reject) => {
16
+ request(`${VERSION_URL}?v=${new Date().getTime()}`, (error, response, body) => {
17
+ if (!error && response && response.statusCode === 200) {
18
+ resolve(JSON.parse(body));
19
+ } else {
20
+ reject(response.statusCode);
21
+ }
22
+ });
23
+ });
24
+ }
25
+
26
+ // 获取当前用户tmskit的版本
27
+ function getUserTmskitVersion() {
28
+ const data = shelljs.exec('tmskit -v', { async: false, silent: true });
29
+ if (data.code === 0) {
30
+ // tmskit 0.0.21 => 0.0.21
31
+ return data.slice(7);
32
+ }
33
+ return '0.0.0';
34
+ }
35
+
36
+ // 询问用户是否安装最新版本
37
+ function isInstallLatestVersion() {
38
+ return inquirer.prompt([
39
+ {
40
+ type: 'confirm',
41
+ name: 'isInstall',
42
+ message: '是否安装最新版本',
43
+ choices: [{
44
+ name: '否',
45
+ value: false,
46
+ }, {
47
+ name: '是',
48
+ value: true,
49
+ }],
50
+ },
51
+ ]);
52
+ }
53
+
54
+ // 获取tmskit的版本是否推荐过
55
+ function getVersionIsRecommend(version) {
56
+ const filePath = VERSION_CACHE_FILE;
57
+ if (!fs.existsSync(filePath)) {
58
+ return false;
59
+ }
60
+ const content = require(filePath);
61
+ return content?.[version];
62
+ }
63
+
64
+ // 设置tmskit版本推荐过
65
+ function setVersionRecommend(version, isRecommend) {
66
+ const filePath = VERSION_CACHE_FILE;
67
+ if (!fs.existsSync(filePath)) {
68
+ const dir = path.dirname(filePath);
69
+ ensureDirExist(dir);
70
+ fs.writeFileSync(filePath, '{}');
71
+ }
72
+ const content = require(filePath);
73
+ content[version] = isRecommend;
74
+ fs.writeFileSync(filePath, JSON.stringify(content, null, 2));
75
+ }
76
+
77
+ // 推荐理由
78
+ function displayRecommends(arr = []) {
79
+ infoNoTime(chalk.green('构建工具有新的版本~~:'));
80
+ arr.forEach((item) => {
81
+ infoNoTime(chalk.green(item));
82
+ });
83
+ }
84
+
85
+ // 推荐tmskit的安装版本
86
+ async function recommendVersion() {
87
+ try {
88
+ // 获取当前用户安装的版本
89
+ const tmskitVersion = getUserTmskitVersion();
90
+ // 获取官方推荐版本
91
+ const recommendRes = await getRecommendVersion();
92
+ const recommendVersion = recommendRes.version;
93
+ // 当前用户安装版本小于官方推荐版本 && 该版本没有推荐过
94
+ if (versionCompare(tmskitVersion, recommendVersion) === -1 && !getVersionIsRecommend(recommendVersion)) {
95
+ displayRecommends(recommendRes.version_detail);
96
+ // 设置该版本推荐过
97
+ setVersionRecommend(recommendVersion, true);
98
+ // 询问用户是否安装最新版本
99
+ const installRes = await isInstallLatestVersion(recommendRes);
100
+ if (installRes.isInstall) {
101
+ // mac
102
+ if (process.platform === 'darwin') {
103
+ infoNoTime(`将执行以下命令: ${chalk.green(`sudo npm install -g ${packageJson.name}@${recommendVersion}`)}`);
104
+ shelljs.exec(`sudo npm install -g ${packageJson.name}@${recommendVersion}`, { async: false, silent: false });
105
+ process.exit(-1);
106
+ } else {
107
+ // window
108
+ infoNoTime(`请使用超级管理员执行以下命令: ${chalk.green(`npm install -g ${packageJson.name}@${recommendVersion}`)}`);
109
+ process.exit(-1);
110
+ }
111
+ }
112
+ }
113
+ } catch {}
114
+ }
115
+
116
+ module.exports = {
117
+ recommendVersion,
118
+ };
@@ -0,0 +1,25 @@
1
+ const request = require('request');
2
+ const { getGitUser } = require('../utils/widgets');
3
+ const apiUrl = 'https://tim.map.qq.com/basic/tmskit/upload';
4
+
5
+ const report = (name, attrs = {}) => {
6
+ try {
7
+ const param = [];
8
+ param[27] = name;
9
+ param[28] = 'tmskit';
10
+ param[29] = getGitUser();
11
+ param[30] = JSON.stringify(attrs);
12
+
13
+ for (let i = 0; i < 40; i++) {
14
+ if (!param[i]) param[i] = null;
15
+ };
16
+
17
+ request.post({ url: apiUrl, json: { param } }, () => {});
18
+ // (error, response, body) => {
19
+ // console.log('body:', body);
20
+ // }
21
+ } catch (e) {
22
+ }
23
+ };
24
+
25
+ module.exports = report;
@@ -12,28 +12,29 @@ const { fail } = require('../utils/log');
12
12
 
13
13
  /**
14
14
  * 读取tms.config.js
15
- * @param env {string} 环境变量
15
+ * @param {string} configPath tms.config.js的路径
16
16
  */
17
- const readTmsConfig = function () {
18
- const tmsConfigPath = resolve(TMS_CONFIG_FILENAME);
17
+ const readTmsConfig = function (configPath) {
18
+ const tmsConfigPath = configPath ? `${configPath}/${TMS_CONFIG_FILENAME}` : resolve(TMS_CONFIG_FILENAME);
19
19
  if (!fs.existsSync(tmsConfigPath)) {
20
- fail('当前执行目录没有tms.config.js的配置项,请进行配置');
20
+ fail(`${path.dirname(tmsConfigPath)}没有找到tms.config.js,请进行配置`);
21
21
  process.exit(1);
22
22
  }
23
23
  const tmsConfigFn = require(tmsConfigPath);
24
24
  const tmsConfig = typeof tmsConfigFn === 'function' ? tmsConfigFn() : tmsConfigFn;
25
25
 
26
26
  // 合并默认值
27
- return loadash.mergeWith(defaultTmsConfig, tmsConfig);
27
+ return loadash.mergeWith({}, defaultTmsConfig, tmsConfig);
28
28
  };
29
29
 
30
30
 
31
31
  /**
32
32
  * 读取tms.private.config.js
33
+ * @param {string} configPath tms.private.config.js的路径
33
34
  */
34
- const readTmsPrivateCf = function () {
35
+ const readTmsPrivateCf = function (configPath) {
35
36
  let tmsPrivateCf = {};
36
- const tmsPrivatePath = resolve(TMS_PRIVATE_FILENAME);
37
+ const tmsPrivatePath = configPath ? `${configPath}/${TMS_PRIVATE_FILENAME}` : resolve(TMS_PRIVATE_FILENAME);
37
38
  if (fs.existsSync(tmsPrivatePath)) {
38
39
  const tmsPrivateFn = require(tmsPrivatePath);
39
40
  tmsPrivateCf = typeof tmsPrivateFn === 'function' ? tmsPrivateFn() : tmsPrivateFn;
@@ -44,11 +45,12 @@ const readTmsPrivateCf = function () {
44
45
 
45
46
  /**
46
47
  * 获取tms.config.js, tms.private.config.js的配置项
48
+ * @param {string} configPath config.js的路径
47
49
  * @returns
48
50
  */
49
- const getTmsConfig = () => {
50
- const tmsPrivateCf = readTmsPrivateCf();
51
- const tmsConfig = readTmsConfig();
51
+ const getTmsConfig = (configPath) => {
52
+ const tmsPrivateCf = readTmsPrivateCf(configPath);
53
+ const tmsConfig = readTmsConfig(configPath);
52
54
 
53
55
  const modules = {};
54
56
  if (Array.isArray(tmsConfig.modules)) {
@@ -116,20 +118,8 @@ function adaptMpCgContent(fileContent, appName) {
116
118
  return content;
117
119
  }
118
120
 
119
- const adaptDependencies = function (dependencies, subPackages) {
120
- const newDependencies = dependencies || [];
121
- subPackages.forEach((item) => {
122
- if (item.dependencies) {
123
- dependencies = newDependencies.concat(item.dependencies);
124
- }
125
- });
126
- return newDependencies;
127
- };
128
-
129
121
  const adaptSubPackages = function (moduleConfig, appName) {
130
- const subPackages = isObject(moduleConfig) && moduleConfig.subPackages
131
- ? moduleConfig.subPackages
132
- : isObject(moduleConfig) ? [moduleConfig] : moduleConfig;
122
+ const { subPackages } = moduleConfig;
133
123
  return adaptMpCgContent(subPackages, appName);
134
124
  };
135
125
 
@@ -151,11 +141,9 @@ function getModulesConfig(modules = [], appName) {
151
141
 
152
142
  // 兼容历史逻辑,后续可删除--- start
153
143
  const subPackages = adaptSubPackages(moduleConfig, appName);
154
- const dependencies = adaptDependencies(moduleConfig.dependencies, subPackages);
155
144
  moduleConfig = {
156
145
  ...(isObject(moduleConfig) ? moduleConfig : {}),
157
146
  subPackages,
158
- dependencies,
159
147
  };
160
148
  // 兼容逻辑--- end
161
149
  modulesConfig.push(moduleConfig);
@@ -208,10 +196,6 @@ const getSubPackageSrcPath = function (tmsConfig, module, subPackage) {
208
196
  const checkModuleItem = (tmsConfig, tmsModuleItem, moduleConfig) => {
209
197
  const newModuleItem = { ...tmsModuleItem, ...moduleConfig };
210
198
 
211
- // 兼容逻辑
212
- if (!newModuleItem.moduleName) newModuleItem.moduleName = newModuleItem.name;
213
- delete newModuleItem.name;
214
-
215
199
  // 参数校验-模块源码路径
216
200
  if (!newModuleItem.path) {
217
201
  throw new Error(`${newModuleItem.moduleName}模块没有找到path字段,请检查tms.config.js的modules.all>module>path路径`);
@@ -248,6 +232,9 @@ const getModulesByMergeDepModules = (tmsConfig, modules, errorIsQuit = false) =>
248
232
  const allModules = new Map();
249
233
  function dfs(tmsConfig, modules) {
250
234
  modules.forEach((moduleItem) => {
235
+ if (!moduleItem.path) {
236
+ throw new Error(`${moduleItem.moduleName}模块没有找到path字段,请检查tms.config.js的modules.all>module>path路径`);
237
+ }
251
238
  const moduleConfigPath = resolve(moduleItem.path, MODULE_CONFIG_FILENAME);
252
239
  if (!fs.existsSync(moduleConfigPath)) {
253
240
  if (!allModules.has(moduleItem.moduleName)) {
package/src/entry.js CHANGED
@@ -6,9 +6,20 @@ module.exports = [
6
6
  require('./scripts/create')(projectName);
7
7
  },
8
8
  },
9
+ {
10
+ command: 'install-cmd <npm-name>',
11
+ description: '安装扩展命令',
12
+ options: [
13
+ ['--registry [registry]', 'npm源'],
14
+ ],
15
+ action: (npmName, cmdOptions) => {
16
+ const res = require('./scripts/extend-cmd');
17
+ res.installCmd(npmName, cmdOptions);
18
+ },
19
+ },
9
20
  {
10
21
  name: 'run',
11
- type: 'child',
22
+ type: 'parent',
12
23
  description: '项目开发使用的命令',
13
24
  commands: [
14
25
  {
@@ -18,8 +29,8 @@ module.exports = [
18
29
  ['-m, --module [moduleName]', '模块名称'],
19
30
  ['-e, --env [env]', '环境变量'],
20
31
  ],
21
- action: (cmd) => {
22
- require('./scripts/run/index')('install', cmd);
32
+ action: (cmdOptions) => {
33
+ require('./scripts/run/index')('install', cmdOptions);
23
34
  },
24
35
  },
25
36
  {
@@ -30,8 +41,8 @@ module.exports = [
30
41
  ['-e, --env [env]', '环境变量'],
31
42
  ['-noCache, --noCache', '不使用缓存功能'],
32
43
  ],
33
- action: (cmd) => {
34
- require('./scripts/run/index')('dev', cmd);
44
+ action: (cmdOptions) => {
45
+ require('./scripts/run/index')('dev', cmdOptions);
35
46
  },
36
47
  },
37
48
  {
@@ -41,8 +52,8 @@ module.exports = [
41
52
  ['-m, --module [moduleName]', '模块名称'],
42
53
  ['-e, --env [env]', '环境变量'],
43
54
  ],
44
- action: (cmd) => {
45
- require('./scripts/run/index')('cloud', cmd);
55
+ action: (cmdOptions) => {
56
+ require('./scripts/run/index')('cloud', cmdOptions);
46
57
  },
47
58
  },
48
59
  {
@@ -52,22 +63,35 @@ module.exports = [
52
63
  ['-m, --module [moduleName]', '模块名称'],
53
64
  ['-e, --env [env]', '环境变量'],
54
65
  ],
55
- action: (cmd) => {
56
- require('./scripts/run/index')('build', cmd);
66
+ action: (cmdOptions) => {
67
+ require('./scripts/run/index')('build', cmdOptions);
68
+ },
69
+ },
70
+ {
71
+ command: 'preview',
72
+ description: '小程序预览',
73
+ options: [
74
+ ['-f, --qrcodeFormat [qrcodeFormat]', '二维码的格式,选项terminal, image, base64。默认terminal'],
75
+ ['-o, --qrcodeOutputDest [qrcodeOutputDest]', '二维码会被输出到给定路径'],
76
+ ['-i, --info-output [infoOutput]', '相关信息会被输出到给定路径'],
77
+ ],
78
+ action: (cmdOptions) => {
79
+ require('./scripts/run/index')('preview', cmdOptions);
80
+ },
81
+ },
82
+ {
83
+ command: 'upload',
84
+ description: '小程序上传',
85
+ options: [
86
+ ['-version, --version [version]', '上传代码版本,version 指定版本号'],
87
+ ['-d, --desc [desc]', '上传代码时的备注'],
88
+ ['-i, --info-output [infoOutput]', '相关信息会被输出到给定路径'],
89
+ ['-r, --robot [robot]', '指定使用哪一个 ci 机器人,可选值:1 ~ 30'],
90
+ ],
91
+ action: (cmdOptions) => {
92
+ require('./scripts/run/index')('upload', cmdOptions);
57
93
  },
58
94
  },
59
- // 对外暂不暴露该命令
60
- // {
61
- // command: 'init',
62
- // description: '模块配置初始化项目(eg: 下载第三方模块代码、安装依赖、生成app.json等)',
63
- // options: [
64
- // ['-m, --module [moduleName]', '模块名称'],
65
- // ['-e, --env [env]', '环境变量'],
66
- // ],
67
- // action: (cmd) => {
68
- // require('./scripts/run/index')('init', cmd);
69
- // },
70
- // },
71
95
  ],
72
96
  },
73
97
  ];
package/src/index.js CHANGED
@@ -1,71 +1,98 @@
1
+ /* eslint-disable no-param-reassign */
1
2
  const chalk = require('chalk');
2
3
  const commander = require('commander');
3
- const { suggestCommands, resolve } = require('./utils/widgets');
4
- const { info } = require('./utils/log');
4
+ const path = require('path');
5
+ const fs = require('fs');
6
+ const { resolve } = require('./utils/widgets');
7
+ const { infoNoTime } = require('./utils/log');
5
8
  const { getTmsConfig } = require('../src/core/tmsMpconfig');
6
9
  const { TMS_NAME } = require('./config/constant.js');
7
10
  const commands = require('./entry');
8
11
  const check = require('./check');
9
- const fs = require('fs');
12
+ const { loadExtendCmd } = require('./scripts/extend-cmd/index.js');
13
+ const report = require('./core/report');
10
14
 
11
15
  check();
12
-
13
16
  const program = new commander.Command(TMS_NAME);
14
-
15
17
  program
16
18
  .version(`${TMS_NAME} ${require('../package.json').version}`, '-v, -V, --version');
17
19
 
20
+ // 注册命令底层实现
18
21
  function registerCommand(program, commands) {
19
22
  commands.forEach((cmd) => {
20
- if (cmd.type === 'child') {
23
+ if (cmd.type === 'parent') {
21
24
  const childProgram = new commander.Command(cmd.name);
22
25
  cmd.usage && childProgram.usage(cmd.usage);
23
26
  cmd.description && childProgram.description(cmd.description);
24
27
  registerCommand(childProgram, cmd.commands);
25
-
26
28
  program.addCommand(childProgram);
27
29
  } else {
28
30
  const command = program.command(cmd.command);
29
-
30
31
  cmd.usage && command.usage(cmd.usage);
31
-
32
32
  cmd.description && command.description(cmd.description);
33
-
34
33
  cmd.options?.forEach(opt => command.option(...opt));
35
-
34
+ // 上报
35
+ command.hook('preAction', (thisCommand) => {
36
+ report(`${thisCommand._name}-pre`);
37
+ });
38
+ // 上报
39
+ command.hook('postAction', (thisCommand) => {
40
+ report(`${thisCommand._name}-post`);
41
+ });
36
42
  command.action(cmd.action);
37
43
  }
38
44
  });
39
45
  }
40
46
 
41
- function register() {
47
+ // 注册扩展命令
48
+ function registerExtendCommand(program, configPath) {
49
+ const tmsConfig = getTmsConfig(configPath);
50
+ if (tmsConfig?.commands) {
51
+ const commands = typeof tmsConfig.commands === 'function' ? tmsConfig.commands() : tmsConfig.commands;
52
+ if (Array.isArray(commands)) {
53
+ registerCommand(program, commands);
54
+ }
55
+ }
56
+ }
57
+ // 注册所有的命令
58
+ function registerAllCmds(program, commands) {
42
59
  // 注册脚手架内部命令
43
60
  registerCommand(program, commands);
44
61
 
45
- // 注册扩展命令
46
- if (fs.existsSync(resolve('tms.config.js'))) {
47
- const tmsConfig = getTmsConfig();
48
- if (Array.isArray(tmsConfig?.commands)) {
49
- registerCommand(program, tmsConfig.commands);
50
- }
62
+ // 注册npm包扩展命令
63
+ const cmdConfigs = loadExtendCmd();
64
+ cmdConfigs.forEach((cmdConfig) => {
65
+ registerExtendCommand(program, path.dirname(cmdConfig));
66
+ });
67
+
68
+ // 注册当前目录扩展命令
69
+ const tmsConfigPath = resolve('./tms.config.js');
70
+ if (fs.existsSync(tmsConfigPath)) {
71
+ registerExtendCommand(program, path.dirname(tmsConfigPath));
51
72
  }
52
73
  }
53
- register();
54
-
55
- program.on('--help', () => {
56
- info(` Run ${chalk.cyan(`${TMS_NAME} <command> --help`)} for detailed usage of given command.`);
57
- });
74
+ registerAllCmds(program, commands);
58
75
 
59
76
  // 捕获未注册的命令
60
77
  program
61
78
  .arguments('<command>')
79
+ .option('-c, --config <value>', '配置', (value) => {
80
+ // 注册指定配置的扩展命令
81
+ registerExtendCommand(program, path.dirname(resolve(value)));
82
+ })
62
83
  .action((cmd) => {
63
- program.outputHelp();
64
- info(` ${chalk.red(`Unknown command ${chalk.yellow(cmd)}.`)}`);
65
- suggestCommands(cmd);
66
- process.exitCode = 1;
84
+ infoNoTime(chalk.yellow(`
85
+ 没有找到${cmd}命令
86
+ 你可以通过${chalk.green('tmskit install-cmd <npm-name>')}安装扩展命令, ${chalk.green('扩展命令列表:https://www.npmjs.com/search?q=tmskit-cmd')}
87
+ 你也可以通过 ${chalk.green('tmskit <command> --config=../tms.config.js')} 指定本地的扩展命令
88
+ `));
89
+ report(`${cmd}-not-find`);
67
90
  });
68
91
 
92
+ program.on('--help', () => {
93
+ infoNoTime(`Run ${chalk.cyan(`${TMS_NAME} <command> --help`)} for detailed usage of given command.`);
94
+ });
95
+
69
96
  if (!process.argv.slice(2).length) {
70
97
  program.outputHelp();
71
98
  process.exit(-1);
Binary file