Bzlmod là tên mã của hệ thống phần phụ thuộc bên ngoài mới được giới thiệu trong Bazel 5.0. Hệ thống này được giới thiệu để giải quyết một số vấn đề của hệ thống cũ mà không thể khắc phục dần; hãy xem mục Tuyên bố về vấn đề trong tài liệu thiết kế ban đầu để biết thêm thông tin chi tiết.
Trong Bazel 5.0, Bzlmod không được bật theo mặc định; bạn cần chỉ định cờ --experimental_enable_bzlmod
để những nội dung sau có hiệu lực. Đúng như tên cờ, tính năng này hiện đang ở giai đoạn thử nghiệm; các API và hành vi có thể thay đổi cho đến khi tính năng này chính thức ra mắt.
Để di chuyển dự án sang Bzlmod, hãy làm theo Hướng dẫn di chuyển Bzlmod. Bạn cũng có thể tìm thấy các ví dụ về cách sử dụng Bzlmod trong kho lưu trữ examples.
Mô-đun Bazel
Hệ thống phần phụ thuộc bên ngoài dựa trên WORKSPACE
cũ tập trung vào kho lưu trữ (hoặc repo), được tạo thông qua quy tắc kho lưu trữ (hoặc quy tắc repo).
Mặc dù kho lưu trữ vẫn là một khái niệm quan trọng trong hệ thống mới, nhưng mô-đun là các đơn vị phụ thuộc cốt lõi.
Về cơ bản, mô-đun là một dự án Bazel có thể có nhiều phiên bản, mỗi phiên bản sẽ xuất bản siêu dữ liệu về các mô-đun khác mà nó phụ thuộc vào. Điều này tương tự như các khái niệm quen thuộc trong các hệ thống quản lý phần phụ thuộc khác: một cấu phần phần mềm Maven, một gói npm, một crate Cargo, một mô-đun Go, v.v.
Một mô-đun chỉ cần chỉ định các phần phụ thuộc bằng cách sử dụng các cặp name
và version
, thay vì các URL cụ thể trong WORKSPACE
. Sau đó, các phần phụ thuộc sẽ được tra cứu trong sổ đăng ký Bazel; theo mặc định, Sổ đăng ký trung tâm của Bazel. Trong không gian làm việc của bạn, mỗi mô-đun sẽ được chuyển thành một kho lưu trữ.
MODULE.bazel
Mỗi phiên bản của mỗi mô-đun đều có một tệp MODULE.bazel
khai báo các phần phụ thuộc và siêu dữ liệu khác. Sau đây là một ví dụ cơ bản:
module(
name = "my-module",
version = "1.0",
)
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
Tệp MODULE.bazel
phải nằm ở thư mục gốc của thư mục không gian làm việc (bên cạnh tệp WORKSPACE
). Không giống như tệp WORKSPACE
, bạn không cần chỉ định các phần phụ thuộc bắc cầu; thay vào đó, bạn chỉ nên chỉ định các phần phụ thuộc trực tiếp và các tệp MODULE.bazel
của các phần phụ thuộc sẽ được xử lý để tự động phát hiện các phần phụ thuộc bắc cầu.
Tệp MODULE.bazel
tương tự như tệp BUILD
vì không hỗ trợ bất kỳ dạng nào của luồng điều khiển; ngoài ra, tệp này còn cấm các câu lệnh load
. Các tệp chỉ thị MODULE.bazel
hỗ trợ là:
module
, để chỉ định siêu dữ liệu về mô-đun hiện tại, bao gồm cả tên, phiên bản, v.v.;bazel_dep
, để chỉ định các phần phụ thuộc trực tiếp trên các mô-đun Bazel khác;- Ghi đè, chỉ có thể được mô-đun gốc sử dụng (tức là không phải mô-đun đang được dùng làm phần phụ thuộc) để tuỳ chỉnh hành vi của một phần phụ thuộc trực tiếp hoặc bắc cầu nhất định:
- Chỉ thị liên quan đến phần mở rộng mô-đun:
Định dạng phiên bản
Bazel có một hệ sinh thái đa dạng và các dự án sử dụng nhiều lược đồ quản lý phiên bản. SemVer là lược đồ phổ biến nhất cho đến nay, nhưng cũng có những dự án nổi bật sử dụng các lược đồ khác, chẳng hạn như Abseil. Các phiên bản của dự án này dựa trên ngày, ví dụ: 20210324.2
.
Vì lý do này, Bzlmod áp dụng một phiên bản thoải mái hơn của quy cách SemVer. Các điểm khác biệt bao gồm:
- SemVer quy định rằng phần "release" (phát hành) của phiên bản phải bao gồm 3 phân đoạn:
MAJOR.MINOR.PATCH
. Trong Bazel, yêu cầu này được nới lỏng để cho phép sử dụng bất kỳ số lượng phân đoạn nào. - Trong SemVer, mỗi phân đoạn trong phần "bản phát hành" chỉ được chứa các chữ số. Trong Bazel, quy tắc này được nới lỏng để cho phép cả chữ cái, đồng thời ngữ nghĩa so sánh sẽ khớp với "mã nhận dạng" trong phần "phát hành trước".
- Ngoài ra, ngữ nghĩa của việc tăng phiên bản chính, phụ và bản vá không được thực thi. (Tuy nhiên, hãy xem cấp độ tương thích để biết thông tin chi tiết về cách chúng tôi biểu thị khả năng tương thích ngược.)
Mọi phiên bản SemVer hợp lệ đều là phiên bản mô-đun Bazel hợp lệ. Ngoài ra, 2 phiên bản SemVer a
và b
so sánh a < b
iff có cùng giá trị khi chúng được so sánh dưới dạng các phiên bản mô-đun Bazel.
Độ phân giải phiên bản
Vấn đề về sự phụ thuộc hình kim cương là một vấn đề thường gặp trong không gian quản lý phần phụ thuộc theo phiên bản. Giả sử bạn có biểu đồ phần phụ thuộc sau:
A 1.0
/ \
B 1.0 C 1.1
| |
D 1.0 D 1.1
Bạn nên sử dụng phiên bản D nào? Để giải quyết vấn đề này, Bzlmod sử dụng thuật toán Lựa chọn phiên bản tối thiểu (MVS) được giới thiệu trong hệ thống mô-đun Go. MVS giả định rằng tất cả các phiên bản mới của một mô-đun đều tương thích ngược, do đó, chỉ cần chọn phiên bản cao nhất do bất kỳ thành phần phụ thuộc nào chỉ định (D 1.1 trong ví dụ của chúng ta). Đây là phiên bản "tối thiểu" vì D 1.1 ở đây là phiên bản tối thiểu có thể đáp ứng các yêu cầu của chúng tôi; ngay cả khi có D 1.2 hoặc phiên bản mới hơn, chúng tôi cũng không chọn các phiên bản đó. Điều này mang lại lợi ích bổ sung là việc chọn phiên bản có độ trung thực cao và có thể tái tạo.
Quá trình phân giải phiên bản được thực hiện cục bộ trên máy của bạn, chứ không phải do sổ đăng ký.
Mức độ tương thích
Xin lưu ý rằng giả định của MVS về khả năng tương thích ngược là hoàn toàn có thể vì MVS chỉ coi các phiên bản không tương thích ngược của một mô-đun là một mô-đun riêng biệt. Về SemVer, điều đó có nghĩa là A 1.x và A 2.x được coi là các mô-đun riêng biệt và có thể cùng tồn tại trong biểu đồ phần phụ thuộc đã phân giải. Điều này có được là nhờ thực tế phiên bản chính được mã hoá trong đường dẫn gói trong Go, nên không có xung đột nào trong thời gian biên dịch hoặc thời gian liên kết.
Trong Bazel, chúng tôi không có những đảm bảo như vậy. Do đó, chúng ta cần một cách để biểu thị số "phiên bản chính" nhằm phát hiện các phiên bản không tương thích ngược. Số này được gọi là cấp độ tương thích và được chỉ định theo từng phiên bản mô-đun trong chỉ thị module()
. Khi có thông tin này, chúng ta có thể đưa ra lỗi khi phát hiện thấy các phiên bản của cùng một mô-đun có các cấp độ tương thích khác nhau trong biểu đồ phần phụ thuộc đã phân giải.
Tên kho lưu trữ
Trong Bazel, mọi phần phụ thuộc bên ngoài đều có tên kho lưu trữ. Đôi khi, cùng một phần phụ thuộc có thể được dùng thông qua các tên kho lưu trữ khác nhau (ví dụ: cả @io_bazel_skylib
và @bazel_skylib
đều có nghĩa là Bazel skylib) hoặc cùng một tên kho lưu trữ có thể được dùng cho các phần phụ thuộc khác nhau trong các dự án khác nhau.
Trong Bzlmod, các kho lưu trữ có thể được tạo bằng các mô-đun Bazel và phần mở rộng mô-đun. Để giải quyết xung đột về tên kho lưu trữ, chúng tôi đang áp dụng cơ chế ánh xạ kho lưu trữ trong hệ thống mới. Sau đây là 2 khái niệm quan trọng:
Tên kho lưu trữ chuẩn: Tên kho lưu trữ riêng biệt trên toàn cầu cho từng kho lưu trữ. Đây sẽ là tên thư mục mà kho lưu trữ nằm trong.
Được tạo như sau (Cảnh báo: định dạng tên chuẩn không phải là một API mà bạn nên phụ thuộc vào, định dạng này có thể thay đổi bất cứ lúc nào):- Đối với các kho lưu trữ mô-đun Bazel:
module_name~version
(Ví dụ.@bazel_skylib~1.0.3
) - Đối với các kho lưu trữ tiện ích mô-đun:
module_name~version~extension_name~repo_name
(Ví dụ.@rules_cc~0.0.1~cc_configure~local_config_cc
)
- Đối với các kho lưu trữ mô-đun Bazel:
Tên kho lưu trữ rõ ràng: Tên kho lưu trữ sẽ được dùng trong các tệp
BUILD
và.bzl
trong một kho lưu trữ. Cùng một phần phụ thuộc có thể có tên hiển thị khác nhau trong các kho lưu trữ khác nhau.
Được xác định như sau:
Mọi kho lưu trữ đều có một từ điển liên kết kho lưu trữ về các phần phụ thuộc trực tiếp. Đây là một mối liên kết từ tên kho lưu trữ rõ ràng đến tên kho lưu trữ chuẩn.
Chúng tôi sử dụng mối liên kết kho lưu trữ để phân giải tên kho lưu trữ khi tạo nhãn. Xin lưu ý rằng không có xung đột về tên kho lưu trữ chuẩn và các cách sử dụng tên kho lưu trữ rõ ràng có thể được phát hiện bằng cách phân tích cú pháp tệp MODULE.bazel
. Do đó, bạn có thể dễ dàng phát hiện và giải quyết các xung đột mà không ảnh hưởng đến các phần phụ thuộc khác.
Phần phụ thuộc nghiêm ngặt
Định dạng chỉ định phần phụ thuộc mới cho phép chúng tôi thực hiện các quy trình kiểm tra nghiêm ngặt hơn. Cụ thể, giờ đây, chúng tôi thực thi quy tắc rằng một mô-đun chỉ có thể sử dụng các kho lưu trữ được tạo từ các phần phụ thuộc trực tiếp của mô-đun đó. Điều này giúp ngăn chặn các lỗi vô tình và khó gỡ lỗi khi có thay đổi trong biểu đồ phần phụ thuộc bắc cầu.
Strict deps được triển khai dựa trên ánh xạ kho lưu trữ. Về cơ bản, việc ánh xạ kho lưu trữ cho mỗi kho lưu trữ chứa tất cả các phần phụ thuộc trực tiếp của kho lưu trữ đó, mọi kho lưu trữ khác đều không hiển thị. Các phần phụ thuộc hiển thị cho mỗi kho lưu trữ được xác định như sau:
- Kho lưu trữ mô-đun Bazel có thể thấy tất cả các kho lưu trữ được giới thiệu trong tệp
MODULE.bazel
thông quabazel_dep
vàuse_repo
. - Một kho lưu trữ tiện ích mô-đun có thể thấy tất cả các phần phụ thuộc hiển thị của mô-đun cung cấp tiện ích, cộng với tất cả các kho lưu trữ khác do cùng một tiện ích mô-đun tạo ra.
Tổ chức quản lý tên miền
Bzlmod phát hiện các phần phụ thuộc bằng cách yêu cầu thông tin của chúng từ sổ đăng ký Bazel. Sổ đăng ký Bazel chỉ đơn giản là một cơ sở dữ liệu gồm các mô-đun Bazel. Hình thức duy nhất được hỗ trợ của sổ đăng ký là sổ đăng ký chỉ mục. Đây là một thư mục cục bộ hoặc máy chủ HTTP tĩnh tuân theo một định dạng cụ thể. Trong tương lai, chúng tôi dự định sẽ thêm tính năng hỗ trợ sổ đăng ký một mô-đun. Đây chỉ đơn giản là các kho lưu trữ git chứa nguồn và nhật ký của một dự án.
Sổ đăng ký chỉ mục
Sổ đăng ký chỉ mục là một thư mục cục bộ hoặc một máy chủ HTTP tĩnh chứa thông tin về danh sách các mô-đun, bao gồm cả trang chủ, người duy trì, tệp MODULE.bazel
của mỗi phiên bản và cách tìm nạp nguồn của mỗi phiên bản. Điều đáng chú ý là nó không cần tự phân phát các tệp lưu trữ nguồn.
Một sổ đăng ký chỉ mục phải tuân theo định dạng dưới đây:
/bazel_registry.json
: Tệp JSON chứa siêu dữ liệu cho sổ đăng ký, chẳng hạn như:mirrors
, chỉ định danh sách các máy chủ phản chiếu sẽ dùng cho kho lưu trữ nguồn.module_base_path
, chỉ định đường dẫn cơ sở cho các mô-đun có loạilocal_repository
trong tệpsource.json
.
/modules
: Một thư mục chứa thư mục con cho từng mô-đun trong sổ đăng ký này./modules/$MODULE
: Một thư mục chứa một thư mục con cho từng phiên bản của mô-đun này, cũng như tệp sau đây:metadata.json
: Tệp JSON chứa thông tin về mô-đun, có các trường sau:homepage
: URL của trang chủ dự án.maintainers
: Danh sách các đối tượng JSON, mỗi đối tượng tương ứng với thông tin của một người duy trì mô-đun trong sổ đăng ký. Xin lưu ý rằng điều này không nhất thiết phải giống với tác giả của dự án.versions
: Danh sách tất cả các phiên bản của mô-đun này có trong sổ đăng ký này.yanked_versions
: Danh sách các phiên bản bị rút lại của mô-đun này. Hiện tại, thao tác này không có tác dụng, nhưng trong tương lai, các phiên bản bị rút sẽ bị bỏ qua hoặc gây ra lỗi.
/modules/$MODULE/$VERSION
: Một thư mục chứa các tệp sau:MODULE.bazel
: TệpMODULE.bazel
của phiên bản mô-đun này.source.json
: Tệp JSON chứa thông tin về cách tìm nạp nguồn của phiên bản mô-đun này.- Loại mặc định là "archive" (lưu trữ) với các trường sau:
url
: URL của tệp lưu trữ nguồn.integrity
: Tổng kiểm tra Tính toàn vẹn của tài nguyên phụ của kho lưu trữ.strip_prefix
: Tiền tố thư mục cần loại bỏ khi trích xuất tệp lưu trữ nguồn.patches
: Một danh sách các chuỗi, mỗi chuỗi đặt tên cho một tệp vá để áp dụng cho kho lưu trữ đã trích xuất. Các tệp vá nằm trong thư mục/modules/$MODULE/$VERSION/patches
.patch_strip
: Tương tự như đối số--strip
của bản vá Unix.
- Bạn có thể thay đổi loại để sử dụng đường dẫn cục bộ với các trường sau:
type
:local_path
path
: Đường dẫn cục bộ đến kho lưu trữ, được tính như sau:- Nếu đường dẫn là đường dẫn tuyệt đối, thì đường dẫn đó sẽ được dùng nguyên trạng.
- Nếu đường dẫn là đường dẫn tương đối và
module_base_path
là đường dẫn tuyệt đối, thì đường dẫn sẽ được phân giải thành<module_base_path>/<path>
- Nếu đường dẫn và
module_base_path
đều là đường dẫn tương đối, thì đường dẫn sẽ được phân giải thành<registry_path>/<module_base_path>/<path>
. Sổ đăng ký phải được lưu trữ cục bộ và do--registry=file://<registry_path>
sử dụng. Nếu không, Bazel sẽ báo lỗi.
- Loại mặc định là "archive" (lưu trữ) với các trường sau:
patches/
: Thư mục không bắt buộc chứa các tệp bản vá, chỉ được dùng khisource.json
có loại "archive".
Sổ đăng ký trung tâm Bazel
Sổ đăng ký trung tâm Bazel (BCR) là một sổ đăng ký chỉ mục nằm tại bcr.bazel.build. Nội dung của trang này được hỗ trợ bởi kho lưu trữ GitHub bazelbuild/bazel-central-registry
.
BCR do cộng đồng Bazel duy trì; các cộng tác viên có thể gửi yêu cầu kéo. Xem Chính sách và quy trình của Sổ đăng ký trung tâm Bazel.
Ngoài việc tuân theo định dạng của một sổ đăng ký chỉ mục thông thường, BCR còn yêu cầu một tệp presubmit.yml
cho mỗi phiên bản mô-đun (/modules/$MODULE/$VERSION/presubmit.yml
). Tệp này chỉ định một số mục tiêu kiểm thử và bản dựng thiết yếu có thể dùng để kiểm tra nhanh tính hợp lệ của phiên bản mô-đun này và được các quy trình CI của BCR dùng để đảm bảo khả năng tương tác giữa các mô-đun trong BCR.
Chọn sổ đăng ký
Bạn có thể dùng cờ Bazel có thể lặp lại --registry
để chỉ định danh sách các sổ đăng ký cần yêu cầu mô-đun, nhờ đó, bạn có thể thiết lập dự án để tìm nạp các phần phụ thuộc từ sổ đăng ký nội bộ hoặc của bên thứ ba. Các lượt đăng ký trước đó sẽ được ưu tiên. Để thuận tiện, bạn có thể đặt danh sách các cờ --registry
trong tệp .bazelrc
của dự án.
Tiện ích mô-đun
Tiện ích mô-đun cho phép bạn mở rộng hệ thống mô-đun bằng cách đọc dữ liệu đầu vào từ các mô-đun trên biểu đồ phần phụ thuộc, thực hiện logic cần thiết để phân giải các phần phụ thuộc và cuối cùng tạo các kho lưu trữ bằng cách gọi các quy tắc kho lưu trữ. Các macro này có chức năng tương tự như macro WORKSPACE
ngày nay, nhưng phù hợp hơn trong thế giới của các mô-đun và phần phụ thuộc bắc cầu.
Các tiện ích mô-đun được xác định trong các tệp .bzl
, giống như các quy tắc kho lưu trữ hoặc macro WORKSPACE
. Chúng không được gọi trực tiếp; thay vào đó, mỗi mô-đun có thể chỉ định các phần dữ liệu được gọi là thẻ để các tiện ích đọc. Sau đó, sau khi quá trình phân giải phiên bản mô-đun hoàn tất, các tiện ích mô-đun sẽ chạy. Mỗi tiện ích được chạy một lần sau khi phân giải mô-đun (vẫn trước khi quá trình tạo thực sự diễn ra) và có thể đọc tất cả các thẻ thuộc về tiện ích đó trên toàn bộ biểu đồ phần phụ thuộc.
[ A 1.1 ]
[ * maven.dep(X 2.1) ]
[ * maven.pom(...) ]
/ \
bazel_dep / \ bazel_dep
/ \
[ B 1.2 ] [ C 1.0 ]
[ * maven.dep(X 1.2) ] [ * maven.dep(X 2.1) ]
[ * maven.dep(Y 1.3) ] [ * cargo.dep(P 1.1) ]
\ /
bazel_dep \ / bazel_dep
\ /
[ D 1.4 ]
[ * maven.dep(Z 1.4) ]
[ * cargo.dep(Q 1.1) ]
Trong biểu đồ phần phụ thuộc mẫu ở trên, A 1.1
và B 1.2
, v.v. là các mô-đun Bazel; bạn có thể coi mỗi mô-đun là một tệp MODULE.bazel
. Mỗi mô-đun có thể chỉ định một số thẻ cho các tiện ích mô-đun; ở đây, một số thẻ được chỉ định cho tiện ích "maven" và một số thẻ được chỉ định cho "cargo". Khi biểu đồ phần phụ thuộc này được hoàn tất (ví dụ: có thể B 1.2
thực sự có bazel_dep
trên D 1.3
nhưng đã được nâng cấp lên D 1.4
do C
), tiện ích "maven" sẽ chạy và đọc tất cả các thẻ maven.*
, sử dụng thông tin trong đó để quyết định tạo kho lưu trữ nào.
Tương tự đối với tiện ích "hàng hoá".
Cách sử dụng tiện ích
Các tiện ích được lưu trữ trong chính các mô-đun Bazel, vì vậy, để sử dụng một tiện ích trong mô-đun của mình, trước tiên bạn cần thêm một bazel_dep
vào mô-đun đó, rồi gọi hàm use_extension
tích hợp sẵn để đưa tiện ích đó vào phạm vi. Hãy xem xét ví dụ sau đây, một đoạn mã từ tệp MODULE.bazel
để dùng một tiện ích "maven" giả định được xác định trong mô-đun rules_jvm_external
:
bazel_dep(name = "rules_jvm_external", version = "1.0")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
Sau khi đưa tiện ích vào phạm vi, bạn có thể sử dụng cú pháp dấu chấm để chỉ định thẻ cho tiện ích đó. Xin lưu ý rằng các thẻ cần tuân theo lược đồ do các lớp thẻ tương ứng xác định (xem định nghĩa về tiện ích bên dưới). Sau đây là ví dụ chỉ định một số thẻ maven.dep
và maven.pom
.
maven.dep(coord="org.junit:junit:3.0")
maven.dep(coord="com.google.guava:guava:1.2")
maven.pom(pom_xml="//:pom.xml")
Nếu tiện ích tạo ra các kho lưu trữ mà bạn muốn dùng trong mô-đun, hãy dùng chỉ thị use_repo
để khai báo các kho lưu trữ đó. Điều này nhằm đáp ứng điều kiện deps nghiêm ngặt và tránh xung đột tên kho lưu trữ cục bộ.
use_repo(
maven,
"org_junit_junit",
guava="com_google_guava_guava",
)
Các kho lưu trữ do một tiện ích tạo ra là một phần của API, vì vậy, từ các thẻ mà bạn đã chỉ định, bạn nên biết rằng tiện ích "maven" sẽ tạo ra một kho lưu trữ có tên là "org_junit_junit" và một kho lưu trữ có tên là "com_google_guava_guava". Với use_repo
, bạn có thể đổi tên chúng trong phạm vi mô-đun của mình (không bắt buộc), chẳng hạn như thành "guava" ở đây.
Định nghĩa về tiện ích
Các tiện ích mô-đun được xác định tương tự như các quy tắc kho lưu trữ, bằng cách sử dụng hàm module_extension
.
Cả hai đều có một hàm triển khai; nhưng trong khi các quy tắc kho lưu trữ có một số thuộc tính, thì các tiện ích mô-đun có một số tag_class
es, mỗi tiện ích có một số thuộc tính. Các lớp thẻ xác định giản đồ cho các thẻ mà tiện ích này sử dụng. Tiếp tục ví dụ về tiện ích "maven" giả định ở trên:
# @rules_jvm_external//:extensions.bzl
maven_dep = tag_class(attrs = {"coord": attr.string()})
maven_pom = tag_class(attrs = {"pom_xml": attr.label()})
maven = module_extension(
implementation=_maven_impl,
tag_classes={"dep": maven_dep, "pom": maven_pom},
)
Các khai báo này cho thấy rõ rằng bạn có thể chỉ định thẻ maven.dep
và maven.pom
bằng cách sử dụng giản đồ thuộc tính được xác định ở trên.
Hàm triển khai tương tự như macro WORKSPACE
, ngoại trừ việc hàm này nhận được một đối tượng module_ctx
, cho phép truy cập vào biểu đồ phần phụ thuộc và tất cả các thẻ có liên quan. Sau đó, hàm triển khai sẽ gọi các quy tắc kho lưu trữ để tạo kho lưu trữ:
# @rules_jvm_external//:extensions.bzl
load("//:repo_rules.bzl", "maven_single_jar")
def _maven_impl(ctx):
coords = []
for mod in ctx.modules:
coords += [dep.coord for dep in mod.tags.dep]
output = ctx.execute(["coursier", "resolve", coords]) # hypothetical call
repo_attrs = process_coursier(output)
[maven_single_jar(**attrs) for attrs in repo_attrs]
Trong ví dụ trên, chúng ta sẽ xem xét tất cả các mô-đun trong biểu đồ phần phụ thuộc (ctx.modules
), mỗi mô-đun là một đối tượng bazel_module
có trường tags
hiển thị tất cả các thẻ maven.*
trên mô-đun. Sau đó, chúng ta sẽ gọi tiện ích CLI Coursier để liên hệ với Maven và thực hiện quy trình phân giải. Cuối cùng, chúng ta sử dụng kết quả phân giải để tạo một số kho lưu trữ, sử dụng quy tắc kho lưu trữ maven_single_jar
giả định.