กฎที่เก็บ

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

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

ที่เก็บภายนอกเป็นโครงสร้างไดเรกทอรี มีไฟล์ต้นฉบับที่ใช้งานได้ในบิลด์ Bazel ซึ่งสร้างตามคำขอโดย โดยใช้กฎที่เก็บที่เกี่ยวข้อง สามารถกำหนด Repos ได้หลากหลาย แต่ท้ายที่สุดแล้ว ที่เก็บแต่ละที่เก็บจะกำหนดโดยการเรียกใช้กฎของที่เก็บ เช่นเดียวกับ เป้าหมายของบิลด์จะกำหนดโดยการเรียกใช้กฎบิลด์ โดยสามารถใช้เพื่ออ้างอิง ไลบรารีของบุคคลที่สาม (เช่น ไลบรารีแบบแพ็กเกจของ 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 ที่กำหนดไว้โดยนัย นี่คือ string ที่ทำงานได้ราวกับใช้เวทมนตร์: เมื่อระบุเป็นอินพุตไปยัง การเรียกใช้กฎที่เก็บ จะใช้ชื่อที่เก็บที่ปรากฏ แต่เมื่ออ่านจาก ฟังก์ชันการใช้งานของกฎที่เก็บโดยใช้ repository_ctx.attr.name ฟังก์ชันจะส่งกลับ ชื่อที่เก็บตามรูปแบบบัญญัติ

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

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

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

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

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

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

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

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

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

  • แอตทริบิวต์ที่ส่งไปยังการเรียกใช้กฎที่เก็บ
  • โค้ด Starlark ประกอบด้วยการใช้งานกฎที่เก็บ
  • ค่าของตัวแปรสภาพแวดล้อมที่ส่งไปยังของ repository_ctx getenv() หรือประกาศด้วยแอตทริบิวต์ 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 ดึงข้อมูลทั้งหมดใหม่ได้ด้วย ที่เก็บภายนอกอย่างไม่มีเงื่อนไขโดยการเรียกใช้ bazel fetch --force --all

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

ตัวอย่าง

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

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

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