代碼風格雖然不像某端技術圈那么容易炸鍋, 也不像編程語言或者編輯器那樣容易站隊, 但人多了總要有一個統(tǒng)一的風格, 提高工作效率. 最近逐漸統(tǒng)一團隊的代碼風格, 記錄一下思考過程.
0x00 確定代碼風格的原則
如何確定一個統(tǒng)一的代碼風格? 空格是用 TAB? 每行最多幾個字符? 某某地方應該空出幾行.... 如果開會來討論這些問題, 估計可以吵一天, 然后把所有的意見寫一本書.
但要推廣下來, 確是要有如下工具支撐才可以高效率的推廣:
- 有命令行工具做代碼格式檢查和代碼格式化, 不能全部靠人力 review 甚至手動格式化代碼
- 工具要方便整合到 CI 中, 方便自動化.
有了這兩個原則, 再爭吵, 誰想推廣自己的方案, 一定要搞定上述兩條才算合格, 否則就是"嘴炮", 不解決問題.
基于上面兩個原則, 翻了一下現有的方案, 發(fā)現 Google 簡直就是一家良心公司啊....基本上照著抄就行了.....
0x01 Go
Go 語言根本都不用費事, gofmt
一下解決, 再在本地代碼中添加如下 pre-commit
的 git hook, 收工了. 多說一句, 我本人還是非常贊賞 Go 這種做法的: 就一種格式, 少 BB.
#!/bin/sh
gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '\.go$')
[ -z "$gofiles" ] && exit 0
unformatted=$(gofmt -l $gofiles)
[ -z "$unformatted" ] && exit 0
# Some files are not gofmt'd. Print message and fail.
echo >&2 "Go files must be formatted with gofmt. Please run:"
for fn in $unformatted; do
echo >&2 " gofmt -w $PWD/$fn"
done
exit 1
0x02 Python
針對 Python 語言 Google 有 yapf: A formatter for Python files. 不解的是, yapf 居然支持一些所謂的"定制化", 這真的有必要嗎?
我們的選擇很簡單也很專制, 直接用 README 中的 example 即可:
[style]
based_on_style = pep8
spaces_before_comment = 4
split_before_logical_operator = true
0x03 Java
Google 官方早就有自己的 Google Java Style, 并且為了貫徹這個, 作了一個項目 google-java-format, 不僅提供了命令行工具, 甚至還有 IDEA 和 eclipse 兩種 IDE 的插件.
不過 google-java-format
命令行工具不支持 --diff
選項, 也就是說將代碼格式化后與原有的代碼進行 diff, 如果代碼格式不符合要求, diff 的內容不為空, 這是方便接入 CI 中自動代碼檢查的關鍵. 因此需要手動實現 diff 功能, 示例代碼如下:
#!/bin/bash
#
set -e
current_dir=`cd $(dirname $0);pwd`
cd $current_dir/../
check_cmd="java -jar sbin/google-java-format-1.3-all-deps.jar "
function check_code_style() {
for java_file in `find src -type f -name '*.java'`
do
tmp_file="/tmp/$RANDOM.java"
$check_cmd $java_file >$tmp_file
local diff_code=`diff $java_file $tmp_file`
rm $tmp_file
if [ -n "$diff_code" ]
then
echo
echo "code style not match, file: $java_file"
echo
printf "use \n\t$check_cmd --replace $java_file \n\nto format the code\n"
echo
exit 2
fi
done
echo
echo "code style check pass"
echo
}
time check_code_style
0x04 SQL
我猜 Google 不怎么寫 SQL, 因此沒有一個官方的 SQL-format 項目出來. 只有使用 sqlparse 自己寫一個 formatter了.
-- EOF --