ホームページ >バックエンド開発 >Golang >golangci-lint アプリケーション

golangci-lint アプリケーション

Golang菜鸟
Golang菜鸟転載
2023-08-04 17:03:361483ブラウズ

golangci-lint とは何ですか?

golangci-lint は Go linters アグリゲータですが、linter はツールを使用してコードのチェックを行い、送信されたコードの品質を保証します。

golangci-lint を直接使用しないのはなぜですか?

プロジェクトは複数人で行う活動なので、手動で実行する必要があります。 , 私はいつも実行するのを忘れますgolangci-lint コードインスペクションを実行します。現在は自分で実行しています。したがって、暗黙的な方法を使用して自動的に実行したいと考えています。そこで、よく考えた結果、git フックを使用していくつかのスクリプトを自動的に実行できます。

この期間中に他にもいくつかの試みがありましたが、この記事では主に git での ci-lint の使用について説明します。興味がある場合は、最終的に git ローカル フックを採用した理由に進むことができます。 . golangci-lint を実行しますか?

git フックを使用してチェックを自動的に実行します。

前提条件:

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
  1. はプロジェクト構造から確認できます。.githooks フォルダーをプロジェクトのルート ディレクトリ

  2. に追加する必要があります。
  3. 次に、 .golangci.yml を追加します。 golangci-lint で使用される設定ファイル

  4. 手動実行goalngci-lintgolangci-lint.sh

  5. の実行スクリプト、そして最後にプロジェクト アプリケーションgithooks のスクリプト init.sh は、このプロジェクトを初期化するために使用されるスクリプトです。

ここまで言っても、これが何のためのものなのかはまだわかりません。まずレンダリングを見てみましょう

commit で fmt:

golangci-lint アプリケーション

がファイル fmt:

###### をサポートしてくれるとき#####When###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 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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はGolang菜鸟で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。