ฟีเจอร์ล็อกไฟล์ใน Bazel จะเปิดใช้การบันทึกเวอร์ชันที่เจาะจงหรือ ทรัพยากร Dependency ของไลบรารีซอฟต์แวร์หรือแพ็กเกจที่โปรเจ็กต์ต้องใช้ ทั้งนี้ บรรลุเป้าหมายนี้โดยการจัดเก็บผลลัพธ์ของความละเอียดและการขยายโมดูล การประเมินมูลค่า ไฟล์ล็อกส่งเสริมงานสร้างที่ทำซ้ำได้เพื่อให้แน่ใจว่ามีความสอดคล้องกัน สภาพแวดล้อมในการพัฒนาซอฟต์แวร์ นอกจากนี้ยังช่วยเพิ่มประสิทธิภาพในการสร้าง โดยทำให้ Bazel ข้ามขั้นตอนการแก้ปัญหาที่ไม่ได้รับผลกระทบจากการเปลี่ยนแปลง ในทรัพยากร Dependency ของโปรเจ็กต์ นอกจากนี้ ไฟล์ล็อกยังมีความเสถียรมากขึ้น เพื่อป้องกันการอัปเดตที่ไม่คาดคิดหรือ ส่งผลต่อการเปลี่ยนแปลงในไลบรารีภายนอก จะช่วยลดความเสี่ยงในการเกิดข้อบกพร่อง
การสร้างไฟล์ล็อก
ไฟล์ล็อกสร้างขึ้นภายใต้รูทของพื้นที่ทำงานโดยใช้ชื่อ
MODULE.bazel.lock
ระบบจะสร้างหรืออัปเดตในระหว่างขั้นตอนการสร้าง
โดยเฉพาะหลังการแก้ปัญหาโมดูลและการประเมินส่วนขยาย ที่สำคัญคือ
รวมเฉพาะทรัพยากร Dependency ที่รวมอยู่ในการเรียกใช้ปัจจุบันของ
งานสร้าง
เมื่อมีการเปลี่ยนแปลงในโปรเจ็กต์ที่ส่งผลต่อทรัพยากร Dependency ไฟล์ Lockfile จะถูก โดยอัตโนมัติเพื่อให้แสดงถึงสถานะใหม่ วิธีนี้ช่วยให้มั่นใจว่าล็อกไฟล์ จะยังคงมุ่งเน้นที่ชุดทรัพยากร Dependency ที่จำเป็น ทำให้เห็นภาพที่ถูกต้องของผลการแก้ปัญหา ทรัพยากร Dependency
การใช้งาน Lockfile
แฟล็กสามารถควบคุมไฟล์ล็อกได้
--lockfile_mode
ถึง
ปรับแต่งลักษณะการทำงานของ Bazel เมื่อสถานะของโปรเจ็กต์แตกต่างจาก
Lockfile โหมดที่ใช้ได้มีดังนี้
update
(ค่าเริ่มต้น): ใช้ข้อมูลที่มีอยู่ในล็อกไฟล์เพื่อ ข้ามการดาวน์โหลดไฟล์รีจิสทรีที่รู้จัก และเพื่อหลีกเลี่ยงการประเมินส่วนขยายซ้ำ ที่ผลการค้นหายังคงเป็นปัจจุบัน หากข้อมูลขาดหายไป ระบบจะ เพิ่มลงในไฟล์ล็อกได้ ในโหมดนี้ Bazel จะหลีกเลี่ยงการรีเฟรชด้วย ข้อมูลที่เปลี่ยนแปลงได้ เช่น เวอร์ชันที่หายไป สำหรับทรัพยากร Dependency ที่ไม่มี มีการเปลี่ยนแปลงrefresh
: เช่นเดียวกับupdate
แต่ข้อมูลที่เปลี่ยนแปลงจะมีการรีเฟรชเสมอ สลับเป็นโหมดนี้และทุกๆ ชั่วโมงโดยประมาณขณะอยู่ในโหมดนี้error
: เช่นupdate
แต่หากข้อมูลขาดหายไปหรือล้าสมัย Bazel จะล้มเหลวเพราะมีข้อผิดพลาด โหมดนี้จะไม่เปลี่ยนล็อกไฟล์หรือ ส่งคำขอเครือข่ายในระหว่างการแก้ปัญหา ส่วนขยายโมดูลที่ทำเครื่องหมาย ตัวเองเป็นreproducible
อาจยังดำเนินการตามคำขอเครือข่าย แต่ จะต้องให้ผลลัพธ์เดียวกันเสมอoff
: ไม่ได้ตรวจสอบหรืออัปเดตไฟล์ล็อก
ประโยชน์ของไฟล์ล็อก
Lockfile มีข้อดีหลายอย่างและใช้ประโยชน์ได้หลากหลายดังนี้
บิลด์ที่ทำซ้ำได้ ด้วยการบันทึกเวอร์ชันหรือทรัพยากร Dependency ที่เฉพาะเจาะจง ของไลบรารีซอฟต์แวร์ ล็อกไฟล์ช่วยให้มั่นใจได้ว่าบิลด์สามารถทำซ้ำได้ จากสภาพแวดล้อมต่างๆ ในช่วงเวลาที่ผ่านมา นักพัฒนาแอปสามารถพึ่งพา ผลลัพธ์ที่สอดคล้องกันและคาดการณ์ได้เมื่อสร้างโปรเจ็กต์
ได้ความละเอียดเพิ่มขึ้นอย่างรวดเร็ว ไฟล์ล็อกช่วยให้ Bazel หลีกเลี่ยง การดาวน์โหลดไฟล์รีจิสทรีที่ใช้อยู่แล้วในบิลด์ก่อนหน้า ซึ่งจะช่วยปรับปรุงประสิทธิภาพของการสร้างได้อย่างมาก โดยเฉพาะในสถานการณ์ที่ อาจต้องใช้เวลานาน
ความเสถียรและการลดความเสี่ยง ไฟล์ล็อกจะช่วยรักษาความเสถียรโดย เพื่อป้องกันการอัปเดตที่ไม่คาดคิดหรือทำให้การเปลี่ยนแปลงในไลบรารีภายนอกเสียหาย โดย การล็อกทรัพยากร Dependency เป็นเวอร์ชันที่เฉพาะเจาะจง ความเสี่ยงที่จะเกิดข้อบกพร่อง จากการอัปเดตที่ใช้ร่วมกันไม่ได้หรือยังไม่ผ่านการทดสอบจะลดลง
เนื้อหาของ Lockfile
ไฟล์ล็อกประกอบด้วยข้อมูลที่จำเป็นทั้งหมดเพื่อพิจารณาว่า เปลี่ยนสถานะโปรเจ็กต์แล้ว นอกจากนี้ยังรวมถึงผลลัพธ์ของการสร้างโครงการ ในสถานะปัจจุบัน ไฟล์ล็อกประกอบด้วย 2 ส่วนหลักดังนี้
- แฮชของไฟล์ระยะไกลทั้งหมดที่เป็นอินพุตสำหรับความละเอียดของโมดูล
- สำหรับส่วนขยายโมดูลแต่ละรายการ ไฟล์ล็อกจะมีอินพุตที่ส่งผลต่อ
แสดงด้วย
bzlTransitiveDigest
,usagesDigest
และฟิลด์อื่นๆ เป็น รวมถึงเอาต์พุตของการเรียกใช้ส่วนขยายนั้น ซึ่งเรียกว่าgeneratedRepoSpecs
ต่อไปนี้เป็นตัวอย่างที่แสดงโครงสร้างของล็อกไฟล์ พร้อมด้วย คําอธิบายสําหรับแต่ละส่วนมีดังนี้
{
"lockFileVersion": 10,
"registryFileHashes": {
"https://bcr.bazel.build/bazel_registry.json": "8a28e4af...5d5b3497",
"https://bcr.bazel.build/modules/foo/1.0/MODULE.bazel": "7cd0312e...5c96ace2",
"https://bcr.bazel.build/modules/foo/2.0/MODULE.bazel": "70390338... 9fc57589",
"https://bcr.bazel.build/modules/foo/2.0/source.json": "7e3a9adf...170d94ad",
"https://registry.mycorp.com/modules/foo/1.0/MODULE.bazel": "not found",
...
},
"selectedYankedVersions": {
"foo@2.0": "Yanked for demo purposes"
},
"moduleExtensions": {
"//:extension.bzl%lockfile_ext": {
"general": {
"bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
"usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
}
},
"//:extension.bzl%lockfile_ext2": {
"os:macos": {
"bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
"usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
},
"os:linux": {
"bzlTransitiveDigest": "eWDzxG/aLsyY3Ubrto....+Jp4maQvEPxn0pLK=",
"usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
}
}
}
}
แฮชไฟล์รีจิสทรี
ส่วน registryFileHashes
มีแฮชของไฟล์ทั้งหมดจาก
รีจิสทรีระยะไกลที่มีการเข้าถึงระหว่างการแก้ไขโมดูล ตั้งแต่ความละเอียด
อัลกอริทึมสามารถถูกกำหนดได้โดยสมบูรณ์เมื่อได้รับอินพุตเดียวกันและระยะไกลทั้งหมด
ระบบจะแฮชข้อมูลเหล่านี้ เพื่อให้แน่ใจว่าผลลัพธ์ของความละเอียดจะ
เกิดขึ้นซ้ำได้อย่างสมบูรณ์
หลีกเลี่ยงการใช้ข้อมูลระยะไกลในล็อกไฟล์มากเกินไป โปรดทราบว่า
จะต้องมีการบันทึกเมื่อรีจิสทรีรายการหนึ่งไม่มี
แต่รีจิสทรีที่มีความสำคัญต่ำกว่า (ดูรายการ "ไม่พบ" ใน
ตัวอย่าง) คุณสามารถอัปเดตข้อมูลตามธรรมชาตินี้ได้ผ่านทาง
bazel mod deps --lockfile_mode=refresh
Bazel ใช้แฮชจากไฟล์ล็อกเพื่อค้นหาไฟล์รีจิสทรีใน ของที่เก็บแคชไว้ก่อนที่จะดาวน์โหลด ซึ่งทำให้เพิ่มความเร็วขึ้นได้ในเวลาต่อมา ความละเอียดสูงสุด
เวอร์ชัน Yanked ที่เลือก
ส่วน selectedYankedVersions
มีโมดูลเวอร์ชันแยก
ที่เลือกตามความละเอียดของโมดูล เนื่องจากโดยปกติแล้วมักจะทำให้เกิดข้อผิดพลาด
เมื่อพยายามสร้าง ส่วนนี้ไม่ว่างเปล่าเมื่อรุ่นที่แยกออกมา
อนุญาตอย่างชัดแจ้งผ่าน --allow_yanked_versions
หรือ
BZLMOD_ALLOW_YANKED_VERSIONS
จำเป็นต้องมีช่องนี้ เนื่องจากเมื่อเทียบกับไฟล์โมดูล ข้อมูลเวอร์ชันที่ย้ายแล้ว
เปลี่ยนแปลงได้อยู่แล้ว จึงอ้างอิงด้วยแฮชไม่ได้ ข้อมูลนี้
สามารถอัปเดตผ่าน bazel mod deps --lockfile_mode=refresh
ส่วนขยายโมดูล
ส่วน moduleExtensions
คือแผนที่ที่มีเฉพาะส่วนขยายที่ใช้
ในการเรียกใช้ปัจจุบันหรือที่เรียกใช้ก่อนหน้านี้ ขณะเดียวกันก็ไม่รวมส่วนขยายใดๆ
ที่ไม่ได้ใช้งานแล้ว กล่าวคือ หากไม่มีการใช้ส่วนขยาย
ในกราฟทรัพยากร Dependency อีกต่อไป โดยจะนำออกจาก moduleExtensions
แผนที่
หากส่วนขยายไม่เกี่ยวข้องกับระบบปฏิบัติการหรือประเภทสถาปัตยกรรม ส่วนนี้แสดงเฉพาะ "ทั่วไป" เพียงอย่างเดียว รายการ มิฉะนั้น คูณ แต่ละรายการ โดยตั้งชื่อตามระบบปฏิบัติการ สถาปัตยกรรม หรือทั้งสองอย่าง ซึ่งตรงกับผลการประเมินส่วนขยายสำหรับข้อมูลเหล่านั้นโดยเฉพาะ
แต่ละรายการในแผนที่ส่วนขยายสอดคล้องกับส่วนขยายที่ใช้และ ที่ระบุโดยไฟล์และชื่อไฟล์ที่มี ค่าที่เกี่ยวข้องสำหรับแต่ละค่า รายการจะมีข้อมูลที่เกี่ยวข้องกับส่วนขยายนั้น ดังนี้
bzlTransitiveDigest
คือสรุปของการติดตั้งใช้งานส่วนขยาย และไฟล์ .bzl ที่โหลดแบบทรานซิชันusagesDigest
คือไดเจสต์ของการใช้งานของส่วนขยายใน กราฟทรัพยากร Dependency ซึ่งมีแท็กทั้งหมด- ฟิลด์ที่ไม่ได้ระบุเพิ่มเติม ซึ่งจะติดตามอินพุตอื่นๆ ไปยังส่วนขยาย เช่น เนื้อหาของไฟล์หรือไดเรกทอรีที่อ่าน หรือสภาพแวดล้อม ตัวแปรที่ใช้อยู่
generatedRepoSpecs
เข้ารหัสที่เก็บที่สร้างโดย ด้วยอินพุตปัจจุบัน- ช่อง
moduleExtensionMetadata
ที่ไม่บังคับมีข้อมูลเมตาจาก ส่วนขยาย เช่น ที่เก็บบางรายการที่ส่วนขยายสร้างขึ้นควร นำเข้าผ่านuse_repo
โดยโมดูลรูท ข้อมูลนี้ช่วยขับเคลื่อน คำสั่งbazel mod tidy
ส่วนขยายโมดูลสามารถเลือกไม่ใช้การรวมในไฟล์ล็อกได้โดยการตั้งค่า
การแสดงผลข้อมูลเมตาพร้อม reproducible = True
ในการทำเช่นนั้น พวกเขาให้สัญญาว่า
โมเดลจะสร้างที่เก็บเดียวกันเสมอเมื่อได้รับอินพุตเดียวกัน
แนวทางปฏิบัติแนะนำ
หากต้องการเพิ่มประโยชน์ของฟีเจอร์ล็อกไฟล์ ให้พิจารณาข้อมูลต่อไปนี้ แนวทางปฏิบัติ:
อัปเดตล็อกไฟล์เป็นประจำเพื่อให้สอดคล้องกับการเปลี่ยนแปลงทรัพยากร Dependency ของโปรเจ็กต์ หรือ การกำหนดค่า ซึ่งทำให้มั่นใจว่าบิลด์ต่อๆ ไปจะอิงตาม ชุดทรัพยากร Dependency ที่เป็นปัจจุบันและถูกต้อง วิธีล็อกส่วนขยายทั้งหมด ให้เรียกใช้
bazel mod deps --lockfile_mode=update
พร้อมกันรวมไฟล์ล็อกไว้ในการควบคุมเวอร์ชันเพื่ออำนวยความสะดวกในการทำงานร่วมกันและ ให้สมาชิกทุกคนในทีมมีสิทธิ์เข้าถึงล็อกไฟล์เดียวกัน ซึ่งจะโปรโมต สภาพแวดล้อมในการพัฒนาซอฟต์แวร์ที่สอดคล้องกันทั้งโครงการ
ใช้
bazelisk
เพื่อเรียกใช้ Bazel และใส่.bazelversion
ในการควบคุมเวอร์ชันที่ระบุเวอร์ชัน Bazel ที่สัมพันธ์กับไฟล์ล็อก เนื่องจากบาเซลเองก็เป็นที่พึ่งพิงของ บิลด์ของคุณ ไฟล์ล็อกจะมีเฉพาะสําหรับเวอร์ชัน Bazel และจะ เปลี่ยนแปลงได้แม้ว่าเข้ากันได้แบบย้อนหลัง Bazel เปิดตัว การใช้bazelisk
ช่วยให้นักพัฒนาซอฟต์แวร์ทุกรายใช้งาน เวอร์ชัน Bazel ที่ตรงกับไฟล์ล็อก
การทำตามแนวทางปฏิบัติแนะนำเหล่านี้จะช่วยให้คุณสามารถใช้ล็อกไฟล์ได้อย่างมีประสิทธิภาพ ใน Bazel ที่จะทำให้มีประสิทธิภาพ เชื่อถือได้ และทำงานร่วมกันได้มากขึ้น การพัฒนาซอฟต์แวร์
ความขัดแย้งในการรวม
รูปแบบ Lockfile ได้รับการออกแบบมาเพื่อลดความขัดแย้งในการรวม แต่ก็ยังสามารถ เกิดขึ้น
ความละเอียดอัตโนมัติ
Bazel เพิ่มช่อง git Merge Driver เพื่อช่วยแก้ไขความขัดแย้งเหล่านี้โดยอัตโนมัติ
ตั้งค่าไดรเวอร์โดยเพิ่มบรรทัดนี้ลงในไฟล์ .gitattributes
ที่รูทของ
ที่เก็บ Git ของคุณ:
# A custom merge driver for the Bazel lockfile.
# https://bazel.build/external/lockfile#automatic-resolution
MODULE.bazel.lock merge=bazel-lockfile-merge
นักพัฒนาแอปแต่ละรายที่ต้องการใช้คนขับจะต้องลงทะเบียนเพียงครั้งเดียวโดย โดยทำตามขั้นตอนต่อไปนี้
- ติดตั้ง jq (1.5 ขึ้นไป)
- เรียกใช้คำสั่งต่อไปนี้
jq_script=$(curl https://raw.githubusercontent.com/bazelbuild/bazel/master/scripts/bazel-lockfile-merge.jq)
printf '%s\n' "${jq_script}" | less # to optionally inspect the jq script
git config --global merge.bazel-lockfile-merge.name "Merge driver for the Bazel lockfile (MODULE.bazel.lock)"
git config --global merge.bazel-lockfile-merge.driver "jq -s '${jq_script}' -- %O %A %B > %A.jq_tmp && mv %A.jq_tmp %A"
การแก้ปัญหาด้วยตนเอง
ความขัดแย้งของการรวมอย่างง่ายใน registryFileHashes
และ selectedYankedVersions
สามารถแก้ช่องได้อย่างปลอดภัยด้วยการเก็บรายการทั้งหมดจากทั้ง 2 ฝั่งของ
ความขัดแย้ง
คุณไม่ควรแก้ไขความขัดแย้งของการรวมประเภทอื่นๆ ด้วยตนเอง ให้ดำเนินการต่อไปนี้แทน
- กู้คืนสถานะก่อนหน้าของ Lockfile
ผ่าน
git reset MODULE.bazel.lock && git checkout MODULE.bazel.lock
- แก้ไขความขัดแย้งในไฟล์
MODULE.bazel
- เรียกใช้
bazel mod deps
เพื่ออัปเดตไฟล์ล็อก