基於 NodeGit 的週報生成工具

秋塵發表於2019-03-27

日子走呀走,就沒了蹤影,也忘了是多少周前,團隊從 SVN 切換到 Git,以前寫的 SVN 週報工具也算是安心退役了。前天終於下定決心寫個基於 Git 的週報工具。

我對工具的構思如下:

  1. 團隊成員約定每次提交都簡短描述變更的功能
  2. 功能描述以「分號」或者「換行」分隔
  3. 如果再次提交相同功能則以“update”作為標識提交資訊
  4. 週報內容為各個專案下各成員的工作資訊
  5. 生成一張週報圖片利於我發郵件

上一個週報工具是用 Nodejs + svn 命令實現的,這次就不想用 git 命令配合了。於是上網搜了一些資料後,發現 NodeGit 這個庫很適合。那麼主旋律確定了,就可以開始動工了,以下是流程圖。

image

根據流程圖得出以下的整體流程程式碼:

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 來判斷。

不存在與本地的 Git 倉庫,考慮到有很多專案是沒必要 clone 到本地的,所以我並不想把整個 Git 倉庫都拉到本地,只是想建立個連結,然後拉取一下 Log 資訊。所以實現的功能如同以下命令:

git init
git fetch origin
git log --all
複製程式碼

獲取 Git 提交記錄,通過 nodeGit 的 Revwalk 實現 log 所有分支的 commit 資訊。其中內部約定重複提交的資訊以 update 字元標識,程式上會忽略這個提交資訊。

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 中配置。

// ./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
        }
    ]
}
複製程式碼

最終的結果如下圖。

image

該週報工具更多的依賴於團隊的約定,否則週報資訊可讀性就很差,後續還需要跟隊員們商量更優的方案。NodeGit 還有很多需要深挖的知識點,後續會花點時間認真研究,從而能優化此週報工具。如有興趣 or 更好想法,可到這裡留言觀看。

相關文章