@farris/cli 1.0.9 → 1.0.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. package/ci/cli.js +116 -25
  2. package/package.json +3 -2
package/ci/cli.js CHANGED
@@ -4,9 +4,12 @@
4
4
 
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
+ const log = require("npmlog");
8
+ const moment = require("moment");
7
9
  const childProcess = require("@lerna/child-process");
8
10
  const { Project } = require("@lerna/project");
9
11
 
12
+
10
13
  const yargs = require('yargs/yargs');
11
14
  const cli = yargs(process.argv.slice(2), process.cwd())
12
15
 
@@ -73,24 +76,53 @@ cli
73
76
  )
74
77
  .argv;
75
78
 
79
+ /**
80
+ * @param {import("@lerna/child-process").ExecOpts} execOpts
81
+ */
82
+ function getLastCommit() {
83
+ if (hasTags()) {
84
+ console.log("getLastTagInBranch");
85
+ return childProcess.execSync("git", ["describe", "--tags", "--abbrev=0"]);
86
+ }
87
+ console.log("getFirstCommit");
88
+ return childProcess.execSync("git", ["rev-list", "--max-parents=0", "HEAD"]);
89
+ }
90
+
91
+ /**
92
+ * @param {import("@lerna/child-process").ExecOpts} opts
93
+ */
94
+ function hasTags() {
95
+ let result = false;
96
+ try {
97
+ result = !!childProcess.execSync("git", ["tag"]);
98
+ } catch (err) {
99
+ log.warn("ENOTAGS", "No git tags were reachable from this branch!");
100
+ log.verbose("hasTags error", err);
101
+ }
102
+ log.verbose("hasTags", result);
103
+ return result;
104
+ }
105
+
106
+
76
107
  /**
77
108
  * 检查指定工程目录下是否存在变更文件
78
109
  * @param {string} projectPath 目标工程路径
79
110
  * @returns 检查结果
80
111
  */
81
112
  function checkProjectChanges(projectPath) {
113
+ const lastCommit = getLastCommit();
82
114
  return childProcess
83
115
  // 使用 git diff 命令查询自上传提交以来,目标工程路径下是否有变更的文件
84
- .exec("git", ["diff", "--name-only", "HEAD^", projectPath])
116
+ .exec("git", ["diff", "--name-only", lastCommit, projectPath])
85
117
  .then((returnValue) => {
86
- // 提取命令输出结果中的文件集合
118
+ // 提取命令输出结果中的文件集合ß
87
119
  const changedFiles = returnValue.stdout.split("\n").filter(Boolean);
88
120
  // 根据文件个数确定是否存在变更
89
121
  const hasChanges = changedFiles.length > 0;
90
122
  if (hasChanges) {
91
- console.log(`${projectPath} has changed.`)
123
+ console.log(`${projectPath} has changed sence last commit ${lastCommit}.`)
92
124
  } else {
93
- console.log(`Did not detect any changes from ${projectPath} sence last commit`)
125
+ console.log(`Did not detect any changes from ${projectPath} sence last commit ${lastCommit}.`)
94
126
  }
95
127
  // 返回检测结果
96
128
  return hasChanges;
@@ -102,7 +134,7 @@ function checkProjectChanges(projectPath) {
102
134
  * @param {string} projectPath 目标工程路径
103
135
  * @returns 更新后的版本
104
136
  */
105
- function updateProjectPrereleaseVersion(projectPath, projectUrl) {
137
+ function updateProjectPrereleaseVersion(projectPath) {
106
138
  return childProcess
107
139
  // 使用 npm version prerelease 更新指定工程的预发布版本
108
140
  .exec('npm', ['version', 'prerelease', '--preid=beta', '--prefix', projectPath])
@@ -119,25 +151,39 @@ function updateProjectPrereleaseVersion(projectPath, projectUrl) {
119
151
  })
120
152
  }
121
153
 
122
- function commitChanges(updatedVersions, commitUrl) {
123
- const commitMessage = updatedVersions.reduce((latestMessage, updateVersion, index, originalArray) => {
124
- if (Object.keys(updateVersion).length) {
125
- const packageName = Object.keys(updateVersion)[0];
126
- const version = updateVersion[packageName];
127
- let message = `${packageName} to ${version}`;
128
- if (index <= originalArray.length - 2) {
129
- message = message + ', ';
130
- }
131
- latestMessage = latestMessage + message;
154
+ function builderVersionChangeMessage(prefix, updatedVersions, suffix = '') {
155
+ const versionMessage = Object.keys(updatedVersions).reduce((latestMessage, packageName, index, originalArray) => {
156
+ const version = updatedVersions[packageName];
157
+ let message = `${packageName} to ${version}`;
158
+ if (index <= originalArray.length - 2) {
159
+ message = message + ', ';
132
160
  }
133
- return latestMessage;
134
- }, 'update ');
161
+ return latestMessage = latestMessage + message;
162
+ }, `${prefix} `)
163
+ return `${versionMessage} ${suffix}`;
164
+ // const versionMessage = updatedVersions.reduce((latestMessage, updateVersion, index, originalArray) => {
165
+ // if (Object.keys(updateVersion).length) {
166
+ // const packageName = Object.keys(updateVersion)[0];
167
+ // const version = updateVersion[packageName];
168
+ // let message = `${packageName} to ${version}`;
169
+ // if (index <= originalArray.length - 2) {
170
+ // message = message + ', ';
171
+ // }
172
+ // latestMessage = latestMessage + message;
173
+ // }
174
+ // return latestMessage;
175
+ // }, `${prefix} `);
176
+ // return `${versionMessage} ${suffix}`;
177
+ }
178
+
179
+ function commitChanges(updatedVersions, commitUrl) {
180
+ const commitMessage = builderVersionChangeMessage('Update', updatedVersions, '.');
135
181
 
136
182
  if (commitMessage) {
137
183
  // 向git缓冲区中添加变更
138
184
  childProcess.execSync('git', ['add', '.']);
139
185
  // // 提交变更记录
140
- childProcess.execSync('git', ['commit', '-m', `${commitMessage}. [skip ci]`]);
186
+ childProcess.execSync('git', ['commit', '-m', `${commitMessage} [skip ci]`]);
141
187
 
142
188
  console.log(commitMessage);
143
189
 
@@ -153,10 +199,27 @@ function commitChanges(updatedVersions, commitUrl) {
153
199
  }
154
200
 
155
201
  function buildWorkspace(workspace) {
202
+ console.log(`executing lerna run build --scope=${workspace.packageName}`)
156
203
  return childProcess.exec('lerna', ['run', 'build', `--scope=${workspace.packageName}`]);
157
204
  // lerna run build --scope=@farris/ide-framework
158
205
  }
159
206
 
207
+ function tagMonoWorkspace(monoWorkspace, commitUrl) {
208
+ const tagMessage = builderVersionChangeMessage('Publish npm packages ', monoWorkspace.updateResult, '.');
209
+ const date = moment(new Date());
210
+ const tagVersion = `v${date.format('yyyyMMddhhmmss')}`;
211
+ console.log(`git tag ${tagVersion} -m ${tagMessage}`);
212
+ childProcess.execSync('git', ['tag', tagVersion, '-m', tagMessage]);
213
+ // 提交变更集
214
+ if (commitUrl) {
215
+ console.log(`git push -o ci.skip ${commitUrl}`);
216
+ return childProcess.exec("git", ["push", '-o', 'ci.skip', commitUrl]);
217
+ } else {
218
+ console.log(`git push -o ci.skip`);
219
+ return childProcess.exec('git', ['push', '-o', 'ci.skip']);
220
+ }
221
+ }
222
+
160
223
  /**
161
224
  * 发布指定路径下的npm包
162
225
  * @param {string} projectPath 目标工程路径
@@ -169,36 +232,55 @@ function publish(projectPath) {
169
232
  const dest = ngPackageConfig.dest;
170
233
  const packagePath = path.normalize(`${projectPath}/${dest}`);
171
234
  // 调用 npm publish 发布指定路径下的npm包
235
+ console.log(`npm publish ${packagePath}`);
172
236
  return childProcess.exec('npm', ['publish', packagePath])
173
237
  }
174
238
 
239
+ /**
240
+ * 将所有变更发布为新的npm包
241
+ * @param {string} commitUrl commit api 地址
242
+ */
175
243
  function publishAll(commitUrl) {
244
+ // 初始化当前工作目录下的多代码仓库项目
176
245
  const monoRepoProject = new Project(process.cwd());
177
246
  let chain = Promise.resolve();
247
+ // 1. 提取当前多代码仓库中的所有子项目,创建多项目工作区
178
248
  chain = chain.then(() => {
249
+ // 提取所有子项目
179
250
  return monoRepoProject.getPackages()
180
251
  .then(packages => {
252
+ // 创建并返回多项目工作区
181
253
  const monoWorkspace = { packages };
182
254
  return monoWorkspace;
183
255
  })
184
256
  });
257
+ // 2. 读取多项目工作区下的Angular工作区和所有Angular项目
185
258
  chain = chain.then((monoWorkspace) => {
259
+ // 提取所有子仓库项目
186
260
  const packages = monoWorkspace.packages;
261
+ // 初始化Angular工作区集合
187
262
  monoWorkspace.workspaces = [];
263
+ // 初始化Angular工程集合
188
264
  monoWorkspace.projects = [];
265
+ // 遍历所有子仓库
189
266
  packages.forEach(packageJson => {
267
+ // 读取Angular工作区路径
190
268
  const workspacePath = packageJson.location;
269
+ // 读取Angular工作区下的angular.json文件内容
191
270
  const angularJson = readAngularJson(workspacePath)
271
+ // 构造Angular工作区
192
272
  const workspace = readWorkspace(angularJson, packageJson);
273
+ // 记录Angular工作区对象
193
274
  monoWorkspace.workspaces.push(workspace);
275
+ // 遍历Angular工作区下的Angular项目,归集到根工作区中
194
276
  workspace.projects.reduce((monoWorkspace, projectInfo) => {
195
277
  monoWorkspace.projects.push(projectInfo);
196
278
  return monoWorkspace;
197
279
  }, monoWorkspace);
198
- // .forEach((projectInfo) => monoWorkspace.projects.push(projectInfo));
199
280
  });
200
281
  return monoWorkspace;
201
282
  });
283
+ // 3. 检查代码提交记录,获取自上次发布以来所有发生变化的Angular工程
202
284
  chain = chain.then(monoWorkspace => {
203
285
  const projects = monoWorkspace.projects;
204
286
  const checkProjects = projects.map((projectInfo) => {
@@ -215,29 +297,38 @@ function publishAll(commitUrl) {
215
297
  return Promise.resolve(monoWorkspace);
216
298
  });
217
299
  });
300
+ // 4. 更新所有变更项目预发布版本,提交代码仓库,供发布时使用
218
301
  chain = chain.then(monoWorkspace => {
219
302
  const changedProjects = monoWorkspace.changedProjects;
220
- const prereleasePromise = changedProjects.map(projectInfo => updateProjectPrereleaseVersion(projectInfo.project.path));
303
+ const prereleasePromise = changedProjects.map(projectInfo => updateProjectPrereleaseVersion(projectInfo.project.path, monoWorkspace));
221
304
  return Promise.all(prereleasePromise)
222
- .then((updatedVersions) => {
305
+ .then((results) => {
306
+ results.reduce((workspace, updateResult) => {
307
+ workspace.updateResult = workspace.updateResult || {};
308
+ Object.assign(workspace.updateResult, updateResult);
309
+ return workspace;
310
+ }, monoWorkspace);
311
+ const updatedVersions = monoWorkspace.updateResult;
223
312
  commitChanges(updatedVersions, commitUrl);
224
313
  return Promise.resolve(monoWorkspace);
225
314
  });
226
315
  });
316
+ // 5. 编译所有Angular工作区
227
317
  chain = chain.then(monoWorkspace => {
228
318
  const buildPromises = monoWorkspace.workspaces.map((workspace) => buildWorkspace(workspace));
229
319
  return Promise.all(buildPromises)
230
- .then(() => {
320
+ .then((results) => {
231
321
  return Promise.resolve(monoWorkspace);
232
322
  });
233
323
  });
324
+ // 6. 将变更项目的内容发布为npm包,并增加发布Tag标签
234
325
  chain = chain.then(monoWorkspace => {
235
326
  const changedProjects = monoWorkspace.changedProjects;
236
327
  const publishPromises = changedProjects.map(projectInfo => publish(projectInfo.project.path));
237
328
  Promise.all(publishPromises)
238
329
  .then(() => {
239
- console.log('published');
240
- })
330
+ return tagMonoWorkspace(monoWorkspace, commitUrl);
331
+ });
241
332
  });
242
333
  }
243
334
 
@@ -262,7 +353,7 @@ function readWorkspace(angularJson, packageJson) {
262
353
  // workspace.set(projectName, projectInfo);
263
354
  workspace.projects.push(projectInfo);
264
355
  }
265
- return workspace; ßß
356
+ return workspace;
266
357
  }, workspace);
267
358
  return workspace;
268
359
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farris/cli",
3
- "version": "1.0.9",
3
+ "version": "1.0.12",
4
4
  "description": "Farris command line interface",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -20,6 +20,7 @@
20
20
  "author": "Sagi Chen",
21
21
  "license": "ISC",
22
22
  "dependencies": {
23
- "lerna": "^4.0.0"
23
+ "lerna": "^4.0.0",
24
+ "moment": "^2.29.3"
24
25
  }
25
26
  }