กฎที่เก็บ

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

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

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

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

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

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

Attributes

แอตทริบิวต์คืออาร์กิวเมนต์ของกฎที่ส่งผ่านเป็น Dict ไปยังอาร์กิวเมนต์ของกฎ 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 ฟังก์ชันนี้มีตรรกะที่แท้จริงของกฎและจะดำเนินการอย่างเคร่งครัดในระยะการโหลด

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

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

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

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

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

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

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

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

repository_rule มีพารามิเตอร์ 2 รายการที่ควบคุมเวลาที่จะดึงที่เก็บซ้ำ ได้แก่

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

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

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

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

การบังคับดึงที่เก็บภายนอกซ้ำ

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

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

ตัวอย่าง

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

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

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