LoginSignup
5
0

More than 3 years have passed since last update.

2020年なのにコード上に履歴持つスタイルを何とかする

Posted at

きっかけ

Ostrich.png

ツイッターで会社にある変な文化みたいな話があった。コードの変更履歴をコードに持つという話。
要はこんな感じ。

// 2020/03/17 UPDATE START
// ....
int x = 2038;
// 2020/03/17 UPDATE END

この履歴の取り方は、私がITに入った2000年頃には存在していた。
もうすでに消滅した文化と思っていたのだが、なんと20年近く同じことを繰り返していたのだ。
今は2020年。コードの変更履歴をコメントで入れる必要など0.01mmも存在しない。
何なら当時から皆これ無駄じゃね?と感づいていた。
まぁ、無駄になったコストは顧客が被ることになるのだが、それはまた別の話。
この変な文化の特徴は、自らコードの可読性を落として、開発リソースを食うと言うアホな独特なスタイルだ。

自らコードの可読性を落として、開発リソースを食う。

どこかで聞いたことはないだろうか。

自ら失敗しやすい状況を作って、失敗する。。。
自分でハードル上げて、コケる。。。
押される状況を作って、押される。。。
そう、まさにダチョウ倶楽部。

私はこの開発手法をダチョウ倶楽部型開発、DCD(Dacho Club Development)と名付けた。
いまだにDCDの手法が生き残っているのならば、エンジニアとして対処しなければならない。

結果

ostrich_result.png

やったぜ(やってない)

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は修正履歴が増えた時に常に外側が最新となる。

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は常に内側が最新となる

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でやる。

ostrich_flow.png

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

image.png

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側で多重起動(と呼び出し順適用など)の対策を行う必要がある。

update
#!/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。コマンド割愛。

main.go
package main

func main() {
  fmt.Println("hello the world")
}

Ostrichブランチへのpushが終わるのをまって

ostrich_apply.png

ostrichブランチを確認

ostrich_result.png

無駄に脳を使うスタイルとか正気じゃないよね。。。

振り返り

git hook連動は何気に初めてだったのでいろんな知見がたまった

  • update内ではgitコマンドがうまく動かない
  • update内から別のWebサービスを呼び出せるが、Webサービス内でコミット情報がうまく取れない。
  • goはテストが書きやすくて超ありがたい。
  • etc

尚、この記事を書こうと決めてから早2カ月が経過している。

2カ月間の間にマスク(アルミ製)を作ったりしてました。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0