กฎที่เก็บ

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ตัวอย่าง

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

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

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