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 các 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 dùng trong tệp WORKSPACE và cho phép hoạt động không khép kín trong giai đoạn tải của Bazel. Mỗi quy tắc kho lưu trữ bên ngoài tạo ra không gian làm việc riêng, với các tệp và cấu phần phần mềm riêng BUILD. Chúng có thể được dùng để phụ thuộc vào các thư viện bên thứ ba (chẳng hạn như 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 sử 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 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 kho lưu trữ gốc. Quy tắc 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 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 bản dựng một cách rõ ràng hoặc nếu đó 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.

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 chúng khi xác định một quy tắc kho 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>.

Tất cả repository_rule đều có các thuộc tính được xác định ngầm ẩn (giống như quy tắc bản dựng ). Hai thuộc tính ngầm ẩn là name (giống như đối với quy tắc bản dựng) và repo_mapping. Bạn có thể truy cập vào tên của một quy tắc kho lưu trữ bằng repository_ctx.name. Ý nghĩa của repo_mapping giống như đối với 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ì đó 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 implementation hàm. Hàm 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 này có đúng một tham số đầu vào là repository_ctx. Hàm này trả về None để biểu thị rằng quy tắc có thể tái tạo được dựa trên các tham số đã chỉ định hoặc một từ điển có một tập hợp tham số cho quy tắc đó, giúp 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ể sử 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 một tệp nhị phân, thực thi một tệp nhị phân, tạo một tệp trong kho lưu trữ hoặc tải một tệp xuống từ Internet). Hãy xem thư viện để biết thêm bối 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 phần phụ thuộc trong biểu đồ phần phụ thuộc (bao gồm cả chính tệp WORKSPACE) sẽ khiến hàm triển khai được thực thi.

Hàm triển khai có thể được khởi động lại nếu một phần phụ thuộc mà hàm yêu cầu là bị thiếu. Phần đầ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ì 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ả đối số nhãn đều 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 một 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.

Cuối cùng, đối với các kho lưu trữ không phải là local, chỉ có sự thay đổi trong các phần phụ thuộc sau đây mới có thể khiến quá trình khởi động lại:

  • Các tệp .bzl cần thiết để xác định quy tắc kho lưu trữ.
  • Khai báo quy tắc kho lưu trữ trong tệp WORKSPACE.
  • Giá trị của bất kỳ biến môi trường nào được khai báo bằng thuộc tính của hàm.environrepository_rule Giá trị của các biến môi trường đó có thể được thực thi từ dòng lệnh bằng --action_env cờ (nhưng cờ này sẽ làm mất hiệu lực mọi hành động của bản dựng).
  • Nội dung của bất kỳ tệp nào được sử dụng và tham chiếu bằng một nhãn (ví dụ: //mypkg:label.txt chứ 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 phần phụ thuộc của kho lưu trữ đó. Ví dụ: một kho lưu trữ tìm nạp 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ả kho lưu trữ bên ngoài vô điều kiện 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 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ụ tự động định cấu hình C++: sử dụng quy tắc kho lưu trữ để tự động tạo 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, 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.