>  기사  >  백엔드 개발  >  golangci-lint 애플리케이션

golangci-lint 애플리케이션

Golang菜鸟
Golang菜鸟앞으로
2023-08-04 17:03:361402검색

golangci-lint란 무엇인가요?

golangci-lint 는 Go 린터 수집기이고 linter는 제출된 코드의 품질을 보장하기 위해 도구를 사용하여 코드에 대한 몇 가지 검사를 제공합니다. 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

golangci-lint를 직접 사용하면 어떨까요?🎜🎜수동으로 실행해야 하는데, 이전 사용 과정에서 프로젝트가 여러 사람이 함께 하는 활동이기 때문에 항상 실행을 잊어버립니다.golangci-lint 코드 검사용, 현재 나 자신. 그래서 우리는 그것을 자동으로 실행하기 위해 암시적인 방법을 사용하고 싶습니다. 그래서 많은 생각 끝에 git Hooks를 사용하여 일부 스크립트를 자동으로 실행할 수 있습니다. 🎜🎜이 기간 동안 다른 시도도 있었지만 이 기사에서는 주로 git에서 ci-lint 사용에 대해 설명합니다. 관심 있는 분들은 마침내 golangci를 실행하는 데 git 로컬 후크가 사용되는 이유를 살펴보겠습니다. 보푸라기? 🎜🎜🎜🎜git Hooks를 사용하여 자동으로 검사를 수행하세요! 🎜🎜전제 조건: 🎜🎜goland의 기본 터미널을 bash, 그렇지 않으면 나중에 스크립트 실행 시 지원되지 않을 수 있습니다. 🎜
🎜이제 버전 관리 시스템(VCS)으로 git을 사용하기 때문에 ), git 일부 작업을 수행하기 전에 스크립트 실행을 허용하므로 일부 작업 전에 코드 검사를 수행할 수 있습니다. 🎜🎜프로젝트 코드 디렉토리: 🎜<pre class="brush:php;toolbar:false;">├── .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</pre><ol class="list-paddingleft-1" data-tool="mdnice编辑器" style="margin-top: 8px;margin-bottom: 8px;padding-left: 25px;"><li><section style="margin-top: 5px;margin-bottom: 5px;line-height: 26px;color: rgb(1, 1, 1);"><p style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;color: black;">는 프로젝트 구조를 통해 확인할 수 있습니다. 프로젝트 루트 디렉터리 -right: 2px;margin-left: 2px;color: rgb(30, 107, 184); background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">.githooks</p></section></li></ol> 폴더, .githooks 文件夹,
  • 然后增加 .golangci.yml golangci-lint 使用的配置文件,

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

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

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

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

    golangci-lint 애플리케이션

    push

    🎜🎜를 추가한 다음 .golangci.yml golangci-에서 사용하는 구성 파일 lint, 🎜🎜🎜🎜수동 실행 추가goalngci-lint 실행 스크립트golangci-lint.sh, 🎜🎜🎜🎜마지막은 프로젝트 애플리케이션입니다git 후크 scriptinit.sh, 이 프로젝트 스크립트를 초기화하는 데 사용됩니다. 🎜<p data-tool="mdnice editor" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">그렇습니다. 아직 이게 무슨 용도인지는 모르겠습니다. 먼저 렌더링을 살펴보겠습니다🎜</p> <p data-tool="mdnice editor" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px ;"><code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb( 30, 107, 184);배경색: rgba(27, 31, 35, 0.05);글꼴 계열: " operator mono consolas monaco menlo monospace break-all>커밋 fmt:🎜
    golangci-lint 애플리케이션

    In푸시하면 전체 프로젝트에 문제가 있는지 확인됩니다. 🎜

    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 0
    fi
    
    echo "check gofmt ..."
    CHECK_FMT=$(gofmt -s -w -l $STAGED_GO_FILES)
    if [ -n "${CHECK_FMT##* }" ]; then
        echo
        echo -e "these files will be\033[32m gofmt\033[0m formatted:"
        for file in ${CHECK_FMT[*]}; do
            echo -e "\033[36m\t$file\033[0m"
        done
        git add ${CHECK_FMT//\/n/ }
        echo
    fi
    
    echo "check goimports ..."
    CHECK_GOPLS=$(goimports -l -w $STAGED_GO_FILES)
    if [ -n "${CHECK_GOPLS##* }" ]; then
        echo
        echo -e "these files will be\033[32m goimports\033[0m formatted:"
        for file in ${CHECK_GOPLS[*]}; do
            echo -e "\033[36m\t$file\033[0m"
        done
        git add ${CHECK_GOPLS//\/n/ }
        echo
    fi
    
    printf "\033[32m COMMIT SUCCEEDED \033[0m\n"
    echo
    
    exit 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:
    #
    #   <local ref> <local oid> <remote ref> <remote oid>
    #
    # This sample shows how to prevent push of commits where the log message starts
    # with "WIP" (work in progress).
    
    #remote="$1"
    #url="$2"
    printf "\033[32m 推送前需要检查当前项目可以 go build 通过 \033[0m\n"
    
    echo "run golangci-lint..."
    echo
    
    # 运行 golangci-lint 检查工具
    golangci-lint run ./...
    if [ $? -ne 0 ]; then
        printf "\033[31m PUSH FAILED \033[0m\n"
        exit 1
    fi
    
    printf "\033[32m PUSH SUCCEEDED \033[0m\n"
    echo
    
    exit 0

    golangci-lint.sh

    #!/bin/sh
    
    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
    fi
    
    #goland 可直接定位文件
    golangci-lint run ./... |sed &#39;s/\\/\//g&#39;

    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: false
    
    linters:
      disable-all: true
      enable:
        - typecheck
        - staticcheck
        - govet
        - gocritic
    
    linters-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 애플리케이션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 Golang菜鸟에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제