对文章的作者,我的同事黛妮表示感谢。我们一起完成了这篇文章。
这里附上原文的地址:https://www.yuque.com/rocket/rocket_doc/pyo2i1
开发目的
快速可交互的搭建生成Change Log更新日志,来提高自己的工作效率。
实现思路
要实现Change log自动生成,需要有脚本可以根据项目提交的commit自动生成Change log ,然后还有脚本自动生成版本号,而且每次生成可以自动修改版本号,还需要把生成的Change log 的markdown文件转换成HTML,以便我们在项目中使用 ,既然要转成HTML文件,那就还需要有HTML的模板。
第三方库
搭建changeLog过程中使用到的库
conventional-changelog ——根据commit生成Change log
conventional-changelog-cli ——根据commit生成Change log的脚手架
marked.js ——解析markdown文件,markdown文件转换成HTML
commander ——可以自动的解析命令和参数,用于处理用户输入的命令
chalk ——在终端给输出的命令行字体加上颜色
log-symbols ——在终端可以输出 √ 或 × 等的图标
inquirer ——通用的命令行用户界面集合,用于和用户进行交互
shelljs ——可使用shell命令来操作文件
具体实现
根据实现思路,分步骤实现此功能
脚本自动生成版本号,而且每次生成可以自动修改版本号
// 读取版本号
function readFile(url) {
var promise = new Promise((resolve, reject) => {
fs.readFile(path.resolve(__dirname, url), 'utf8', (err, rs) => {
if (err) {
reject(chalk.red.bold(logSymbols.error, '读取文件失败 \n' + err));
} else {
let temp = JSON.parse(rs);
resolve(temp);
}
})
})
return promise
}
// 写入版本号
function writeFile(url, version) {
var promise = new Promise((resolve, reject) => {
fs.readFile(path.resolve(__dirname, url), 'utf8', (err, data) => {
if (err) {
throw err;
reject(chalk.red.bold(logSymbols.error, '读取文件失败 \n' + err))
} else {
var tempData = JSON.parse(data);
tempData.version = version;
var content = JSON.stringify(tempData, null, 4)
fs.writeFile(path.resolve(__dirname, url), content, err => {
if (err) {
reject(chalk.red.bold(logSymbols.error, '写入文件失败 \n' + err))
} else {
console.log(chalk.green.bold(logSymbols.success, url + ' 写入版本号成功'));
resolve(true)
}
})
}
})
})
return promise
}
// 比较版本号
function compareVersion(v1, v2) {
var arr1 = v1.replace(/[-_]/g, '.').split('.');
var arr2 = v2.replace(/[-_]/g, '.').split('.');
var len = Math.max(arr1.length, arr2.length);
for (var i = 0; i < len; i++) {
if (parseInt(arr1[i]) == parseInt(arr2[i])) continue;
return parseInt(arr1[i]) < parseInt(arr2[i]) ? true : false;
}
return false;
}
把生成的Change log 的markdown文件转换成HTML
// 读取html模板文件
fs.readFile(path.resolve(__dirname, '../static/changeLog/template.html'), 'utf8', (err, template) => {
if (err) {
throw err;
} else {
fs.readFile(filePath, 'utf8', (err, markContent) => {
let replaceList = [
{
're': /http:\/\/git\.ascs\.tech\/website/g,
'reAim': 'https://bitbucket.ascs.tech/projects/WEBSITE/repos'
},
];
for (let item of replaceList) {
markContent = markContent.replace(item.re, item.reAim);
}
if (err) {
throw err;
} else {
let htmlStr = marked(markContent.toString());
template = template.replace('@markdown', htmlStr);
fs.writeFile(path.resolve(__dirname, '../static/changeLog/CHANGELOG.html'), template, err => {
if (err) {
throw err;
} else {
console.log(chalk.green.bold(logSymbols.success, ' 成功将markdown文件转换成HTML文件'));
}
})
}
})
}
})
HTML的模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ChangeLog</title>
<link href='./css/changeLog.css' rel='stylesheet' type='text/css'/>
</head>
<body>
<div id="head">
<header>
<img class="logoImg" src="C:/Users/Administrator/Desktop/images/logo.png">
<span id="headerTitle">CityWorks® Intranet<span>
<img class="toolsImg" src="C:/Users/Administrator/Desktop/images/archive.png">
<img class="toolsImg" src="C:/Users/Administrator/Desktop/images/new.png">
<img class="toolsImg" src="C:/Users/Administrator/Desktop/images/search.png">
</header>
</div>
<div id="logTiile">
<span id="spanTiile"><img src="C:/Users/Administrator/Desktop/images/title.png">更新日志</span>
<hr>
</div>
<div id='write'>
@markdown
</div>
</body>
<script>
(function changeStyle(){
let h2s = document.querySelectorAll("h2");
let h2sArr = [...h2s];
h2sArr.forEach(h2=>{
let content = h2.innerHTML;
let newContentArr = content.split(" ");
let version = newContentArr[0];
let date = newContentArr[1].replace(/[\(,\)]/g,"");
h2.innerHTML = `${version}<span class='version-date'>${date}</span>`;
})
})()
</script>
</html>
使用command.js来解析命令和参数
program
.command('simple')
.option('-s --simple')
.alias('s')
.description('需要配置文件的简单初始化')
.action(function () {
使用inquirer来进行命令行的交互
Plain Text
inquirer
.prompt([
{
type: 'input',
name: 'version',
message: '请输入新的版本号:',
validate: function (input) {
var isVersion = changeVersion.compareVersion(rs.version, input);
if (isVersion) {
return true
} else {
return '请输入正确的版本号'
}
}
}
])
.then((answers) => {
(async function test() {
await changeVersion.writeHtmlFile(answers.version)
for (let i of config.changeVersionPath) {
await changeVersion.writeFile(i, answers.version)
}
await shell.exec('conventional-changelog -p angular -i CHANGELOG.md -s')
await console.log(chalk.green.bold(logSymbols.success, ' 成功增加版本信息'))
var execUrl = "./bin/createChangeLog.js";
await shell.exec('node ' + execUrl);
})()
});