日子走呀走,就沒了蹤跡,也忘了是多少周前,團隊從 SVN 切換到 Git,之前寫的 SVN 週報工具也算是安心退役了。前天終於下定決心寫個基於 Git 的週報工具。javascript
我對工具的構思以下:java
上一個週報工具是用 Nodejs + svn 命令實現的,此次就不想用 git 命令配合了。因而上網搜了一些資料後,發現 NodeGit 這個庫很適合。那麼主旋律肯定了,就能夠開始動工了,如下是流程圖。node
根據流程圖得出如下的總體流程代碼:git
async function init() {
const folders = fs.readdirSync(config.dir)
// 獲取到不存在的git倉庫(約定文件夾都是git倉庫)(其實也能夠根據是否有.git 或者 nodeGit的exist)
const emptyProjects = config.projects.filter(
v => folders.indexOf(v.folder) === -1
)
if (emptyProjects.length) {
// 建立本地不存在git倉庫
await createRespository(emptyProjects)
}
// 獲取commit信息
const logs = await getRepositoryLog()
// 生成周報
renderReport(logs)
}
複製代碼
讀取本地 Git 倉庫目錄,這裏取(tou)巧(lan)了,約定存在文件夾即認爲存在 git 倉庫,其實也能夠根據是否有.git 目錄或者經過 nodeGit 的 exit 來判斷。github
不存在與本地的 Git 倉庫,考慮到有不少項目是不必 clone 到本地的,因此我並不想把整個 Git 倉庫都拉到本地,只是想建立個連接,而後拉取一下 Log 信息。因此實現的功能如同如下命令:shell
git init
git fetch origin
git log --all
複製代碼
獲取 Git 提交記錄,經過 nodeGit 的 Revwalk 實現 log 全部分支的 commit 信息。其中內部約定重複提交的信息以 update 字符標識,程序上會忽略這個提交信息。markdown
const repo = await nodeGit.Repository.open(`${temporaryFolder}/.git`)
const walker = nodeGit.Revwalk.create(repo)
// 經過pushGlob來獲取全部分支的提交記錄
walker.pushGlob('*')
// 獲取符合日期的commits
const commits = await walker.getCommitsUntil(c => {
const now = c.date()
return now > beginDate && now < endDate
})
const selfCommits = []
Promise.all(
commits
.filter(x => {
// 過濾不須要記錄的commit信息
const regexp = new RegExp(`${projectFolder}|update|merge`, 'gi')
return !regexp.test(x.message())
})
.map(async x => {
// 是否須要統計行數
const total = needCount ? await countLines(x) : 0
// 構建週報信息集
selfCommits.push({
msg: x
.message()
.split(/\n|;/g)
.filter(v => v.length),
total,
project: projectName,
committer: x.committer().name()
})
})
).then(() => {
resolve(selfCommits)
})
複製代碼
生成周報,最後經過 markvis、markdown-it、d3-node 生成周報圖片,具體的項目路徑、名字、帳號、密碼、是否統計行數在 config/index.js 中配置。async
// ./config/index.js
module.exports = {
username: 'username', // Git username
password: 'password', // Git password
reponame: 'origin', // Repository name
dir: 'Git directory path', // /Users/viccici/github
reportDir: 'Report directory path', // /Users/viccici/report
commiter: {
'Git name': 'Real name' // Git committer name matching the real name
},
projects: [
{
name: 'Project name', // We often use chinese project name
folder: 'Project folder', // Git folder name that based on git path. [ PS: weekly-report-git ]
path: 'Git path',
count: true // Whether to count
}
]
}
複製代碼
最終的結果以下圖。svn
該週報工具更多的依賴於團隊的約定,不然週報信息可讀性就不好,後續還須要跟隊員們商量更優的方案。NodeGit 還有不少須要深挖的知識點,後續會花點時間認真研究,從而能優化此週報工具。若有興趣 or 更好想法,可到這裏留言觀看。工具