Warnung
Nilaway befindet sich derzeit in aktiver Entwicklung: Fehlalarme und Bruchänderungen können stattfinden. Wir freuen uns sehr über Feedback und Beiträge!
Nilaway ist ein statisches Analyse -Tool, mit dem Entwicklern die Produktion von NIL -Panik vermieden werden soll, indem sie sie eher zur Kompilierzeit als zur Laufzeit fangen. Nilaway ähnelt dem Standard -Nilness -Analysator, es wird jedoch viel anspruchsvollere und leistungsstarke statische Analysetechniken verwendet, um Null -Flows innerhalb eines Pakets über Pakete hinweg zu verfolgen, und Fehler berichten, die den Benutzern die Nilness -Ströme für einfacheres Debuggen liefern.
Nilaway genießt drei wichtige Eigenschaften, die es hervorheben:
Es ist vollautomatisch : Nilaway ist mit einer Inferenzmotor ausgestattet, sodass es keine zusätzlichen Informationen von den Entwicklern (z. B. Annotationen) neben dem Standard-Go-Code erfordern.
Es ist schnell : Wir haben Nilaway so konzipiert, dass wir schnell und skalierbar sind, was es für große Codebasen geeignet ist. In unseren Messungen haben wir bei Aktivierung von Nilaway weniger als 5% Build-Time-Overhead beobachtet. Wir wenden auch ständig Optimierungen an, um den Fußabdruck weiter zu verringern.
Es ist praktisch : Es verhindert nicht alle möglichen NIL-Paniken in Ihrem Code, aber es fängt die meisten potenziellen NIL-Paniken auf, die wir in der Produktion beobachtet haben, und ermöglicht es Nilaway, ein gutes Gleichgewicht zwischen Nützlichkeit und Zeit für die Bauzeit aufrechtzuerhalten.
? Weitere detailliertere technische Diskussionen finden Sie in unserem Wiki, unserem Ingenieurblog und Papier (WIP).
Nilaway wird mithilfe der Standard-GO/-analyse implementiert, die es einfach macht, in vorhandene Analysator-Treiber (dh, Golangci-Lint, Nogo oder als eigenständige Überprüfung) zu integrieren.
Wichtig
Standardmäßig analysiert Nilaway alle GO -Code, einschließlich der Standardbibliotheken und Abhängigkeiten. Dies hilft Nilaway, die Abhängigkeiten der Codeform besser zu verstehen und seine falsch negativen Negative zu verringern. Dies würde jedoch auch zu erheblichen Leistungskosten (nur einmal für Fahrer mit modularer Unterstützung) und die Anzahl der nicht verwirkten Fehler in Abhängigkeiten erhöhen, für große GO-Projekte mit vielen Abhängigkeiten.
Wir empfehlen dringend, das inclupt-PKGS-Flag zu verwenden, um die Analyse ausschließlich in den Code Ihres Projekts einzugrenzen. Dies weist Nilaway an, die Analyse von Abhängigkeiten (z. B. Bibliotheken von Drittanbietern) zu überspringen, sodass Sie sich ausschließlich auf potenzielle NIL-Panik konzentrieren können, die Nilaway in Ihrem First-Party-Code gemeldet haben!
Wichtig
Aufgrund der Raffinesse der Analysen, die Nilaway durchführt, rückt Nilaway seine Ergebnisse über ein bestimmtes Paket über den Tatsachenmechanismus aus dem GO/Analyse -Framework aus. Daher wird dringend empfohlen, einen Treiber zu nutzen, der die modulare Analyse (dh Bazel/Nogo oder Golangci-Lint, nicht den eigenständigen Checker, unterstützt, da es alle Fakten im Speicher speichert) für eine bessere Leistung bei großen Projekten. Der eigenständige Checker wird mehr für Bewertungszwecke bereitgestellt, da es einfach ist, loszulegen.
Installieren Sie die Binärdehnung aus der Quelle durch Ausführen:
go install go.uber.org/nilaway/cmd/nilaway@latestFühren Sie dann den Linter mit: Führen Sie mit:
nilaway -include-pkgs= " <YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2> " ./...Tipp
Deaktivieren Sie die Flagge pretty-print wenn Sie als JSON ausgeben:
nilaway -json -pretty-print=false -include-pkgs= " <YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2> " ./...Nilaway kann in seiner aktuellen Form falsch positive Ergebnisse melden. Dies behindert leider die sofortige Verschmelzung in Golangci-Lint und wird als Linter angeboten (siehe PR#4045). Daher müssen Sie Nilaway als Plugin für Golangci-Lint bauen, um als privater Linter ausgeführt zu werden. Es gibt zwei Plugin-Systeme in Golangci-Lint, und es ist viel einfacher, das Modul-Plugin-System (seit V1.57.0 eingeführt) zu verwenden, und es ist der einzige unterstützte Ansatz, um Nilaway in Golangci-Lint zu betreiben.
(1) Erstellen Sie eine .custom-gcl.yml Datei am Stamm des Repositorys Wenn Sie dies nicht getan haben, fügen Sie den folgenden Inhalt hinzu:
# 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) Nilaway in die Linter -Konfigurationsdatei .golangci.yaml :
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) Erstellen Sie einen benutzerdefinierten Golangci-Lint-Binärer mit inklusiven Nilaway:
# Note that your `golangci-lint` to bootstrap the custom binary must also be version >= v1.57.0.
$ golangci-lint custom Standardmäßig wird die benutzerdefinierte Binärdatei aufgebaut . Mit dem Namen custom-gcl , der in .custom-gcl.yml Datei weiter angepasst werden kann (Anweisungen finden Sie unter Modul-Plugin-System).
Tipp
Cache Die benutzerdefinierte Binärdatei, um zu vermeiden .custom-gcl.yml dass es erneut erstellt wird, um Ressourcen zu sparen. Wenn Sie latest als Nilaway -Version verwenden, können Sie das Erstellungsdatum an den Cache -Schlüssel anhängen, um den Ablauf des Cache nach einem bestimmten Zeitraum zu erzwingen.
(4) Führen Sie den benutzerdefinierten Binäranstelle von golangci-lint aus:
# Arguments are the same as `golangci-lint`.
$ ./custom-gcl run ./...Das Laufen mit Bazel/Nogo erfordert etwas mehr Anstrengungen. Befolgen Sie zunächst die Anweisungen von Rules_GO, Gazelle und Nogo, um Ihr GO -Projekt so einzurichten, dass es mit Bazel/Nogo ohne oder Standard -Linter konfiguriert werden kann. Dann,
(1) import _ "go.uber.org/nilaway" zu Ihrer tools.go -Datei (oder einer anderen Datei, die Sie zum Konfigurieren von Toolabhängigkeiten verwenden, sehen Sie, wie ich Toolabhängigkeiten für ein Modul aus der Dokumentation von Go -Modulen verfolgen kann), um go mod tidy aus der Entfernung von Nilaway als Toolabhängigkeit zu vermeiden.
(2) Führen Sie die folgenden Befehle aus, um Nilaway als Werkzeugabhängigkeit zu Ihrem Projekt hinzuzufügen:
# 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 zu Nogo-Konfigurationen (normalerweise in BUILD.bazel -Datei auf oberster Ebene) hinzufügen:
nogo(
name = "my_nogo",
visibility = ["//visibility:public"], # must have public visibility
deps = [
+++ "@org_uber_go_nilaway//:go_default_library",
],
config = "config.json",
) (4) Run Bazel Build, um zu sehen --keep_going dass Nilaway funktioniert (jeder Nogo -Fehler stoppt den Basel -Build.
$ bazel build --keep_going //...(5) Siehe NOGO -Dokumentation zum Übergeben einer Konfiguration JSON an den Nogo -Treiber und finden Sie unsere Wiki -Seite, wie Sie Konfigurationen an Nilaway übergeben.
Schauen wir uns einige Beispiele an, um zu sehen, wie Nilaway dazu beitragen kann, NIL -Panik zu verhindern.
// Example 1:
var p * P
if someCondition {
p = & P {}
}
print ( p . f ) // nilness reports NO error here, but NilAway does. In diesem Beispiel wird die lokale Variable p nur initialisiert, wenn someCondition wahr ist. Bei der Field Access pf kann eine Panik auftreten, wenn someCondition falsch ist. Nilaway ist in der Lage, diesen potenziellen NIL -Fluss zu fangen und meldet den folgenden Fehler, der diesen Nilness -Fluss zeigt:
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`
Wenn wir diese Derreferenz mit einer Nullness -Prüfung ( if p != nil ) bewachen, verschwindet der Fehler.
Nilaway kann auch Nil -Flüsse über Funktionen fangen. Betrachten Sie beispielsweise den folgenden Code -Snippet:
// Example 2:
func foo () * int {
return nil
}
func bar () {
print ( * foo ()) // nilness reports NO error here, but NilAway does.
} In diesem Beispiel gibt die Funktion foo einen Null -Zeiger zurück, der direkt in bar abgeleitet ist, was zu einer Panik führt, wenn bar aufgerufen wird. Nilaway ist in der Lage, diesen potenziellen NIL -Fluss zu fangen und meldet den folgenden Fehler, wobei der Nilness -Fluss über Funktionsgrenzen hinweg beschreibt:
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
Beachten Sie, dass foo im obigen Beispiel nicht unbedingt im gleichen Paket wie bar liegen muss. Nilaway kann auch Nil -Flüsse über Pakete verfolgen. Darüber hinaus verarbeitet Nilaway GO-spezifische Sprachkonstrukte wie Empfänger, Schnittstellen, Typbehauptungen, Typschalter und mehr.
Wir enthüllen eine Reihe von Flags über den Standard -Flag -Passing -Mechanismus in GO/Analyse. Bitte überprüfen Sie die Wiki/-konfiguration, um die verfügbaren Flags anzuzeigen und wie Sie sie mit verschiedenen Lintertreibern übergeben.
Wir folgen der gleichen Versionsunterstützungsrichtlinie wie The Go Project: Wir unterstützen und testen die letzten beiden Hauptversionen von Go.
Bitte öffnen Sie ein Github -Problem, wenn Sie Fragen, Fehlerberichte und Feature -Anfragen haben.
Wir würden uns freuen, wenn Sie zu Nilaway beitragen! Bitte beachten Sie, dass Sie nach dem Erstellen einer Pull -Anfrage aufgefordert werden, unsere UBER -Mitwirkungslizenzvereinbarung zu unterschreiben.
Dieses Projekt ist Copyright 2023 Uber Technologies, Inc. und unter Apache 2.0 lizenziert.