กฎที่เก็บ

รายงานปัญหา ดูแหล่งที่มา

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

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

คำจำกัดความของกฎที่เก็บ

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

องค์ประกอบหลัก 2 รายการของคำจำกัดความของกฎที่เก็บคือสคีมาแอตทริบิวต์และฟังก์ชันการใช้งาน สคีมาแอตทริบิวต์จะเป็นตัวกำหนดชื่อและประเภทแอตทริบิวต์ที่ส่งไปยังการเรียกใช้กฎที่เก็บ และฟังก์ชันการใช้งานจะเรียกใช้เมื่อต้องดึงข้อมูลที่เก็บ

Attributes

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

http_archive = repository_rule(
    implementation=_impl,
    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 ทั้งหมดมีแอตทริบิวต์ name ที่กำหนดไว้โดยนัย โดยเป็นแอตทริบิวต์สตริงที่ทำงานได้อย่างยอดเยี่ยม กล่าวคือเมื่อระบุเป็นอินพุตสำหรับการเรียกใช้กฎที่เก็บ จะมีการใช้ชื่อที่เก็บที่เห็นได้ชัด แต่เมื่ออ่านจากฟังก์ชันการใช้งานของกฎที่เก็บโดยใช้ repository_ctx.attr.name จะแสดงชื่อที่เก็บ Canonical

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

บางครั้งที่เก็บภายนอกอาจล้าสมัยโดยไม่มีการเปลี่ยนแปลงใดๆ ต่อคำจำกัดความหรือทรัพยากร Dependency ตัวอย่างเช่น แหล่งที่มาการดึงข้อมูลที่เก็บอาจติดตามสาขาใดสาขาหนึ่งของที่เก็บของบุคคลที่สาม และคอมมิตใหม่จะมีอยู่ในสาขานั้น ในกรณีนี้ คุณสามารถขอให้ Bazel ดึงข้อมูล Repos ภายนอกทั้งหมดอีกครั้งโดยไม่มีเงื่อนไขได้โดยเรียกใช้ bazel fetch --force --all

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

ตัวอย่าง

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

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

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