@farris/cli 1.0.9 → 1.0.12

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 (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
  }