Quy tắc kho lưu trữ

Báo cáo vấn đề Xem nguồn Hằng đêm · 7,4 của Google. 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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 kín trong giai đoạn tải Bazel. Mỗi quy tắc của kho lưu trữ bên ngoài sẽ tạo không gian làm việc riêng, với tệp và cấu phần phần mềm BUILD riêng. Họ có thể được dùng để phụ thuộc vào bên thứ ba các thư viện (chẳng hạn như 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.

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 mới cho kho lưu trữ 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. Nó 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 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 được tải khi bạn tạo quy tắc 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.

Thuộc tính

Thuộc tính là đố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 thuộc tính được xác định sẽ được liệt kê khi bạn xác định quy tắc kho lưu trữ. Ví dụ về cách xác định các thuộc tính urlsha256 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ư quy tắc bản dựng). Hai thuộc tính ngầm ẩn là name (giống như đối với các quy tắc bản dựng) và repo_mapping. Bạn 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 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ì thuộc tính đó 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 cần có 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 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 giá trị nhận dạng thay đổi cụ thể thay vì một nhánh nổi ban đầu được chỉ định.

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 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 thông tin. 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?

Chức năng triển khai của 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 kho lưu trữ) 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 kho lưu trữ trong tệp hệ thống. Đâ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, kho lưu trữ không nhất thiết phải được tìm nạp lại khi có thay đổi nào đó 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 đó, 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 phầ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 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. Giá trị của các biến môi trường này có thể được kết nối 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 sync đượ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 sync 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 bạn đặt cờ local, 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 bất kỳ tệp nào ảnh hưởng đến nội dung khai báo của kho lưu trữ thay đổi (ví dụ: tệp WORKSPACE hoặc tệp mà tệp đó tải), bất kể các thay đổi đó có dẫn đến thay đổi nội dung khai báo của kho lưu trữ hoặc mã của kho lưu trữ hay không.

    Các kho lưu trữ không 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à giao tiếp với mạng hoặc có chi phí cao.

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

Bạn có thể khởi động lại hàm triển khai trong khi một kho lưu trữ đang được tìm nạp nếu thiếu một phần phụ thuộc mà hàm này yêu cầ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ó sự thay đổi nào định nghĩa hoặc phần phụ thuộc. Ví dụ: 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 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 sync.

Ngoài ra, một số quy tắc 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 những 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 sync --configure.

Ví dụ

  • Chuỗi công cụ C++ được tự động định cấu hình: 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á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.

  • Theo mặc định, rules_jvm_external sẽ tạo một kho lưu trữ bên ngoài có tên là @maven. 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.