Gitでディレクトリの変更監視してLumeのBuildする

5 min read

Image
こんにちは、無能です。
そこそこ前に
inotifywaitを使用して静的サイトSSGのLumeCMSで変更があった時だけ再ビルドを行う
これで自動でビルドさせるようにしたのですが、vimのswapファイルが出来たときにも動いちゃったり他にも気づいたらプロセス死んでいたり無駄にビルド走ったりあんまり安定しなくて気になったので「gitで管理しちゃえば変更あったときにビルドのフロー回せるしなにかあったら戻せるしいいんじゃね」ということを思い、ある程度シェルスクリプトで書くものも頭に浮かんで来ていたのでやってみました。

こんなかんじ

完結に最初っからコードを
Github上でも公開しています。

#!/bin/bash

LUME_DIR="/your/lume/dir"
SRC_DIR="$LUME_DIR/src"
BUILD_DIR="site"
WEBPSH="/your/webp/convert/path"
COMMIT_COMMENT="`echo "Memory" && free -h | head -2 | awk  '{print $(NF-5)"," $(NF-4)"," $(NF-3)}' | column -t -s ","`"

export DENO_INSTALL="/home/$USER/.deno"
export PATH="$DENO_INSTALL/bin:$PATH"

cd "$SRC_DIR" || exit
ls "$SRC_DIR/.git" || git init || exit
git add . || exit

git commit -m "$COMMIT_COMMENT"

if [ $? -eq 0 ]; then
  $WEBPSH
  cd $LUME_DIR || exit
  # deno task lume --dest=$BUILD_DIR
  deno task lume --dest=$BUILD_DIR > /dev/null 2>&1
else
  exit 1
fi

とりあえず、出来る限り短いコードで実装したかったのでこうなりました。
まあやけにCOMMIT_COMMENTがごちゃごちゃしていますが遊びゴコロです・・・。

最初はdateで時間記録していたのですがもはやgit logで確認できちゃうし要らなくね?となり。
(もはやなにかランダムなAAいれていっても良いかもなあ・・・)

画像上のスクリプトをcronで5分起きに実行させています。

gitの戻り値を見ていこう

とりあえず、gitでgit add .したときの戻り値って変更を検知出来るものではないようで例えばgit initしてないときの戻り値

alleycat:[haturatu]:~/git/gittest$ ls -la
合計 8
drwxr-xr-x  2 haturatu haturatu 4096 10月 14 01:08 .
drwxr-xr-x 72 haturatu haturatu 4096 10月 14 01:08 ..
alleycat:[haturatu]:~/git/gittest$ git add .
fatal: not a git repository (or any of the parent directories): .git
alleycat:[haturatu]:~/git/gittest$ echo $?
128

128ですね。
では、git initしたあとにファイルを作成したり消したりしよう。

alleycat:[haturatu]:~/git/gittest$ ls -la
合計 12
drwxr-xr-x  3 haturatu haturatu 4096 10月 14 01:11 .
drwxr-xr-x 72 haturatu haturatu 4096 10月 14 01:08 ..
drwxr-xr-x  7 haturatu haturatu 4096 10月 14 01:11 .git
alleycat:[haturatu]:~/git/gittest$ git add .
alleycat:[haturatu]:~/git/gittest$ echo $?
0
alleycat:[haturatu]:~/git/gittest$ touch test
alleycat:[haturatu]:~/git/gittest$ ls -la
合計 12
drwxr-xr-x  3 haturatu haturatu 4096 10月 14 01:11 .
drwxr-xr-x 72 haturatu haturatu 4096 10月 14 01:08 ..
drwxr-xr-x  7 haturatu haturatu 4096 10月 14 01:11 .git
-rw-r--r--  1 haturatu haturatu    0 10月 14 01:11 test
alleycat:[haturatu]:~/git/gittest$ git add .
alleycat:[haturatu]:~/git/gittest$ echo $?
0

なので、git add .では戻り値変わらないので変更検知出来ないです。
じゃあ、commitしたときの戻り値を見てみましょう。

alleycat:[haturatu]:~/git/gittest$ ls -la
合計 12
drwxr-xr-x  3 haturatu haturatu 4096 10月 14 01:11 .
drwxr-xr-x 72 haturatu haturatu 4096 10月 14 01:08 ..
drwxr-xr-x  7 haturatu haturatu 4096 10月 14 01:11 .git
-rw-r--r--  1 haturatu haturatu    0 10月 14 01:11 test
alleycat:[haturatu]:~/git/gittest$ git commit -m "nyaa"
[master (root-commit) 60bed93] nyaa
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test
alleycat:[haturatu]:~/git/gittest$ echo $?
0
alleycat:[haturatu]:~/git/gittest$ git commit -m "nyan nyan"
On branch master
nothing to commit, working tree clean
alleycat:[haturatu]:~/git/gittest$ echo $?
1

変更がなければ1が帰ってくるようでした。
なのでここの戻り値から判定出来るのであとはどうにでもなります。

割と奥が深そうな変更監視

というわけで、割とこの方法って他にも使えそうな変更管理な気がします。
ただずっと模索しているのがもっとお手軽に軽量で再帰的にディレクトリの変更監視を行うのって割とかんたんそうでそうじゃない。
findコマンドの場合、非常に強力なコマンドなので変更監視時に走らせるのは結構億劫なところがあり(gitの内部コマンドとしても実行しているのかな?)
自分で変更監視のコードを書かなければいけないとなると、除外ディレクトリに関しても判定をいれなければいけません。この点で言えばgitで行う変更監視は監視をしたくない不必要なディレクトリは.gitignoreに記述してしまえば実質的に変更監視から除外できます。

この点で言ってもgitは非常に優れています。
ただしgitの場合キャッシュを.gitに入れているので大きなファイルが存在するディレクリを監視には向かないかもしれません。そのため、それぞれのファイルをハッシュして/tmpにテキストファイルとして格納、diffを取り差分がある戻り値が帰ってくれば変更があったときのフローに回す。
みたいなことは出来るかもしれませんね。
とは言えど、ファイルを除外出来る用にコード入れて、diff前にsortして・・・みたいなことやってたら割と複雑化しそうなのであまりやりたくないです。

書いているときに思ったけど・・・

findを実行させなくても普通にls -laR/tmpに出力させて差分取ればいいだけですね。
でもgitのほうが軽量に感じるのはなぜなんだろう・・・・?となると今度はGitの解体をし始めないといけなくなって来る気がするので今日はここまで。

それではまた、よろしくおねがいします。