@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.
- package/ci/cli.js +116 -25
- 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",
|
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
|
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
|
123
|
-
const
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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
|
-
},
|
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}
|
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((
|
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
|
-
|
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.
|
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
|
}
|