@tmsfe/tmskit 0.0.6 → 0.0.9-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.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs.js +1203 -977
  3. package/main.js +1 -3
  4. package/package.json +2 -4
  5. package/src/{gulp → compile}/build.js +0 -0
  6. package/src/{gulp → compile}/compile.js +10 -7
  7. package/src/{gulp → compile}/dev.js +42 -15
  8. package/src/{gulp → compile}/plugins/less.js +0 -0
  9. package/src/{gulp → compile}/plugins/mpCommonDep.js +1 -1
  10. package/src/{gulp → compile}/plugins/mpJsonDep.js +7 -3
  11. package/src/{gulp → compile}/plugins/mpWxmlDep.js +1 -1
  12. package/src/{gulp → compile}/plugins/postcss-font-base64.js +0 -0
  13. package/src/{gulp → compile}/plugins/replaceEnv.js +0 -0
  14. package/src/{gulp → compile}/plugins/utils/pluginError.js +0 -0
  15. package/src/config/constant.js +6 -8
  16. package/src/{utils → core}/buildAppJson.js +14 -69
  17. package/src/{utils → core}/checkDependencies.js +3 -3
  18. package/src/core/cloneModules.js +203 -0
  19. package/src/{utils → core}/handleError.js +4 -2
  20. package/src/core/isInIt.js +69 -0
  21. package/src/{utils/mpCiUtils.js → core/mpCi.js} +0 -0
  22. package/src/core/npm.js +218 -0
  23. package/src/core/symbolicLink.js +24 -0
  24. package/src/{utils/tkitUtils.js → core/tmsMpconfig.js} +85 -9
  25. package/src/entry.js +13 -11
  26. package/src/index.js +7 -6
  27. package/src/init.js +2 -2
  28. package/src/scripts/create/index.js +2 -2
  29. package/src/scripts/run/build/index.js +3 -4
  30. package/src/scripts/run/dev/index.js +11 -53
  31. package/src/scripts/run/index.js +57 -28
  32. package/src/scripts/run/init/index.js +19 -11
  33. package/src/scripts/run/install/index.js +8 -6
  34. package/src/utils/global.js +19 -33
  35. package/src/utils/io.js +3 -2
  36. package/src/utils/log.js +3 -0
  37. package/src/utils/widgets.js +54 -43
  38. package/src/utils/cliUtils.js +0 -35
  39. package/src/utils/cloneModules.js +0 -116
  40. package/src/utils/npmUtils.js +0 -166
package/main.js CHANGED
@@ -1,3 +1 @@
1
- #!/usr/bin/env node
2
-
3
- require('./dist/index.cjs'); // eslint-disable-line
1
+ require('dist/index.cjs.js');
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@tmsfe/tmskit",
3
- "version": "0.0.6",
3
+ "version": "0.0.9-beta.0",
4
4
  "description": "tmskit",
5
- "main": "main.js",
5
+ "main": "dist/index.cjs",
6
6
  "bin": {
7
7
  "tmskit": "main.js"
8
8
  },
@@ -39,13 +39,11 @@
39
39
  "chalk": "^4.1.0",
40
40
  "commander": "^8.3.0",
41
41
  "copy-webpack-plugin": "^9.1.0",
42
- "download-git-repo": "^3.0.2",
43
42
  "ejs": "^3.1.5",
44
43
  "fs-extra": "^10.0.1",
45
44
  "glob-ignore": "^1.0.2",
46
45
  "gulp": "^4.0.2",
47
46
  "gulp-cache": "^1.1.3",
48
- "gulp-image": "^5.1.0",
49
47
  "gulp-postcss": "^9.0.1",
50
48
  "gulp-px-to-rpx": "^1.0.7",
51
49
  "gulp-watch": "^5.0.1",
File without changes
@@ -1,14 +1,14 @@
1
1
  const { src, dest, lastRun } = require('gulp');
2
2
  const px2rpx = require('gulp-px-to-rpx');
3
- const postcss = require('gulp-postcss');
4
3
  const watch = require('gulp-watch');
5
4
  // const cache = require('gulp-cache');
6
5
  // const image = require('gulp-image');
7
- const replaceEnv = require('./plugins/replaceEnv');
6
+ // const replaceEnv = require('./plugins/replaceEnv');
8
7
  const { mpCommonDep } = require('./plugins/mpCommonDep');
9
8
  const { mpJsonDep } = require('./plugins/mpJsonDep');
10
9
  const { mpWxmlDep } = require('./plugins/mpWxmlDep');
11
- const base64 = require('./plugins/postcss-font-base64');
10
+ // const postcss = require('gulp-postcss');
11
+ // const base64 = require('./plugins/postcss-font-base64');
12
12
  const { fail } = require('../utils/log');
13
13
 
14
14
  const since = task => file => (lastRun(task) > file.stat.ctime ? lastRun(task) : 0);
@@ -35,7 +35,7 @@ module.exports = function (
35
35
  switch (globKey) {
36
36
  case 'js':
37
37
  srcPipe
38
- .pipe(replaceEnv(/process\.env(\.(\w*))?/g, tmsConfig.envData))
38
+ // .pipe(replaceEnv(/process\.env(\.(\w*))?/g, tmsConfig.envData))
39
39
  .pipe(mpCommonDep(tmsConfig, module, ['.js', '.ts', '.wxs', '.json'], isWatch))
40
40
  .pipe(dest(destPath))
41
41
  .on('error', (err) => {
@@ -45,10 +45,13 @@ module.exports = function (
45
45
  case 'wxss':
46
46
  srcPipe
47
47
  .pipe(mpCommonDep(tmsConfig, module, ['.wxss', '.less'], isWatch))
48
- .pipe(postcss([base64()]))
49
48
  .on('error', (err) => {
50
- fail(`postcss编译报错${err}`);
49
+ fail(`mpCommonDep编译报错${err}`);
51
50
  })
51
+ // .pipe(postcss([base64()]))
52
+ // .on('error', (err) => {
53
+ // fail(`postcss编译报错${err}`);
54
+ // })
52
55
  .pipe(px2rpx({
53
56
  designWidth: 375, // 设计稿宽度,默认为750
54
57
  precision: 2, // 小数最大精度,默认为6
@@ -59,7 +62,7 @@ module.exports = function (
59
62
  srcPipe
60
63
  .pipe(mpJsonDep(tmsConfig, module, ['.json'], ['.wxml', '.json', '.js', '.ts', '.wxss', '.less'], isWatch))
61
64
  .on('error', (err) => {
62
- fail(`json编译报错${err}`);
65
+ fail(`mpJsonDep编译报错${err}`);
63
66
  })
64
67
  .pipe(dest(destPath));
65
68
  break;
@@ -1,6 +1,8 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
1
3
  const watch = require('gulp-watch');
2
4
  const { resolve } = require('../utils/widgets');
3
- const { buildOutputAppJson } = require('../utils/buildAppJson');
5
+ const { buildOutputAppJson } = require('../core/buildAppJson');
4
6
  const { DEFAULT_COPY_CONFIG } = require('../config/constant');
5
7
  const compile = require('./compile');
6
8
 
@@ -23,6 +25,13 @@ function excludeGlob(glob) {
23
25
  return Array.from(otherArr);
24
26
  }
25
27
 
28
+ function adaptPath(pathDir) {
29
+ let newPath = pathDir;
30
+ newPath = newPath.startsWith('/') ? newPath : resolve(newPath);
31
+ newPath = newPath.endsWith('/') ? newPath.slice(0, newPath.length - 1) : newPath;
32
+ return newPath;
33
+ }
34
+
26
35
  module.exports = async (tmsConfig, newModules, isWatch = true) => {
27
36
  // 监听app.json
28
37
  if (isWatch) {
@@ -37,8 +46,8 @@ module.exports = async (tmsConfig, newModules, isWatch = true) => {
37
46
  compile(tmsConfig, {
38
47
  glob: {
39
48
  json: DEFAULT_COPY_CONFIG.map(item => resolve(item)),
40
- wxss: ['app.less', 'app.wxss'].map(item => resolve(item)),
41
- js: ['app.js', 'app.ts'].map(item => resolve(item)),
49
+ // wxss: ['app.less', 'app.wxss'].map(item => resolve(item)),
50
+ // js: ['app.js', 'app.ts'].map(item => resolve(item)),
42
51
  },
43
52
  module: { from: '', to: '' },
44
53
  destPath: resolve(tmsConfig.outputDir),
@@ -62,18 +71,19 @@ module.exports = async (tmsConfig, newModules, isWatch = true) => {
62
71
  }
63
72
 
64
73
  const excludes = module.exclude.map(key => `!${resolve(key)}`);
74
+ const modulePath = adaptPath(module.path);
65
75
  const glob = {
66
- js: [`${resolve(module.path)}/**/*.{js,ts,wxs}`, ...excludes],
67
- json: [`${resolve(module.path)}/**/*.json`, ...excludes],
68
- wxss: [`${resolve(module.path)}/**/*.{less,wxss}`, ...excludes],
69
- wxml: [`${resolve(module.path)}/**/*.wxml`, ...excludes],
70
- image: [`${resolve(module.path)}/**/*.{png,jpg,jpeg,gif,svg}`, ...excludes],
76
+ js: [`${modulePath}/**/*.{js,ts,wxs}`, ...excludes],
77
+ json: [`${modulePath}/**/*.json`, ...excludes],
78
+ wxss: [`${modulePath}/**/*.{less,wxss}`, ...excludes],
79
+ wxml: [`${modulePath}/**/*.wxml`, ...excludes],
80
+ image: [`${modulePath}/**/*.{png,jpg,jpeg,gif,svg}`, ...excludes],
71
81
  };
72
82
 
73
83
  compile(tmsConfig, {
74
84
  glob: {
75
85
  ...glob,
76
- other: [`${resolve(module.path)}/**/*`, ...excludeGlob(glob)],
86
+ other: [`${modulePath}/**/*`, ...excludeGlob(glob)],
77
87
  },
78
88
  destPath: resolve(tmsConfig.outputDir, module.root),
79
89
  module: { from: module.path, to: module.root },
@@ -85,15 +95,32 @@ module.exports = async (tmsConfig, newModules, isWatch = true) => {
85
95
  // 静态资源目录-拷贝
86
96
  if (tmsConfig?.static && tmsConfig?.static.length > 0) {
87
97
  for (const item of tmsConfig.static) {
88
- const from = item?.from.startsWith('/') ? item.from : resolve(item.from);
89
- const to = item?.to.startsWith('/') ? item.to : resolve(item.to);
98
+ item.from = adaptPath(item.from);
99
+ item.to = adaptPath(item.to);
100
+
101
+ let glob = {};
102
+ const ext = path.extname(item.from).slice(1);
103
+ if (ext) {
104
+ glob[ext] = [item.from];
105
+ } else {
106
+ glob = {
107
+ js: [`${item.from}/**/*.{js,ts,wxs}`],
108
+ json: [`${item.from}/**/*.json`],
109
+ wxss: [`${item.from}/**/*.{less,wxss}`],
110
+ wxml: [`${item.from}/**/*.wxml`],
111
+ image: [`${item.from}/**/*.{png,jpg,jpeg,gif,svg}`],
112
+ };
113
+ glob.other = [`${item.from}/**/*`, ...excludeGlob(glob)];
114
+ }
90
115
 
116
+ const from = fs.lstatSync(item.from).isFile() ? path.dirname(item.from) : item.from;
91
117
  compile(tmsConfig, {
92
- glob: {
93
- other: [from],
118
+ glob,
119
+ destPath: item.to,
120
+ module: {
121
+ from,
122
+ to: item.to,
94
123
  },
95
- destPath: to,
96
- module: item,
97
124
  srcOption: { allowEmpty: true },
98
125
  isWatch,
99
126
  });
File without changes
@@ -85,7 +85,7 @@ function mpCommonDep(tmsConfig, module, extensions = [], isWatch = true) {
85
85
  }
86
86
 
87
87
  // eslint-disable-next-line
88
- const reg = new RegExp(`^(\.\.\/)+.*\/${includeName}\/(.*)`);
88
+ const reg = new RegExp(`^(\./|\.\.\/)+.*\/${includeName}\/(.*)`);
89
89
  const regRes = depItem.match(reg) || [];
90
90
  if (regRes[2]) {
91
91
  const depDestPath = resolve(tmsConfig.outputDir, module.to, includeName, regRes[2]);
@@ -21,10 +21,14 @@ function mpJsonDep(
21
21
  const anaFileDestFile = resolve(tmsConfig.outputDir, module.to, anaFileRelativeModule);
22
22
 
23
23
  if (file.isBuffer()) {
24
- const copyModules = new Map();
25
24
  let contents = String(file.contents);
25
+ const copyModules = new Map();
26
26
  try {
27
- contents = JSON.parse(contents);
27
+ try {
28
+ contents = contents ? JSON.parse(contents) : {};
29
+ } catch (e) {
30
+ throw new Error(`解析${file.path}出现错误,请检查配置信息: ${e}`);
31
+ }
28
32
  if (contents.usingComponents) {
29
33
  Object.keys(tmsConfig.dependencies).forEach((includeName) => {
30
34
  const includePath = tmsConfig.dependencies[includeName];
@@ -45,7 +49,7 @@ function mpJsonDep(
45
49
  }
46
50
 
47
51
  // eslint-disable-next-line
48
- const reg = new RegExp(`^(\.\.\/)+.*\/${includeName}\/(.*)`);
52
+ const reg = new RegExp(`^(\./\.\.\/)+.*\/${includeName}\/(.*)`);
49
53
  const regRes = componentPath.match(reg) || [];
50
54
  if (regRes[2]) {
51
55
  const depDestPath = resolve(tmsConfig.outputDir, module.to, includeName, regRes[2]);
@@ -133,7 +133,7 @@ function mpWxmlDep(tmsConfig, module, isWatch) {
133
133
  }
134
134
 
135
135
  // eslint-disable-next-line
136
- const reg = new RegExp(`^(\.\.\/)+.*\/${includeName}\/(.*)`);
136
+ const reg = new RegExp(`^(\./\.\.\/)+.*\/${includeName}\/(.*)`);
137
137
  const regRes = attributes.src.match(reg) || [];
138
138
  if (regRes[2]) {
139
139
  const depDestPath = resolve(tmsConfig.outputDir, module.to, includeName, regRes[2]);
File without changes
@@ -1,7 +1,8 @@
1
1
  const path = require('path');
2
+ const os = require('os');
2
3
 
3
4
  // 用户目录
4
- const HOME_DIR = process.env.HOME;
5
+ const HOME_DIR = os.homedir();
5
6
 
6
7
  // 所有文件的缓存目录
7
8
  const CACHE_DIR = path.resolve(HOME_DIR, '.tmskit');
@@ -26,6 +27,9 @@ const TMS_PRIVATE_FILENAME = 'tms.private.config.js';
26
27
  // 模块代码的默认在modules子目录
27
28
  const DEFAULT_MODULE_DIR = 'modules';
28
29
 
30
+ // 模块代码的默认在modules子目录
31
+ const DEFAULT_CLOUD_MODULE_DIR = './cloud';
32
+
29
33
  // 模块的配置文件的名称
30
34
  const MODULE_CONFIG_FILENAME = 'module.config.json';
31
35
 
@@ -37,12 +41,6 @@ const DEFAULT_WEBPACK_ENTRY = {
37
41
  // 默认从源码拷贝到编译后的配置
38
42
  const DEFAULT_COPY_CONFIG = ['package.json', 'sitemap.json'];
39
43
 
40
- // 开发模式
41
- const MODE = {
42
- all: 'all',
43
- multi: 'multi',
44
- };
45
-
46
44
  const ENV = {
47
45
  dev: 'development',
48
46
  prod: 'production',
@@ -64,8 +62,8 @@ export {
64
62
  DEFAULT_WEBPACK_ENTRY,
65
63
  DEFAULT_COPY_CONFIG,
66
64
  MODULE_CODE_DIR,
67
- MODE,
68
65
  ENV,
69
66
  TEMPLATE_TKIT_DIR,
70
67
  MODULE_CONFIG_INVALID_KEY,
68
+ DEFAULT_CLOUD_MODULE_DIR,
71
69
  };
@@ -1,57 +1,15 @@
1
+ /**
2
+ * 生成编译后的app.json
3
+ */
1
4
  const fs = require('fs');
2
5
  const { MODULE_CONFIG_FILENAME, MODULE_CONFIG_INVALID_KEY } = require('../config/constant');
3
- const { fail } = require('./log');
4
- const { resolve, isObject, isArray } = require('./widgets');
6
+ const { getModuleConfig, getValidModules } = require('./tmsMpconfig');
7
+ const { fail } = require('../utils/log');
8
+ const { resolve, isObject } = require('../utils/widgets');
5
9
  const { handleError } = require('./handleError');
6
10
 
7
11
  /**
8
- * 获取每个模块下面的信息,并且收集,后续更新到appJson里面
9
- * @param { object } file 操作目录下面所有的文件
10
- * @param { string } appName 小程序的名称
11
- */
12
-
13
- function setModuleConfig(file, appName) {
14
- const content = file.contents ? JSON.parse(file.contents.toString()) : JSON.parse(file);
15
-
16
-
17
- if (isArray(content)) {
18
- let i = content.length - 1;
19
- while (i >= 0) {
20
- let current = content[i];
21
-
22
- if (appName && current.mpConfig && current.mpConfig[appName]) {
23
- current = { ...current, ...current.mpConfig[appName] };
24
- }
25
-
26
- delete current.mpConfig;
27
- delete current.isSubpackages;
28
-
29
- content[i] = current;
30
- i--; // eslint-disable-line
31
- }
32
- }
33
- return content;
34
- }
35
-
36
- /**
37
- * 递归获取本地所有模块的配置信息
38
- */
39
- function getLocalModuleConfig(modules = [], appName, moduleConfigFilename) {
40
- const modulesConfig = {};
41
-
42
- modules.forEach(({ path }) => {
43
- const moduleConfigPath = resolve(path, moduleConfigFilename);
44
- if (fs.existsSync(moduleConfigPath)) {
45
- const content = fs.readFileSync(moduleConfigPath, 'utf-8');
46
- modulesConfig[moduleConfigPath] = setModuleConfig(content, appName);
47
- }
48
- });
49
-
50
- return modulesConfig;
51
- }
52
-
53
- /**
54
- * 更新appJson里面的首页配置
12
+ * 更新appJson里面的主包配置
55
13
  * @param { object } appJson appJson信息
56
14
  * @param { array } mainPackages 小程序主包信息
57
15
  * @returns { object } appJson小程序主页配置信息
@@ -85,7 +43,7 @@ function updateMainPackages(appJson, mainPackages = []) {
85
43
  }
86
44
  /**
87
45
  * 获取app.json内容
88
- * @param {string} sourceAppJsonPath
46
+ * @param {string} sourceAppJsonPath app.json存在的源码路径
89
47
  * @returns
90
48
  */
91
49
  const getAppJsonContent = (sourceAppJsonPath) => {
@@ -116,22 +74,12 @@ const updateSubpackages = (appJson, modulesConfig) => {
116
74
  appJson.subpackages = appJson.subpackages.concat(validModules);
117
75
  }
118
76
  };
119
- /**
120
- * 过滤页面为空的分包
121
- * @param {Array} moduleCfg 模块配置内容
122
- * @returns pages不为空的分包
123
- */
124
- const getValidModules = (moduleCfg) => {
125
- // 过滤 pages 为空的情况
126
- const validModules = moduleCfg.filter(item => item.pages.length > 0);
127
- return validModules;
128
- };
129
77
 
130
78
  /**
131
79
  * 处理合并subpackages后的appjson, 整理重复不合法的地方
132
80
  * @param {Object} appJson appjson
133
81
  */
134
- const processAppJson = (appJson) => {
82
+ const fixAppJson = (appJson) => {
135
83
  const { subpackages } = appJson;
136
84
  const pluginsMap = {};
137
85
  Object.keys(appJson.plugins || {}).forEach(key => pluginsMap[key] = ['app.json']);
@@ -186,23 +134,22 @@ const processAppJson = (appJson) => {
186
134
  appJson.subpackages = subps;
187
135
  };
188
136
 
189
-
190
137
  /**
191
138
  * 动态生成编译后的app.json
192
139
  * @param {object} tmsConfig
193
- * @param {array} modules
140
+ * @param {array} modules 用户要编译的模块列表
194
141
  * @returns
195
142
  */
196
- function buildOutputAppJson(tmsConfig, modules, isDev) {
143
+ function buildOutputAppJson(tmsConfig, modules) {
197
144
  try {
198
145
  // 获取当前 modules 下的所有子模块的配置内容
199
- const modulesConfig = getLocalModuleConfig(modules, tmsConfig.appName, MODULE_CONFIG_FILENAME);
146
+ const modulesConfig = getModuleConfig(modules, tmsConfig.appName, MODULE_CONFIG_FILENAME);
200
147
  // 获取app.json的配置
201
148
  const appJson = getAppJsonContent(resolve('./app.json'));
202
149
  // 更新app.json中的subpackages
203
150
  updateSubpackages(appJson, modulesConfig);
204
151
  // 处理appJson中重复||冲突的地方
205
- processAppJson(appJson);
152
+ fixAppJson(appJson);
206
153
  // 更新主包,需在subpackages处理完成后执行, pages/
207
154
  updateMainPackages(appJson, tmsConfig.mainPackages);
208
155
 
@@ -210,12 +157,10 @@ function buildOutputAppJson(tmsConfig, modules, isDev) {
210
157
 
211
158
  return appJson;
212
159
  } catch (e) {
213
- handleError(`生成app.json出现错误: ${e}`, isDev);
160
+ handleError(`生成app.json出现错误: ${e}`);
214
161
  }
215
162
  }
216
163
 
217
164
  module.exports = {
218
- setModuleConfig,
219
- getValidModules,
220
165
  buildOutputAppJson,
221
166
  };
@@ -1,6 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const semver = require('semver');
3
- const { resolve } = require('./widgets');
3
+ const { resolve } = require('../utils/widgets');
4
4
  const path = require('path');
5
5
  const shelljs = require('shelljs');
6
6
  const { handleError } = require('./handleError');
@@ -17,7 +17,7 @@ const getLatestVersion = (npmName) => {
17
17
  * @param {*} outputDir 待检查node_modules存放的目录 (eg: dist/node_modules)
18
18
  * @returns
19
19
  */
20
- const checkDependencies = (modules, cwd, outputDir, isDev) => {
20
+ const checkDependencies = (modules, cwd, outputDir) => {
21
21
  // 步骤1. 收集package.json
22
22
  const packageJsonName = 'package.json'; // 查找文件名
23
23
  // 1.1根目录的package.json
@@ -46,7 +46,7 @@ const checkDependencies = (modules, cwd, outputDir, isDev) => {
46
46
  const json = JSON.parse(packageJson);
47
47
  dependencies = json?.dependencies ? json?.dependencies : {};
48
48
  } catch (e) {
49
- handleError(`解析${item.srcPackageDir}报错,请检查是否是正确的json配置项`, isDev);
49
+ handleError(`解析${item.srcPackageDir}报错,请检查是否是正确的json配置项 ${e}`);
50
50
  }
51
51
  const dependenciesKeys = Object.keys(dependencies);
52
52
  for (const key of dependenciesKeys) {
@@ -0,0 +1,203 @@
1
+ /**
2
+ * 下载第三方代码
3
+ */
4
+ const MetalSmith = require('metalsmith');
5
+ const crypto = require('crypto');
6
+ const { downloadRepoForGit, pullRepoForGit, resolve } = require('../utils/widgets');
7
+ const { fail, info } = require('../utils/log');
8
+ const fs = require('fs');
9
+ const shelljs = require('shelljs');
10
+ const { handleError } = require('./handleError');
11
+ const { global } = require('../utils/global');
12
+
13
+ /**
14
+ * 处理用户没有clone git仓库权限问题,拼接tms.private.config.js的账号信息
15
+ * @param {*} httpRepoUrl
16
+ * @param {*} moduleName
17
+ * @returns
18
+ */
19
+ function replaceGitUrlAccount(httpRepoUrl, moduleName) {
20
+ // 用户本地的私有项目配置(用来配置环境\模块信息\账号信息)
21
+ const tmsPrivateCf = global.getData('tmsPrivateCf');
22
+
23
+ let gitUrl = httpRepoUrl;
24
+ const { username = '', pass = '' } = tmsPrivateCf?.gitAccout?.[moduleName] || {};
25
+
26
+ const urlPrefixReg = /http(s)?:\/\//;
27
+ if (username && pass && urlPrefixReg.test(gitUrl)) {
28
+ gitUrl = gitUrl.replace(urlPrefixReg, val => `${val}${encodeURIComponent(username)}:${pass}@`);
29
+ }
30
+
31
+ return gitUrl;
32
+ }
33
+
34
+ /**
35
+ * 对克隆下来的模块进行相应的文件处理操作,比如收集处理模块信息,进行信息缓存等操作
36
+ * @param { string } sourceDir 缓存文件夹
37
+ * @param { string } targetDir 目标文件夹
38
+ * @param { arrary } ignore
39
+ * @returns { undefined } no return
40
+ */
41
+ function moveFile(sourceDir, targetDir, ignore = []) {
42
+ // 删除不是文件夹的文件
43
+ return new Promise((resolve, reject) => {
44
+ MetalSmith(__dirname)
45
+ .ignore(ignore)
46
+ .source(sourceDir)
47
+ .destination(targetDir)
48
+ .build((e) => {
49
+ if (e) {
50
+ fail(`${sourceDir} moveFile ${targetDir}出现错误: ${e}`);
51
+ reject(e);
52
+ }
53
+ resolve();
54
+ });
55
+ });
56
+ }
57
+
58
+ /**
59
+ * 根据gitUrl 和 branch取md5值
60
+ * @param {*} gitUrl
61
+ * @param {*} branch
62
+ * @returns
63
+ */
64
+ function md5ByGitUrlBranch(gitUrl, branch) {
65
+ const newBranch = branch && typeof branch === 'string' ? branch : 'master';
66
+ return crypto.createHash('md5').update(JSON.stringify({ gitUrl, branch: newBranch }))
67
+ .digest('hex');
68
+ }
69
+
70
+ /**
71
+ * 下载目标模块
72
+ * @param { string } sourceDir 缓存文件夹
73
+ * @param { string } targetDir 目标文件夹
74
+ * @returns { array } modules 描述模块的列表
75
+ */
76
+ async function cloneModules(sourceDir, targetDir, modules) {
77
+ // 收集下载模块代码的任务
78
+ const downloadTasksMap = collectDownLoadTasksMap(sourceDir, targetDir, modules);
79
+
80
+ // 开始执行下载和移动代码的任务
81
+ const arrPromises = [];
82
+ downloadTasksMap.forEach(({ promiseTask, params, callbacks }) => {
83
+ arrPromises.push(promiseTask(...Object.keys(params).map(key => params[key]))
84
+ .then(async () => {
85
+ const callArr = callbacks.map(async ({
86
+ params: cParams,
87
+ fn,
88
+ }) => fn(...Object.keys(cParams).map(key => cParams[key])));
89
+ return Promise.all(callArr);
90
+ })
91
+ .catch((e) => {
92
+ handleError(`下载代码${params.httpRepoUrl}出现错误:${e}`);
93
+ }));
94
+ });
95
+
96
+ await Promise.all(arrPromises);
97
+ }
98
+
99
+ /**
100
+ * 收集下载模块代码的任务
101
+ * @param { string } sourceDir 代码缓存文件夹
102
+ * @param { string } targetDir 代码要放到的目标文件夹
103
+ * @returns { array } modules 描述模块的列表
104
+ */
105
+ function collectDownLoadTasksMap(sourceDir, targetDir, modules) {
106
+ // 下载代码任务 Map (key解释 缓存代码路径/md5(gitUrl,branch)
107
+ // {
108
+ // '/Users/odile/.tmskit/modules_code/026cb72509c2369dbd75779181f820bc': {
109
+ // promiseTask, 下载代码的任务
110
+ // params: { 下载代码时的参数
111
+ // gitUrl,
112
+ // sourcePath,
113
+ // branch,
114
+ // },
115
+ // callbacks: [callback],// 下载完代码后的回调
116
+ // }
117
+ // }
118
+ const downloadTasksMap = new Map();
119
+ for (const moduleInfo of modules) {
120
+ if (moduleInfo.repoInfo) {
121
+ const { repoInfo: { buildGitTag: branch, httpRepoUrl, path: gitPath = '' }, path, name } = moduleInfo;
122
+
123
+ // 处理仓库权限问题
124
+ const gitUrl = replaceGitUrlAccount(httpRepoUrl, name);
125
+ // 根据gitUrl与branch计算md5
126
+ const md5Key = md5ByGitUrlBranch(gitUrl, branch);
127
+ // git源码临时存在的源目录
128
+ const sourcePath = resolve(sourceDir, md5Key);
129
+ // 模块源码要放到目标目录
130
+ const targetPath = resolve(targetDir, path);
131
+ // 从git源码仓库中找到模块源码路径 (一个仓库存在存放多个模块的情况)
132
+ const sourceModulePath = gitPath ? `${sourcePath}/${gitPath}` : sourcePath;
133
+
134
+ // 下载完代码后,添加回调函数(主要将模块代码从临时目录移动代码到目标目录)
135
+ const callback = {
136
+ params: { sourceModulePath, targetPath },
137
+ fn: async (sourceModulePath, targetPath) => {
138
+ if (fs.existsSync(targetPath)) {
139
+ shelljs.rm('-rf', `${targetPath}/*`);
140
+ }
141
+
142
+ await moveFile(`${sourceModulePath}`, targetPath, [
143
+ 'node_modules',
144
+ '.git',
145
+ ]);
146
+ },
147
+ };
148
+
149
+ if (downloadTasksMap.has(sourcePath)) {
150
+ const task = downloadTasksMap.get(sourcePath);
151
+ task.callbacks.push(callback);
152
+ downloadTasksMap.set(sourcePath, task);
153
+ } else {
154
+ let promiseTask;
155
+ if (fs.existsSync(sourcePath) && fs.existsSync(`${sourcePath}/.git`)) {
156
+ promiseTask = (gitUrl, sourcePath, branch, httpRepoUrl) => {
157
+ info(`git pull仓库:${httpRepoUrl}`);
158
+ return pullRepoForGit(sourcePath, branch);
159
+ };
160
+ } else {
161
+ promiseTask = (gitUrl, sourcePath, branch, httpRepoUrl) => {
162
+ info(`git clone仓库: ${httpRepoUrl}`);
163
+ return downloadRepoForGit(gitUrl, sourcePath, branch);
164
+ };
165
+ }
166
+ downloadTasksMap.set(sourcePath, {
167
+ promiseTask,
168
+ params: {
169
+ gitUrl,
170
+ sourcePath,
171
+ branch,
172
+ httpRepoUrl,
173
+ },
174
+ callbacks: [callback],
175
+ });
176
+ }
177
+ }
178
+ }
179
+ return downloadTasksMap;
180
+ }
181
+
182
+ /**
183
+ * 检查远程模块的gitUrl与 branch是否有更新
184
+ * @param {string} sourceDir 模块源码在缓存区的目录
185
+ * @param {object} moduleInfo 模块的配置信息
186
+ * @returns
187
+ */
188
+ function checkRemoteModGitUrlBranch(sourceDir, moduleInfo) {
189
+ if (moduleInfo.repoInfo) {
190
+ const { repoInfo: { buildGitTag, httpRepoUrl }, name } = moduleInfo;
191
+ const gitUrl = replaceGitUrlAccount(httpRepoUrl, name);
192
+ const md5Key = md5ByGitUrlBranch(gitUrl, buildGitTag);
193
+ if (!fs.existsSync(`${sourceDir}/${md5Key}`)) {
194
+ return true;
195
+ }
196
+ }
197
+ return false;
198
+ }
199
+
200
+ module.exports = {
201
+ cloneModules,
202
+ checkRemoteModGitUrlBranch,
203
+ };
@@ -1,7 +1,9 @@
1
- const { fail } = require('./log');
1
+ const { fail } = require('../utils/log');
2
+ const { global } = require('../utils/global');
2
3
 
3
- function handleError(error, isDev = false) {
4
+ function handleError(error) {
4
5
  const errMsg = typeof error === 'object' ? error.message : error;
6
+ const isDev = global.getData('isDev');
5
7
  if (isDev) {
6
8
  fail(errMsg);
7
9
  } else {