Trang này trình bày cách tạo quy tắc kho lưu trữ và cung cấp ví dụ để biết thêm thông tin chi tiết.
Kho lưu trữ bên ngoài là một quy tắc chỉ có thể dùng trong tệp WORKSPACE
và cho phép hoạt động không khép kín ở giai đoạn tải của Bazel. Mỗi quy tắc kho lưu trữ bên ngoài sẽ tạo không gian làm việc riêng, với các tệp và cấu phần phần mềm BUILD
riêng. Bạn có thể dùng các tệp này để phụ thuộc vào các thư viện bên thứ ba (chẳng hạn như các thư viện được đóng gói Maven) nhưng cũng có thể dùng để tạo các tệp BUILD
dành riêng cho máy chủ mà Bazel đang chạy.
Tạo quy tắc kho lưu trữ
Trong tệp .bzl
, hãy dùng hàm repository_rule để tạo một quy tắc kho lưu trữ mới và lưu trữ quy tắc đó trong một biến chung.
Bạn có thể sử dụng quy tắc kho lưu trữ tuỳ chỉnh giống như quy tắc kho lưu trữ gốc. Thư viện này có một thuộc tính name
bắt buộc và mọi mục tiêu có trong tệp bản dựng đều có thể được tham chiếu dưới dạng @<name>//package:target
, trong đó <name>
là giá trị của thuộc tính name
.
Quy tắc này được tải khi bạn tạo rõ ràng hoặc nếu đó là một phần phụ thuộc của bản dựng. Trong trường hợp này, Bazel sẽ thực thi hàm implementation
. Hàm này mô tả cách tạo kho lưu trữ, nội dung và các tệp BUILD
của kho lưu trữ đó.
Thuộc tính
Thuộc tính là các đối số quy tắc được truyền dưới dạng một từ điển đến đối số quy tắc attrs
.
Các thuộc tính và loại của chúng được xác định và liệt kê khi bạn xác định một quy tắc kho lưu trữ. Ví dụ về việc xác định các thuộc tính url
và sha256
dưới dạng chuỗi:
local_repository = repository_rule(
implementation=_impl,
local=True,
attrs={
"url": attr.string(mandatory=True)
"sha256": attr.string(mandatory=True)
}
)
Để truy cập vào một thuộc tính trong hàm triển khai, hãy sử dụng repository_ctx.attr.<attribute_name>
:
def _impl(repository_ctx):
url = repository_ctx.attr.url
checksum = repository_ctx.attr.sha256
Tất cả repository_rule
đều có các thuộc tính được xác định ngầm (giống như các quy tắc xây dựng). Hai thuộc tính ngầm ẩn là name
(giống như đối với các quy tắc xây dựng) và repo_mapping
. Bạn có thể truy cập tên của một quy tắc kho lưu trữ bằng repository_ctx.name
. Ý nghĩa của repo_mapping
cũng giống như đối với các quy tắc kho lưu trữ gốc local_repository
và new_local_repository
.
Nếu tên thuộc tính bắt đầu bằng _
, thì đó là thuộc tính riêng tư và người dùng không thể đặt thuộc tính đó.
Hàm triển khai
Mọi quy tắc kho lưu trữ đều yêu cầu một hàm implementation
. Nó chứa logic thực tế của quy tắc và được thực thi nghiêm ngặt trong Giai đoạn tải.
Hàm này có đúng một tham số đầu vào, repository_ctx
. Hàm này trả về None
để biểu thị rằng quy tắc có thể tái tạo với các tham số đã chỉ định hoặc một từ điển có một tập hợp các tham số cho quy tắc đó sẽ biến quy tắc đó thành một quy tắc có thể tái tạo tạo ra cùng một kho lưu trữ. Ví dụ: đối với một quy tắc theo dõi kho lưu trữ git, điều đó có nghĩa là trả về một mã nhận dạng cam kết cụ thể thay vì một nhánh nổi được chỉ định ban đầu.
Bạn có thể dùng tham số đầu vào repository_ctx
để truy cập vào các giá trị thuộc tính và các hàm không khép kín (tìm tệp nhị phân, thực thi tệp nhị phân, tạo tệp trong kho lưu trữ hoặc tải tệp xuống từ Internet). Hãy xem thư viện để biết thêm ngữ cảnh. Ví dụ:
def _impl(repository_ctx):
repository_ctx.symlink(repository_ctx.attr.path, "")
local_repository = repository_rule(
implementation=_impl,
...)
Khi nào hàm triển khai được thực thi?
Hàm triển khai của một kho lưu trữ sẽ được thực thi khi Bazel cần một mục tiêu từ kho lưu trữ đó, chẳng hạn như khi một mục tiêu khác (trong một kho lưu trữ khác) phụ thuộc vào mục tiêu đó hoặc nếu mục tiêu đó được đề cập trên dòng lệnh. Sau đó, hàm triển khai dự kiến sẽ tạo kho lưu trữ trong hệ thống tệp. Quá trình này được gọi là "tìm nạp" kho lưu trữ.
Ngược lại với các mục tiêu thông thường, các kho lưu trữ không nhất thiết phải được tìm nạp lại khi có thay đổi khiến kho lưu trữ khác đi. Lý do là Bazel không thể phát hiện những thay đổi hoặc sẽ gây ra quá nhiều chi phí cho mỗi bản dựng (ví dụ: những thứ được tìm nạp từ mạng). Do đó, các kho lưu trữ chỉ được tìm nạp lại nếu một trong những điều sau đây thay đổi:
- Các tham số được truyền đến khai báo kho lưu trữ trong tệp
WORKSPACE
. - Mã Starlark bao gồm việc triển khai kho lưu trữ.
- Giá trị của mọi biến môi trường được khai báo bằng thuộc tính
environ
củarepository_rule
. Bạn có thể cố định các giá trị của những biến môi trường này trên dòng lệnh bằng cờ--action_env
(nhưng cờ này sẽ làm mất hiệu lực mọi thao tác của bản dựng). - Nội dung của mọi tệp được truyền đến
read()
,execute()
và các phương thức tương tự củarepository_ctx
được tham chiếu bằng một nhãn (ví dụ://mypkg:label.txt
nhưng không phảimypkg/label.txt
) - Khi
bazel sync
được thực thi.
Có hai tham số của repository_rule
kiểm soát thời điểm các kho lưu trữ được tìm nạp lại:
- Nếu cờ
configure
được đặt, kho lưu trữ sẽ chỉ được tìm nạp lại trênbazel sync
khi tham số--configure
được truyền đến kho lưu trữ đó (nếu thuộc tính chưa được đặt, lệnh này sẽ không gây ra thao tác tìm nạp lại) Nếu cờ
local
được đặt, ngoài các trường hợp trên, kho lưu trữ cũng được tìm nạp lại khi máy chủ Bazel khởi động lại hoặc khi có bất kỳ tệp nào ảnh hưởng đến việc khai báo kho lưu trữ thay đổi (ví dụ: tệpWORKSPACE
hoặc tệp mà tệp đó tải), bất kể những thay đổi đó có dẫn đến thay đổi đối với việc khai báo kho lưu trữ hay mã của kho lưu trữ hay không.Các kho lưu trữ không phải kho lưu trữ cục bộ sẽ không được tìm nạp lại trong những trường hợp này. Điều này là do các kho lưu trữ này được giả định là sẽ giao tiếp với mạng hoặc tốn nhiều chi phí.
Khởi động lại hàm triển khai
Hàm triển khai có thể được khởi động lại trong khi một kho lưu trữ đang được tìm nạp nếu một phần phụ thuộc mà hàm này yêu cầu bị thiếu. Trong trường hợp đó, quá trình thực thi hàm triển khai sẽ dừng, phần phụ thuộc bị thiếu sẽ được giải quyết và hàm sẽ được thực thi lại sau khi phần phụ thuộc được giải quyết. Để tránh các lần khởi động lại không cần thiết (tốn kém, vì có thể phải lặp lại quyền truy cập mạng), các đối số nhãn sẽ được tìm nạp trước, miễn là tất cả các đối số nhãn có thể được phân giải thành một tệp hiện có. Xin lưu ý rằng việc phân giải một đường dẫn từ một chuỗi hoặc nhãn chỉ được tạo trong quá trình thực thi hàm vẫn có thể khiến quá trình khởi động lại.
Buộc tìm nạp lại các kho lưu trữ bên ngoài
Đôi khi, một kho lưu trữ bên ngoài có thể trở nên lỗi thời mà không có bất kỳ thay đổi nào đối với định nghĩa hoặc các phần phụ thuộc của kho lưu trữ đó. Ví dụ: một kho lưu trữ tìm nạp các nguồn có thể tuân theo một nhánh cụ thể của kho lưu trữ bên thứ ba và các cam kết mới có sẵn trên nhánh đó. Trong trường hợp này, bạn có thể yêu cầu bazel tìm nạp lại tất cả các kho lưu trữ bên ngoài vô điều kiện bằng cách gọi bazel sync
.
Ngoài ra, một số quy tắc kiểm tra máy cục bộ và có thể trở nên lỗi thời nếu máy cục bộ được nâng cấp. Tại đây, bạn có thể yêu cầu bazel chỉ tìm nạp lại những kho lưu trữ bên ngoài mà định nghĩa repository_rule
có thuộc tính configure
được đặt, hãy sử dụng bazel sync --configure
.
Ví dụ
Chuỗi công cụ C++ được định cấu hình tự động: sử dụng một quy tắc kho lưu trữ để tự động tạo các tệp cấu hình C++ cho Bazel bằng cách tìm trình biên dịch C++ cục bộ, môi trường và các cờ mà trình biên dịch C++ hỗ trợ.
Kho lưu trữ Go sử dụng một số
repository_rule
để xác định danh sách các phần phụ thuộc cần thiết để sử dụng các quy tắc Go.rules_jvm_external tạo một kho lưu trữ bên ngoài có tên là
@maven
theo mặc định, kho lưu trữ này sẽ tạo các mục tiêu bản dựng cho mọi cấu phần phần mềm Maven trong cây phần phụ thuộc bắc cầu.