قد لا تحدد السمة visibility
أهدافًا لا تتبع package_group
.
لا يؤدي تنفيذ هذا الإجراء إلى ظهور خطأ "مقتصرة
مستوى رؤية هدف القاعدة
حق دخول قاعدة الهدف هو:
قيمة سمة visibility
، في حال ضبطها، أو غير ذلك
قيمة وسيطة
default_visibility
في بيان package
في ملف BUILD
target's، في حال وجود هذا البيان، أو غير ذلك
//visibility:private
.
أفضل الممارسات: تجنَّب ضبط السمة default_visibility
على علنية. وقد يكون من الملائم
إنشاء نماذج أولية أو في قواعد رموز صغيرة، إلا أن خطر إنشاء
أهداف عامة عن غير قصد يزداد مع زيادة قاعدة الرموز. من الأفضل أن تكون واضحًا بشأن الاستهدافات التي تُعد جزءًا من الواجهة العامة للحزمة.
مثال
الملف //frobber/bin/BUILD
:
# This target is visible to everyone
cc_binary(
name = "executable",
visibility = ["//visibility:public"],
deps = [":library"],
)
# This target is visible only to targets declared in the same package
cc_library(
name = "library",
# No visibility -- defaults to private since no
# package(default_visibility = ...) was used.
)
# This target is visible to targets in package //object and //noun
cc_library(
name = "subject",
visibility = [
"//noun:__pkg__",
"//object:__pkg__",
],
)
# See package group "//frobber:friends" (below) for who can
# access this target.
cc_library(
name = "thingy",
visibility = ["//frobber:friends"],
)
الملف //frobber/BUILD
:
# This is the package group declaration to which target
# //frobber/bin:thingy refers.
#
# Our friends are packages //frobber, //fribber and any
# subpackage of //fribber.
package_group(
name = "friends",
packages = [
"//fribber/...",
"//frobber",
],
)
تم إنشاء حق الدخول إلى الملف.
ويكون للملف الهدف المُنشَأ حق الوصول نفسه الذي يستخدمه الهدف من القاعدة.
حق الوصول المستهدف إلى ملف المصدر
يمكنك إعداد حق الوصول صراحةً إلى هدف الملف المصدر عن طريق استدعاء
exports_files
. عند عدم تمرير وسيطة visibility
إلى exports_files
، يؤدي ذلك إلى ظهور مستوى العرض للجميع.
لا يمكن استخدام exports_files
لإلغاء حق الوصول لملف تم إنشاؤه.
بالنسبة إلى استهدافات الملفات المصدر التي لا تظهر في استدعاء إلى exports_files
،
يعتمد الظهور على قيمة العلامة
--incompatible_no_implicit_file_export
:
تجنَّب الاعتماد على السلوك القديم. اكتب دائمًا بيان exports_files
عندما يحتاج استهداف ملف المصدر إلى إذن وصول غير خاص.
أفضل الممارسات: يُفضَّل عرض استهداف قاعدة بدلاً من ملف مصدر، إن أمكن ذلك. على سبيل المثال، بدلاً من طلب exports_files
في ملف .java
،
يمكنك لف الملف في هدف java_library
غير خاص. وبوجهٍ عام، يجب أن تشير أهداف القواعد
فقط إلى الملفات المصدر التي تتوفر في الحزمة نفسها.
مثال
الملف //frobber/data/BUILD
:
exports_files(["readme.txt"])
الملف //frobber/bin/BUILD
:
cc_binary(
name = "my-program",
data = ["//frobber/data:readme.txt"],
)
ضبط إعدادات الضبط
في السابق، لم يفرض Bazel إذن الوصول إلى أهداف config_setting
التي تتم الإشارة إليها في مفاتيح select()
. ثمة علامتان لإزالة هذا السلوك القديم:
تتيح لك --incompatible_enforce_config_setting_visibility
إمكانية التحقق من مستوى الرؤية لهذه الأهداف. وللمساعدة في نقل البيانات، يؤدي ذلك أيضًا إلى اعتبار أي خاصية config_setting
لا تحدّد أنّها visibility
عامة (بغض النظر عن default_visibility
على مستوى الحزمة).
يؤدي --incompatible_config_setting_private_default_visibility
إلى تحديد config_setting
بدون تحديد visibility
للالتزام
بحزمة default_visibility
's و/أو الاحتفاظ بنسخة احتياطية من إذن الوصول الخاص، مثل
أي هدف قاعدة آخر. وهي حالة غير مفعّلة في حال عدم ضبط السياسة --incompatible_enforce_config_setting_visibility
.
تجنَّب الاعتماد على السلوك القديم. يجب أن تحتوي أي حزمة config_setting
مخصّصة
لاستخدامها خارج الحزمة الحالية على رمز visibility
فاضح، إذا لم
تضبط الحزمة default_visibility
مناسبًا من قبل.
مستوى الظهور المستهدف لمجموعة الحزم
لا تتضمّن استهدافات package_group
سمة visibility
. وتكون هذه العناصر
مرئية للجميع.
إذن الوصول إلى العناصر التابعة الضمنية
وبعض القواعد تحتوي على اعتماديات ضمنية —
تعتمد عليها في ملف BUILD
ولكنها في الواقع مضمّنة في كل مثيل من هذه القاعدة. على سبيل المثال، قد تُنشئ قاعدة cc_library
اعتمادية ضمنية من كل هدف من قواعدها إلى هدف قابل للتنفيذ يمثل تمثيل +C++.
حاليًا، لأغراض الاعتماد، يتم التعامل مع هذه العناصر الضمنية مثل أي اعتمادية أخرى. وهذا يعني أن الهدف الذي يعتمد على (مثل برنامج التجميع C++ ) يجب أن يكون مرئيًا لكل مثيل من القاعدة. من الناحية العملية، عادةً ما يعني هذا أن الاستهداف يجب أن يكون مرئيًا للجميع.
يمكنك تغيير هذا السلوك من خلال ضبط
--incompatible_visibility_private_attributes_at_definition
. عند التفعيل، يجب أن يكون الهدف المعني مرئيًا فقط للقاعدة التي تعلن عن اعتمادية ضمنية. وهذا يعني أنها يجب أن تكون مرئية للحزمة التي تحتوي على ملف .bzl
الذي تم تحديد القاعدة فيه. في المثال الذي نقدّمه، يمكن أن تكون أداة التجميع C++
خاصة طالما أنها في الحزمة نفسها مثل تعريف
قاعدة cc_library
.
تحميل مستوى الرؤية
يتحكّم مستوى ظهور التحميل في إمكانية تحميل ملف .bzl
من
ملفات BUILD
أو .bzl
الأخرى.
بالطريقة نفسها التي تحمي بها أذونات الوصول الهدف رمز المصدر الذي يتم تضمينه
من خلال الأهداف، يحمي مستوى رؤية التحميل منطق الإصدار. على سبيل المثال، قد يرغب مؤلف الملف BUILD
في تضمين بعض تعريفات الاستهداف المتكررة في وحدة ماكرو في ملف .bzl
. وبدون حماية حق الدخول، قد يعثر المستخدمون على وحدة ماكرو أخرى يُعيد استخدامها المتعاونون الآخرون في مساحة العمل نفسها، بحيث يؤدي تعديل وحدة الماكرو إلى تعطّل الفِرق الأخرى.
تجدر الإشارة إلى أنّ الملف .bzl
قد يحتوي أو لا يحتوي على هدف ملف مصدر مطابق.
وإذا حدث ذلك، لا يوجد ضمان بأن هناك حقون تحميل ومطابقتَا مستوى رؤية الهدف. وهذا يعني أن ملف BUILD
نفسه قد يكون قادرًا على تحميل ملف .bzl
وليس إدراجه في srcs
من filegroup
، أو العكس. وقد يؤدي ذلك أحيانًا إلى حدوث مشاكل في القواعد التي تريد استهلاك
ملفات .bzl
كرمز مصدر، مثل إنشاء المستندات أو اختبارها.
بالنسبة إلى النماذج الأولية، يمكنك إيقاف فرض مستوى رؤية التحميل من خلال ضبط
--check_bzl_visibility=false
. كما هي الحال مع --check_visibility=false
،
لا يجب تنفيذ هذا الإجراء للرمز المرسَل.
يمكنك الاطّلاع على خيارات التحميل اعتبارًا من Bazel 6.0.
الإعلان عن مستوى رؤية التحميل
لضبط حق الدخول إلى ملف .bzl
، عليك استدعاء دالة
visibility()
من داخل الملف.
الوسيطة إلى visibility()
هي قائمة بمواصفات الحزمة، مثل
السمة packages
في
package_group
. ومع ذلك، لا يقبل visibility()
المواصفات السلبية للحزمة.
يجب أن يتم طلب المكالمة إلى visibility()
مرة واحدة فقط لكل ملف، على المستوى العلوي (وليس داخل دالة)، ومن الأفضل أن يتبع عبارات load()
مباشرةً.
على عكس حق الدخول المستهدَف، تكون حق الوصول التلقائي لتحميل البيانات علنيًا دائمًا. يمكن دائمًا تحميل الملفات التي لا تطلب visibility()
من أي مكان في مساحة العمل. يُفضَّل إضافة visibility("private")
إلى أعلى أي ملف .bzl
جديد غير مخصّص للاستخدام خارج الحزمة بشكل خاص.
مثال
# //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
...
تحميل ممارسات مستوى العرض
يوضّح هذا القسم نصائح لإدارة إقرارات مستوى عرض بيانات التحميل.
مراعاة عوامل الظهور
عندما يكون للعديد من ملفات .bzl
حق الوصول نفسه، من المفيد أخذ مواصفات حزمها في قائمة شائعة. مثلاً:
# //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)
...
يساعد ذلك على منع حدوث انحراف غير مقصود بين مختلف ملفات .bzl
'ومرئيات. ويمكن أيضًا أن يقرأه المستخدمون أكثر عندما تكون قائمة clients
كبيرة.
تركيب أذونات الدخول
في بعض الأحيان، قد يكون ملف .bzl
مرئيًا لقائمة مسموح بها
مكوّنة من عدة قوائم مسموح بها. وتتشابه هذه الطريقة مع الطريقة التي تستخدم بها السمة package_group
سمات package_group
أخرى من خلال
السمة includes
.
لنفترض أنك بصدد إيقاف وحدة ماكرو شائعة الاستخدام على نطاق واسع. تريد أن يكون مرئيًا فقط للمستخدمين الحاليين
وللحزم التي يمتلكها فريقك. يمكنك كتابة:
# //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)
إزالة التكرار من خلال مجموعات الحِزم
وعلى عكس مستوى رؤية الهدف، لا يمكنك تحديد مستوى رؤية التحميل من حيث package_group
. وإذا كنت تريد إعادة استخدام القائمة المسموح بها نفسها لكل من حق الوصول
إلى مستوى الرؤية والتحميل، من الأفضل استنادًا إلى المثال الموضّح في القسم ظهور المرئيات
أعلاه، يمكنك كتابة ما يلي:
# //mylib/BUILD
load(":internal_defs", "clients")
package_group(
name = "my_pkg_grp",
packages = clients,
)
وينطبق هذا الإجراء فقط في حال كانت القائمة لا تتضمّن أي مواصفات سلبية للحزمة.
حماية الرموز الفردية
لا يمكن تحميل أي رمز Starlark يبدأ اسمه بشرطة سفلية من
ملف آخر. يسهّل ذلك إنشاء الرموز الخاصة، ولكن لا يسمح لك بمشاركة هذه الرموز مع مجموعة محدودة من الملفات الموثوق بها. من ناحية أخرى، يتيح لك مستوى رؤية التحميل إمكانية التحكّم في الحِزم الأخرى التي قد يظهر فيها
.bzl file
، ولكنه لا يسمح لك بمنع تحميل أي رمز بدون شرطة سفلية.
لحسن الحظ، يمكنك الجمع بين هاتين الميزتين للحصول على عنصر التحكم الدقيق.
# //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-vision
يتوفّر رابط أداة الإنشاء
الذي يقدّم تحذيرًا في حال حمّل المستخدمون ملفًا من دليل باسم internal
أو private
، عندما لا يكون ملف المستخدم نفسه أسفل الدليل الرئيسي لهذا
الدليل. سيؤدي هذا الإجراء إلى ظهور ميزة مستوى رؤية التحميل بشكل غير مسبق، وهو أمر غير ضروري في مساحات العمل التي توضح فيها ملفات .bzl
إذن الوصول.