きっかけ
ツイッターで会社にある変な文化みたいな話があった。コードの変更履歴をコードに持つという話。
要はこんな感じ。
// 2020/03/17 UPDATE START
// ....
int x = 2038;
// 2020/03/17 UPDATE END
この履歴の取り方は、私がITに入った2000年頃には存在していた。
もうすでに消滅した文化と思っていたのだが、なんと20年近く同じことを繰り返していたのだ。
今は2020年。コードの変更履歴をコメントで入れる必要など0.01mmも存在しない。
何なら当時から皆これ無駄じゃね?
と感づいていた。
まぁ、無駄になったコストは顧客が被ることになるのだが、それはまた別の話。
この変な文化の特徴は、自らコードの可読性を落として、開発リソースを食う
と言うアホな独特なスタイルだ。
自らコードの可読性を落として、開発リソースを食う。
どこかで聞いたことはないだろうか。
自ら失敗しやすい状況を作って、失敗する。。。
自分でハードル上げて、コケる。。。
押される状況を作って、押される。。。
そう、まさにダチョウ倶楽部。
私はこの開発手法をダチョウ倶楽部型開発、DCD(Dacho Club Development)と名付けた。
いまだにDCDの手法が生き残っているのならば、エンジニアとして対処しなければならない。
結果
やったぜ(やってない)
DCD支援(?)ツールはgithubに上げた。
現状のままでは実務プロジェクトには適用できるレベルではない。
なので使われる事はまずないとは思うが、マジで使われることが無い事を祈ってる。
アプローチ
2020年現在であの変なコメント(以下、「Ostrich Comment」)を必要としているのは下記の様な人のハズ
- Ostrich Comment付きでコードレビューがしたい
- Ostrich Commentがある事で安心感を得たい
であれば、Ostricher向けのブランチ(以下、「ostrichブランチ」)を作り、Ostricherをそこに閉じ込める事でOstrich Commentの影響を最小限に抑えられるハズ。
開発チームはmaster/developで健全な開発を行えるという寸法だ。
やる事は
- master/developへのpushを検知
- コミット内容を解析
- Ostrich Comment(*1)を差し込む
- ostrichなブランチへpushする。
Ostrich Commentのルールは以下の通り
追加された行に関するOstrich
// 2020/04/01 ADD START MIYATAMA
追加された行
// 2020/04/01 ADD END MIYATAMA
変更された行に関するOstrich
// 2020/04/01 UPDATE START MIYATAMA
// 変更前の行
変更後の行
// 2020/04/01 UPDATA END MIYATAMA
削除された行に関するOstrich
// 2020/04/01 DELETE START MIYATAMA
// 削除された行
// 2020/04/01 DELETE END MIYATAMA
うん。何回見ても開発をうまく進めないための正しいやり方。
さらに、尚、歴戦のDCD経験者ならばとInnerOstrichの違いを指摘したいところだろう(今回は対象外の機能)。
OuterOstrichは修正履歴が増えた時に常に外側が最新となる。
func main() {
// 2020/03/27 DEL START MIYATAMA
// // 2020/03/26 MOD START MIYATAMA
// // // 2020/03/25 ADD START MIYATAMA
// // fmt.Println("hellow world")
// // // 2020/03/25 ADD START MIYATAMA
// fmt.Println("hello world")
// // 2020/03/26 MOD END MIYATAMA
// 2020/03/27 DEL END MIYATAMA
}
InnerOstrichは常に内側が最新となる
func main() {
// 2020/03/25 ADD START MIYATAMA
// 2020/03/26 MOD START MIYATAMA
// fmt.Println("hellow world")
// 2020/03/27 DEL START MIYATAMA
// fmt.Println("hello world")
// 2020/03/27 DEL END MIYATAMA
// 2020/03/26 MOD END MIYATAMA
// 2020/03/25 ADD END MIYATAMA
}
デジタルネイティブの方は、さぞ正気か?
と感じたことだろう。
おっさんから上の人間は真面目な顔してこれやってたのだ。
尚、実務利用に当たっては下記機能が必要となるが今回は対象外。やりたいなら自分で作ったら良いと思う。
- ホワイトリスト(Ostrich対象外ファイルの指定)
- inner ostrich/outer ostrichの指定
- ostrich commentのフォーマット指定
- 2回目以降の修正(複数コミットの対応)
*1: ダチョウ倶楽部型開発で使うコメントルール
使い方
githubはやらかすと怖いリスクが高いので今回はgogsを元に組んでゆく。
- Gitサービスを立ててリポジトリ作る
- OstrichDevを仕掛ける
- Git hookを仕掛ける <- ここで呼ばれる
- pushしてダチョウ倶楽部感を得る
ざっくりとした流れは下記の通り。ostrichdevはWebIFでやる。
Gitサービスを立ててリポジトリを作る
gogsでサービス立てる。とある理由でラズパイ使う。
sudo apt-get update && sudo apt-get -y upgrade
curl -OL https://github.com/gogs/gogs/releases/download/v0.11.91/raspi_armv7.tar.gz
tar fx raspi_armv7.tar.gz
cd ./gogs
デフォルトで3000を使うので、ポート番号指定させないためにnginxを導入する。自前でビルドするもよし、apt経由で取るもよし。nginxの導入に関しては下記リンク参照にて割愛。
で、nginxとgogs起動
sudo nginx
./gogs web &
後はブラウザから開いて適当にリポジトリ作ったら、developのブランチ作成。
git clone
cd script-checker
touch README.md
cat << EOF >> main.go
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
EOF
git add ./*
git commit -m "this is first commit"
git push origin master
git checkout -b developgit add ./*
git push origin develop
こんな感じになってればOK
OstrichDevを仕掛ける
ローカルホストの3030で待ち受ける。ラズパイへのGo言語設定はRaspberry PiにGo言語をインストールすると言う素晴らしい記事を参照の事。
git clone github.com/miyatama/ostrichdev
cd ostrichdev
make
mkdir -p ~/ostrichdev/log
cp ./ostrichdev ~/ostrichdev/
cd ~/ostrichdev
./ostrichdev -behavior web -port 3030 >./log/ostrichdev.log 2>&1 &
Git hookを仕掛ける
gogsはGUI上でサーバサイドhookの編集ができる。尚、実際に利用する際はostrichdev側で多重起動(と呼び出し順適用など)の対策を行う必要がある。
#!/bin/bash
user_home="/home/pi"
script_home="${user_home}/ostrichdev"
log_dir="${script_home}/log"
log_file="${log_dir}/ostrichdev.log"
mkdir -p "${log_dir}"
echo "branch: ${1}" >> ${log_file}
echo "before commt: ${2}" >> ${log_file}
echo "after commit: ${3}" >> ${log_file}
branch=`echo "${1}" | tr '/' ' ' | awk '{ print $NF }'`
commit_id="${3}"
echo "branch: ${branch}" >> ${log_file}
echo "commit id: ${commit_id}" >> ${log_file}
if [ "${branch}" = "develop" ]; then
data=`cat << EOF
{
"repository": "pi@miyapi:miyatama/ostrichers-project.git",
"fromBranch": "${branch}",
"ostrichBranch": "ostrich",
"commitId": "${commit_id}"
}
EOF
`
curl \
-L \
-XPOST \
-H 'Content-Type: application/json' \
-d "${data}" \
http://localhost:3030/ostrich &
fi
exit 0
pushしてダチョウ倶楽部感を感じる
さぁ、あとは編集したり追加したりしてpushするだけ。
developで編集してpush。コマンド割愛。
package main
func main() {
fmt.Println("hello the world")
}
Ostrichブランチへのpushが終わるのをまって
ostrichブランチを確認
無駄に脳を使うスタイルとか正気じゃないよね。。。
振り返り
git hook連動は何気に初めてだったのでいろんな知見がたまった
- update内ではgitコマンドがうまく動かない
- update内から別のWebサービスを呼び出せるが、Webサービス内でコミット情報がうまく取れない。
- goはテストが書きやすくて超ありがたい。
- etc
尚、この記事を書こうと決めてから早2カ月が経過している。
そうか、まだコメントで変更履歴残すなんて物が生き残ってるのか。よし分かった。
— miyatama@長所は早退で来世はサバ (@miyata080825) March 17, 2020
developにpushしたら差分をコメントにしてmasterにpushするアプリを作ろう。そしたらdevelopが最新だ(混乱)
2カ月間の間にマスク(アルミ製)を作ったりしてました。