Closed3

執筆commit時、スプレッドシートに行数を記録する方法

junkawajunkawa

処理の流れ

  1. 執筆する
  2. git add、git commitする
  3. .git/hooks/post-commit でcommit時の行数とファイル名を取得し、スプレッドシートへPOST
    • curl -X POST <URL?パラメータ>
      • 日付
      • 行数
      • ファイル名
      • キー
  4. スプレッドシートのGoogle Apps ScriptでPOST処理
    • GASはWebアプリケーションとして公開
    • doPost() でパラメタを解析
  5. スプレッドシートへ記録

セキュリティ

  • Webアプリケーションへのアクセスは「全員」とした
    • OAuth認証は作業が重いので避けた
    • 代替としてパラメタにKEYを用意し、doPost()時にKEYが一致しないと弾くようにした
junkawajunkawa

commit時の処理

.git/hooks/post-commit
#!/usr/bin/env bash

declare -a commit_files=()
mapfile commit_files <<<$(git log -1 HEAD --numstat --pretty="%H" --no-merges articles/ books/ | awk 'NF==3 {if ($1-$2 != 0) printf("%d %s\n", $1-$2, $3)}')

for loc_filename in "${commit_files[@]}"; do
    declare -a loc=()
    loc=($(echo $loc_filename)) # loc[0]=loc, loc[1]=filename
    echo -n -e "${loc[0]}\n${loc[1]}\n" | postKpi >/dev/null # POST to google spreadsheet
done
  • git log -1 HEAD で直前のコミットを対象とする

  • git log --numstat --pretty="%H" の出力

    • 追加行数、削除行数、ファイル名
    <コミットハッシュ値>
    
    10      0       articles/xxxxxxxxxxxxxxxxxxx.md 
    20      3       articles/yyyyyyyyyyyyyyyyyy.md 
    
  • awk で「変更行数 ファイル名」を出力する

    • 列数が3の行(NF==3)を抜き出すことで、コミットハッシュ値の行は除く
    • 変更行数は、追加行数 - 削除行数 としている
    • mapfile を使い、行毎に配列に入れる
  • POSTは、次の postKpi シェルスクリプトで行なう

    • 標準入力に変更行数\nファイル名\nを渡している
~/.local/bin/postKpi
#!/usr/bin/env bash

URL=""
KEY=""

# OUTPUT_LOD
OUTPUT_LOD=""
echo -n "OUTPUT_LOD > "
read input
if [[ "$input" =~ ^[0-9]+$ ]]; then
    OUTPUT_LOD=$input
fi

# OUTPUT_COMMENT
OUTPUT_COMMENT=""
echo -n "OUTPUT_COMMENT > "
read input
OUTPUT_COMMENT=$input

# curl
DATE=$(date "+%Y-%m-%d")
PARAMETER="KEY=${KEY}&DATE=${DATE}&OUTPUT_LOD=${OUTPUT_LOD}&OUTPUT_COMMENT=${OUTPUT_COMMENT}"
curl -s -S -X POST "${URL}?${PARAMETER}" >/dev/null
  • URLは、GASのWebアプリケーションをデプロイした時に表示されるもの
    • スプレッドシートのURLではない
  • KEYは、後述のGASのコード中に埋め込んだ値と同じものを使用する
  • 行数OUTPUT_LODとファイル名OUTPUT_COMMENTを標準入力から受け取る
    • 行数は数値のみを受け付ける
junkawajunkawa

スプレッドシートのGASコード

コード.js
const VALID_KEY = '';
function doPost(e) {
  try {
    const DATE = e.parameter.DATE; // yyyy-mm-dd
    const OUTPUT_LOD = e.parameter.OUTPUT_LOD;
    const OUTPUT_COMMENT = e.parameter.OUTPUT_COMMENT;
    const KEY = e.parameter.KEY;
    if (VALID_KEY !== KEY) {
      throw "error1";
    }
    addKPI(DATE, OUTPUT_LOD, OUTPUT_COMMENT);
  } catch(error) {
    console.log(error);
    throw "error2";
  }
  return "";
}

function addKPI(DATE, OUTPUT_LOD, OUTPUT_COMMENT) {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = spreadsheet.getSheetByName('KPI');
  const lastRow = sheet.getLastRow();
  const line = [[DATE, OUTPUT_LOD, OUTPUT_COMMENT]];
  sheet.getRange(lastRow+1, 1, 1, 3).setValues(line);
}
  • VALID_KEY に十分長い文字列を指定する
    • postKpiのKEYに同じ文字列をセットする
  • スプレッドシートのシート名はKPIとしている
  • スプレッドシートの最終行に追記していく
このスクラップは2021/06/22にクローズされました