Bu sayfada, Bazel'in üç görünürlük sistemi ele alınmaktadır: hedef görünürlüğü, geçişli görünürlük ve yükleme görünürlüğü.
Bu görünürlük türleri, diğer geliştiricilerin kitaplığınızın herkese açık API'si ile uygulama ayrıntıları arasında ayrım yapmasına yardımcı olur ve çalışma alanınız büyüdükçe yapıyı zorunlu kılmaya yardımcı olur. Görünürlüğü, herkese açık bir API'yi kullanımdan kaldırırken yeni kullanıcılara izin vermeyip mevcut kullanıcılara izin vermek için de kullanabilirsiniz.
Hedef görünürlük
Hedef görünürlüğü, hedefinize kimlerin bağlı olabileceğini, yani deps gibi bir özellikte hedefinizin etiketini kimlerin kullanabileceğini kontrol eder. Bir hedef, bağımlılıklarından birinin görünürlüğünü ihlal ederse analiz aşamasında derlenemez.
Genellikle bir A hedefi, aynı konumda bulunmaları veya A hedefinin B hedefinin konumuna görünürlük izni vermesi durumunda B hedefi tarafından görülebilir. Sembolik makrolar yoksa "konum" terimi yalnızca "paket" olarak basitleştirilebilir. Sembolik makrolar hakkında daha fazla bilgi için aşağıya bakın.
Görünürlük, izin verilen paketler listelenerek belirtilir. Bir pakete izin verilmesi, alt paketlerine de izin verildiği anlamına gelmez. Paketler ve alt paketler hakkında daha fazla bilgi için Kavramlar ve terminoloji başlıklı makaleyi inceleyin.
Prototip oluşturma için --check_visibility=false işaretini ayarlayarak hedef görünürlük yaptırımını devre dışı bırakabilirsiniz. Gönderilen kodda üretim kullanımı için bu yapılmamalıdır.
Görünürlüğü kontrol etmenin birincil yolu, kuralın visibility özelliğini kullanmaktır.
Aşağıdaki alt bölümlerde, özelliğin biçimi, çeşitli hedef türlerine nasıl uygulanacağı ve görünürlük sistemi ile sembolik makrolar arasındaki etkileşim açıklanmaktadır.
Görünürlük özellikleri
Tüm kural hedeflerinde, etiket listesi alan bir visibility özelliği bulunur. Her etiketin aşağıdaki biçimlerden biri vardır. Son biçim hariç olmak üzere, bunlar yalnızca söz dizimsel yer tutuculardır ve gerçek bir hedefe karşılık gelmez.
"//visibility:public": Tüm paketlere erişim izni verir."//visibility:private": Ek erişim izni vermez. Bu hedefi yalnızca bu konumun paketindeki hedefler kullanabilir."//foo/bar:__pkg__"://foo/barpaketine erişim izni verir (ancak alt paketlerine erişim izni vermez)."//foo/bar:__subpackages__"://foo/barve tüm doğrudan ve dolaylı alt paketlerine erişim izni verir."//some_pkg:my_package_group": Belirtilenpackage_groupkapsamındaki tüm paketlere erişim izni verir.- Paket grupları, paketleri belirtmek için farklı bir söz dizimi kullanır. Bir paket grubunda
"//foo/bar:__pkg__"ve"//foo/bar:__subpackages__"formları sırasıyla"//foo/bar"ve"//foo/bar/..."ile değiştirilir. Benzer şekilde,"//visibility:public"ve"//visibility:private","public"ve"private"'dir.
- Paket grupları, paketleri belirtmek için farklı bir söz dizimi kullanır. Bir paket grubunda
Örneğin, //some/package:mytarget öğesinin visibility değeri [":__subpackages__", "//tests:__pkg__"] olarak ayarlanmışsa //some/package/... kaynak ağacının parçası olan tüm hedefler ve //tests/BUILD içinde tanımlanan hedefler tarafından kullanılabilir ancak //tests/integration/BUILD içinde tanımlanan hedefler tarafından kullanılamaz.
En iyi uygulama: Birden fazla hedefin aynı paket grubuna görünür olmasını sağlamak için her hedefin visibility özelliğindeki listeyi tekrarlamak yerine package_group kullanın. Bu sayede okunabilirlik artar ve listelerin senkronizasyonunun bozulması önlenir.
En iyi uygulama: Başka bir ekibin projesine görünürlük izni verirken, proje geliştikçe ve yeni alt paketler eklendikçe gereksiz görünürlük karmaşasını önlemek için __pkg__ yerine __subpackages__ kullanmayı tercih edin.
Kural hedefi görünürlüğü
Bir kural hedefinin görünürlüğü, visibility özelliği (veya belirtilmemişse uygun bir varsayılan değer) alınarak ve hedefin bildirildiği konum eklenerek belirlenir. Sembolik bir makroda tanımlanmayan hedefler için paket bir default_visibility belirtiyorsa bu varsayılan değer kullanılır. Diğer tüm paketler ve sembolik bir makroda tanımlanan hedefler için varsayılan değer ["//visibility:private"] olur.
# //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/..."],
)
En iyi uygulama: default_visibility değerini herkese açık olarak ayarlamaktan kaçının. Prototip oluşturma veya küçük kod tabanları için uygun olabilir ancak kod tabanı büyüdükçe yanlışlıkla herkese açık hedefler oluşturma riski artar. Bir paketin herkese açık arayüzünün parçası olan hedefleri açıkça belirtmek daha iyidir.
Oluşturulan dosyanın hedef görünürlüğü
Oluşturulan bir dosya hedefi, onu oluşturan kural hedefiyle aynı görünürlüğe sahiptir.
# //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",
]
...
)
Kaynak dosya hedef görünürlüğü
Kaynak dosya hedefleri, exports_files kullanılarak açıkça tanımlanabilir veya bir kuralın etiket özelliğinde (sembolik makro dışında) dosya adına atıfta bulunularak dolaylı olarak oluşturulabilir. Kural hedeflerinde olduğu gibi, exports_files çağrısının konumu veya giriş dosyasına başvuran BUILD dosyası, her zaman otomatik olarak dosyanın görünürlüğüne eklenir.
exports_files tarafından tanımlanan dosyaların görünürlüğü, bu işlevin visibility parametresiyle ayarlanabilir. Bu parametre belirtilmezse görünürlük herkese açık olur.
exports_files çağrısında görünmeyen dosyaların görünürlüğü, --incompatible_no_implicit_file_export işaretinin değerine bağlıdır:
İşaret doğruysa görünürlük gizlidir.
Aksi takdirde eski davranış geçerli olur: Görünürlük,
BUILDdosyasınındefault_visibilityile aynıdır veya varsayılan görünürlük belirtilmemişse gizlidir.
Eski davranışa güvenmekten kaçının. Kaynak dosya hedefinin gizli olmayan görünürlüğe ihtiyacı olduğunda her zaman exports_files bildirimi yazın.
En iyi uygulama: Mümkün olduğunda kaynak dosya yerine kural hedefini göstermeyi tercih edin. Örneğin, bir .java dosyasında exports_files işlevini çağırmak yerine dosyayı gizli olmayan bir java_library hedefine sarmalayın. Genellikle kural hedefleri, yalnızca aynı pakette bulunan kaynak dosyalara doğrudan referans vermelidir.
Örnek
//frobber/data/BUILD. dosya:
exports_files(["readme.txt"])
//frobber/bin/BUILD. dosya:
cc_binary(
name = "my-program",
data = ["//frobber/data:readme.txt"],
)
Yapılandırma ayarı görünürlüğü
Bazel, geçmişte bir select() anahtarlarında referans verilen config_setting hedefleri için görünürlüğü zorunlu kılmıyordu. Bu eski davranışı kaldırmak için iki işaret vardır:
--incompatible_enforce_config_setting_visibilitybu hedefler için görünürlük kontrolünü etkinleştirir. Taşıma işlemine yardımcı olmak için,visibilitybelirtmeyen tümconfig_settingöğelerinin herkese açık olarak kabul edilmesine de neden olur (paket düzeyindekidefault_visibilityne olursa olsun).--incompatible_config_setting_private_default_visibilityvisibilitybelirtmeyenconfig_settingöğelerinin, paketindefault_visibilityöğesine uymasına ve diğer tüm kural hedefleri gibi gizli görünürlüğe geri dönmesine neden olur.--incompatible_enforce_config_setting_visibilityayarlanmamışsa işlem yapılmaz.
Eski davranışa güvenmekten kaçının. Geçerli paketin dışında kullanılmak istenen tüm config_setting, pakette uygun bir default_visibility belirtilmemişse açık bir visibility içermelidir.
Paket grubu hedef görünürlüğü
package_group hedeflerinde visibility özelliği yok. Bu bilgiler her zaman herkese açık olarak gösterilir.
Dolaylı bağımlılıkların görünürlüğü
Bazı kuralların dolaylı bağımlılıkları vardır. Bunlar, BUILD dosyasında açıkça belirtilmeyen ancak kuralın her örneğinde bulunan bağımlılıklardır. Örneğin, bir cc_library kuralı, kural hedeflerinin her birinden C++ derleyicisini temsil eden yürütülebilir bir hedefe örtük bir bağımlılık oluşturabilir.
Bu tür dolaylı bağımlılıkların görünürlüğü, kuralın (veya yönün) tanımlandığı .bzl dosyasını içeren pakete göre kontrol edilir. Örneğimizde, C++ derleyicisi cc_library kuralının tanımıyla aynı pakette olduğu sürece gizli olabilir. Yedek olarak, dolaylı bağımlılık tanımda görünmüyorsa cc_library hedefine göre kontrol edilir.
Bir kuralın kullanımını belirli paketlerle kısıtlamak istiyorsanız bunun yerine load visibility'yi kullanın.
Görünürlük ve sembolik makrolar
Bu bölümde, görünürlük sisteminin sembolik makrolarla nasıl etkileşime girdiği açıklanmaktadır.
Sembolik makrolardaki konumlar
Görünürlük sisteminin önemli bir ayrıntısı, bir bildirimin konumunu nasıl belirlediğimizdir. Sembolik bir makroda tanımlanmayan hedefler için konum, hedefin bulunduğu pakettir (BUILD dosyasının paketi).
Ancak sembolik bir makroda oluşturulan hedefler için konum, makronun tanımının (my_macro = macro(...) ifadesi) göründüğü .bzl dosyasını içeren pakettir. Bir hedef birden fazla iç içe yerleştirilmiş hedef içinde oluşturulduğunda her zaman en içteki sembolik makronun tanımı kullanılır.
Belirli bir bağımlılığın görünürlüğüne göre hangi konumun kontrol edileceğini belirlemek için de aynı sistem kullanılır. Tüketen hedef bir makro içinde oluşturulduysa tüketen hedefin bulunduğu paket yerine en içteki makronun tanımına bakarız.
Bu, kodu aynı pakette tanımlanan tüm makroların otomatik olarak birbirleriyle "arkadaş" olduğu anlamına gelir. //lib:defs.bzl içinde tanımlanan bir makro tarafından doğrudan oluşturulan tüm hedefler, makroların gerçekte hangi paketlerde örneklendirildiğine bakılmaksızın //lib içinde tanımlanan diğer tüm makrolardan görülebilir. Benzer şekilde, doğrudan //lib/BUILD ve eski makrolarında tanımlanan hedefleri görebilir ve bu hedefler tarafından görülebilirler. Bununla birlikte, aynı pakette bulunan hedeflerden en az biri sembolik bir makro tarafından oluşturulmuşsa bu hedefler birbirini göremeyebilir.
Sembolik makronun uygulama işlevinde visibility parametresi, makronun çağrıldığı konum eklendikten sonra makronun visibility özelliğinin geçerli değerine sahip olur. Bir makronun hedeflerinden birini çağırana aktarmasının standart yolu, bu değeri some_rule(..., visibility = visibility) örneğinde olduğu gibi hedefin bildirimine iletmektir. Bu özelliği atlayan hedefler, makro tanımıyla aynı pakette olmadığı sürece makroyu çağıran tarafından görülemez. Bu davranış,
alt makrolara yapılan iç içe yerleştirilmiş çağrı zincirinin her birinin visibility = visibility değerini iletebileceği ve iç makronun dışa aktarılan hedeflerini her düzeyde arayana yeniden aktarabileceği şekilde oluşturulur. Bu işlem, makroların uygulama ayrıntılarını göstermeden yapılır.
Bir alt makroya ayrıcalıklar verme
Görünürlük modelinin, bir makronun izinlerini bir alt makroya devretmesine olanak tanıyan özel bir özelliği vardır. Bu, makroları çarpanlara ayırma ve oluşturma açısından önemlidir.
Başka bir paketten kural some_library kullanarak bağımlılık kenarı oluşturan bir makronuz my_macro olduğunu varsayalım:
# //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", ...)
//pkg:foo_dependency hedefinin visibility değeri belirtilmediğinden yalnızca //macro içinde görünür. Bu durum, tüketen hedef için sorun oluşturmaz. //lib kütüphanesinin yazarı, some_library kuralını makro kullanarak yeniden düzenlerse ne olur?
# //lib:defs.bzl
def _impl(name, visibility, deps, ...):
some_rule(
# Main target, exported.
name = name,
visibility = visibility,
deps = deps,
...)
some_library = macro(implementation = _impl, ...)
Bu değişiklikle birlikte //pkg:foo_consumer artık //macro yerine //lib konumunda yer alıyor. Bu nedenle, //pkg:foo_dependency kullanımı bağımlılığın görünürlüğünü ihlal ediyor. my_macro adlı paketin yazarının, bu uygulama ayrıntısını çözmek için bağımlılık beyanına visibility = ["//lib"] değerini iletmesi beklenemez.
Bu nedenle, bir hedefin bağımlılığı aynı zamanda hedefi tanımlayan makronun özellik değeri olduğunda, bağımlılığın görünürlüğünü tüketen hedefin konumu yerine makronun konumuna göre kontrol ederiz.
Bu örnekte, //pkg:foo_consumer öğesinin //pkg:foo_dependency öğesini görüp göremediğini doğrulamak için //pkg:foo_dependency öğesinin de my_macro içindeki some_library çağrısına giriş olarak iletildiğini görüyoruz ve bunun yerine bağımlılığın görünürlüğünü bu çağrının konumu olan //macro ile karşılaştırıyoruz.
Bu işlem, bir hedef veya makro bildirimi, bağımlılığın etiketini etiket türündeki özelliklerinden birinde alan başka bir sembolik makronun içinde olduğu sürece yinelemeli olarak tekrarlanabilir.
Sonlandırıcılar
Kural sonlandırıcıda (finalizer = True içeren sembolik makro) tanımlanan hedefler, normal sembolik makro görünürlük kurallarına uyan hedefleri görmenin yanı sıra sonlandırıcı hedefin paketi tarafından görülebilen tüm hedefleri de görebilir.
Diğer bir deyişle, native.existing_rules() tabanlı eski bir makroyu bir sonlandırıcıya taşırsanız sonlandırıcı tarafından tanımlanan hedefler eski bağımlılıklarını görmeye devam eder.
Bir sonlandırıcının native.existing_rules() kullanarak inceleyebileceği ancak görünürlük sistemi kapsamında bağımlılık olarak kullanamayacağı hedefler tanımlamak mümkündür. Örneğin, makro tarafından tanımlanan bir hedef kendi paketinde veya sonlandırıcı makronun tanımında görünmüyorsa ve sonlandırıcıya atanmamışsa sonlandırıcı bu hedefi göremez. Ancak native.existing_rules() tabanlı eski bir makronun da bu tür bir hedefi göremeyeceğini unutmayın.
Geçişli görünürlük
Geçişli görünürlük, bağımlılığın yalnızca dolaylı olduğu durumlar da dahil olmak üzere bir hedefe kimlerin bağımlı olabileceğini kısıtlamanın bir yoludur. Bu kural, normal hedef görünürlük sisteminden ayrı olarak uygulanır. Bu nedenle, bağımlılık zincirindeki her bağlantı geçerli olsa bile geçişli görünürlük hatası oluşabilir. Bu sayede hedefin yazarı, hedefi güvenilir bir istemci hedefleri grubuyla paylaşabilir ve derlemenin geri kalanına yanlışlıkla sızdırılmasını önleyebilir.
Geçişli görünürlük, [package][package] işlevinin transitive_visibility parametresi kullanılarak paket düzeyinde tanımlanır. Bu beyan, paketteki tüm hedefler için geçerlidir. Parametre,
hedefleri geçişli olarak bu paketin hedeflerine bağlı olabilecek paketleri
belirten bir package_group etiketi alır.
# //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"]
)
//third_party/sensitive_dep:sensitive_dep'e bağlı olan ancak transitive_visibility'nin parçası olmayan //not_allowed:bad derlendiğinde şu hata oluşur:
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.
transitive_visibility içinde kullanılan paket grupları diğer paket gruplarını include.
Bir hedefin geçişli görünürlük kısıtlaması olan geçişli bir bağımlılığı varsa hedefin kendisi kısıtlamayı devralır ve kendisine bağlı hedeflere iletir. Bir hedefin geçişli görünürlük kısıtlamaları olan birden fazla geçişli bağımlılığı varsa tüm kısıtlamaları karşılaması gerekir.
Geçişli görünürlük, sembolik makrolarda tanımlanan hedefler için de geçerlidir. Ancak normal hedef görünürlüğünün aksine, sembolik makroyu tanımlayan paketi değil, yalnızca bu hedeflerin bulunduğu paketi dikkate alır.
Yük görünürlüğü
Yükleme görünürlüğü, bir .bzl dosyasının geçerli paketin dışındaki diğer BUILD veya .bzl dosyalarından yüklenip yüklenemeyeceğini kontrol eder.
Hedef görünürlüğü, hedefler tarafından kapsüllenmiş kaynak kodunu koruduğu gibi, yükleme görünürlüğü de .bzl dosyaları tarafından kapsüllenmiş derleme mantığını korur. Örneğin, bir BUILD dosyası yazarı, bazı tekrarlayan hedef bildirimlerini bir .bzl dosyasındaki makroya dahil etmek isteyebilir. Yük görünürlüğü koruması olmadan, makrolarının aynı çalışma alanındaki diğer ortak çalışanlar tarafından yeniden kullanıldığını ve makroyu değiştirmenin diğer ekiplerin derlemelerini bozduğunu görebilirler.
.bzl dosyasının karşılık gelen bir kaynak dosya hedefi olabilir veya olmayabilir.
Eşleşse bile yük görünürlüğü ile hedef görünürlüğünün çakışacağı garanti edilmez. Yani aynı BUILD dosyası, .bzl dosyasını yükleyebilir ancak bir filegroup öğesinin srcs bölümünde listelemeyebilir veya tam tersi olabilir. Bu durum bazen, .bzl dosyalarını kaynak kodu olarak kullanmak isteyen kurallarda (ör. doküman oluşturma veya test etme) sorunlara neden olabilir.
Prototip oluşturma için --check_bzl_visibility=false ayarını yaparak yükleme görünürlüğü yaptırımını devre dışı bırakabilirsiniz. --check_visibility=false gibi, bu da gönderilen kod için yapılmamalıdır.
Yükleme görünürlüğü, Bazel 6.0'dan itibaren kullanılabilir.
Yük görünürlüğünü bildirme
Bir .bzl dosyasının yükleme görünürlüğünü ayarlamak için dosyanın içinden visibility() işlevini çağırın.
visibility() bağımsız değişkeni, package_group öğesinin packages özelliği gibi bir paket özellikleri listesidir. Ancak visibility(), negatif paket spesifikasyonlarını kabul etmez.
visibility() çağrısı, dosya başına yalnızca bir kez, en üst düzeyde (bir işlevin içinde değil) ve ideal olarak load() ifadelerinin hemen ardından yapılmalıdır.
Hedef görünürlüğün aksine, varsayılan yükleme görünürlüğü her zaman herkese açıktır. visibility() işlevini çağırmayan dosyalar, çalışma alanının her yerinden her zaman yüklenebilir. Paket dışında kullanılmak üzere özel olarak tasarlanmamış yeni .bzl dosyalarının en üstüne visibility("private") eklemeniz önerilir.
Örnek
# //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
...
Yük görünürlüğü uygulamaları
Bu bölümde, yük görünürlüğü beyanlarını yönetmeyle ilgili ipuçları açıklanmaktadır.
Görünürlükleri hesaba katma
Birden fazla .bzl dosyasının aynı görünürlüğe sahip olması gerektiğinde, paket özelliklerini ortak bir listeye dahil etmek faydalı olabilir. Örneğin:
# //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)
...
Bu sayede, çeşitli .bzl dosyalarının görünürlükleri arasında yanlışlıkla oluşabilecek uyumsuzluklar önlenir. Ayrıca clients listesi büyük olduğunda daha kolay okunur.
Oluşturma görünürlükleri
Bazen bir .bzl dosyasının, birden fazla küçük izin verilenler listesinden oluşan bir izin verilenler listesi tarafından görülebilmesi gerekebilir. Bu, bir package_group öğesinin includes özelliği aracılığıyla diğer package_group öğelerini nasıl dahil edebileceğine benzer.
Yaygın olarak kullanılan bir makroyu kullanımdan kaldırdığınızı varsayalım. Bu paketin yalnızca mevcut kullanıcılar ve kendi ekibinize ait paketler tarafından görülebilmesini istiyorsunuz. Şuna benzer bir mesaj yazabilirsiniz:
# //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)
Paket gruplarıyla tekilleştirme
Hedef görünürlüğün aksine, yük görünürlüğünü package_group cinsinden tanımlayamazsınız. Hem hedef görünürlüğü hem de yükleme görünürlüğü için aynı izin verilenler listesini yeniden kullanmak istiyorsanız paket spesifikasyonları listesini bir .bzl dosyasına taşımanız önerilir. Bu dosyada her iki tür beyan da bu listeye başvurabilir. Yukarıdaki Görünürlükleri hesaba katma bölümündeki örnekten yola çıkarak şunları yazabilirsiniz:
# //mylib/BUILD
load(":internal_defs", "clients")
package_group(
name = "my_pkg_grp",
packages = clients,
)
Bu, yalnızca listede negatif paket spesifikasyonları yoksa çalışır.
Tek tek sembolleri koruma
Adı alt çizgiyle başlayan Starlark sembolleri başka bir dosyadan yüklenemez. Bu sayede özel semboller oluşturmak kolaylaşır ancak bu sembolleri sınırlı sayıda güvenilir dosyayla paylaşmanıza izin verilmez. Öte yandan, yükleme görünürlüğü, diğer paketlerin .bzl file paketinizi görmesini kontrol etmenizi sağlar ancak alt çizgi içermeyen simgelerin yüklenmesini engellemenize izin vermez.
Neyse ki ayrıntılı kontrol elde etmek için bu iki özelliği birleştirebilirsiniz.
# //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
Kullanıcılar, internal veya private adlı bir dizinden dosya yüklediğinde ve kullanıcının dosyası bu dizinin üst dizini altında olmadığında uyarı veren bir Buildifier lint vardır. Bu lint, yükleme görünürlüğü özelliğinden önce oluşturulmuştur ve .bzl dosyalarının görünürlükleri beyan ettiği çalışma alanlarında gereksizdir.