กฎที่เก็บ

รายงานปัญหา ดูแหล่งที่มา รุ่น Nightly · 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

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

ระบบจะโหลดกฎเมื่อคุณสร้างกฎอย่างชัดเจน หรือหากกฎเป็นข้อกำหนดของบิลด์ ในกรณีนี้ 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 เพียง 1 รายการ ฟังก์ชันนี้จะแสดงผล None เพื่อบ่งบอกว่ากฎทำซ้ำได้เมื่อมีพารามิเตอร์ที่ระบุ หรือคำสั่งที่มีชุดพารามิเตอร์สำหรับกฎนั้นจะเปลี่ยนกฎดังกล่าวให้กลายเป็นที่เก็บเดียวกันซึ่งทำซ้ำได้ เช่น สําหรับกฎที่ติดตามที่เก็บ Git ผลลัพธ์ที่ได้คือตัวระบุการคอมมิตที่เฉพาะเจาะจงแทนสาขาลอยที่ระบุไว้ตั้งแต่แรก

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

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

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

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

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

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

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

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

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

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

การเริ่มฟังก์ชันการติดตั้งใช้งานอีกครั้ง

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

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

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