Quy tắc kho lưu trữ

Báo cáo vấn đề Xem nguồn Hằng đêm · 7,3 · 7,2 · 7.1 · 7 · 6,5

Trang này trình bày cách xác định các quy tắc về kho lưu trữ và cung cấp các ví dụ cho chi tiết hơn.

Kho lưu trữ bên ngoài là một cây thư mục, chứa các tệp nguồn có thể sử dụng trong bản dựng Bazel, được tạo theo yêu cầu bằng chạy quy tắc kho lưu trữ tương ứng. Repos có thể được xác định theo vô số nhưng cuối cùng, mỗi repo được xác định bằng cách gọi quy tắc repo, giống như mục tiêu bản dựng được xác định bằng cách gọi quy tắc bản dựng. Chúng có thể được dùng để phụ thuộc vào các thư viện của bên thứ ba (chẳng hạn như các thư viện đóng gói Maven) mà còn để tạo Các tệp BUILD dành riêng cho máy chủ lưu trữ Bazel đang chạy.

Định nghĩa quy tắc kho lưu trữ

Trong tệp .bzl, hãy sử dụng Hàm repository_rule để xác định quy tắc repo mới và lưu trữ nó trong biến toàn cục. Sau khi xác định quy tắc repo, nó có thể được gọi dưới dạng hàm để xác định repos. Lời gọi này thường là được thực hiện từ bên trong quá trình triển khai tiện ích mô-đun .

Hai thành phần chính của định nghĩa quy tắc repo là giản đồ thuộc tính và chức năng triển khai. Giản đồ thuộc tính xác định tên và loại được truyền đến lệnh gọi quy tắc repo và hàm triển khai chạy khi cần tìm nạp repo.

Thuộc tính

Thuộc tính là các đối số được truyền đến lệnh gọi quy tắc repo. Giản đồ của các thuộc tính mà quy tắc repo chấp nhận được chỉ định bằng đối số attrs khi quy tắc repo được xác định bằng lệnh gọi đến repository_rule. Ví dụ về cách xác định Thuộc tính urlsha256 dưới dạng chuỗi:

http_archive = repository_rule(
    implementation=_impl,
    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ó thuộc tính name được xác định ngầm. Đây là một thuộc tính chuỗi hoạt động hơi kỳ diệu: khi được chỉ định làm dữ liệu đầu vào cho lệnh gọi quy tắc repo, nó sẽ có một tên repo rõ ràng; nhưng khi đọc từ hàm triển khai của quy tắc repo bằng repository_ctx.attr.name thì hàm này sẽ trả về tên kho lưu trữ chính tắc.

Chức năng triển khai

Mọi quy tắc repo đều yêu cầu một hàm implementation. Chiến dịch này có 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 trả về None để biểu thị rằng quy tắc có thể tái tạo được các tham số được chỉ định hoặc một lệnh chính tả có tập hợp các tham số cho quy tắc đó sẽ biến quy tắc đó thành quy tắc có thể tái tạo tạo ra cùng một repo. Để ví dụ: đối với quy tắc theo dõi kho lưu trữ git, 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 ban đầu đã chỉ định.

Tham số đầu vào repository_ctx có thể được dùng để truy cập các giá trị thuộc tính và các hàm không gián đoạ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 tệp xuống từ Internet). Hãy xem tài liệu API để ngữ cảnh hơn. 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 quy tắc kho lưu trữ được thực thi khi Bazel cần một đích từ kho lưu trữ đó, ví dụ: khi một mục tiêu khác (trong một mục tiêu khác repo) phụ thuộc vào nó hoặc liệu nó có được đề cập trên dòng lệnh hay không. Chiến lược phát hành đĩa đơn hàm triển khai dự kiến sẽ tạo repo trong tệp hệ thống. Đây được gọi là "tìm nạp" kho lưu trữ.

Khác với 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 một điều gì đó thay đổi khiến kho lưu trữ khác đi. Đây là vì có những thứ mà Bazel không thể phát hiện được hoặc gây ra quá nhiều chi phí trên mỗi bản dựng (ví dụ: những thứ được tìm nạp khỏi mạng). Do đó, các kho lưu trữ chỉ được tìm nạp lại nếu một trong những thay đổi sau đây:

  • Các thuộc tính được truyền đến lệnh gọi quy tắc kho lưu trữ.
  • Mã Starlark bao gồm việc triển khai quy tắc repo.
  • Giá trị của bất kỳ biến môi trường nào được truyền đến giá trị của repository_ctx getenv() hoặc được khai báo bằng environ của phương thức repository_rule. Các giá trị của các biến môi trường này có thể được gắn cứng trên dòng lệnh bằng Cờ --repo_env.
  • Nội dung của bất kỳ tệp nào được truyền cho read(), execute() và các phương thức tương tự của repository_ctx được tham chiếu bằng một nhãn (ví dụ: //mypkg:label.txt nhưng không phải mypkg/label.txt)
  • Khi bazel fetch --force được thực thi.

Có hai tham số của repository_rule kiểm soát thời điểm kho lưu trữ được tìm nạp lại:

  • Nếu bạn đặt cờ configure, thì kho lưu trữ chỉ được tìm nạp lại trên bazel fetch khi tham số --configure được truyền vào đó (nếu giá trị chưa đặt, lệnh này sẽ không gây ra việc tìm nạp lại)
  • Nếu cờ local được đặt thì ngoài những trường hợp trên, kho lưu trữ sẽ cũng tìm nạp lại khi máy chủ Bazel khởi động lại.

Khởi động lại hàm triển khai

Bạn có thể bắt đầu lại hàm triển khai trong khi một kho lưu trữ đang diễn ra được tìm nạp nếu phần phụ thuộc mà nó yêu cầu bị thiếu. Trong trường hợp đó, việc 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. Người nhận tránh việc khởi động lại một cách không cần thiết (việc khởi động lại rất tốn kém vì việc truy cập mạng có thể phải lặp lại), đối số nhãn được tìm nạp trước, miễn là tất cả các đối số trên đối số nhãn có thể được phân giải thành tệp hiện có. Lưu ý rằng việc giải quyết đường dẫn từ một chuỗi hoặc nhãn chỉ được tạo trong quá trình thực thi của hàm vẫn có thể gây ra khởi động lại.

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 phần định nghĩa hoặc phần phụ thuộc. Ví dụ: một kho lưu trữ có thể tìm nạp các nguồn 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 là 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 một cách vô điều kiện bằng cách gọi bazel fetch --force --all.

Ngoài ra, một số quy tắc repo kiểm tra máy cục bộ và có thể trở thành 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 đó khi repository_rule có tập hợp thuộc tính configure, hãy sử dụng bazel fetch --all --configure.

Ví dụ

  • Chuỗi công cụ được tự động định cấu hình C++: nó sẽ sử dụng quy tắc repo để 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ợ.

  • Truy cập vào kho lưu trữ sử dụng một vài 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 có chức năng 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.