경고
Nilaway는 현재 활발한 발전을 받고 있습니다. 잘못된 긍정적 인 긍정과 변화가 발생할 수 있습니다. 우리는 모든 피드백과 기여에 감사드립니다!
Nilaway는 개발자가 런타임이 아닌 컴파일 타임에 걸림받은 시간에 NIL 패닉을 피할 수 있도록 노력하는 정적 분석 도구입니다. Nilaway는 표준 Nilness 분석기와 유사하지만 패키지 내에서 NIL 흐름을 추적하기 위해 훨씬 더 정교하고 강력한 정적 분석 기술을 사용하여 패키지 내 에서 NIL 흐름을 추적하고 사용자에게 NILNESS 흐름을 더 쉽게 디버깅 할 수 있도록 제공하는 오류를보고합니다.
Nilaway는 세 가지 주요 속성을 즐기며 눈에 띄게합니다.
Nilaway에는 추론 엔진이 장착 되어 있어 표준 GO 코드 외에 개발자 (예 : 주석)의 추가 정보가 필요 하지 않습니다 .
빠르며 : 우리는 Nilaway를 빠르고 확장 가능하도록 설계하여 대형 코드베이스에 적합합니다. 측정에서 Nilaway가 활성화 될 때 5% 미만의 빌드 타임 오버 헤드가 관찰되었습니다. 또한 발자국을 더욱 줄이기 위해 최적화를 지속적으로 적용하고 있습니다.
실용적 입니다. 코드에서 가능한 모든 NIL 패닉을 막을 수는 없지만 생산에서 관찰 한 잠재적 인 NIL 패닉의 대부분을 포착하여 Nilaway는 유용성과 건축 시간 간접 사이의 균형을 유지할 수 있습니다.
? 보다 자세한 기술 토론은 Wiki, 엔지니어링 블로그 및 용지 (WIP)를 확인하십시오.
Nilaway는 표준 GO/분석을 사용하여 구현하여 기존 분석기 드라이버 (예 : Golangci-Lint, NOGO 또는 독립형 체커로 실행)와 쉽게 통합 할 수 있습니다.
중요한
기본적으로 Nilaway는 표준 라이브러리 및 종속성을 포함한 모든 GO 코드를 분석합니다. 이를 통해 Nilaway는 코드 양식 종속성을 더 잘 이해하고 잘못된 부정적인 것을 줄입니다. 그러나 이는 또한 많은 의존성을 가진 대규모 GO 프로젝트의 경우 상당한 성능 비용 (모듈 식 지원을받은 드라이버의 경우 한 번만)에 의존 할 수없는 오류의 수를 늘립니다.
포함 PKGS 플래그를 사용하여 프로젝트 코드의 분석을 독점적으로 좁히는 것이 좋습니다. 이를 통해 Nilaway는 의존성 분석 (예 : 타사 라이브러리)을 건너 뛰도록 지시하여 Nilaway가보고 한 잠재적 인 NIL Panics에만 초점을 맞출 수 있습니다!
중요한
Nilaway가하는 분석의 정교함으로 인해 Nilaway는 Go/Analysis Framework의 사실 메커니즘을 통해 특정 패키지에 대한 결과를 캐시합니다. 따라서 대규모 프로젝트에서 더 나은 성능을 제공하기 위해 모듈 식 분석 (예 : 바젤/NOGO 또는 GOLANGCI-LINT를 지원하지만 독립형 체커는 아닙니다 )을 지원하는 드라이버를 활용하는 것이 좋습니다 . 독립형 체커는 시작하기 쉽기 때문에 평가 목적으로 더 많이 제공됩니다.
실행하여 소스에서 바이너리를 설치하십시오.
go install go.uber.org/nilaway/cmd/nilaway@latest그런 다음 다음으로 Linter를 실행하십시오.
nilaway -include-pkgs= " <YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2> " ./...팁
JSON으로 출력 할 때 pretty-print 플래그를 비활성화하십시오.
nilaway -json -pretty-print=false -include-pkgs= " <YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2> " ./...현재 형태의 Nilaway는 잘못된 긍정을보고 할 수 있습니다. 불행히도 이것은 Golangci-Lint의 즉각적인 병합을 방해하고 Linter로 제공됩니다 (PR#4045 참조). 따라서 개인 린터로 실행하려면 Golangci-Lint의 플러그인으로 Nilaway를 빌드해야합니다. Golangci-Lint에는 두 가지 플러그인 시스템이 있으며 모듈 플러그인 시스템 (V1.57.0 이후에 도입)을 사용하는 것이 훨씬 쉽고 Golangci-Lint에서 Nilaway를 실행하는 유일한 지원 접근 방식입니다.
(1) 저장소의 루트에서 .custom-gcl.yml 파일을 만듭니다. 그렇지 않은 경우 다음 내용을 추가하십시오.
# This has to be >= v1.57.0 for module plugin system support.
version : v1.57.0
plugins :
- module : " go.uber.org/nilaway "
import : " go.uber.org/nilaway/cmd/gclplugin "
version : latest # Or a fixed version for reproducible builds. (2) Linter 구성 파일 .golangci.yaml 에 Nilaway 추가 :
linters-settings :
custom :
nilaway :
type : " module "
description : Static analysis tool to detect potential nil panics in Go code.
settings :
# Settings must be a "map from string to string" to mimic command line flags: the keys are
# flag names and the values are the values to the particular flags.
include-pkgs : " <YOUR_PACKAGE_PREFIXES> "
# NilAway can be referred to as `nilaway` just like any other golangci-lint analyzers in other
# parts of the configuration file.(3) Nilaway가 포함 된 맞춤형 Golangci-Lint Binary를 구축하십시오.
# Note that your `golangci-lint` to bootstrap the custom binary must also be version >= v1.57.0.
$ golangci-lint custom 기본적으로 사용자 정의 바이너리가 구축됩니다 . .custom-gcl.yml 파일에서 추가로 사용자 정의 할 수있는 Name custom-gcl (지침 모듈 플러그인 시스템 참조).
팁
CARCHE를 사용하여 자원을 저장하기 위해 다시 빌드하지 않아도 .custom-gcl.yml 파일의 해시를 고정 버전의 Nilaway를 사용하는 경우 캐시 키로 사용할 수 있습니다. 최신 버전으로 latest 버전을 사용하는 경우 빌드 날짜를 캐시 키로 추가하여 특정 기간 후에 캐시 만료를 강제로 추가 할 수 있습니다.
(4) golangci-lint 대신 사용자 정의 바이너리를 실행하십시오.
# Arguments are the same as `golangci-lint`.
$ ./custom-gcl run ./...Bazel/Nogo와 함께 달리면 약간 더 많은 노력이 필요합니다. 먼저 Rules_go, Gazelle 및 Nogo의 지침을 따르면 GO 프로젝트를 설정하여 Bazel/Nogo로 구성된 Linters가 구성되지 않은 세트를 구성 할 수 있습니다. 그 다음에,
(1) import _ "go.uber.org/nilaway" 를 tools.go 에 추가하십시오. GO 파일 (또는 도구 종속성 구성에 사용하는 기타 파일을 모듈에 대한 도구 go mod tidy 을 추적 할 수있는 방법을 확인하십시오.
(2) 다음 명령을 실행하여 Nilaway를 프로젝트에 도구 의존으로 추가하십시오.
# Get NilAway as a dependency, as well as getting its transitive dependencies in go.mod file.
$ go get go.uber.org/nilaway@latest
# This should not remove NilAway as a dependency in your go.mod file.
$ go mod tidy
# Run gazelle to sync dependencies from go.mod to WORKSPACE file.
$ bazel run //:gazelle -- update-repos -from_file=go.mod (3) NILAWAY에 NOGO 구성에 추가하십시오 (일반적으로 최상위 BUILD.bazel 파일) :
nogo(
name = "my_nogo",
visibility = ["//visibility:public"], # must have public visibility
deps = [
+++ "@org_uber_go_nilaway//:go_default_library",
],
config = "config.json",
) (4) Bazel 빌드를 실행하여 Nilaway가 작동하는지 확인하십시오 (Nogo 오류는 Bazel 빌드가 중지됩니다. --keep_going 플래그를 사용하여 바젤을 최대한 많이 빌드하도록 요청할 수 있습니다).
$ bazel build --keep_going //...(5) 구성 JSON을 NOGO 드라이버에 전달하는 방법에 대한 NOGO 문서를 참조하고 Nilaway에 구성을 전달하는 방법에 대한 Wiki 페이지를 참조하십시오.
Nilaway가 Nil Panics를 예방하는 데 어떻게 도움이 될 수 있는지 알아 보려면 몇 가지 예를 살펴 보겠습니다.
// Example 1:
var p * P
if someCondition {
p = & P {}
}
print ( p . f ) // nilness reports NO error here, but NilAway does. 이 예에서, 로컬 변수 p someCondition true 일 때만 초기화됩니다. 필드 액세스 pf 에서, someCondition false 인 경우 공황이 발생할 수 있습니다. Nilaway는이 잠재적 인 NIL 흐름을 포착 할 수 있으며이 Nilness 흐름을 보여주는 다음 오류를보고합니다.
go.uber.org/example.go:12:9: error: Potential nil panic detected. Observed nil flow from source to dereference point:
- go.uber.org/example.go:12:9: unassigned variable `p` accessed field `f`
우리 가이 부정을 nilness 검사 ( if p != nil )로 보호하면 오류가 사라집니다.
Nilaway는 또한 기능을 통해 NIL 흐름을 잡을 수 있습니다. 예를 들어 다음 코드 스 니펫을 고려하십시오.
// Example 2:
func foo () * int {
return nil
}
func bar () {
print ( * foo ()) // nilness reports NO error here, but NilAway does.
} 이 예에서, foo 는 FOO가 NIL 포인터를 반환하며, 이는 bar 에서 직접 불필요하여 bar 호출 될 때마다 공황이 생깁니다. Nilaway는이 잠재적 인 Nil 흐름을 포착 할 수 있으며 기능 경계를 가로 지르는 Nilness 흐름을 설명하는 다음 오류를보고합니다.
go.uber.org/example.go:23:13: error: Potential nil panic detected. Observed nil flow from source to dereference point:
- go.uber.org/example.go:20:14: literal `nil` returned from `foo()` in position 0
- go.uber.org/example.go:23:13: result 0 of `foo()` dereferenced
위의 예에서 foo 반드시 bar 와 동일한 패키지에 상주 할 필요는 없습니다. Nilaway는 패키지에서도 NIL 흐름을 추적 할 수 있습니다. 또한 Nilaway는 수신기, 인터페이스, 타입 어설 션, 유형 스위치 등과 같은 이동 관련 언어 구성을 처리합니다.
GO/분석에서 표준 플래그 전달 메커니즘을 통해 플래그 세트를 노출시킵니다. 사용 가능한 플래그와 다른 Linter 드라이버를 사용하여 전달하는 방법을 확인하려면 Wiki/Configuration을 확인하십시오.
우리는 GO 프로젝트와 동일한 버전 지원 정책을 따릅니다. 마지막 두 가지 주요 버전의 GO를 지원하고 테스트합니다.
질문, 버그 보고서 및 기능 요청이 있으면 GitHub 문제를 자유롭게 열어주십시오.
우리는 당신이 Nilaway에 기여하기를 바랍니다! 풀 요청을 작성하면 Uber 기고자 라이센스 계약에 서명하라는 요청을받습니다.
이 프로젝트는 Copyright 2023 Uber Technologies, Inc.이며 Apache 2.0에 따라 라이센스가 부여됩니다.