node.jsでgit logを加工してブラウザ上に表示する

master ブランチのgitログを更新履歴としてweb画面に表示するっていうことをやりたい。




環境



PC: MacBook Pro 2016
OS: OS X Sierra
エディタ: Visual Studio Code
言語: Node.js
フレームワーク: Express
テンプレートエンジン: pug(jade)
その他: Material Design Lite

多少環境が変わっても、だいたいやることは一緒だと思います。




node.js からgit log呼び出し



child_process を利用することで任意のコマンドを実行可能です。
http://nodejs.jp/nodejs.org_ja/api/child_process.html
のchild_process.exec(command, [options], callback) を参照

const execSync = require('child_process').execSync;
const cmd = 'git log'; // コマンド
const result = execSync(cmd).toString();
console.log(result);




取得したgit logをNode.jsで加工、表示



git logを取得するコマンド


https://git-scm.com/docs/git-log

Git の基本 - コミット履歴の閲覧
あたりを参考に実際にコマンドを叩いてみて検討してみます。

今回は以下のコマンドで取得したログを使用します。
git log -n 5 --format=%cd,%s


結果
Mon Mar 6 17:46:44 2017 +0900,commitMsg5
Mon Mar 6 17:46:24 2017 +0900,commitMsg4
Fri Mar 3 14:28:48 2017 +0900,commitMsg3
Thu Mar 2 16:52:34 2017 +0900,commitMsg2
Thu Mar 2 15:53:03 2017 +0900,commitMsg1

カンマ区切りで[日付,コミットメッセージ]の最新5件を抽出しています。



取得したgit logをテーブル表示


index.js
----------------------------------
/* eslint-env node, express */

var express = require("express")
var router = express.Router()

/* GET home page. */
router.get("/", /* @callback */ function (req, res, next) {
  const eol = require("os").EOL
  const execSync = require("child_process").execSync
  const cmd = "git log -n 5 --format=%cd,%s" // コマンド
  const logs = execSync(cmd).toString().split(eol)
  const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

  let logData = []
  logs.forEach(function (log) {
    if (log !== "") {
      const logDatum = log.split(",")
      const date = new Date(logDatum[0])
      // yyyy/MM/dd hh:mm 形式
      const dateText = `${date.getFullYear()}/${monthNames[date.getMonth()]}/${("00" + date.getDate()).slice(-2)} ${date.getHours()}:${date.getMinutes()}`
      logData.push({ date: dateText, msg: logDatum[1] })
    }
  })

  res.render("index", { title: "Watson Demos", logData: logData })
})

module.exports = router

日付回りの処理が面倒なだけでやっていることは、
ログ単位で分割して
logData(配列)に{date:[コミット日], msg:[コミットメッセージ]} の形式でデータを詰めて受け渡しているだけです。



index.pug (jade)
画面のレイアウトデザインにMaterial Desigin Lite を使用しています。
h2 更新履歴
table.mdl-data-table.mdl-js-data-table.mdl-shadow--2dp
thead
  tr
    th.mdl-data-table__cell--non-numeric 更新日付
    th.mdl-data-table__cell--non-numeric 更新内容
tbody
  each val in logData
    tr
      td.mdl-data-table__cell--non-numeric #{val[0]}
      td.mdl-data-table__cell--non-numeric #{val[1]}



以下のように表示されます。

ブラウザでgit logのテーブル表示


イイ感じ





2017年3月7日火曜日