Quy tắc kho lưu trữ

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ể được sử dụng trong tệp WORKSPACE và cho phép hoạt động không theo kiểu tuần tự trong 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 BUILD và cấu phần phần mềm riêng. Bạn có thể dùng các tệp này để phụ thuộc vào thư viện của bên thứ ba (chẳng hạn như thư viện đóng gói Maven), cũng như để tạo các tệp BUILD dành riêng cho máy chủ lưu trữ 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 quy tắc kho lưu trữ mới và lưu trữ quy tắc đó trong biến toàn cục.

Bạn có thể sử dụng quy tắc kho lưu trữ tuỳ chỉnh giống như quy tắc cho kho lưu trữ gốc. Lớp này có 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 gọi là @<name>//package:target, trong đó <name> là giá trị của thuộc tính name.

Quy tắc này sẽ được tải khi bạn tạo một cách rõ ràng hoặc nếu quy tắc là 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à tệp BUILD trong kho lưu trữ đó.

Thuộc tính

Thuộc tính là một đối số quy tắc, chẳng hạn như url hoặc sha256. Bạn phải liệt kê các thuộc tính và loại của các thuộc tính đó khi xác định quy tắc lưu trữ.

local_repository = repository_rule(
    implementation=_impl,
    local=True,
    attrs={"path": attr.string(mandatory=True)})

Để truy cập vào một thuộc tính, hãy sử dụng repository_ctx.attr.<attribute_name>.

Mọi repository_rule đều có các thuộc tính được xác định ngầm (giống như quy tắc bản dựng). Hai thuộc tính ngầm ẩn là name (tương tự như quy tắc tạo bản dựng) và repo_mapping. Có thể truy cập tên của quy tắc kho lưu trữ bằng repository_ctx.name. Ý nghĩa của repo_mapping giống như ý nghĩa của các quy tắc kho lưu trữ gốc local_repositorynew_local_repository.

Nếu tên thuộc tính bắt đầu bằng _ thì tên đó là thuộc tính riêng tư và người dùng không thể đặt được.

Hàm triển khai

Mọi quy tắc kho lưu trữ yêu cầu một hàm implementation. Thành phần này 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 có đúng một tham số đầu vào là repository_ctx. Hàm trả về None để biểu thị rằng quy tắc có thể tạo lại nhờ các tham số đã chỉ định hoặc một lệnh với tập hợp các tham số cho quy tắc đó sẽ chuyển quy tắc đó thành quy tắc có thể mô phỏng tạo 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, tức là trả về một giá trị 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 ẩ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?

Nếu kho lưu trữ được khai báo là local thì việc thay đổi một phần phụ thuộc trong biểu đồ phần phụ thuộc (bao gồm cả chính tệp WORKSPACE) sẽ dẫn đến việc thực thi hàm triển khai.

Hàm triển khai có thể khởi động lại nếu phần phụ thuộc mà hàm yêu cầu bị thiếu. Điểm bắt đầu của hàm triển khai sẽ được thực thi lại sau khi phần phụ thuộc đã được giải quyết. Để tránh việc khởi động lại không cần thiết (tốn kém, vì quyền truy cập mạng có thể phải lặp lại), đối số nhãn sẽ được tìm nạp trước, miễn là tất cả đối số nhãn đều có thể được phân giải thành 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 một nhãn chỉ được tạo trong quá trình thực thi hàm vẫn có thể gây ra việc khởi động lại.

Cuối cùng, đối với các kho lưu trữ không phải local, chỉ một thay đổi trong các phần phụ thuộc sau đây có thể dẫn đến việc khởi động lại:

  • Cần có .bzl tệp để xác định quy tắc lưu trữ.
  • Khai báo quy tắc lưu trữ trong tệp WORKSPACE.
  • Giá trị của mọi biến môi trường được khai báo bằng thuộc tính environ của hàm repository_rule. Bạn có thể thực thi giá trị của các biến môi trường đó từ dòng lệnh bằng cờ --action_env (nhưng cờ này sẽ vô hiệu hoá mọi hành động của bản dựng).
  • Nội dung của bất kỳ tệp nào được nhãn sử dụng và tham chiếu đến (ví dụ: //mypkg:label.txt không phải mypkg/label.txt).

Buộc tìm nạp lại 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 thay đổi 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 vô điều kiện tất cả kho lưu trữ bên ngoài bằng cách gọi bazel sync.

Hơn nữa, 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 các kho lưu trữ bên ngoài đó, trong đó định nghĩa repository_rule đã có bộ thuộc tính configure được đặt, hãy sử dụng bazel sync --configure.

Ví dụ

  • Chuỗi công cụ định cấu hình tự động C++: sử dụng 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ờ 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 quy tắc Go.

  • rules_jvm_external sẽ 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 tạo 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.