Halaman ini membahas tiga sistem visibilitas Bazel: visibilitas target, visibilitas transitif, dan visibilitas pemuatan.
Jenis visibilitas ini membantu developer lain membedakan antara API publik library Anda dan detail implementasinya, serta membantu menerapkan struktur seiring berkembangnya ruang kerja Anda. Anda juga dapat menggunakan visibilitas saat menghentikan penggunaan API publik untuk mengizinkan pengguna saat ini sekaligus menolak pengguna baru.
Visibilitas target
Visibilitas target mengontrol siapa yang dapat bergantung pada target Anda — yaitu, siapa yang dapat
menggunakan label target Anda di dalam atribut seperti deps. Target akan gagal
di-build selama fase analisis jika
melanggar visibilitas salah satu dependensinya.
Secara umum, target A dapat dilihat oleh target B jika berada di lokasi yang sama, atau jika A memberikan visibilitas ke lokasi B. Jika tidak ada
makro simbolis, istilah "lokasi" dapat disederhanakan
menjadi "paket" saja; lihat di bawah untuk mengetahui informasi selengkapnya tentang makro simbolis.
Visibilitas ditentukan dengan mencantumkan paket yang diizinkan. Mengizinkan paket tidak berarti subpaketnya juga diizinkan. Untuk mengetahui detail selengkapnya tentang paket dan subpaket, lihat Konsep dan terminologi.
Untuk pembuatan prototipe, Anda dapat menonaktifkan penerapan visibilitas target dengan menetapkan
flag --check_visibility=false. Hal ini tidak boleh dilakukan untuk penggunaan produksi dalam
kode yang dikirimkan.
Cara utama untuk mengontrol visibilitas adalah dengan atribut
visibility aturan.
Subbagian berikut menjelaskan format atribut, cara menerapkannya ke
berbagai jenis target, serta interaksi antara sistem visibilitas dan
makro simbolis.
Spesifikasi visibilitas
Semua target aturan memiliki atribut visibility yang menggunakan daftar label. Setiap label memiliki salah satu bentuk berikut. Kecuali untuk bentuk terakhir, ini
hanyalah placeholder sintaksis yang tidak sesuai dengan target sebenarnya.
"//visibility:public": Memberikan akses ke semua paket."//visibility:private": Tidak memberikan akses tambahan; hanya target dalam paket lokasi ini yang dapat menggunakan target ini."//foo/bar:__pkg__": Memberikan akses ke//foo/bar(tetapi bukan subpaketnya)."//foo/bar:__subpackages__": Memberikan akses ke//foo/bardan semua sub-paket langsung dan tidak langsungnya."//some_pkg:my_package_group": Memberikan akses ke semua paket yang merupakan bagian daripackage_groupyang diberikan.- Grup paket menggunakan
sintaksis yang berbeda untuk
menentukan paket. Dalam grup paket, bentuk
"//foo/bar:__pkg__"dan"//foo/bar:__subpackages__"masing-masing diganti dengan"//foo/bar"dan"//foo/bar/...". Demikian pula,"//visibility:public"dan"//visibility:private"hanyalah"public"dan"private".
- Grup paket menggunakan
sintaksis yang berbeda untuk
menentukan paket. Dalam grup paket, bentuk
Misalnya, jika //some/package:mytarget memiliki visibility yang ditetapkan ke
[":__subpackages__", "//tests:__pkg__"], maka target tersebut dapat digunakan oleh target apa pun
yang merupakan bagian dari hierarki sumber //some/package/..., serta target
yang dideklarasikan di //tests/BUILD, tetapi tidak oleh target yang ditentukan di
//tests/integration/BUILD.
Praktik terbaik: Agar beberapa target terlihat oleh kumpulan paket yang sama, gunakan package_group, bukan mengulangi daftar di atribut visibility setiap target. Hal ini meningkatkan keterbacaan dan mencegah
daftar menjadi tidak sinkron.
Praktik terbaik: Saat memberikan visibilitas ke project tim lain, pilih
__subpackages__ daripada __pkg__ untuk menghindari churn visibilitas yang tidak perlu seiring
perkembangan project tersebut dan penambahan subpaket baru.
Visibilitas target aturan
Visibilitas target aturan ditentukan dengan mengambil atribut visibility-nya
-- atau default yang sesuai jika tidak diberikan -- dan menambahkan lokasi tempat
target dideklarasikan. Untuk target yang tidak dideklarasikan dalam makro simbolis, jika
paket menentukan default_visibility,
default ini akan digunakan; untuk semua paket lainnya dan untuk target yang dideklarasikan dalam
makro simbolis, defaultnya adalah ["//visibility:private"].
# //mypkg/BUILD
package(default_visibility = ["//friend:__pkg__"])
cc_library(
name = "t1",
...
# No visibility explicitly specified.
# Effective visibility is ["//friend:__pkg__", "//mypkg:__pkg__"].
# If no default_visibility were given in package(...), the visibility would
# instead default to ["//visibility:private"], and the effective visibility
# would be ["//mypkg:__pkg__"].
)
cc_library(
name = "t2",
...
visibility = [":clients"],
# Effective visibility is ["//mypkg:clients, "//mypkg:__pkg__"], which will
# expand to ["//another_friend:__subpackages__", "//mypkg:__pkg__"].
)
cc_library(
name = "t3",
...
visibility = ["//visibility:private"],
# Effective visibility is ["//mypkg:__pkg__"]
)
package_group(
name = "clients",
packages = ["//another_friend/..."],
)
Praktik terbaik: Hindari menyetel default_visibility ke publik. Hal ini mungkin
berguna untuk pembuatan prototipe atau dalam codebase kecil, tetapi risiko membuat
target publik secara tidak sengaja meningkat seiring berkembangnya codebase. Sebaiknya
jelaskan target mana yang merupakan bagian dari antarmuka publik paket.
Visibilitas target file yang dihasilkan
Target file yang dihasilkan memiliki visibilitas yang sama dengan target aturan yang menghasilkannya.
# //mypkg/BUILD
java_binary(
name = "foo",
...
visibility = ["//friend:__pkg__"],
)
# //friend/BUILD
some_rule(
name = "bar",
deps = [
# Allowed directly by visibility of foo.
"//mypkg:foo",
# Also allowed. The java_binary's "_deploy.jar" implicit output file
# target the same visibility as the rule target itself.
"//mypkg:foo_deploy.jar",
]
...
)
Visibilitas target file sumber
Target file sumber dapat dideklarasikan secara eksplisit menggunakan
exports_files, atau dibuat secara implisit
dengan merujuk ke nama filenya dalam atribut label aturan (di luar
makro simbolis). Seperti target aturan, lokasi panggilan ke
exports_files, atau file BUILD yang merujuk ke file input, selalu
ditambahkan secara otomatis ke visibilitas file.
File yang dideklarasikan oleh exports_files dapat visibilitasnya ditetapkan oleh parameter visibility ke fungsi tersebut. Jika parameter ini tidak diberikan, visibilitasnya adalah publik.
Untuk file yang tidak muncul dalam panggilan ke exports_files, visibilitasnya
bergantung pada nilai flag
--incompatible_no_implicit_file_export:
Jika flag bernilai benar (true), visibilitasnya bersifat pribadi.
Jika tidak, perilaku lama akan berlaku: Visibilitasnya sama dengan
default_visibilityfileBUILD, atau pribadi jika visibilitas default tidak ditentukan.
Hindari mengandalkan perilaku lama. Selalu tulis deklarasi exports_files
setiap kali target file sumber memerlukan visibilitas non-pribadi.
Praktik terbaik: Jika memungkinkan, sebaiknya ekspos target aturan, bukan
file sumber. Misalnya, daripada memanggil exports_files pada file .java,
gabungkan file dalam target java_library non-pribadi. Umumnya, target aturan
hanya boleh mereferensikan file sumber secara langsung yang berada dalam paket yang sama.
Contoh
File //frobber/data/BUILD:
exports_files(["readme.txt"])
File //frobber/bin/BUILD:
cc_binary(
name = "my-program",
data = ["//frobber/data:readme.txt"],
)
Visibilitas setelan konfigurasi
Secara historis, Bazel belum menerapkan visibilitas untuk target config_setting yang direferensikan dalam kunci select(). Ada
dua flag untuk menghapus perilaku lama ini:
--incompatible_enforce_config_setting_visibilitymengaktifkan pemeriksaan visibilitas untuk target ini. Untuk membantu migrasi, opsi ini juga menyebabkanconfig_settingyang tidak menentukanvisibilitydianggap publik (terlepas daridefault_visibilitytingkat paket).--incompatible_config_setting_private_default_visibilitymenyebabkanconfig_settingyang tidak menentukanvisibilityuntuk mengikutidefault_visibilitypaket dan kembali ke visibilitas pribadi, sama seperti target aturan lainnya. Ini adalah no-op jika--incompatible_enforce_config_setting_visibilitytidak ditetapkan.
Hindari mengandalkan perilaku lama. Setiap config_setting yang dimaksudkan untuk
digunakan di luar paket saat ini harus memiliki visibility eksplisit, jika
paket belum menentukan default_visibility yang sesuai.
Visibilitas target grup paket
Target package_group tidak memiliki atribut visibility. Keduanya selalu
terlihat secara publik.
Visibilitas dependensi implisit
Beberapa aturan memiliki dependensi implisit —
dependensi yang tidak dijabarkan dalam file BUILD, tetapi melekat pada
setiap instance aturan tersebut. Misalnya, aturan cc_library mungkin membuat
dependensi implisit dari setiap target aturannya ke target yang dapat dieksekusi
yang mewakili compiler C++.
Visibilitas dependensi implisit tersebut diperiksa sehubungan dengan
paket yang berisi file .bzl tempat aturan (atau aspek) ditentukan. Dalam
contoh kita, compiler C++ dapat bersifat pribadi selama berada dalam paket
yang sama dengan definisi aturan cc_library. Sebagai pengganti, jika
dependensi implisit tidak terlihat dari definisi, dependensi tersebut akan diperiksa sehubungan
dengan target cc_library.
Jika Anda ingin membatasi penggunaan aturan untuk paket tertentu, gunakan visibilitas pemuatan.
Visibilitas dan makro simbolis
Bagian ini menjelaskan cara sistem visibilitas berinteraksi dengan makro simbolis.
Lokasi dalam makro simbolis
Detail penting dari sistem visibilitas adalah cara kami menentukan lokasi
deklarasi. Untuk target yang tidak dideklarasikan dalam makro simbolis, lokasinya
hanyalah paket tempat target berada -- paket file BUILD.
Namun, untuk target yang dibuat dalam makro simbolis, lokasinya adalah paket
yang berisi file .bzl tempat definisi makro (pernyataan
my_macro = macro(...)) muncul. Jika target dibuat di dalam
beberapa target bertingkat, definisi makro simbolis terdalamlah yang selalu
digunakan.
Sistem yang sama digunakan untuk menentukan lokasi yang akan diperiksa terhadap visibilitas dependensi tertentu. Jika target penggunaan dibuat di dalam makro, kita akan melihat definisi makro terdalam, bukan paket tempat target penggunaan berada.
Artinya, semua makro yang kodenya ditentukan dalam paket yang sama akan
otomatis menjadi "teman" satu sama lain. Setiap target yang dibuat langsung oleh makro
yang ditentukan di //lib:defs.bzl dapat dilihat dari makro lain yang ditentukan di //lib,
terlepas dari paket apa yang sebenarnya digunakan untuk membuat instance makro. Demikian pula,
mereka dapat melihat, dan dapat dilihat oleh, target yang dideklarasikan langsung di //lib/BUILD dan
makro lamanya. Sebaliknya, target yang berada dalam paket yang sama tidak
selalu dapat melihat satu sama lain jika setidaknya salah satunya dibuat oleh makro
simbolis.
Dalam fungsi implementasi makro simbolis, parameter visibility
memiliki nilai efektif atribut visibility makro setelah menambahkan
lokasi tempat makro dipanggil. Cara standar bagi makro untuk mengekspor
salah satu targetnya ke pemanggilnya adalah dengan meneruskan nilai ini ke deklarasi
target, seperti dalam some_rule(..., visibility = visibility). Target yang menghilangkan
atribut ini tidak akan terlihat oleh pemanggil makro, kecuali jika pemanggil
berada dalam paket yang sama dengan definisi makro. Perilaku ini
menyusun, dalam arti bahwa rantai panggilan bertingkat ke submakro dapat meneruskan
visibility = visibility, mengekspor ulang target yang diekspor makro dalam ke
pemanggil di setiap level, tanpa mengekspos detail implementasi
makro apa pun.
Mendelegasikan hak istimewa ke submakro
Model visibilitas memiliki fitur khusus yang memungkinkan makro mendelegasikan izinnya ke submakro. Hal ini penting untuk memfaktorkan dan menyusun makro.
Misalkan Anda memiliki makro my_macro yang membuat edge dependensi menggunakan aturan
some_library dari paket lain:
# //macro/defs.bzl
load("//lib:defs.bzl", "some_library")
def _impl(name, visibility, ...):
...
native.genrule(
name = name + "_dependency"
...
)
some_library(
name = name + "_consumer",
deps = [name + "_dependency"],
...
)
my_macro = macro(implementation = _impl, ...)
# //pkg/BUILD
load("//macro:defs.bzl", "my_macro")
my_macro(name = "foo", ...)
Target //pkg:foo_dependency tidak memiliki visibility yang ditentukan, sehingga hanya
terlihat dalam //macro, yang berfungsi dengan baik untuk target yang menggunakan. Sekarang, apa yang terjadi jika penulis //lib memfaktorkan ulang some_library untuk diimplementasikan menggunakan makro?
# //lib:defs.bzl
def _impl(name, visibility, deps, ...):
some_rule(
# Main target, exported.
name = name,
visibility = visibility,
deps = deps,
...)
some_library = macro(implementation = _impl, ...)
Dengan perubahan ini, lokasi //pkg:foo_consumer kini menjadi //lib, bukan
//macro, sehingga penggunaan //pkg:foo_dependency melanggar visibilitas
dependensi. Pembuat my_macro tidak dapat diharapkan untuk meneruskan
visibility = ["//lib"] ke deklarasi dependensi hanya untuk mengatasi
detail implementasi ini.
Oleh karena itu, jika dependensi target juga merupakan nilai atribut makro yang mendeklarasikan target, kami akan memeriksa visibilitas dependensi terhadap lokasi makro, bukan lokasi target yang menggunakan.
Dalam contoh ini, untuk memvalidasi apakah //pkg:foo_consumer dapat melihat
//pkg:foo_dependency, kita melihat bahwa //pkg:foo_dependency juga diteruskan sebagai
input ke panggilan ke some_library di dalam my_macro, dan sebagai gantinya memeriksa
visibilitas dependensi terhadap lokasi panggilan ini, //macro.
Proses ini dapat berulang secara rekursif, selama deklarasi target atau makro berada di dalam makro simbolis lain yang mengambil label dependensi di salah satu atribut berjenis labelnya.
Finalizer
Target yang dideklarasikan dalam finalizer aturan (makro simbolis dengan finalizer = True),
selain melihat target yang mengikuti aturan visibilitas makro simbolis
biasa, juga dapat melihat semua target yang terlihat oleh paket target
finalizer.
Dengan kata lain, jika Anda memigrasikan makro lama berbasis native.existing_rules() ke
finalizer, target yang dideklarasikan oleh finalizer akan tetap dapat melihat
dependensi lamanya.
Anda dapat menentukan target yang dapat diintrospeksi oleh finalizer menggunakan
native.existing_rules(), tetapi tidak dapat digunakan sebagai dependensi di bawah
sistem visibilitas. Misalnya, jika target yang ditentukan makro tidak terlihat oleh
paketnya sendiri atau definisi makro finalizer, dan tidak didelegasikan ke
finalizer, finalizer tidak dapat melihat target tersebut. Namun, perhatikan bahwa makro lama berbasis native.existing_rules() juga tidak akan dapat melihat target tersebut.
Visibilitas transitif
Visibilitas transitif adalah cara untuk membatasi siapa yang dapat bergantung pada target, termasuk jika dependensinya hanya tidak langsung. Sistem ini berlaku secara terpisah dari sistem visibilitas target biasa, sehingga error visibilitas transitif dapat terjadi meskipun setiap link dalam rantai dependensi valid. Hal ini memungkinkan penulis target untuk membagikannya dengan kumpulan target klien tepercaya sekaligus mencegah kebocoran yang tidak disengaja ke bagian build lainnya.
Visibilitas transitif dideklarasikan di tingkat paket, menggunakan parameter transitive_visibility dari fungsi [package][package]. Deklarasi ini berlaku untuk semua target dalam paket. Parameter ini
mengambil satu label package_group, yang menentukan paket yang
targetnya mungkin bergantung secara transitif pada target paket ini.
# //third_party/sensitive_dep/BUILD
package(
# This must be explicitly listed
transitive_visibility = ":sensitive_dep_users",
)
package_group(
name = "sensitive_dep_users",
packages = [
"//third_party/sensitive_dep/...", # has to include itself
"//allowed",
],
)
sh_library(
name = "sensitive_dep"
)
# //not_allowed/BUILD
sh_binary(
name = "bad",
deps = ["//third_party/sensitive_dep:sensitive_dep"]
)
Membangun //not_allowed:bad, yang bergantung pada
//third_party/sensitive_dep:sensitive_dep, tetapi bukan bagian dari
transitive_visibility, akan menghasilkan error berikut:
Transitive visibility error: //third_party/sensitive_dep:sensitive_dep is not transitively visible from ///not_allowed:bad. //"//third_party/sensitive_dep:sensitive_dep inherits a transitive_visibility declaration from its package or one of its dependencies that does not allow //not_allowed:bad.
Grup paket yang digunakan di transitive_visibility tidak boleh include grup paket
lainnya.
Perhatikan bahwa jika target memiliki dependensi transitif dengan batasan visibilitas transitif, target itu sendiri akan mewarisi batasan tersebut dan meneruskannya ke target yang bergantung padanya. Jika target memiliki beberapa dependensi transitif dengan batasan visibilitas transitif, target tersebut harus memenuhi semua batasan.
Visibilitas transitif juga berlaku untuk target yang dideklarasikan dalam makro simbolis. Namun, tidak seperti visibilitas target biasa, visibilitas ini hanya mempertimbangkan paket tempat target ini berada, bukan paket yang menentukan makro simbolis.
Visibilitas muatan
Visibilitas pemuatan mengontrol apakah file .bzl dapat dimuat dari file BUILD atau .bzl lain di luar paket saat ini.
Sama seperti visibilitas target yang melindungi kode sumber yang dienkapsulasi
oleh target, visibilitas pemuatan melindungi logika build yang dienkapsulasi oleh file
.bzl. Misalnya, penulis file BUILD mungkin ingin memfaktorkan beberapa deklarasi target
yang berulang ke dalam makro dalam file .bzl. Tanpa perlindungan
visibilitas pemuatan, mereka mungkin mendapati makro mereka digunakan kembali oleh kolaborator lain di
ruang kerja yang sama, sehingga mengubah makro akan merusak build tim lain.
Perhatikan bahwa file .bzl mungkin memiliki atau tidak memiliki target file sumber yang sesuai.
Jika demikian, tidak ada jaminan bahwa visibilitas pemuatan dan visibilitas target akan bertepatan. Artinya, file BUILD yang sama mungkin dapat memuat
file .bzl, tetapi tidak mencantumkannya dalam srcs filegroup,
atau sebaliknya. Terkadang, hal ini dapat menyebabkan masalah pada aturan yang ingin menggunakan file .bzl sebagai kode sumber, seperti untuk pembuatan dokumentasi atau pengujian.
Untuk pembuatan prototipe, Anda dapat menonaktifkan penerapan visibilitas pemuatan dengan menetapkan
--check_bzl_visibility=false. Seperti halnya --check_visibility=false, hal ini tidak boleh dilakukan untuk kode yang dikirimkan.
Visibilitas pemuatan tersedia mulai Bazel 6.0.
Mendeklarasikan visibilitas pemuatan
Untuk menetapkan visibilitas pemuatan file .bzl, panggil fungsi visibility() dari dalam file.
Argumen untuk visibility() adalah daftar spesifikasi paket, sama seperti
atribut packages dari
package_group. Namun, visibility() tidak menerima spesifikasi paket negatif.
Panggilan ke visibility() hanya boleh terjadi sekali per file, di tingkat teratas (bukan di dalam fungsi), dan idealnya segera setelah pernyataan load().
Tidak seperti visibilitas target, visibilitas pemuatan default selalu publik. File yang tidak memanggil visibility() selalu dapat dimuat dari mana saja di ruang kerja. Sebaiknya tambahkan visibility("private") ke bagian atas file .bzl baru yang tidak secara khusus ditujukan untuk digunakan di luar paket.
Contoh
# //mylib/internal_defs.bzl
# Available to subpackages and to mylib's tests.
visibility(["//mylib/...", "//tests/mylib/..."])
def helper(...):
...
# //mylib/rules.bzl
load(":internal_defs.bzl", "helper")
# Set visibility explicitly, even though public is the default.
# Note the [] can be omitted when there's only one entry.
visibility("public")
myrule = rule(
...
)
# //someclient/BUILD
load("//mylib:rules.bzl", "myrule") # ok
load("//mylib:internal_defs.bzl", "helper") # error
...
Praktik visibilitas muatan
Bagian ini menjelaskan tips untuk mengelola deklarasi visibilitas pemuatan.
Memperhitungkan visibilitas
Jika beberapa file .bzl harus memiliki visibilitas yang sama, sebaiknya
faktorkan spesifikasi paketnya ke dalam daftar umum. Contoh:
# //mylib/internal_defs.bzl
visibility("private")
clients = [
"//foo",
"//bar/baz/...",
...
]
# //mylib/feature_A.bzl
load(":internal_defs.bzl", "clients")
visibility(clients)
...
# //mylib/feature_B.bzl
load(":internal_defs.bzl", "clients")
visibility(clients)
...
Hal ini membantu mencegah penyimpangan yang tidak disengaja antara visibilitas berbagai file .bzl. Kode ini juga lebih mudah dibaca jika daftar clients berukuran besar.
Menyusun visibilitas
Terkadang, file .bzl mungkin perlu terlihat oleh daftar yang diizinkan yang
terdiri dari beberapa daftar yang diizinkan yang lebih kecil. Hal ini sama seperti cara
package_group dapat menggabungkan package_group lain melalui
atribut includes.
Misalnya, Anda menghentikan penggunaan makro yang banyak digunakan. Anda ingin agar class tersebut hanya terlihat oleh pengguna yang ada dan paket yang dimiliki oleh tim Anda sendiri. Anda dapat menulis:
# //mylib/macros.bzl
load(":internal_defs.bzl", "our_packages")
load("//some_big_client:defs.bzl", "their_remaining_uses")
# List concatenation. Duplicates are fine.
visibility(our_packages + their_remaining_uses)
Menghapus duplikat dengan grup paket
Tidak seperti visibilitas target, Anda tidak dapat menentukan visibilitas pemuatan dalam hal
package_group. Jika Anda ingin menggunakan kembali daftar yang diizinkan yang sama untuk visibilitas target
dan visibilitas pemuatan, sebaiknya pindahkan daftar spesifikasi
paket ke file .bzl, tempat kedua jenis deklarasi dapat merujuk
ke file tersebut. Berdasarkan contoh di Memfaktorkan visibilitas
di atas, Anda dapat menulis:
# //mylib/BUILD
load(":internal_defs", "clients")
package_group(
name = "my_pkg_grp",
packages = clients,
)
Hal ini hanya berfungsi jika daftar tidak berisi spesifikasi paket negatif.
Melindungi simbol tertentu
Simbol Starlark apa pun yang namanya diawali dengan garis bawah tidak dapat dimuat dari
file lain. Hal ini memudahkan pembuatan simbol pribadi, tetapi tidak memungkinkan
Anda membagikan simbol ini kepada sekumpulan file tepercaya yang terbatas. Di sisi lain, visibilitas pemuatan memberi Anda kontrol atas paket lain yang dapat melihat .bzl file Anda, tetapi tidak memungkinkan Anda mencegah pemuatan simbol yang tidak digarisbawahi.
Untungnya, Anda dapat menggabungkan kedua fitur ini untuk mendapatkan kontrol yang mendetail.
# //mylib/internal_defs.bzl
# Can't be public, because internal_helper shouldn't be exposed to the world.
visibility("private")
# Can't be underscore-prefixed, because this is
# needed by other .bzl files in mylib.
def internal_helper(...):
...
def public_util(...):
...
# //mylib/defs.bzl
load(":internal_defs", "internal_helper", _public_util="public_util")
visibility("public")
# internal_helper, as a loaded symbol, is available for use in this file but
# can't be imported by clients who load this file.
...
# Re-export public_util from this file by assigning it to a global variable.
# We needed to import it under a different name ("_public_util") in order for
# this assignment to be legal.
public_util = _public_util
bzl-visibility Buildifier lint
Ada lint Buildifier
yang memberikan peringatan jika pengguna memuat file dari direktori bernama internal
atau private, saat file pengguna tidak berada di bawah induk direktori
tersebut. Lint ini sudah ada sebelum fitur visibilitas pemuatan dan tidak diperlukan di
ruang kerja tempat file .bzl mendeklarasikan visibilitas.