Peringatan
Nilaway saat ini sedang dalam pengembangan aktif: positif palsu dan perubahan perubahan dapat terjadi. Kami sangat menghargai umpan balik dan kontribusi apa pun!
Nilaway adalah alat analisis statis yang berupaya membantu pengembang menghindari panik NIL dalam produksi dengan menangkapnya pada waktu kompilasi daripada runtime. Nilaway mirip dengan Nilness Analyzer standar, namun, ia menggunakan teknik analisis statis yang jauh lebih canggih dan kuat untuk melacak aliran nil dalam satu paket serta paket, dan melaporkan kesalahan yang memberi pengguna aliran nilness untuk debugging yang lebih mudah.
Nilaway menikmati tiga properti utama yang membuatnya menonjol:
Ini sepenuhnya otomatis : Nilaway dilengkapi dengan mesin inferensi, membuatnya tidak memerlukan informasi tambahan dari pengembang (misalnya, anotasi) selain kode GO standar.
Ini cepat : kami telah merancang Nilaway untuk menjadi cepat dan terukur, membuatnya cocok untuk basis kode besar. Dalam pengukuran kami, kami telah mengamati overhead waktu kurang dari 5% ketika Nilaway diaktifkan. Kami juga terus -menerus menerapkan optimisasi untuk mengurangi jejaknya lebih lanjut.
Ini praktis : itu tidak mencegah semua kemungkinan panik nil dalam kode Anda, tetapi ia menangkap sebagian besar potensi panik nil yang telah kami amati dalam produksi, memungkinkan Nilaway untuk menjaga keseimbangan yang baik antara kegunaan dan overhead waktu pembangunan.
? Untuk diskusi teknis yang lebih rinci, silakan periksa wiki, blog teknik, dan kertas (WIP) kami.
Nilaway diimplementasikan menggunakan GO/analisis standar, membuatnya mudah untuk diintegrasikan dengan driver penganalisis yang ada (IE, Golangci-Lint, Nogo, atau berjalan sebagai pemeriksa mandiri).
Penting
Secara default, Nilaway menganalisis semua kode GO, termasuk pustaka standar dan dependensi. Ini membantu Nilaway lebih memahami dependensi bentuk kode dan mengurangi negatifnya yang salah. Namun, ini juga akan menimbulkan biaya kinerja yang signifikan (hanya sekali untuk pengemudi dengan dukungan modular) dan meningkatkan jumlah kesalahan yang tidak dapat diakui dalam dependensi, untuk proyek GO besar dengan banyak ketergantungan.
Kami sangat merekomendasikan menggunakan flag include-pKGS untuk mempersempit analisis ke kode proyek Anda secara eksklusif. Ini mengarahkan Nilaway untuk melewatkan menganalisis dependensi (misalnya, perpustakaan pihak ketiga), memungkinkan Anda untuk hanya fokus pada potensi panik nil yang dilaporkan oleh Nilaway dalam kode pihak pertama Anda!
Penting
Karena kecanggihan analisis yang dilakukan Nilaway, Nilaway menyimpan temuannya tentang paket tertentu melalui mekanisme fakta dari kerangka kerja GO/analisis. Oleh karena itu, sangat disarankan untuk memanfaatkan pengemudi yang mendukung analisis modular (yaitu, Bazel/Nogo atau Golangci-Lint, tetapi bukan pemeriksa mandiri karena ia menyimpan semua fakta dalam memori) untuk kinerja yang lebih baik pada proyek besar. Pemeriksa mandiri disediakan lebih banyak untuk tujuan evaluasi karena mudah untuk memulai.
Pasang biner dari sumber dengan menjalankan:
go install go.uber.org/nilaway/cmd/nilaway@latestKemudian, jalankan linter dengan:
nilaway -include-pkgs= " <YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2> " ./...Tip
Nonaktifkan bendera pretty-print saat output sebagai JSON:
nilaway -json -pretty-print=false -include-pkgs= " <YOUR_PKG_PREFIX>,<YOUR_PKG_PREFIX_2> " ./...Nilaway, dalam bentuknya saat ini, dapat melaporkan positif palsu. Sayangnya ini menghambat penggabungan langsungnya di Golangci-Lint dan ditawarkan sebagai linter (lihat PR#4045). Oleh karena itu, Anda perlu membangun Nilaway sebagai plugin ke Golangci-Lint untuk dieksekusi sebagai linter pribadi. Ada dua sistem plugin di Golangci-Lint, dan jauh lebih mudah untuk menggunakan sistem plugin modul (diperkenalkan sejak v1.57.0), dan itu adalah satu-satunya pendekatan yang didukung untuk menjalankan Nilaway di Golangci-Lint.
(1) Buat file .custom-gcl.yml di root repositori jika Anda belum melakukannya, tambahkan konten berikut:
# 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) Tambahkan Nilaway ke file konfigurasi 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) Bangun biner Golangci-Lint khusus dengan Nilaway termasuk:
# Note that your `golangci-lint` to bootstrap the custom binary must also be version >= v1.57.0.
$ golangci-lint custom Secara default, biner khusus akan dibangun di . Dengan nama custom-gcl , yang dapat disesuaikan lebih lanjut dalam file .custom-gcl.yml (lihat Sistem Plugin Modul untuk instruksi).
Tip
Cache Biner khusus untuk menghindari keharusan membangunnya lagi untuk menyimpan sumber daya, Anda dapat menggunakan hash dari file .custom-gcl.yml sebagai kunci cache jika Anda menggunakan versi tetap Nilaway. Jika Anda menggunakan versi Nilaway latest , Anda dapat menambahkan tanggal build ke kunci cache untuk memaksa cache kedaluwarsa setelah periode waktu tertentu.
(4) Jalankan biner khusus alih-alih golangci-lint :
# Arguments are the same as `golangci-lint`.
$ ./custom-gcl run ./...Berlari dengan Bazel/Nogo membutuhkan sedikit lebih banyak upaya. Pertama -tama ikuti instruksi dari Rules_go, Gazelle, dan Nogo untuk mengatur proyek GO Anda sehingga dapat dibangun dengan Bazel/Nogo tanpa atau set linter default yang dikonfigurasi. Kemudian,
(1) Tambahkan import _ "go.uber.org/nilaway" go mod tidy file tools.go Anda.
(2) Jalankan perintah berikut untuk menambahkan Nilaway sebagai ketergantungan alat pada proyek Anda:
# 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) Tambahkan Nilaway ke Konfigurasi NOGO (biasanya dalam file level 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) Jalankan Bazel Build untuk melihat Nilaway bekerja (kesalahan NOGO apa pun akan menghentikan Bazel Build, Anda dapat menggunakan bendera --keep_going untuk meminta Bazel membangun sebanyak mungkin):
$ bazel build --keep_going //...(5) Lihat dokumentasi NOGO tentang cara meneruskan konfigurasi JSON ke driver NOGO, dan lihat halaman wiki kami tentang cara meneruskan konfigurasi ke Nilaway.
Mari kita lihat beberapa contoh untuk melihat bagaimana Nilaway dapat membantu mencegah kepanikan nil.
// Example 1:
var p * P
if someCondition {
p = & P {}
}
print ( p . f ) // nilness reports NO error here, but NilAway does. Dalam contoh ini, variabel lokal p hanya diinisialisasi ketika someCondition benar. Di lapangan akses pf , kepanikan dapat terjadi jika someCondition salah. Nilaway mampu menangkap aliran nil potensial ini dan melaporkan kesalahan berikut yang menunjukkan aliran nilness ini:
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`
Jika kita menjaga dereferensi ini dengan cek nilness ( if p != nil ), kesalahan hilang.
Nilaway juga dapat menangkap aliran NIL di seluruh fungsi. Misalnya, pertimbangkan cuplikan kode berikut:
// Example 2:
func foo () * int {
return nil
}
func bar () {
print ( * foo ()) // nilness reports NO error here, but NilAway does.
} Dalam contoh ini, fungsi foo mengembalikan pointer nil, yang secara langsung terdereferping di bar , menghasilkan kepanikan kapan pun bar dipanggil. Nilaway mampu menangkap aliran NIL yang potensial ini dan melaporkan kesalahan berikut, menggambarkan aliran nilness melintasi batas fungsi:
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
Perhatikan bahwa dalam contoh di atas, foo tidak harus tinggal di paket yang sama dengan bar . Nilaway juga dapat melacak aliran nil di seluruh paket. Selain itu, Nilaway menangani konstruksi bahasa spesifik-go seperti penerima, antarmuka, jenis pernyataan, jenis sakelar, dan banyak lagi.
Kami mengekspos satu set bendera melalui mekanisme lewat bendera standar dalam GO/analisis. Silakan periksa wiki/konfigurasi untuk melihat bendera yang tersedia dan cara meneruskannya menggunakan driver linter yang berbeda.
Kami mengikuti kebijakan dukungan versi yang sama dengan proyek GO: kami mendukung dan menguji dua versi utama terakhir dari GO.
Silakan membuka masalah GitHub jika Anda memiliki pertanyaan, laporan bug, dan permintaan fitur.
Kami ingin Anda berkontribusi pada Nilaway! Harap dicatat bahwa begitu Anda membuat permintaan tarik, Anda akan diminta untuk menandatangani perjanjian lisensi kontributor Uber kami.
Proyek ini adalah Hak Cipta 2023 Uber Technologies, Inc., dan dilisensikan di bawah Apache 2.0.