การโต้ตอบแบบวันต่อวันกับ Bazel จะเกิดขึ้นผ่านคำสั่ง 2-3 คำสั่งเป็นหลัก ได้แก่ build
, test
และ run
แต่บางครั้งอาจมีข้อจำกัด เช่น พุชแพ็กเกจไปยังที่เก็บ เผยแพร่เอกสารสำหรับผู้ใช้ปลายทาง หรือทำให้แอปพลิเคชันใช้งานได้ด้วย Kubernetes แต่ Bazel ไม่มีคำสั่ง publish
หรือ
deploy
การดำเนินการเหล่านี้เหมาะกับตำแหน่งใด
คำสั่งเรียกใช้ Bazel
การมุ่งเน้นของ Bazel ในด้านความสุจริต การทำซ้ำ และส่วนเพิ่มทำให้คำสั่ง build
และ test
ไม่มีประโยชน์ต่องานข้างต้น การดำเนินการเหล่านี้อาจทำงานในแซนด์บ็อกซ์โดยมีสิทธิ์เข้าถึงเครือข่ายที่จำกัด และไม่รับประกันว่าจะทำงานซ้ำในทุก bazel build
แต่ให้ใช้ bazel run
แทน ซึ่งเป็นภาระงานที่คุณต้องการให้มีผลข้างเคียง ผู้ใช้ Bazel คุ้นเคยกับกฎที่สร้างคำสั่ง และผู้เขียนกฎสามารถทำตามชุดรูปแบบทั่วไปเพื่อขยายข้อความนี้ไปยัง "คำกริยาที่กำหนดเอง"
ป่าเถื่อน: rules_k8s
ตัวอย่างเช่น ลองพิจารณา rules_k8s
กฎ Kubernetes สำหรับ Bazel สมมติว่าคุณมีเป้าหมายต่อไปนี้
# BUILD file in //application/k8s
k8s_object(
name = "staging",
kind = "deployment",
cluster = "testing",
template = "deployment.yaml",
)
กฎ k8s_object
จะสร้างไฟล์ Kubernetes YAML มาตรฐานเมื่อมีการใช้ bazel build
ในเป้าหมาย staging
อย่างไรก็ตาม มาโคร k8s_object
จะสร้างเป้าหมายเพิ่มเติมที่มีชื่ออย่างเช่น staging.apply
และ :staging.delete
ด้วย สคริปต์บิลด์เหล่านี้เพื่อดำเนินการดังกล่าว และเมื่อดำเนินการด้วย bazel run
staging.apply
สคริปต์เหล่านี้จะทำงานเหมือนคำสั่ง bazel k8s-apply
หรือ bazel
k8s-delete
ของเราเอง
อีกตัวอย่างหนึ่ง: ts_api_guardian_test
รูปแบบนี้สามารถดูในโปรเจ็กต์ Angular ได้ด้วย มาโคร ts_api_guardian_test
จะสร้างเป้าหมาย 2 รายการ รายการแรกคือเป้าหมาย nodejs_test
มาตรฐาน ซึ่งจะเปรียบเทียบเอาต์พุตที่สร้างขึ้นบางรายการกับไฟล์ "สีทอง" (ซึ่งก็คือไฟล์ที่มีเอาต์พุตที่คาดไว้) ซึ่งสร้างและเรียกใช้ได้ด้วยการเรียกใช้ bazel
test
ปกติ ใน angular-cli
คุณสามารถเรียกใช้เป้าหมายดังกล่าวด้วย bazel test //etc/api:angular_devkit_core_api
เมื่อเวลาผ่านไป คุณอาจต้องอัปเดตไฟล์ทองคำนี้ด้วยเหตุผลที่เหมาะสม
การอัปเดตนี้ด้วยตัวเองเป็นเรื่องน่าเบื่อและเกิดข้อผิดพลาดได้ง่าย มาโครนี้จึงมีเป้าหมาย nodejs_binary
ที่อัปเดตไฟล์ทองคำแทนที่จะเปรียบเทียบด้วย สามารถเขียนสคริปต์ทดสอบเดียวกันให้ทำงานในโหมด "ยืนยัน" หรือ "ยอมรับ" ได้อย่างมีประสิทธิภาพ โดยขึ้นอยู่กับลักษณะการเรียกใช้ ซึ่งเป็นไปตามรูปแบบที่คุณได้เรียนรู้ไปแล้ว กล่าวคือไม่มีคำสั่ง bazel test-accept
ดั้งเดิม แต่จะได้ผลลัพธ์ที่เหมือนกันด้วย bazel run //etc/api:angular_devkit_core_api.accept
รูปแบบนี้อาจใช้ได้ผลดีมาก และค่อนข้างจะเป็นรูปแบบที่พบได้บ่อยเมื่อคุณเรียนรู้ที่จะจดจำ
การปรับกฎของคุณเอง
มาโครคือหัวใจของรูปแบบนี้ มาโครนั้นใช้เหมือนกับกฎ แต่สามารถสร้างเป้าหมายได้หลายเป้าหมาย โดยทั่วไปพวกเขาจะสร้างเป้าหมายด้วยชื่อที่ระบุ ซึ่งจะดำเนินการบิลด์หลัก ซึ่งอาจเป็นการสร้างไบนารีปกติ อิมเมจ Docker หรือที่เก็บถาวรของซอร์สโค้ด ในรูปแบบนี้ ระบบจะสร้างเป้าหมายเพิ่มเติมเพื่อสร้างสคริปต์ที่สร้างผลลัพธ์ข้างเคียงตามผลลัพธ์ของเป้าหมายหลัก เช่น การเผยแพร่ไบนารีที่เป็นผลลัพธ์หรืออัปเดตเอาต์พุตทดสอบที่คาดไว้
เพื่อให้เห็นภาพชัดขึ้น ให้รวมกฎสมมติที่สร้างเว็บไซต์ด้วย Sphinx กับมาโครเพื่อสร้างเป้าหมายเพิ่มเติมที่อนุญาตให้ผู้ใช้เผยแพร่เมื่อพร้อม พิจารณากฎที่มีอยู่ต่อไปนี้สำหรับการสร้างเว็บไซต์ที่มี Sphinx
_sphinx_site = rule(
implementation = _sphinx_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)
จากนั้น ให้พิจารณากฎต่อไปนี้ ซึ่งจะสร้างสคริปต์ที่เมื่อเรียกใช้ จะเผยแพร่หน้าเว็บที่สร้างขึ้น
_sphinx_publisher = rule(
implementation = _publish_impl,
attrs = {
"site": attr.label(),
"_publisher": attr.label(
default = "//internal/sphinx:publisher",
executable = True,
),
},
executable = True,
)
สุดท้าย ให้กำหนดมาโครต่อไปนี้เพื่อสร้างเป้าหมายสำหรับกฎทั้ง 2 ข้อข้างต้นร่วมกัน
def sphinx_site(name, srcs = [], **kwargs):
# This creates the primary target, producing the Sphinx-generated HTML.
_sphinx_site(name = name, srcs = srcs, **kwargs)
# This creates the secondary target, which produces a script for publishing
# the site generated above.
_sphinx_publisher(name = "%s.publish" % name, site = name, **kwargs)
ในไฟล์ BUILD
ให้ใช้มาโครเหมือนกับว่าเพียงแค่สร้างเป้าหมายหลัก
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
ในตัวอย่างนี้ ระบบจะสร้างเป้าหมาย "เอกสาร" เช่นเดียวกับที่มาโครเป็นกฎ Bazel มาตรฐานเดียว เมื่อสร้างแล้ว กฎจะสร้างการกำหนดค่าบางอย่าง
และเรียกใช้ Sphinx เพื่อสร้างเว็บไซต์ HTML ซึ่งพร้อมสำหรับการตรวจสอบด้วยตนเอง อย่างไรก็ตาม จะมีการสร้างเป้าหมาย "docs.publish" เพิ่มเติมด้วย ซึ่งจะสร้างสคริปต์สำหรับการเผยแพร่เว็บไซต์ เมื่อตรวจสอบเอาต์พุตของเป้าหมายหลักแล้ว คุณจะใช้ bazel run :docs.publish
เพื่อเผยแพร่รายการดังกล่าวเพื่อการบริโภคแบบสาธารณะได้ เช่นเดียวกับคำสั่ง bazel publish
ในจินตนาการ
แต่ยังไม่ทราบชัดเจนทันทีว่าการใช้งานกฎ _sphinx_publisher
มีลักษณะอย่างไร การดำเนินการเช่นนี้มักจะเขียนสคริปต์เชลล์ Launcher
โดยทั่วไปเมธอดนี้จะเกี่ยวข้องกับการใช้ ctx.actions.expand_template
เพื่อเขียนสคริปต์ Shell แบบง่ายมาก ซึ่งในกรณีนี้จะเรียกใช้ไบนารีของผู้เผยแพร่โฆษณาที่มีเส้นทางไปยังเอาต์พุตของเป้าหมายหลัก วิธีนี้ทำให้การใช้งานของผู้เผยแพร่โฆษณายังคงเป็นแบบทั่วไป กฎ _sphinx_site
จะสร้าง HTML ได้เท่านั้น และสคริปต์ขนาดเล็กนี้ก็เป็นสิ่งที่จำเป็นในการรวม 2 ทั้ง 2 อย่างไว้ด้วยกัน
ใน rules_k8s
นี่คือสิ่งที่ .apply
ทำจริงๆ
expand_template
เขียนสคริปต์ Bash แบบง่ายๆ โดยอิงจาก apply.sh.tpl
ซึ่งเรียกใช้ kubectl
พร้อมเอาต์พุตของเป้าหมายหลัก จากนั้นสคริปต์นี้จะสามารถสร้างและเรียกใช้ด้วย bazel run :staging.apply
โดยมีคำสั่ง k8s-apply
สำหรับเป้าหมาย k8s_object
อย่างมีประสิทธิภาพ