โมดูล Bazel

วันที่ รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

โมดูล Bazel คือโปรเจ็กต์ Bazel ที่มีได้หลายเวอร์ชัน โดยแต่ละเวอร์ชัน ซึ่งจะเผยแพร่ข้อมูลเมตาเกี่ยวกับโมดูลอื่นๆ ที่เกี่ยวข้อง นี่คือ คล้ายกับแนวคิดที่คุ้นเคยในระบบการจัดการทรัพยากร Dependency อื่นๆ เช่น อาร์ติแฟกต์ Maven, แพ็กเกจ npm, โมดูล Go หรือลัง Cargo

โมดูลต้องมีไฟล์ MODULE.bazel ที่รูทที่เก็บ (ถัดจาก WORKSPACE) ไฟล์นี้เป็นไฟล์ Manifest ของโมดูล โดยประกาศชื่อไฟล์ เวอร์ชัน รายการทรัพยากร 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")

หากต้องการปรับความละเอียดของโมดูล Bazel จะเริ่มต้นด้วยการอ่าน MODULE.bazel แล้วขอทรัพยากร Dependency ต่างๆ ซ้ำหลายครั้ง MODULE.bazel ไฟล์จากรีจิสทรีของ Bazel จนกว่าจะมีข้อมูล จะค้นพบกราฟทรัพยากร Dependency ทั้งหมด

โดยค่าเริ่มต้น Bazel จะเลือกเวอร์ชัน 1 เวอร์ชันของแต่ละโมดูล ในการใช้กัน Bazel แสดงแต่ละโมดูลด้วยที่เก็บ และปรึกษาสำนักทะเบียน อีกครั้งเพื่อเรียนรู้วิธีกำหนดที่เก็บแต่ละรายการ

รูปแบบเวอร์ชัน

Bazel มีระบบนิเวศที่หลากหลาย และโปรเจ็กต์ต่างๆ ก็ใช้รูปแบบการกำหนดเวอร์ชันที่หลากหลาย ยอดนิยมที่สุดจนถึงตอนนี้คือ SemVer แต่ก็มี รวมไปถึงโครงการที่โดดเด่นโดยใช้แผนการต่างๆ เช่น Abseil ที่ เวอร์ชันจะยึดตามวันที่ เช่น 20210324.2)

ด้วยเหตุนี้ Bzlmod จึงใช้ข้อกำหนดของ SemVer เวอร์ชันที่ผ่อนคลายมากกว่า ความแตกต่างมีดังนี้

  • SemVer กำหนดว่าการ "เผยแพร่" ส่วนหนึ่งของเวอร์ชันต้องประกอบด้วย 3 กลุ่ม: MAJOR.MINOR.PATCH ใน Bazel ข้อกำหนดนี้ได้ผ่อนปรนแล้ว อนุญาตให้มีกลุ่มจำนวนเท่าใดก็ได้
  • ใน SemVer แต่ละส่วนใน "รุ่น" ส่วนต้องเป็นตัวเลขเท่านั้น ใน Bazel เราอนุญาตให้ใช้ตัวอักษรได้เช่นเดียวกับการเปรียบเทียบ ความหมายตรงกับ "ตัวระบุ" ใน "ก่อนเผยแพร่"
  • นอกจากนี้ ความหมายของการเพิ่มขึ้นหลัก เล็กน้อย และเวอร์ชันแพตช์นั้น ไม่ได้บังคับใช้ โปรดดูระดับความเข้ากันได้สำหรับ รายละเอียดว่าเราแสดงถึงความเข้ากันได้แบบย้อนหลังได้อย่างไร

เวอร์ชัน SemVer ที่ถูกต้องคือเวอร์ชันโมดูล Bazel ที่ถูกต้อง นอกจากนี้ SemVer เวอร์ชัน a และ b จะเปรียบเทียบ a < b ก็ต่อเมื่อมีการคงไว้ชั่วคราวเดียวกันเมื่อ และถูกเปรียบเทียบด้วยเวอร์ชันโมดูล Bazel

การเลือกเวอร์ชัน

ลองพิจารณาปัญหาเกี่ยวกับการขึ้นต่อกันแบบไดมอนด์ ซึ่งเป็นองค์ประกอบหลักในทรัพยากร 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 จะสร้าง กระบวนการเลือกเวอร์ชันที่มีความแม่นยำสูงและทำซ้ำได้

เวอร์ชันแย้ง

รีจิสทรีสามารถประกาศบางเวอร์ชันเป็น yanked ได้หากควรหลีกเลี่ยง (เช่น สำหรับช่องโหว่ด้านความปลอดภัย) Bazel แสดงข้อผิดพลาดเมื่อเลือก แยกโมดูลออกมา ในการแก้ไขข้อผิดพลาดนี้ ให้อัปเกรดเป็นเวอร์ชันใหม่ ไม่ใช่เวอร์ชันเพิ่มเติม หรือใช้ --allow_yanked_versions เพื่ออนุญาตเวอร์ชันที่แยกอย่างชัดเจน

ระดับความเข้ากันได้

ใน Go สมมติฐานของ MVS เกี่ยวกับความเข้ากันได้แบบย้อนหลังนั้นใช้ได้ผลเนื่องจากพิจารณา นำโมดูลเวอร์ชันที่เข้ากันไม่ได้มาใช้เป็นโมดูลแยกต่างหาก ในแง่ของ SemVer ซึ่งหมายความว่า A 1.x และ A 2.x ถือเป็นโมดูลที่แตกต่างกัน และ อยู่ร่วมกันในกราฟทรัพยากร Dependency ที่ได้รับการแก้ไข ซึ่งก็ทำได้โดย จะเข้ารหัสเวอร์ชันหลักในเส้นทางแพ็กเกจใน Go จึงจะไม่มีการเข้ารหัส เวลาคอมไพล์หรือเวลาลิงก์ไม่ตรงกัน

อย่างไรก็ตาม Bazel ไม่สามารถรับประกันดังกล่าว จึงต้องใช้ "เวอร์ชันหลัก" เพื่อตรวจหาเวอร์ชันที่ใช้ร่วมกันไม่ได้ย้อนหลัง หมายเลขนี้โทรหา ระดับความเข้ากันได้ และระบุโดยเวอร์ชันโมดูลแต่ละเวอร์ชันใน คำสั่ง module() ข้อมูลนี้ทำให้ Bazel แสดงข้อผิดพลาดได้เมื่อ ตรวจพบว่าโมดูลเดียวกันในเวอร์ชันเดียวกันที่มีระดับความเข้ากันได้แตกต่างกัน อยู่ในกราฟทรัพยากร Dependency ที่ได้รับการแก้ไข

ลบล้าง

ระบุการลบล้างในไฟล์ MODULE.bazel เพื่อเปลี่ยนลักษณะการทำงานของ Bazel ความละเอียดของโมดูล เฉพาะการลบล้างของโมดูลรูทเท่านั้นที่มีผล หากโมดูลคือ ที่ใช้เป็นทรัพยากร Dependency จะถูกละเว้น

การลบล้างแต่ละรายการถูกระบุสำหรับชื่อโมดูลหนึ่งๆ ซึ่งส่งผลต่อ เวอร์ชันในกราฟทรัพยากร Dependency แม้ว่าการลบล้างของโมดูลรูทเท่านั้น อาจเป็นการขึ้นต่อกันแบบทรานซิทีฟที่โมดูลรากไม่ได้ ที่เกี่ยวข้องโดยตรง

การลบล้างเวอร์ชันเดียว

single_version_override มีประโยชน์หลายอย่าง ดังนี้

  • คุณสามารถใช้แอตทริบิวต์ version เพื่อปักหมุดทรัพยากร Dependency ได้ ไม่ว่าจะมีการขอทรัพยากร Dependency เวอร์ชันใดก็ตามใน กราฟการขึ้นต่อกัน
  • คุณสามารถใช้แอตทริบิวต์ registry เพื่อบังคับให้การอ้างอิงนี้มาจาก รีจิสทรีเฉพาะ แทนที่จะใช้รีจิสทรีปกติ ของเรา
  • คุณระบุชุดแพตช์ที่จะใช้ได้ด้วยแอตทริบิวต์ patch* โมดูลที่ดาวน์โหลดแล้ว

แอตทริบิวต์เหล่านี้เป็นตัวเลือกทั้งหมด และสามารถนำไปผสมและจับคู่ได้

การลบล้างแบบหลายเวอร์ชัน

multiple_version_override สามารถระบุเพื่อให้โมดูลเดียวกันหลายเวอร์ชันอยู่ร่วมกันใน กราฟทรัพยากร Dependency ที่ได้รับการแก้ไขแล้ว

คุณสามารถระบุรายการเวอร์ชันที่อนุญาตของโมดูลอย่างชัดแจ้ง ซึ่งต้อง ทั้งหมดจะแสดงในกราฟทรัพยากร Dependency ก่อนแก้ปัญหา การขึ้นต่อกันแบบทรานซิทีฟบางรายการโดยขึ้นอยู่กับแต่ละเวอร์ชันที่อนุญาต หลัง ของเรา เฉพาะเวอร์ชันที่อนุญาตของโมดูลเท่านั้นจะยังคงอยู่ ขณะที่การอัปเกรด Bazel เวอร์ชันอื่นๆ ของโมดูลให้เป็นเวอร์ชันที่สูงกว่าที่ได้รับอนุญาตซึ่งใกล้เคียงที่สุด ระดับความเข้ากันได้ หากไม่มีเวอร์ชันที่อนุญาตสูงกว่าซึ่งมีความเข้ากันได้เหมือนกัน มีเลเวลแล้ว Bazel แสดงข้อผิดพลาด

ตัวอย่างเช่น หากมีเวอร์ชัน 1.1, 1.3, 1.5, 1.7 และ 2.0 อยู่ใน กราฟทรัพยากร Dependency ก่อนแก้ปัญหาและเวอร์ชันหลักคือความเข้ากันได้ ระดับ:

  • การลบล้างในหลายเวอร์ชันที่อนุญาต 1.3, 1.7 และ 2.0 ส่งผลให้ 1.1 กำลังอัปเกรดเป็น 1.3, 1.5 กำลังอัปเกรดเป็น 1.7 และอื่นๆ เวอร์ชันต่างๆ ยังคงเหมือนเดิม
  • การลบล้างในหลายเวอร์ชันที่อนุญาต 1.5 และ 2.0 ทำให้เกิดข้อผิดพลาด เช่น 1.7 ไม่มีเวอร์ชันที่สูงกว่าซึ่งมีระดับความเข้ากันได้ที่ระดับเดียวกันให้อัปเกรด
  • การลบล้างในหลายเวอร์ชันที่อนุญาต 1.9 และ 2.0 ทำให้เกิดข้อผิดพลาด เช่น 1.9 ไม่ปรากฏในกราฟทรัพยากร Dependency ก่อนแก้ปัญหา

นอกจากนี้ ผู้ใช้ยังลบล้างรีจิสทรีโดยใช้ registry ได้ด้วย ซึ่งคล้ายกับการลบล้างเวอร์ชันเดียว

การลบล้างที่ไม่ใช่รีจิสทรี

การลบล้างที่ไม่ใช่รีจิสทรีจะนำโมดูลออกจากการแปลงเวอร์ชันโดยสมบูรณ์ บาเซล ไม่ขอไฟล์ MODULE.bazel รายการนี้จากรีจิสทรี แต่ขอจาก ที่เก็บได้นั้นเอง

Bazel รองรับการลบล้างที่ไม่ใช่รีจิสทรีต่อไปนี้

ชื่อที่เก็บและหน่วยงานที่เข้มงวด

ชื่อ Canonical ของที่เก็บที่รองรับ โมดูลคือ module_name~version (เช่น bazel_skylib~1.0.3) สำหรับโมดูลที่มี ลบล้างค่าที่ไม่ใช่รีจิสทรี แทนที่ส่วน version ด้วยสตริง override โปรดทราบว่ารูปแบบของชื่อ Canonical ไม่ใช่ API ที่คุณควรใช้และอาจมีการเปลี่ยนแปลงได้ทุกเมื่อ

ชื่อที่ปรากฏของที่เก็บที่สนับสนุน ไปยังปลายทางโดยตรงของโมดูลที่มีค่าเริ่มต้นเป็นชื่อโมดูล เว้นแต่ว่า แอตทริบิวต์ repo_name ของ bazel_dep หรือไม่เช่นนั้น ซึ่งหมายความว่าโมดูลจะดูได้เฉพาะ ทรัพยากร Dependency วิธีนี้จะช่วยป้องกันการหยุดทำงานโดยไม่ตั้งใจจากการเปลี่ยนแปลงใน ทรัพยากร Dependency แบบสับเปลี่ยน

ส่วนขยายโมดูลยังแนะนำที่เก็บเพิ่มเติมได้ด้วย ให้อยู่ภายในขอบเขตที่มองเห็นได้ของโมดูล