惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LINUX DO - 热门话题
Blog — PlanetScale
Blog — PlanetScale
博客园 - Franky
J
Java Code Geeks
腾讯CDC
博客园 - 聂微东
The Cloudflare Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
Last Week in AI
Last Week in AI
量子位
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
Google DeepMind News
Google DeepMind News
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Schneier on Security
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
有赞技术团队
有赞技术团队
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Securelist
AWS News Blog
AWS News Blog
GbyAI
GbyAI
L
LINUX DO - 最新话题
大猫的无限游戏
大猫的无限游戏
Forbes - Security
Forbes - Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Attack and Defense Labs
Attack and Defense Labs
C
CXSECURITY Database RSS Feed - CXSecurity.com
Y
Y Combinator Blog
W
WeLiveSecurity
T
Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
P
Proofpoint News Feed
D
DataBreaches.Net
博客园 - 三生石上(FineUI控件)
V
V2EX
N
News and Events Feed by Topic
Google DeepMind News
Google DeepMind News
D
Docker
The Hacker News
The Hacker News
A
About on SuperTechFans
Security Latest
Security Latest
NISL@THU
NISL@THU
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
博客园_首页
H
Hacker News: Front Page

Razeen`s Blog

Let's Encrypt 推出 Gen Y 根证书架构:揭示 Web PKI 的五大未来趋势 通过 Wi-Fi 自动备份你的 iPhone 到 Nas 管理培训感悟:从技术视角看管理之路 UPS 一拖多:保护你的 NAS 和 Linux 服务器 从影音中心到 AI 助手:我的50款 Homelab 服务清单 从SSL证书有效期将缩短到47天聊开去 部署一个自己的 Running Page 谈谈特斯拉 Model Y 用车一年的感受和费用分析 弃用 Disqus 评论,使用自建 Waline 使用 Prometheus 和 Grafana 搭建你的证书监控面板 服务器迁移记:一次磁盘换板引发的Linux分区与挂载的学习 改善信息来源, 利用 RSS 高效获取资讯 (RSShub + Reeder5 + WeWe RSS) 多种 Docker 镜像拉取解决方案与实践 App分享 | AppCleaner - Mac上的卸载神器 Azure OpenAI API 申请和使用 如何开通 OneKey 虚拟信用卡,并充值消费 如何拥有一个可长期在国内使用的国外手机号码 分享开通 ChatGPT Plus 过程 如何开通 Depay 虚拟信用卡,并充值消费 如何开通欧易Web3钱包, 交易入账 如何5分钟内1块钱注册 ChatGPT 如何注册美区的 Apple ID (2023年/无需科学上网) NAS折腾记(11): NASTool3.0体验和降级 NAS折腾记(10): Docker版本的NASTool配置 NAS折腾记(9): NASTool与微信交互,微信发送消息远程下载电影【多图】 NAS折腾记(8):群晖安装 NASTool 实现影音半自动化【多图】 内网穿透(2):Tailscale 组网实现内网穿透,操作简单,无成本 内网穿透(1):总结了11中内网穿透的方式,总有一种适合你 NAS折腾记(7):从零开始设置(黑)群晖系统 NAS折腾记(6):黑群晖系统安装好后怎么洗白? NAS折腾记(5):群晖硬盘休眠设置与分析 NAS折腾记(4): 20分钟手把手带你完美安装 DS918+ 黑群晖7.1.1 NAS折腾记(3):NAS 装机 NAS折腾记(2):B360-ITX 双M.2 双2.5G网口 6 SATA主版 开箱 NAS折腾记(1):328元的4盘位Nas机箱开箱 Openwrt + Clash 全局科学上网 Newifi3 刷入 OpenWrt 固件 v21.02 利用 Markdown 画一些流程图、时序图、甘特图等 Homelab(8): 搭建自用 Gitlab 与 Docker 仓库 Nginx Tcp 转发保留客户端真实 IP (PROXY Protocol) Homelab (7):IPSec VPN(基于证书认证)客户端设置 Homelab (6): 基于自签发证书的 IPSec VPN 搭建 Homelab (5): DDNS 动态域名解析 Homelab (4): Linux 服务器基础环境准备 Homelab (3): 整体网络与基础硬件介绍 Go学习笔记(十)老项目迁移 go module 大型灾难记录 Github Actions 初体验之自动化部署 Hexo 博客 记一次 Nginx DNS 缓存导致转发问题 Homelab (2): 电信悦me网关修改桥接模式,路由器拨号 Homelab (1):5分钟上手黑群晖 NAS 终极 Bash 脚本指南 Typora 自动上传图片到七牛云 Ubuntu 20.04 LTS 有线网卡驱动安装 折腾 Ubuntu 20.04 LTS 开发环境 Go学习笔记(九) 计时器的生命周期[译] 规范 git commit message 与自动化版本控制 超详细 vim 配置 (with MacVim) Golang 中的 RESTful API 最佳实践 折腾服务器(开篇) 我的第一台个人服务器 Newifi3 实现低成本家庭级科学上网 Go学习笔记(八) | 使用 os/exec 执行命令 如何用 Go 调用 Windows API Mac OS 自动根据 WI-FI 名字改变网络位置 关于 Docker 清理 MIME Types 速查表 Go学习笔记(七) | 理解OAuth 2.0并实现一个客户端 我又又又把博客迁移了 Go学习笔记(六) | 使用swaggo自动生成Restful API文档 Go学习笔记(五) | 使用代码片段(snippets)提高编码效率 书单 - 2018 IPFS 初体验,利用 IPFS 托管你的静态网站 记一次 PostgreSQL LIKE 索引优化,联合字段 LIKE 查询优化。 Disqus 添加有趣的 Reactions 的功能 TLS 1.3 详解 (RFC 8446解读) gRPC在Go中的使用(三)gRPC实现TLS加密通信与流模式 gRPC在Go中的使用(二)gRPC实现简单通讯 gRPC在Go中的使用(一)Protocol Buffers语法与相关使用 CentOS 安装 tshark 抓包工具 Go学习笔记(四) | win上使用VSCode搭建Go开发环境 日常 Postgres 数据库点滴记录 简单了解 PKCS 规范 美食篇 | DIY戚风蛋糕(烤箱做蛋糕) Go学习笔记(三) | 怎么写Go基准测试(性能测试) TLS1.3正式更新,为Nginx添加TLS1.3的支持 一次诡异的数据库删除 GitHub Pages自定义域名开启HTTPS 证书透明度是什么?它是怎么工作的? Go学习笔记(二) | 我对 recover 的一点误解 搭建证书透明度(certificate-transparency)日志服务之从入门到放弃 修复远程登陆 Centos 时,出现 UTF-8 Warning HTTPS篇之SSL握手过程详解 Go学习笔记(一) | postgres与golang点点滴滴 AWS 命令行界面(aws-cli)从安装到快速上手 数字证书分类及怎么区分各类数字证书 常用 linux 命令小结(一)文件目录操作 云服务器搭建 hexo 博客,git hooks自动更新 SSH 免密登陆, SSH Config 配置 Golang CGO Mac 交叉编译 Windows 使用 goose 让数据库迁移更加轻松 开始使用Ghost
利用 git hook 规范你的代码与 commit message
2020-04-13 · via Razeen`s Blog

在团队协作时,由于个人编码习惯的差异,导致代码格式,风格都会有所不同,这就给代码审核带来一定的困难,更严重的是会导致整体的代码质量不可控。这时,我们有必要借助一些工具来约束我们的代码格式。在Go中,我们经常使用的工具有:

  • goimports: 自动导包;
  • gofmt : 格式化我们的代码;
  • golint: 检查代码命名,注释等;
  • go vet: 静态错误检查。

那么,我们可以利用这些工具来规范团队的代码风格。但如果每次手动执行这些命令,或者仅仅依靠IDE去检查,这是不靠谱的,因为人的行为本身是不靠谱的==。

于是,我们可以结合git hook, 强制执行这些检查,检查不通过,代码都无法提交,从而达到强一致性。

同时,结合上一篇«规范git commit message与自动化版本控制», 这里我们介绍一下利用pre-commit 约束commit-msg来约束我们的代码与git commit message。

源码在这里

go pre-commit hook

那么,我们怎么写一个pre-commit hook呢?

  • 首先,我们需要判断用户是否装上面这些工具;
  • 然后,我们需要对git暂存区的代码(不包括vendor),利用上面提到的四个工具进检查。

直接上代码。

#!/bin/sh

has_errors=0

# 获取git暂存的所有go代码
# --cached 暂存的
# --name-only 只显示名字
# --diff-filter=ACM 过滤暂存文件,A=Added C=Copied M=Modified, 即筛选出添加/复制/修改的文件
allgofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '.go$')

gofiles=()
godirs=()
for allfile in ${allgofiles[@]}; do 
    # 过滤vendor的
    # 过滤prootobuf自动生产的文件
    if [[ $allfile == "vendor"* || $allfile == *".pb.go" ]];then
        continue
    else
        gofiles+=("$allfile")

        # 文件夹去重
        existdir=0
        dir=`echo "$allfile" |xargs -n1 dirname|sort -u`
        for somedir in ${godirs[@]}; do
            if [[ $dir == $somedir ]]; then 
                existdir=1
                break
            fi
        done

        if [[ $existdir -eq 0 ]]; then 
            godirs+=("$dir")
        fi
    fi
done

[ -z "$gofiles" ] && exit 0

# gofmt 格式化代码
unformatted=$(gofmt -l ${gofiles[@]})
if [ -n "$unformatted" ]; then
	echo >&2 "gofmt FAIL:\n Run following command:"
	for f in ${unformatted[@]}; do
		echo >&2 " gofmt -w $PWD/$f"
	done
	echo "\n"
	has_errors=1
fi

# goimports 自动导包
if goimports >/dev/null 2>&1; then  # 检测是否安装
	unimports=$(goimports -l ${gofiles[@]})
	if [ -n "$unimports" ]; then
		echo >&2 "goimports FAIL:\nRun following command:"
		for f in ${unimports[@]} ; do
			echo >&2 " goimports -w $PWD/$f"
		done
		echo "\n"
		has_errors=1
	fi
else
	echo 'Error: goimports not install. Run: "go get -u golang.org/x/tools/cmd/goimports"' >&2
	exit 1
fi

# golint 代码规范检测
if golint >/dev/null 2>&1; then  # 检测是否安装
	lint_errors=false
	for file in ${gofiles[@]} ; do
		lint_result="$(golint $file)" # run golint
		if test -n "$lint_result" ; then
			echo "golint '$file':\n$lint_result"
			lint_errors=true
			has_errors=1
		fi
	done
	if [ $lint_errors = true ] ; then
		echo "\n"
	fi
else
	echo 'Error: golint not install. Run: "go get -u github.com/golang/lint/golint"' >&2
	exit 1
fi

# go vet 静态错误检查
show_vet_header=true
for dir in ${godirs[@]} ; do
    vet=$(go vet $PWD/$dir 2>&1)
    if [ -n "$vet" -a $show_vet_header = true ] ; then
	echo "govet FAIL:"
	show_vet_header=false
    fi
    if [ -n "$vet" ] ; then
	echo "$vet\n"
	has_errors=1
    fi
done


exit $has_errors

commit-msg hook

结合上一篇的规范化git commit message提交,我们这里做几点限制:

  • 至少15个字符(15个字符都没有,提交信息肯定不详细);
  • 必须以feat|fix|chore|docs关键词开头,可选(scope) , 之后必须紧跟冒号和空格: ,之后就是具体的描述。

直接上脚本:

#!/bin/sh

# 忽略merge request
MERGE_MSG=`cat $1 | egrep '^Merge branch*'`

if [ "$MERGE_MSG" != "" ]; then
    exit 0
fi

COMMIT_MSG=`cat $1 | egrep "^(feat|fix|docs|chore)(\(\w+\))?:\s(\S|\w)+"`

if [ "$COMMIT_MSG" = "" ]; then
    echo "Commit Message Irregular,Please check!\n"
    exit 1
fi

if [ ${#COMMIT_MSG} -lt 15 ]; then
    echo "Commit Message Too Short,Please show me more detail!\n"
    exit 1
fi

配置Hooks

git hooks已经写好了,我们开始配置。

首先进入你的项目,找到.git/hooks文件夹,可以看到很多*.simple结尾的文件,我们新增commit-msgpre-commit文件,或者去掉commit-msg.simplepre-commit.simplesimple后缀。

然后,我们分别用 go pre-commit hookcommit-msg hook两部分的脚本替换pre-commitcommit-msg的内容。

最后,我们给这两个文件执行权限。

chmod +x commit-msg pre-commit

之后我们就可以正常使用了。

一键安装

用Mac电脑的童鞋,可以在需要支持的项目下面,一键安装。

curl -kSL https://raw.githubusercontent.com/razeencheng/git-hooks/master/install.sh | sh