Bzlmod คือชื่อรหัสของระบบทรัพยากร Dependency ภายนอกใหม่ ที่นำเสนอใน Bazel 5.0 โครงการนี้เริ่มใช้เพื่อแก้ไขประเด็นปัญหาต่างๆ ระบบเก่าที่ไม่สามารถค่อยๆ แก้ไขได้ โปรดดู ส่วนการแถลงปัญหาของเอกสารการออกแบบต้นฉบับ เพื่อดูรายละเอียดเพิ่มเติม
ใน Bazel 5.0 จะไม่มีการเปิดใช้ Bzlmod โดยค่าเริ่มต้น ธง
ต้องระบุ --experimental_enable_bzlmod
เพื่อให้ทำสิ่งต่อไปนี้ได้
อย่างที่ชื่อธงบอกไว้ ปัจจุบันฟีเจอร์นี้อยู่ระหว่างการทดสอบ
API และลักษณะการทำงานอาจมีการเปลี่ยนแปลงจนกว่าฟีเจอร์จะเปิดตัวอย่างเป็นทางการ
หากต้องการย้ายข้อมูลโปรเจ็กต์ไปยัง Bzlmod ให้ทำตามคู่มือการย้ายข้อมูล Bzlmod นอกจากนี้ คุณยังดูตัวอย่างการใช้ Bzlmod ได้ในที่เก็บ examples
โมดูล Bazel
ระบบทรัพยากร Dependency ภายนอกแบบเก่าซึ่งใช้ WORKSPACE
เป็นศูนย์กลาง
ที่เก็บ (หรือที่เก็บ) สร้างขึ้นผ่านกฎที่เก็บ (หรือกฎที่เก็บ)
แม้ว่า Repos จะยังคงเป็นแนวคิดที่สำคัญในระบบใหม่ โมดูลคือ
หน่วยหลักของทรัพยากร Dependency
โดยพื้นฐานแล้ว โมดูลก็คือโปรเจ็กต์ Bazel ที่มีได้หลายเวอร์ชัน โดยแต่ละเวอร์ชัน ซึ่งจะเผยแพร่ข้อมูลเมตาเกี่ยวกับโมดูลอื่นๆ ที่จะขึ้นอยู่กับโมดูลนั้นๆ นี่คือ คล้ายกับแนวคิดที่คุ้นเคยในระบบการจัดการทรัพยากร Dependency อื่น ซึ่งก็คือ Maven artifact, แพ็กเกจ npm, ลัง Cargo, โมดูล Go เป็นต้น
โมดูลจะระบุทรัพยากร Dependency โดยใช้คู่ name
และ version
แทน URL ที่เฉพาะเจาะจงใน WORKSPACE
จากนั้นจะค้นหาทรัพยากร Dependency ใน
รีจิสทรีของ Bazel โดยค่าเริ่มต้น
Bazel Central Registry ในพื้นที่ทํางาน แต่ละ
ก็จะเปลี่ยนเป็นที่เก็บ
MODULE.bazel
ทุกเวอร์ชันของทุกโมดูลมีไฟล์ MODULE.bazel
ที่ประกาศ
ทรัพยากร Dependency และข้อมูลเมตาอื่นๆ ต่อไปนี้คือตัวอย่างพื้นฐาน
module(
name = "my-module",
version = "1.0",
)
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
ไฟล์ MODULE.bazel
ควรอยู่ที่รูทของไดเรกทอรีพื้นที่ทำงาน
(ถัดจากไฟล์ WORKSPACE
) ซึ่งต่างจากไฟล์ WORKSPACE
คุณไม่จําเป็นต้อง
เพื่อระบุทรัพยากร Dependency แบบสโลแกน คุณควรระบุเฉพาะ
ทรัพยากร Dependency โดยตรง และไฟล์ MODULE.bazel
ของทรัพยากร Dependency
ประมวลผลเพื่อค้นหาทรัพยากร Dependency แบบทรานซิทีฟโดยอัตโนมัติ
ไฟล์ MODULE.bazel
คล้ายกับ BUILD
เนื่องจากไม่รองรับไฟล์
รูปแบบของการควบคุม และยังห้ามคำสั่ง load
ด้วย คำสั่ง
การรองรับไฟล์ MODULE.bazel
ได้แก่
module
เพื่อระบุข้อมูลเมตา เกี่ยวกับโมดูลปัจจุบัน รวมถึงชื่อ เวอร์ชัน และอื่นๆbazel_dep
เพื่อระบุโดยตรง ทรัพยากร Dependency ในโมดูล Bazel อื่นๆ- การลบล้าง ซึ่งใช้ได้เฉพาะโดยโมดูลรูทเท่านั้น (กล่าวคือ ไม่ใช่โดย ซึ่งใช้เป็นทรัพยากร Dependency ได้) เพื่อปรับแต่งลักษณะการทำงานของ การขึ้นต่อกันโดยตรงหรือแบบสับเปลี่ยนบางอย่าง:
- คำสั่งที่เกี่ยวข้องกับส่วนขยายโมดูล
รูปแบบเวอร์ชัน
Bazel มีระบบนิเวศที่หลากหลาย และโปรเจ็กต์ต่างๆ ก็ใช้รูปแบบการกำหนดเวอร์ชันที่หลากหลาย
ยอดนิยมที่สุดจนถึงตอนนี้คือ SemVer แต่ก็มี
รวมไปถึงโครงการที่โดดเด่นโดยใช้แผนการต่างๆ เช่น
Abseil ที่
เวอร์ชันจะยึดตามวันที่ เช่น 20210324.2
)
ด้วยเหตุนี้ Bzlmod จึงใช้ข้อกำหนดของ SemVer เวอร์ชันที่ผ่อนคลายมากกว่า ความแตกต่างมีดังนี้
- SemVer กำหนดว่าการ "เผยแพร่" ส่วนหนึ่งของเวอร์ชันต้องประกอบด้วย 3
กลุ่ม:
MAJOR.MINOR.PATCH
ใน Bazel ข้อกำหนดนี้ได้ผ่อนปรนแล้ว อนุญาตให้มีกลุ่มจำนวนเท่าใดก็ได้ - ใน SemVer แต่ละส่วนใน "รุ่น" ส่วนต้องเป็นตัวเลขเท่านั้น ใน Bazel เราอนุญาตให้ใช้ตัวอักษรได้เช่นเดียวกับการเปรียบเทียบ ความหมายตรงกับ "ตัวระบุ" ใน "ก่อนเผยแพร่"
- นอกจากนี้ ความหมายของการเพิ่มขึ้นหลัก เล็กน้อย และเวอร์ชันแพตช์นั้น ไม่ได้บังคับใช้ (อย่างไรก็ตาม โปรดดูระดับความเข้ากันได้สำหรับ รายละเอียดเกี่ยวกับวิธีที่เราแสดงความเข้ากันได้แบบย้อนหลัง)
เวอร์ชัน SemVer ที่ถูกต้องคือเวอร์ชันโมดูล Bazel ที่ถูกต้อง นอกจากนี้
SemVer เวอร์ชัน a
และ b
เปรียบเทียบ a < b
กับการคงไว้ชั่วคราวเดียวกันเมื่อ
เมื่อเทียบกับเวอร์ชันโมดูล Bazel
ความละเอียดเวอร์ชัน
ปัญหาการขึ้นต่อกันแบบ Diamond เป็นองค์ประกอบหลักของทรัพยากร Dependency ที่มีเวอร์ชัน พื้นที่จัดการ สมมติว่าคุณมีกราฟทรัพยากร Dependency ต่อไปนี้
A 1.0
/ \
B 1.0 C 1.1
| |
D 1.0 D 1.1
ควรใช้ D เวอร์ชันใด ในการแก้ปัญหานี้ Bzlmod ใช้ การเลือกเวอร์ชันขั้นต่ำ (MVS) ที่เปิดตัวในระบบโมดูล Go MVS ถือว่าใหม่ทั้งหมด โมดูลเวอร์ชันต่างๆ สามารถเข้ากันได้แบบย้อนหลัง เราจึงเลือกเวอร์ชันสูงสุด เวอร์ชันที่ระบุโดยขึ้นต่อกันใดๆ (D 1.1 ในตัวอย่างของเรา) เรียกว่า "ขั้นต่ำสุด" เนื่องจาก D 1.1 ในที่นี้เป็นเวอร์ชันต่ำสุดที่สามารถตรงตามข้อกำหนดของเรา ถึงแม้จะมี D 1.2 หรือรุ่นที่ใหม่กว่าอยู่แล้ว เราจะไม่เลือก ฟีเจอร์นี้มีประโยชน์เพิ่มเติม การเลือกเวอร์ชันมีความแม่นยำสูงและทำซ้ำได้
การแก้ปัญหาเวอร์ชันจะดำเนินการในเครื่องของคุณ ไม่ใช่จากรีจิสทรี
ระดับความเข้ากันได้
โปรดทราบว่าสมมติฐานของ MVS เกี่ยวกับความเข้ากันได้แบบย้อนหลังนั้นสามารถเป็นไปได้เพราะ ถือว่าโมดูลเวอร์ชันที่เข้ากันไม่ได้แบบย้อนหลังเป็นโมดูลที่แยกต่างหาก ในแง่ของ SemVer หมายความว่า A 1.x และ A 2.x ถือเป็นโมดูลที่แยกกัน และอยู่ในกราฟทรัพยากร Dependency ที่ได้รับการแก้ไขแล้วได้ ในทางกลับกัน จะเป็นไปได้ก็ต่อเมื่อเวอร์ชันหลักมีการเข้ารหัสในเส้นทางแพ็กเกจใน พยายามอย่าให้เวลาคอมไพล์หรือเวลาลิงก์ขัดแย้งกัน
เราไม่ได้รับการรับรองใน Bazel ดังนั้นเราจึงต้องมีวิธีที่จะแสดง "หลัก"
รุ่น" เพื่อตรวจหาเวอร์ชันที่ใช้ร่วมกันไม่ได้ย้อนหลัง หมายเลขนี้
เรียกว่าระดับความเข้ากันได้ และระบุโดยเวอร์ชันโมดูลแต่ละเวอร์ชันใน
คำสั่ง module()
เมื่อมีข้อมูลนี้อยู่ในมือ เราก็จะสามารถแสดงข้อผิดพลาด
เมื่อเราตรวจพบว่าเวอร์ชันต่างๆ ของโมดูลเดียวกันที่มีความเข้ากันได้แตกต่างกัน
ระดับต่างๆ อยู่ในกราฟทรัพยากร Dependency ที่ได้รับการแก้ไขแล้ว
ชื่อที่เก็บ
ทรัพยากร Dependency ภายนอกทุกรายการใน Bazel จะมีชื่อที่เก็บ บางครั้ง ก็
ทรัพยากร Dependency อาจใช้ผ่านชื่อที่เก็บที่ต่างกันได้ (ตัวอย่างเช่น ทั้ง 2 อย่าง
ค่าเฉลี่ย @io_bazel_skylib
และ @bazel_skylib
Bazel skylib) หรือ
อาจมีการใช้ชื่อที่เก็บสำหรับทรัพยากร Dependency ที่แตกต่างกันในโปรเจ็กต์ต่างๆ
ใน Bzlmod โมดูล Bazel จะสร้างที่เก็บได้และ ส่วนขยายโมดูล หากต้องการแก้ไขความขัดแย้งของชื่อที่เก็บ เรากำลังนำการแมปที่เก็บมาใช้ ในระบบใหม่ แนวคิดสำคัญมี 2 ประการดังนี้
ชื่อที่เก็บ Canonical: ชื่อที่เก็บที่ไม่ซ้ำกันทั่วโลกสำหรับแต่ละโดเมน ที่เก็บได้ ตัวแปรนี้จะเป็นชื่อไดเรกทอรีที่มีที่เก็บอยู่
ซึ่งมีโครงสร้างดังนี้ (คำเตือน: รูปแบบชื่อ Canonical คือ ไม่ใช่ API ที่คุณควรใช้ แต่อาจมีการเปลี่ยนแปลงได้ตลอดเวลา):- สำหรับที่เก็บโมดูล Bazel:
module_name~version
(ตัวอย่าง@bazel_skylib~1.0.3
) - สำหรับที่เก็บส่วนขยายโมดูล:
module_name~version~extension_name~repo_name
(ตัวอย่าง@rules_cc~0.0.1~cc_configure~local_config_cc
)
- สำหรับที่เก็บโมดูล Bazel:
ชื่อที่เก็บที่ปรากฏ: ชื่อที่เก็บที่จะใช้ใน
BUILD
และ.bzl
ไฟล์ในที่เก็บ ทรัพยากร Dependency เดียวกันอาจมีความแตกต่างกัน ในที่เก็บต่างๆ
มีการกำหนดไว้ดังนี้
ที่เก็บทุกแห่งมีพจนานุกรมการแมปที่เก็บสำหรับทรัพยากร Dependency โดยตรง
ซึ่งเป็นแมปจากชื่อที่เก็บที่ชัดเจนไปยังชื่อที่เก็บแบบ Canonical
เราใช้การแมปที่เก็บเพื่อแก้ไขชื่อที่เก็บเมื่อสร้าง
ป้ายกำกับ โปรดทราบว่าชื่อที่เก็บแบบ Canonical และ
คุณสามารถค้นหาการใช้งานชื่อที่เก็บที่ปรากฏได้โดยการแยกวิเคราะห์ MODULE.bazel
ดังนั้น ความขัดแย้งจึงสามารถตรวจพบและแก้ไขได้อย่างง่ายดายโดยไม่ส่งผลกระทบต่อ
ทรัพยากร Dependency อื่นๆ
ระดับความเข้มงวด
รูปแบบข้อมูลจำเพาะของทรัพยากร Dependency ใหม่ช่วยให้เราตรวจสอบได้อย่างเข้มงวดยิ่งขึ้น ใน โดยเฉพาะอย่างยิ่ง ขณะนี้เราบังคับใช้ว่าโมดูลจะสามารถใช้ที่เก็บที่สร้างจาก ทรัพยากร Dependency โดยตรง วิธีนี้จะช่วยป้องกันการหยุดทำงานโดยไม่ได้ตั้งใจและที่แก้ไขข้อบกพร่องได้ยาก เมื่อบางอย่างในกราฟทรัพยากร Dependency เปลี่ยนไป
การบังคับใช้นโยบายอย่างเคร่งครัดอิงตาม การแมปที่เก็บ โดยพื้นฐานแล้ว การแมปที่เก็บสำหรับแต่ละที่เก็บมีทรัพยากร Dependency โดยตรงทั้งหมดของที่เก็บนั้น ที่เก็บอื่นไม่ปรากฏ ทรัพยากร Dependency ที่มองเห็นได้สำหรับแต่ละที่เก็บคือ ดังนี้
- ที่เก็บโมดูล Bazel จะดูที่เก็บทั้งหมดที่แนะนำในไฟล์
MODULE.bazel
ได้ ผ่านbazel_dep
และuse_repo
- ที่เก็บส่วนขยายโมดูลสามารถดูทรัพยากร Dependency ทั้งหมดที่มองเห็นได้ของโมดูลนั้น ให้ส่วนขยาย รวมทั้งที่เก็บอื่นๆ ทั้งหมดที่สร้างขึ้นโดยโมดูลเดียวกัน ส่วนขยาย
รีจิสทรี
Bzlmod ค้นพบทรัพยากร Dependency โดยขอข้อมูลจาก Bazel registries รีจิสทรี Bazel เป็นเพียงฐานข้อมูลของโมดูล Bazel มีเพียง รูปแบบรีจิสทรีที่รองรับคือรีจิสทรีดัชนี ซึ่งเป็น ไดเรกทอรีภายในหรือเซิร์ฟเวอร์ HTTP แบบคงที่ตามรูปแบบที่เฉพาะเจาะจง ใน เราวางแผนที่จะเพิ่มการรองรับรีจิสทรีโมดูลเดียว ซึ่ง git repos ที่มีแหล่งที่มาและประวัติของโปรเจ็กต์
รีจิสทรีดัชนี
รีจิสทรีดัชนีคือไดเรกทอรีภายในหรือเซิร์ฟเวอร์ HTTP แบบคงที่ที่มี
เกี่ยวกับรายการโมดูล ซึ่งรวมถึงหน้าแรก ผู้ดูแล
MODULE.bazel
ไฟล์ของแต่ละเวอร์ชัน และวิธีดึงข้อมูลแหล่งที่มาของแต่ละเวอร์ชัน
เวอร์ชัน ที่สำคัญคือ ไม่จำเป็นต้องแสดงที่เก็บซอร์สด้วยตัวเอง
รีจิสทรีดัชนีต้องเป็นไปตามรูปแบบด้านล่าง
/bazel_registry.json
: ไฟล์ JSON ที่มีข้อมูลเมตาสำหรับรีจิสทรี เช่นmirrors
ระบุรายการมิเรอร์ที่จะใช้สำหรับที่เก็บถาวรของแหล่งที่มาmodule_base_path
ซึ่งระบุเส้นทางฐานสำหรับโมดูลที่มีlocal_repository
ประเภทในไฟล์source.json
/modules
: ไดเรกทอรีที่มีไดเรกทอรีย่อยสำหรับแต่ละโมดูลใน รีจิสทรี/modules/$MODULE
: ไดเรกทอรีที่มีไดเรกทอรีย่อยสำหรับแต่ละเวอร์ชัน ของโมดูลนี้ รวมถึงไฟล์ต่อไปนี้metadata.json
: ไฟล์ JSON ที่มีข้อมูลเกี่ยวกับโมดูล ด้วยฟิลด์ต่อไปนี้homepage
: URL หน้าแรกของโปรเจ็กต์maintainers
: รายการออบเจ็กต์ JSON โดยแต่ละรายการจะสอดคล้องกับ ข้อมูลผู้ดูแลโมดูลในรีจิสทรี โปรดทราบว่าอีเมลนี้ไม่จำเป็นต้องเหมือนกับผู้เขียนversions
: รายการเวอร์ชันทั้งหมดของโมดูลนี้ที่สามารถดูได้ใน รีจิสทรีนี้yanked_versions
: รายการเวอร์ชันที่แยกของโมดูลนี้ ช่วงเวลานี้ ยังเป็นเวอร์ชันที่ไม่มีการดำเนินการ แต่ในอนาคต เวอร์ชันที่แยกออกจะเป็น ข้ามหรือแสดงข้อผิดพลาด
/modules/$MODULE/$VERSION
: ไดเรกทอรีที่มีไฟล์ต่อไปนี้MODULE.bazel
: ไฟล์MODULE.bazel
ของโมดูลเวอร์ชันนี้source.json
: ไฟล์ JSON ที่มีข้อมูลเกี่ยวกับวิธีดึงข้อมูล ของโมดูลเวอร์ชันนี้- ประเภทเริ่มต้นคือ "เก็บถาวร" ด้วยฟิลด์ต่อไปนี้
url
: URL ของที่เก็บถาวรต้นทางintegrity
: ความสมบูรณ์ของทรัพยากรย่อย checksum ของที่เก็บถาวรstrip_prefix
: คำนำหน้าไดเรกทอรีที่จะตัดออกเมื่อดึงข้อมูล ที่เก็บถาวรของแหล่งที่มาpatches
: รายการสตริง แต่ละสตริงจะตั้งชื่อไฟล์แพตช์ ใช้กับไฟล์ที่เก็บถาวรที่แยกออกมา ไฟล์แพตช์อยู่ภายใต้ ไดเรกทอรี/modules/$MODULE/$VERSION/patches
patch_strip
: เหมือนกับอาร์กิวเมนต์--strip
ของแพตช์ Unix
- คุณเปลี่ยนประเภทเพื่อใช้เส้นทางภายในที่มีช่องต่อไปนี้ได้
type
:local_path
path
: เส้นทางในเครื่องไปยังที่เก็บ ซึ่งคำนวณดังนี้- หากเส้นทางเป็นเส้นทางสัมบูรณ์ ระบบจะใช้ตามที่เป็นอยู่
- หากเส้นทางเป็นเส้นทางสัมพัทธ์และ
module_base_path
เป็นเส้นทางสัมบูรณ์ แก้ไขเส้นทางเป็น<module_base_path>/<path>
แล้ว - ถ้าเส้นทางและ
module_base_path
เป็นเส้นทางสัมพัทธ์ เส้นทางจะเป็น แก้ไขเป็น<registry_path>/<module_base_path>/<path>
แล้ว รีจิสทรีต้องโฮสต์ในเครื่องและใช้โดย--registry=file://<registry_path>
มิฉะนั้น Bazel จะแสดงข้อผิดพลาด
- ประเภทเริ่มต้นคือ "เก็บถาวร" ด้วยฟิลด์ต่อไปนี้
patches/
: ไดเรกทอรีที่ไม่บังคับซึ่งมีไฟล์แพตช์ ใช้เมื่อsource.json
มี "เก็บถาวร" เท่านั้น ประเภท
สำนักทะเบียน Bazel Central
Bazel Central Registry (BCR) เป็นบริษัทรับจดทะเบียนดัชนีซึ่งมีอยู่ที่
bcr.bazel.build. เนื้อหา
ได้รับการสนับสนุนจากที่เก็บ GitHub
bazelbuild/bazel-central-registry
BCR ได้รับการดูแลโดยชุมชน Bazel สนับสนุนให้ผู้ร่วมให้ข้อมูล ดึงคำขอ โปรดดู นโยบายและขั้นตอนของ Bazel Central Registry
นอกจากการทำตามรูปแบบของรีจิสทรีดัชนีปกติแล้ว BCR ยังต้องมี
ไฟล์ presubmit.yml
สำหรับแต่ละเวอร์ชันโมดูล
(/modules/$MODULE/$VERSION/presubmit.yml
) ไฟล์นี้ระบุข้อมูลที่จำเป็นบางส่วน
สร้างและทดสอบเป้าหมายที่สามารถใช้เพื่อตรวจสอบความถูกต้องของเหตุการณ์
เวอร์ชันโมดูล และใช้โดยไปป์ไลน์ CI ของ BCR เพื่อให้แน่ใจว่าความสามารถในการทำงานร่วมกัน
ระหว่างโมดูลใน BCR
การเลือกรีจิสทรี
แฟล็ก Bazel ที่ทำซ้ำได้ --registry
สามารถใช้เพื่อระบุรายการของ
รีจิสทรีที่จะขอโมดูลเพื่อให้คุณตั้งค่าโปรเจ็กต์ในการดึงข้อมูลได้
ทรัพยากร Dependency จากรีจิสทรีหรือบุคคลที่สาม รีจิสทรีก่อนหน้านี้ใช้เวลา
ลำดับความสำคัญ เพื่อความสะดวก คุณสามารถใส่รายการ Flag --registry
ไว้ใน
.bazelrc
ของโปรเจ็กต์
ส่วนขยายโมดูล
ส่วนขยายโมดูลช่วยให้คุณขยายระบบโมดูลได้โดยการอ่านข้อมูลอินพุต
จากโมดูลต่างๆ ในกราฟทรัพยากร Dependency ได้ดำเนินการตรรกะที่จำเป็นเพื่อแก้ไข
ทรัพยากร Dependency และสุดท้ายคือการสร้างที่เก็บโดยการเรียกใช้กฎที่เก็บ ผลการค้นหาคล้ายกัน
ใช้งานกับมาโคร WORKSPACE
ในปัจจุบันได้ แต่จะเหมาะสมกว่าสำหรับโลกของ
และการขึ้นต่อกันแบบทรานซิทีฟ
ส่วนขยายโมดูลมีการกำหนดไว้ในไฟล์ .bzl
เช่นเดียวกับกฎที่เก็บหรือ
มาโคร WORKSPACE
รายการ โดยจะไม่เรียกใช้โดยตรง แต่แต่ละโมดูลสามารถ
ระบุส่วนของข้อมูลที่เรียกว่าแท็กสำหรับส่วนขยายที่จะอ่าน จากนั้น หลังจากโมดูล
ความละเอียดเวอร์ชันเสร็จแล้ว ระบบจะเรียกใช้ส่วนขยายโมดูล แต่ละส่วนขยายจะทำงาน
ทันทีที่ความละเอียดโมดูล (ยังเกิดขึ้นจริงก่อนที่จะมีการสร้างขึ้นมาจริงๆ) และ
จะอ่านแท็กทั้งหมดที่เป็นของแท็กนั้นในกราฟทรัพยากร Dependency ทั้งหมด
[ 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) ]
ในกราฟทรัพยากร Dependency ด้านบน A 1.1
และ B 1.2
เป็นต้น คือโมดูล Bazel
ให้นึกว่าแต่ละไฟล์เป็นไฟล์ MODULE.bazel
แต่ละโมดูลสามารถระบุ
แท็กสำหรับส่วนขยายโมดูล ในที่นี้มีการระบุบางส่วนสำหรับส่วนขยาย "maven"
และบางรายการมีการระบุเป็น "cargo" เมื่อกราฟทรัพยากร Dependency เสร็จสมบูรณ์ (สำหรับ
ตัวอย่างเช่น B 1.2
อาจมี bazel_dep
ใน D 1.3
แต่ได้รับการอัปเกรดเป็น
D 1.4
เนื่องจาก C
) ส่วนขยาย "ผู้เชี่ยวชาญ" ทำงาน และมีการอ่านค่า
maven.*
โดยใช้ข้อมูลในนั้นเพื่อตัดสินใจว่าจะสร้างที่เก็บใด
เช่นเดียวกันกับ "cargo" ส่วนขยาย
การใช้ส่วนขยาย
ส่วนขยายจะโฮสต์อยู่ในโมดูล Bazel เอง ดังนั้นหากต้องการใช้ส่วนขยายใน
คุณจะต้องเพิ่ม bazel_dep
ลงในโมดูลนั้นก่อน จากนั้นจึงเรียกใช้
use_extension
ในตัว
มาไว้ในขอบเขต ลองดูตัวอย่างต่อไปนี้
ไฟล์ MODULE.bazel
เพื่อใช้ "ผู้เชี่ยวชาญ" สมมติ ที่กำหนดไว้ใน
โมดูล rules_jvm_external
:
bazel_dep(name = "rules_jvm_external", version = "1.0")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
หลังจากนำส่วนขยายไปใช้กับขอบเขตแล้ว คุณสามารถใช้ไวยากรณ์แบบจุดเพื่อ
ระบุแท็กสำหรับแท็กดังกล่าว โปรดทราบว่าแท็กต้องเป็นไปตามสคีมาที่กำหนดโดย
คลาสแท็กที่เกี่ยวข้อง (ดูคำจำกัดความของส่วนขยาย
ที่ด้านล่าง) นี่คือตัวอย่างการระบุแท็ก maven.dep
และ 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")
หากส่วนขยายสร้างที่เก็บที่คุณต้องการใช้ในโมดูล ให้ใช้
คำสั่ง use_repo
สำหรับประกาศ
ให้พวกเขา เพื่อให้เป็นไปตามเงื่อนไข Dependency ที่เข้มงวดและหลีกเลี่ยงการใช้ชื่อที่เก็บในพื้นที่
ความขัดแย้ง
use_repo(
maven,
"org_junit_junit",
guava="com_google_guava_guava",
)
ที่เก็บที่สร้างโดยส่วนขยายจะเป็นส่วนหนึ่งของ API ดังนั้นจากแท็กที่คุณ
คุณควรทราบว่า "ผู้เชี่ยวชาญ" จะสร้างส่วนขยาย
ที่เก็บชื่อ "org_junit_junit" และที่เก็บชื่อ "com_google_guava_guava" ด้วย
use_repo
คุณเลือกที่จะเปลี่ยนชื่อได้ในขอบเขตของโมดูล ดังเช่น
"ฝรั่ง" ที่นี่
คำจำกัดความของส่วนขยาย
ส่วนขยายโมดูลได้รับการกำหนดในลักษณะเดียวกันกับกฎที่เก็บ โดยใช้
module_extension
ทั้ง 2 อย่างมีฟังก์ชันการใช้งาน แต่แม้ว่ากฎที่เก็บจะมี
แต่ส่วนขยายโมดูลจะมี
tag_class
โดยที่แต่ละช่องจะมี
จำนวนของแอตทริบิวต์ คลาสแท็กจะกำหนดสคีมาสำหรับแท็กที่แท็กนี้ใช้
ส่วนขยาย การต่อยอดตัวอย่างของ "ผู้เชี่ยวชาญ" สมมติ ส่วนขยายด้านบน:
# @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},
)
ประกาศเหล่านี้ระบุอย่างชัดเจนว่าแท็ก maven.dep
และ maven.pom
ที่ระบุ โดยใช้สคีมาแอตทริบิวต์ที่ระบุไว้ด้านบน
ฟังก์ชันการติดตั้งใช้งานคล้ายกับมาโคร WORKSPACE
แต่ต่างกันตรงที่
ได้รับออบเจ็กต์ module_ctx
ซึ่งจะให้
สิทธิ์เข้าถึงกราฟทรัพยากร Dependency และแท็กที่เกี่ยวข้องทั้งหมด การใช้งาน
จากนั้น ควรเรียกกฎที่เก็บเพื่อสร้างที่เก็บ:
# @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]
ในตัวอย่างข้างต้น เราจะดูโมดูลทั้งหมดในกราฟทรัพยากร Dependency
(ctx.modules
) แต่ละฟิลด์เป็น
ออบเจ็กต์ bazel_module
ซึ่งมีช่อง tags
จะแสดงแท็ก maven.*
ทั้งหมดในโมดูล จากนั้นเราจะเรียกใช้ยูทิลิตี CLI
Coursier เพื่อติดต่อ Maven และแก้ไขปัญหา สุดท้ายเราใช้ความละเอียด
ผลลัพธ์เพื่อสร้างจำนวนที่เก็บโดยใช้ maven_single_jar
สมมติ
กฎที่เก็บ