กฎที่เก็บ

รายงานปัญหา ดูแหล่งที่มา /3} /4} {3/4} {3/4} {3/4} {3/4} /4.

หน้านี้ครอบคลุมวิธีสร้างกฎที่เก็บและแสดงตัวอย่างสำหรับรายละเอียดเพิ่มเติม

ที่เก็บภายนอกเป็นกฎที่ใช้ได้ในไฟล์ WORKSPACE เท่านั้น และเปิดใช้การดำเนินการแบบไม่อิงตามอุณหภูมิในขั้นตอนการโหลด Bazel กฎที่เก็บภายนอกแต่ละกฎจะสร้างพื้นที่ทำงานของตนเอง โดยมีไฟล์ BUILD และอาร์ติแฟกต์ของตนเอง โดยอาจใช้เพื่อขึ้นอยู่กับไลบรารีของบุคคลที่สาม (เช่น ไลบรารีแพ็กเกจ Maven) แต่เพื่อสร้างไฟล์ BUILD เฉพาะโฮสต์ Bazel ที่กำลังใช้งาน

การสร้างกฎที่เก็บ

ในไฟล์ .bzl ให้ใช้ฟังก์ชัน repository_rule เพื่อสร้างกฎที่เก็บใหม่และจัดเก็บไว้ในตัวแปรร่วม

กฎที่เก็บที่กำหนดเองจะใช้งานได้เช่นเดียวกับกฎที่เก็บในเครื่อง ซึ่งอาจมีแอตทริบิวต์ name ที่จำเป็น และทุกเป้าหมายที่อยู่ในไฟล์บิลด์อาจเรียกว่า @<name>//package:target โดยที่ <name> คือค่าของแอตทริบิวต์ name

กฎจะโหลดเมื่อคุณสร้างอย่างชัดแจ้งหรือหากเป็นทรัพยากร Dependency ของบิลด์ ในกรณีนี้ Bazel จะเรียกใช้ฟังก์ชัน implementation ฟังก์ชันนี้อธิบายวิธีสร้างที่เก็บ เนื้อหา และไฟล์ BUILD

Attributes

แอตทริบิวต์คืออาร์กิวเมนต์กฎที่ส่งผ่านเป็นคำสั่งไปยังอาร์กิวเมนต์กฎ attrs ระบบจะกำหนดแอตทริบิวต์และประเภทแอตทริบิวต์เมื่อคุณกำหนดกฎที่เก็บ ตัวอย่างการกำหนดแอตทริบิวต์ url และ sha256 เป็นสตริง

local_repository = repository_rule(
    implementation=_impl,
    local=True,
    attrs={
        "url": attr.string(mandatory=True)
        "sha256": attr.string(mandatory=True)
    }
)

หากต้องการเข้าถึงแอตทริบิวต์ภายในฟังก์ชันการใช้งาน ให้ใช้ repository_ctx.attr.<attribute_name> ดังนี้

def _impl(repository_ctx):
    url = repository_ctx.attr.url
    checksum = repository_ctx.attr.sha256

repository_rule ทั้งหมดมีแอตทริบิวต์ที่กำหนดไว้โดยนัย (เหมือนกฎการสร้าง) แอตทริบิวต์โดยนัย 2 รายการคือ name (เช่นเดียวกับกฎบิลด์) และ repo_mapping คุณเข้าถึงชื่อของกฎที่เก็บได้ด้วย repository_ctx.name repo_mapping มีความหมายเหมือนกันกับกฎที่เก็บในเครื่อง local_repository และ new_local_repository

หากชื่อแอตทริบิวต์ขึ้นต้นด้วย _ จะเป็นแบบส่วนตัว และผู้ใช้ไม่สามารถตั้งชื่อได้

ฟังก์ชันการใช้งาน

กฎที่เก็บทุกกฎต้องมีฟังก์ชัน implementation ซึ่งประกอบด้วยตรรกะที่แท้จริงของกฎ และจะดำเนินการในขั้นตอนการโหลดอย่างเคร่งครัด

ฟังก์ชันนี้มีพารามิเตอร์อินพุต repository_ctx เท่านั้น ฟังก์ชันนี้จะแสดงผล None เพื่อบ่งบอกว่ากฎทำซ้ำได้เมื่อมีพารามิเตอร์ที่ระบุ หรือคำสั่งที่มีชุดพารามิเตอร์สำหรับกฎนั้นจะเปลี่ยนกฎดังกล่าวให้กลายเป็นที่เก็บเดียวกันซึ่งทำซ้ำได้ ตัวอย่างเช่น สำหรับกฎที่ติดตามที่เก็บ Git ซึ่งนั่นหมายถึงการส่งกลับตัวระบุคอมมิตที่เจาะจงแทนที่จะเป็น Branch แบบลอยที่มีการระบุไว้แต่แรก

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

def _impl(repository_ctx):
  repository_ctx.symlink(repository_ctx.attr.path, "")

local_repository = repository_rule(
    implementation=_impl,
    ...)

ฟังก์ชันการใช้งานจะทำงานเมื่อใด

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

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

  • พารามิเตอร์ที่ส่งไปยังการประกาศของที่เก็บในไฟล์ WORKSPACE
  • โค้ด Starlark ประกอบด้วยการใช้งานที่เก็บ
  • ค่าของตัวแปรสภาพแวดล้อมที่ประกาศด้วยแอตทริบิวต์ environ ของ repository_rule ค่าของตัวแปรสภาพแวดล้อมเหล่านี้สามารถเดินสายถาวรในบรรทัดคำสั่งที่มีแฟล็ก --action_env ได้ (แต่แฟล็กนี้จะทำให้การดำเนินการทั้งหมดของบิลด์เป็นโมฆะ)
  • เนื้อหาของไฟล์ที่ส่งไปยัง read(), execute() และวิธีการที่คล้ายกันของ repository_ctx ซึ่งอ้างอิงถึงโดยป้ายกำกับ (เช่น //mypkg:label.txt แต่ไม่ใช่ mypkg/label.txt)
  • เมื่อมีการเรียกใช้ bazel sync

มีพารามิเตอร์ 2 ตัวของ repository_rule ที่ควบคุมเวลาที่จะดึงข้อมูลที่เก็บอีกครั้ง ดังนี้

  • หากตั้งค่าแฟล็ก configure ไว้ ระบบจะดึงข้อมูลที่เก็บอีกครั้งใน bazel sync เมื่อมีการส่งพารามิเตอร์ --configure ไปยังที่เก็บ (หากไม่ได้ตั้งค่าแอตทริบิวต์ คำสั่งนี้จะไม่ทำให้เกิดการดึงข้อมูลอีกครั้ง)
  • หากตั้งค่าแฟล็ก local นอกเหนือจากกรณีข้างต้น ระบบจะดึงข้อมูลที่เก็บอีกครั้งเมื่อเซิร์ฟเวอร์ Bazel รีสตาร์ท หรือเมื่อไฟล์ที่ส่งผลต่อการประกาศการเปลี่ยนแปลงที่เก็บ (เช่น ไฟล์ WORKSPACE หรือไฟล์ที่โหลดขึ้น) ไม่ว่าการเปลี่ยนแปลงจะส่งผลให้เกิดการเปลี่ยนแปลงการประกาศที่เก็บหรือโค้ดหรือไม่

    ในกรณีเหล่านี้จะไม่มีการดึงข้อมูลที่เก็บที่ไม่ใช่ในเครื่องอีกครั้ง เนื่องจากระบบถือว่าที่เก็บเหล่านี้เชื่อมต่อกับเครือข่ายหรือมีต้นทุนสูง

กำลังรีสตาร์ทฟังก์ชันการใช้งาน

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

การบังคับให้ดึงข้อมูลที่เก็บภายนอกอีกครั้ง

บางครั้งที่เก็บภายนอกอาจล้าสมัยโดยไม่มีการเปลี่ยนแปลงคำจำกัดความหรือทรัพยากร Dependency ตัวอย่างเช่น แหล่งที่มาของการดึงข้อมูลที่เก็บอาจติดตาม Branch เฉพาะของที่เก็บของบุคคลที่สาม และคอมมิตใหม่จะใช้ได้ใน Branch ดังกล่าว ในกรณีนี้ คุณขอให้ bazel ดึงข้อมูลที่เก็บภายนอกทั้งหมดอีกครั้งอย่างไม่มีเงื่อนไขได้โดยโทรหา bazel sync

นอกจากนี้ กฎบางข้อจะตรวจสอบเครื่องภายในและอาจล้าสมัยหากมีการอัปเกรดเครื่อง ในส่วนนี้คุณสามารถขอให้ bazel ดึงข้อมูลที่เก็บภายนอกอีกครั้งเฉพาะเมื่อการกำหนด repository_rule มีชุดแอตทริบิวต์ configure ให้ใช้ bazel sync --configure

ตัวอย่าง

  • เครื่องมือเชนการกำหนดค่าอัตโนมัติของ C++: จะใช้กฎที่เก็บเพื่อสร้างไฟล์การกำหนดค่า C++ ให้กับ Bazel โดยอัตโนมัติ โดยการมองหาคอมไพเลอร์ C++ ในเครื่อง สภาพแวดล้อม และแฟล็กที่คอมไพเลอร์ C++ รองรับ

  • ที่เก็บ Go ใช้ repository_rule หลายรายการในการกำหนดรายการทรัพยากร Dependency ที่ต้องใช้กฎ Go

  • rules_jvm_external สร้างที่เก็บภายนอกชื่อ @maven โดยค่าเริ่มต้น ซึ่งจะสร้างเป้าหมายบิลด์สำหรับอาร์ติแฟกต์ Maven ทุกรายการในทรีดีพึ่งทรานซิทีฟ