golangci-lint应用

golangci-lint 是什么?

golangci-lint 是一个 Go linters 聚合器,而 linter 是使用工具来对代码提供一些检查,保证提交代码的质量。

为什么不直接使用 golangci-lint ?

需要手动执行,在之前使用的过程中,由于项目是多人活动,总是会忘记执行golangci-lint 进行代码检查,当前我自己也是。所以我们希望采用一种隐式的方式来自动执行。那么经过多番思考,采用 git 的 hooks 可以来自动执行一些脚本。

这期间还有一些其他的尝试,不过这个文章主要说 在git中的使用ci-lint,有兴趣的可以移步到为什么最终采用git 本地 hooks 的方式执行golangci-lint?

采用 git 的 hooks 来自动执行检查!

前提条件

请设置 goland 的默认终端为 bash,不然后面执行脚本的时候,可能会不支持。

golangci-lint应用

由于现在采用 git 作为我们的版本管理系统(VCS),而git在执行一些操作之前,允许执行脚本,这就可以让我们来执行一些操作前的代码检查。

项目代码目录:

├── .githooks│   ├── applypatch-msg.sample│   ├── commit-msg.sample│   ├── fsmonitor-watchman.sample│   ├── post-update.sample│   ├── pre-applypatch.sample│   ├── pre-commit│   ├── pre-merge-commit.sample│   ├── pre-push│   ├── pre-rebase.sample│   ├── pre-receive.sample│   ├── prepare-commit-msg.sample│   ├── push-to-checkout.sample│   └── update.sample├── .golangci.yml├── go.mod├── golangci-lint.sh└── init.sh

登录后复制

可以通过项目结构看到,需要在项目根目录增加一个 .githooks 文件夹,

然后增加 .golangci.yml golangci-lint 使用的配置文件,

增加一个 手动执行goalngci-lint的执行脚本golangci-lint.sh,

最后就是项目应用 git hooks 的脚本init.sh,用于初始化这个项目的脚本。

说了这么多,还不知道这个到底是干啥的,先来看一下效果图

在commit的时候会帮助我们进行文件的 fmt:

golangci-lint应用

在push的时候会检查整个项目是否存在有问题的地方:

golangci-lint应用

如果项目存在可能的问题,那么是不会让你 push 的。通过这种方式来保证服务器上的代码都是符合规则的。

使用方式:

1. 项目中已经存在这些内容

首次通过执行 init.sh 脚本进行项目初始化设置。

golangci-lint应用

这会检查你的环境,如果一些工具不存在,它会自动下载。并会修改默认 git 钩子指向当前项目的 .githooks 文件夹。

好了,就这样,就是这么简单。

2. 新建项目这个怎么搞

这都是小问题,复制内容过去吧。

但是在复制这些之前,你一定已经是在一个git 管理的根目录下。

那么下面就开始你的复制吧。

.githooks/pre-commit:

#!/bin/sh## An example hook script to verify what is about to be committed.# Called by "git commit" with no arguments.  The hook should# exit with non-zero status after issuing an appropriate message if# it wants to stop the commit.## To enable this hook, rename this file to "pre-commit".# 获取所有变化的go文件STAGED_GO_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep .go$)if [ "$STAGED_GO_FILES" = "" ]; then    exit 0fiecho "check gofmt ..."CHECK_FMT=$(gofmt -s -w -l $STAGED_GO_FILES)if [ -n "${CHECK_FMT##* }" ]; then    echo    echo -e "these files will be[32m gofmt[0m formatted:"    for file in ${CHECK_FMT[*]}; do        echo -e "[36m$file[0m"    done    git add ${CHECK_FMT///n/ }    echofiecho "check goimports ..."CHECK_GOPLS=$(goimports -l -w $STAGED_GO_FILES)if [ -n "${CHECK_GOPLS##* }" ]; then    echo    echo -e "these files will be[32m goimports[0m formatted:"    for file in ${CHECK_GOPLS[*]}; do        echo -e "[36m$file[0m"    done    git add ${CHECK_GOPLS///n/ }    echofiprintf "[32m COMMIT SUCCEEDED [0m"echoexit 0

登录后复制

.githooks/pre-push:

#!/bin/sh# An example hook script to verify what is about to be pushed.  Called by "git# push" after it has checked the remote status, but before anything has been# pushed.  If this script exits with a non-zero status nothing will be pushed.## This hook is called with the following parameters:## $1 -- Name of the remote to which the push is being done# $2 -- URL to which the push is being done## If pushing without using a named remote those arguments will be equal.## Information about the commits which are being pushed is supplied as lines to# the standard input in the form:##      ## This sample shows how to prevent push of commits where the log message starts# with "WIP" (work in progress).#remote="$1"#url="$2"printf "[32m 推送前需要检查当前项目可以 go build 通过 [0m"echo "run golangci-lint..."echo# 运行 golangci-lint 检查工具golangci-lint run ./...if [ $? -ne 0 ]; then    printf "[31m PUSH FAILED [0m"    exit 1fiprintf "[32m PUSH SUCCEEDED [0m"echoexit 0

登录后复制

golangci-lint.sh

#!/bin/shif ! command -v golangci-lint &>/dev/null; then    echo "golangci-lint not installed or available in the PATH" >&2    echo "install golangci-lint ..." >&2    go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.50.1fi#goland 可直接定位文件golangci-lint run ./... |sed 's/\///g'

登录后复制

init.sh

#!/bin/sh# 检查 go 是否安装checkGoEnv() {    # go是否安装    if ! command -v go &>/dev/null; then        echo "go not installed or available in the PATH" >&2        echo "please check https://golang.google.cn" >&2        exit 1    fi    # go proxy 是否设置    if [ -z $GOPROXY ]; then        echo "go proxy not set in the PATH" >&2        echo "please set GOPROXY, https://goproxy.cn,direct || https://goproxy.io,direct" >&2        exit 1    fi    echo "go env installed ..."}# 检查 go 相关工具包是否安装checkGoLintEnv() {    if ! command -v goimports &>/dev/null; then        echo "goimports not installed or available in the PATH" >&2        echo "install goimports ..." >&2        go install golang.org/x/tools/cmd/goimports@latest        checkGoLintEnv        return    fi    echo "goimports installed ..."}# 检查 golangci-lint 是否安装checkCiLintEnv() {    if ! command -v golangci-lint &>/dev/null; then        echo "golangci-lint not installed or available in the PATH" >&2        echo "install golangci-lint ..." >&2        go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.50.1        checkCiLintEnv    fi    echo "golangci-lint installed ..."}# 初始化钩子配置initHooks() {    # 如果当前目录不存在 .githooks 目录,说明位置不对    if [ ! -d ".githooks" ]; then        echo "exec incorrect position"        exit 1    fi    # 检查是否已经设置了    exist=$(git config core.hooksPath)    if [ -z $exist ]; then        # 设置 hooks 默认位置        git config core.hooksPath .githooks        echo "init git hooks ..." >&2    fi}main() {    checkGoEnv    checkGoLintEnv    checkCiLintEnv    initHooks}main

登录后复制

.golangci.yml

run:  timeout: 2m  tests: falselinters:  disable-all: true  enable:    - typecheck    - staticcheck    - govet    - gocriticlinters-settings:  govet:    check-shadowing: true    disable-all: true    enable:      - asmdecl      - assign      - atomic      - atomicalign      - bools      - buildtag      - cgocall      - composites      - copylocks      - httpresponse      - loopclosure      - lostcancel      - nilfunc      - nilness      - printf      - shadow      - shift      - stdmethods      - structtag      - tests      - unmarshal      - unreachable      - unsafeptr      - unusedresult  staticcheck:    go: "1.17"    checks: [ "all", "-SA3*", "-SA6000", "-SA6001", "-SA6003", "-ST*", "ST1006", "ST1008", "ST1016", "-QF1" ]  gocritic:    enabled-tags:      - diagnostic      - experimental      - opinionated      - style    enabled-checks:      - sliceClear    disabled-tags:      - performance    disabled-checks:      - assignOp      - badLock      - badRegexp      - codegenComment      - commentFormatting      - commentedOutCode      - docStub      - dupArg      - dupBranchBody      - dupCase      - dupImport      - exitAfterDefer      - externalErrorReassign      - flagDeref      - hexLiteral      - ifElseChain      - importShadow      - initClause      - mapKey      - nestingReduce      - newDeref      - redundantSprint      - regexpMust      - regexpPattern      - regexpSimplify      - ruleguard      - sloppyLen      - sloppyTypeAssert      - sortSlice      - sprintfQuotedString      - sqlQuery      - stringConcatSimplify      - syncMapLoadAndDelete      - tooManyResultsChecker      - typeDefFirst      - typeUnparen      - underef      - unlabelStmt      - unlambda      - unnecessaryBlock      - unnecessaryDefer      - yodaStyleExpr      - whyNoLint      - paramTypeCombine      - emptyStringTest

登录后复制

好了,现在你应该是这样的结构了吧

项目代码目录:

├── .githooks│   ├── pre-commit│   └── pre-push├── .golangci.yml├── golangci-lint.sh└── init.sh

登录后复制

如果不是,请返回到上面在看一下步骤。

这个时候可以执行 init.sh 脚本来初始化了。

最后可以在 https://github.com/ywanbing/golangci仓库中获取代码。

以上就是golangci-lint应用的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2373347.html

(0)
上一篇 2025年3月2日 01:09:44
下一篇 2025年3月2日 01:09:58

AD推荐 黄金广告位招租... 更多推荐

相关推荐

发表回复

登录后才能评论