กฎที่เก็บ

รายงานปัญหา ดูซอร์สโค้ด รุ่น Nightly · 8.0 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • แอตทริบิวต์ที่ส่งไปยังการเรียกใช้กฎของ repo
  • โค้ด Starlark ที่ประกอบด้วยการใช้งานกฎของพื้นที่เก็บข้อมูล
  • ค่าของตัวแปรสภาพแวดล้อมที่ส่งไปยังเมธอด getenv() ของ repository_ctx หรือประกาศด้วยแอตทริบิวต์ environ ของ repository_rule ค่าของตัวแปรสภาพแวดล้อมเหล่านี้สามารถกำหนดค่าในบรรทัดคำสั่งได้โดยใช้แฟล็ก --repo_env
  • สถานะ เนื้อหา และประเภทของเส้นทางที่watchในฟังก์ชันการใช้งานของกฎรีโป
    • วิธีการอื่นๆ บางวิธีของ repository_ctx ที่มีพารามิเตอร์ watch เช่น read(), execute() และ extract() อาจทําให้ระบบติดตามเส้นทางด้วย
    • ในทํานองเดียวกัน repository_ctx.watch_tree และ path.readdir อาจทําให้ระบบติดตามเส้นทางด้วยวิธีอื่นๆ
  • เมื่อมีการเรียกใช้ bazel fetch --force

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

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

การบังคับให้ดึงข้อมูลรีโปภายนอกอีกครั้ง

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

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

ตัวอย่าง

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

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

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