Avertissement
Nilaway est actuellement en cours de développement actif: les faux positifs et les changements de rupture peuvent se produire. Nous apprécions fortement les commentaires et les contributions!
Nilaway est un outil d'analyse statique qui cherche à aider les développeurs à éviter les paniques nulles en production en les attrapant au moment de la compilation plutôt que du temps d'exécution. Nilaway est similaire à l'analyseur Nilness standard, cependant, il utilise des techniques d'analyse statique beaucoup plus sophistiquées et puissantes pour suivre les flux nuls dans un package ainsi que des packages, et signaler les erreurs fournissant aux utilisateurs les flux Nilness pour un débogage plus facile.
Nilaway bénéficie de trois propriétés clés qui le font ressortir:
Il est entièrement automatisé : Nilaway est équipé d'un moteur d'inférence, ce qui ne nécessite aucune information supplémentaire des développeurs (par exemple, annotations) en plus du code GO standard.
C'est rapide : nous avons conçu Nilaway pour être rapide et évolutif, ce qui le rend adapté aux grandes bases de code. Dans nos mesures, nous avons observé moins de 5% des frais généraux de construction lorsque Nilaway est activé. Nous appliquons également constamment des optimisations pour réduire davantage son empreinte.
Il est pratique : il n'empêche pas toutes les paniques nulles possibles dans votre code, mais il attrape la plupart des paniques nulles potentielles que nous avons observées en production, permettant à Nilaway de maintenir un bon équilibre entre l'utilité et les frais généraux du temps de construction.
? Pour une discussion technique plus détaillée, veuillez consulter notre wiki, notre blog d'ingénierie et le papier (WIP).
Nilaway est implémenté à l'aide de la standard GO / Analysis, ce qui facilite l'intégration avec les pilotes d'analyseur existants (c'est-à-dire Golangci-lint, NOGO ou exécutant en tant que vérificateur autonome).
Important
Par défaut, NilAway analyse tous le code GO, y compris les bibliothèques et les dépendances standard. Cela aide Nilaway à mieux comprendre les dépendances du formulaire de code et réduire ses faux négatifs. Cependant, cela entraînerait également un coût de performance significatif (une seule fois pour les conducteurs avec un support modulaire) et augmenterait le nombre d'erreurs non ragenables dans les dépendances, pour les projets GO à grande partie avec de nombreuses dépendances.
Nous vous recommandons fortement d'utiliser le drapeau include-PKGS pour affiner l'analyse au code de votre projet exclusivement. Cela ordonne à Nilaway de sauter des dépendances analysant (par exemple, bibliothèques tierces), vous permettant de vous concentrer uniquement sur les paniques potentielles nuls par Nilaway dans votre code de premier parti!
Important
En raison de la sophistication des analyses que fait Nilaway, Nilaway cache ses résultats sur un ensemble particulier via le mécanisme de faits du cadre GO / Analyse. Par conséquent, il est fortement recommandé de tirer parti d'un pilote qui prend en charge l'analyse modulaire (c'est-à-dire Bazel / Nogo ou Golangci-lint, mais pas le vérificateur autonome car il stocke tous les faits en mémoire) pour de meilleures performances sur les grands projets. Le vérificateur autonome est davantage fourni à des fins d'évaluation car il est facile de commencer.
Installez le binaire à partir de la source en fonctionnant:
go install go.uber.org/nilaway/cmd/nilaway@latestEnsuite, exécutez le linter par:
nilaway -include-pkgs= " <YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2> " ./...Conseil
Désactivez l'indicateur pretty-print lors de la sortie comme JSON:
nilaway -json -pretty-print=false -include-pkgs= " <YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2> " ./...Nilaway, dans sa forme actuelle, peut signaler les faux positifs. Cela entrave malheureusement sa fusion immédiate dans Golangci-lint et sera offerte comme linter (voir PR # 4045). Par conséquent, vous devez construire Nilaway en tant que plugin de Golangci-lint pour être exécuté en tant que linter privé. Il existe deux systèmes de plugin dans Golangci-lint, et il est beaucoup plus facile d'utiliser le système de plugin de module (introduit depuis V1.57.0), et c'est la seule approche prise en charge pour exécuter Nilaway à Golangci-lint.
(1) Créez un fichier .custom-gcl.yml à la racine du référentiel Si vous ne l'avez pas fait, ajoutez le contenu suivant:
# 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) Ajouter Nilaway au fichier de configuration de Linter .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) Construire un binaire Golangci-lint personnalisé avec Nilaway inclus:
# Note that your `golangci-lint` to bootstrap the custom binary must also be version >= v1.57.0.
$ golangci-lint custom Par défaut, le binaire personnalisé sera construit à . avec le nom custom-gcl , qui peut être personnalisé dans le fichier .custom-gcl.yml (voir le système de plugin du module pour les instructions).
Conseil
Cachez le binaire personnalisé pour éviter d'avoir à le construire à nouveau pour enregistrer les ressources, vous pouvez utiliser le hachage du fichier .custom-gcl.yml comme clé de cache si vous utilisez une version fixe de Nilaway. Si vous utilisez latest version de Nilaway, vous pouvez ajouter la date de construction à la clé de cache pour forcer l'expiration du cache après une certaine période de temps.
(4) Exécutez le binaire personnalisé au lieu de golangci-lint :
# Arguments are the same as `golangci-lint`.
$ ./custom-gcl run ./...Courir avec Bazel / Nogo nécessite un peu plus d'efforts. Suivez d'abord les instructions de Rule_Go, Gazelle et Nogo pour configurer votre projet GO de sorte qu'il peut être construit avec Bazel / Nogo avec un ensemble de liners non par défaut configurés. Alors,
(1) Ajouter import _ "go.uber.org/nilaway" dans votre fichier tools.go (ou tout autre fichier que vous utilisez pour configurer les dépendances d'outils, voir comment puis-je suivre les dépendances d'outils pour un module? Depuis la documentation des modules GO) pour éviter go mod tidy de supprimer Nilaway en tant que dépendance de l'outil.
(2) Exécutez les commandes suivantes pour ajouter Nilaway comme dépendance à votre projet:
# 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) Ajouter Nilaway aux configurations NOGO (généralement dans le fichier BUILD.bazel de niveau supérieur):
nogo(
name = "my_nogo",
visibility = ["//visibility:public"], # must have public visibility
deps = [
+++ "@org_uber_go_nilaway//:go_default_library",
],
config = "config.json",
) (4) Exécutez Bazel Build pour voir NilaWay fonctionner (toute erreur NOGO arrêtera la construction du bazel, vous pouvez utiliser le drapeau --keep_going pour demander à Bazel de construire autant que possible):
$ bazel build --keep_going //...(5) Voir la documentation NOGO sur la façon de passer une configuration JSON au pilote NOGO et voir notre page Wiki sur la façon de passer les configurations à Nilaway.
Examinons quelques exemples pour voir comment Nilaway peut aider à prévenir les paniques nulles.
// Example 1:
var p * P
if someCondition {
p = & P {}
}
print ( p . f ) // nilness reports NO error here, but NilAway does. Dans cet exemple, la variable locale p n'est initialisée que lorsque someCondition est vraie. À l'accès sur le terrain pf , une panique peut se produire si someCondition est fausse. Nilaway est capable de capter ce flux potentiel et de rapporter l'erreur suivante montrant ce flux nulle:
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`
Si nous gardons cette déréférence avec une vérification Nilness ( if p != nil ), l'erreur disparaît.
Nilaway est également capable d'attraper des flux nul à travers les fonctions. Par exemple, considérez l'extrait de code suivant:
// Example 2:
func foo () * int {
return nil
}
func bar () {
print ( * foo ()) // nilness reports NO error here, but NilAway does.
} Dans cet exemple, la fonction foo renvoie un pointeur nil, qui est directement déréféré dans bar , ce qui entraîne une panique chaque fois que bar est appelée. Nilaway est capable d'attraper ce flux potentiel et de rapporter l'erreur suivante, décrivant le flux de la Nilness à travers les limites de la fonction:
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
Notez que dans l'exemple ci-dessus, foo n'a pas nécessairement à résider dans le même package que bar . Nilaway est également capable de suivre les flux nuls sur les packages. De plus, NilaWay gère les constructions de langage spécifiques à GO telles que les récepteurs, les interfaces, les assertions de type, les commutateurs de type, etc.
Nous exposons un ensemble de drapeaux via le mécanisme de passage du drapeau standard dans GO / analyse. Veuillez vérifier le wiki / la configuration pour voir les indicateurs disponibles et comment les passer à l'aide de différents pilotes Linter.
Nous suivons la même politique de support de version que le projet GO: nous soutenons et testons les deux dernières versions principales de GO.
N'hésitez pas à ouvrir un problème GitHub si vous avez des questions, des rapports de bogues et des demandes de fonctionnalités.
Nous aimerions que vous contribuez à Nilaway! Veuillez noter qu'une fois que vous aurez créé une demande de traction, il vous sera demandé de signer notre accord de licence de contributeur Uber.
Ce projet est Copyright 2023 Uber Technologies, Inc., et sous licence sous Apache 2.0.