คู่มือการย้ายข้อมูล Bzlmod

รายงานปัญหา ดูแหล่งที่มา รุ่น Nightly · 7.4

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

WORKSPACE เทียบกับ Bzlmod

WORKSPACE และ Bzlmod ของ Bazel มีฟีเจอร์ที่คล้ายกันแต่ไวยากรณ์ต่างกัน ส่วนนี้อธิบายวิธีย้ายข้อมูลจากฟังก์ชัน WORKSPACE ที่เฉพาะเจาะจงไปยัง Bzlmod

กำหนดรูทของพื้นที่ทํางาน Bazel

ไฟล์ WORKSPACE จะทำเครื่องหมายรูทต้นทางของโปรเจ็กต์ Bazel และจะแทนที่ความรับผิดชอบนี้ด้วย MODULE.bazel ใน Bazel เวอร์ชัน 6.3 ขึ้นไป เมื่อใช้ Bazel เวอร์ชันก่อน 6.3 ควรมีไฟล์ WORKSPACE หรือ WORKSPACE.bazel ที่รูทพื้นที่ทำงานของคุณ ซึ่งอาจมีความคิดเห็นอย่างเช่น

  • WORKSPACE

    # This file marks the root of the Bazel workspace.
    # See MODULE.bazel for external dependencies setup.
    

เปิดใช้ Bzlmod ใน bazelrc

.bazelrc ช่วยให้คุณตั้งค่าแฟล็กที่จะมีผลทุกครั้งที่เรียกใช้ Bazel ได้ หากต้องการเปิดใช้ Bzlmod ให้ใช้แฟล็ก --enable_bzlmod และนำไปใช้กับคำสั่ง common เพื่อให้มีผลกับทุกคำสั่ง ดังนี้

  • .bazelrc

    # Enable Bzlmod for every Bazel command
    common --enable_bzlmod
    

ระบุชื่อที่เก็บสำหรับพื้นที่ทำงาน

  • พื้นที่ทำงาน

    ใช้ฟังก์ชัน workspace เพื่อระบุชื่อที่เก็บสำหรับพื้นที่ทำงาน ซึ่งจะช่วยให้อ้างอิง //foo:bar เป้าหมายในพื้นที่ทำงานเป็น @<workspace name>//foo:bar ได้ หากไม่ได้ระบุไว้ ชื่อที่เก็บข้อมูลเริ่มต้นสำหรับที่ทำงานของคุณจะเป็น __main__

    ## WORKSPACE
    workspace(name = "com_foo_bar")
    
  • Bzlmod

    ขอแนะนำให้อ้างอิงเป้าหมายในพื้นที่ทำงานเดียวกันด้วยไวยากรณ์ //foo:bar ที่ไม่มี @<repo name> แต่หากต้องการใช้ไวยากรณ์เดิม ก็ใช้ชื่อโมดูลที่ระบุโดยฟังก์ชัน module เป็นชื่อที่เก็บได้ หากชื่อโมดูลแตกต่างจากชื่อที่เก็บข้อมูลที่จําเป็น คุณสามารถใช้แอตทริบิวต์ repo_name ของฟังก์ชัน module เพื่อลบล้างชื่อที่เก็บข้อมูล

    ## MODULE.bazel
    module(
        name = "bar",
        repo_name = "com_foo_bar",
    )
    

ดึงข้อมูล Dependency ภายนอกเป็นโมดูล Bazel

หากทรัพยากร Dependency ของคุณเป็นโปรเจ็กต์ Bazel คุณก็ควรพึ่งพาโปรเจ็กต์ดังกล่าวเป็นโมดูลของ Bazel ได้เมื่อมีการใช้ Bzlmod ด้วย

  • พื้นที่ทำงาน

    ใน Workspace เป็นเรื่องปกติที่จะใช้กฎที่เก็บ http_archive หรือ git_repository เพื่อดาวน์โหลดแหล่งที่มาของโปรเจ็กต์ Bazel

    ## WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "bazel_skylib",
        urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz"],
        sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
    )
    load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
    bazel_skylib_workspace()
    
    http_archive(
        name = "rules_java",
        urls = ["https://github.com/bazelbuild/rules_java/releases/download/6.1.1/rules_java-6.1.1.tar.gz"],
        sha256 = "76402a50ae6859d50bd7aed8c1b8ef09dae5c1035bb3ca7d276f7f3ce659818a",
    )
    load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
    rules_java_dependencies()
    rules_java_toolchains()
    

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

  • Bzlmod

    เมื่อใช้ Bzlmod ตราบใดที่ข้อกำหนดของคุณมีอยู่ใน Bazel Central Registry หรือ Bazel registry ที่กำหนดเอง คุณก็ใช้ข้อกำหนดดังกล่าวได้โดยใช้คำสั่ง bazel_dep

    ## MODULE.bazel
    bazel_dep(name = "bazel_skylib", version = "1.4.2")
    bazel_dep(name = "rules_java", version = "6.1.1")
    

    Bzlmod จะแก้ไขการพึ่งพาโมดูล Bazel แบบทรานซิทีฟโดยใช้อัลกอริทึม MVS ดังนั้น ระบบจะเลือก platform เวอร์ชันสูงสุดที่จำเป็นโดยอัตโนมัติ

ลบล้างทรัพยากร Dependency เป็นโมดูล Bazel

ในฐานะโมดูลรูท คุณสามารถลบล้างการพึ่งพาโมดูล Bazel ได้หลายวิธี

โปรดอ่านข้อมูลเพิ่มเติมในส่วนการลบล้าง

คุณดูตัวอย่างการใช้ตัวอย่างได้ในที่เก็บตัวอย่าง

ดึงข้อมูลทรัพยากร Dependency ภายนอกด้วยส่วนขยายโมดูล

หากทรัพยากร Dependency ไม่ใช่โปรเจ็กต์ Bazel หรือยังไม่พร้อมใช้งานในรีจิสทรี Bazel ใดๆ คุณสามารถนําเข้าโดยใช้ use_repo_rule หรือส่วนขยายของข้อบังคับ

  • พื้นที่ทำงาน

    ดาวน์โหลดไฟล์โดยใช้กฎที่เก็บ http_file

    ## WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    
    http_file(
        name = "data_file",
        url = "http://example.com/file",
        sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    
  • Bzlmod

    เมื่อใช้ Bzlmod คุณจะใช้คำสั่ง use_repo_rule ในไฟล์ MODULE.bazel เพื่อสร้างอินสแตนซ์ของที่เก็บโดยตรงได้ ดังนี้

    ## MODULE.bazel
    http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    http_file(
        name = "data_file",
        url = "http://example.com/file",
        sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    

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

    ## repositories.bzl
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    def my_data_dependency():
        http_file(
            name = "data_file",
            url = "http://example.com/file",
            sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        )
    

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

    ## extensions.bzl
    load("//:repositories.bzl", "my_data_dependency")
    def _non_module_dependencies_impl(_ctx):
        my_data_dependency()
    
    non_module_dependencies = module_extension(
        implementation = _non_module_dependencies_impl,
    )
    

    หากต้องการทำให้ที่เก็บปรากฏแก่โปรเจ็กต์รูท คุณควรประกาศการใช้ส่วนขยายโมดูลและที่เก็บในไฟล์ MODULE.bazel

    ## MODULE.bazel
    non_module_dependencies = use_extension("//:extensions.bzl", "non_module_dependencies")
    use_repo(non_module_dependencies, "data_file")
    

แก้ไขทรัพยากร Dependency ภายนอกที่มีข้อขัดแย้งด้วยส่วนขยายโมดูล

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

สมมติว่าโปรเจ็กต์ foo มีมาโครต่อไปนี้ซึ่งใช้ version เป็นอาร์กิวเมนต์

## repositories.bzl in foo {:#repositories.bzl-foo}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
def data_deps(version = "1.0"):
    http_file(
        name = "data_file",
        url = "http://example.com/file-%s" % version,
        # Omitting the "sha256" attribute for simplicity
    )
  • WORKSPACE

    เมื่อใช้ WORKSPACE คุณจะโหลดมาโครจาก @foo และระบุเวอร์ชันของข้อมูลที่ต้องพึ่งพาที่ต้องการได้ สมมติว่าคุณมี @bar รายการอื่น ซึ่งก็ขึ้นอยู่กับ @foo ด้วย แต่ต้องใช้ข้อมูล Dependency เวอร์ชันอื่น

    ## WORKSPACE
    
    # Introduce @foo and @bar.
    ...
    
    load("@foo//:repositories.bzl", "data_deps")
    data_deps(version = "2.0")
    
    load("@bar//:repositories.bzl", "bar_deps")
    bar_deps() # -> which calls data_deps(version = "3.0")
    

    ในกรณีนี้ ผู้ใช้ปลายทางต้องปรับลําดับมาโครใน WORKSPACE อย่างระมัดระวังเพื่อรับเวอร์ชันที่ต้องการ นี่เป็นปัญหาที่ใหญ่ที่สุดปัญหาหนึ่งของ WORKSPACE เนื่องจากไม่ได้ให้วิธีที่เหมาะสมในการแก้ปัญหาการพึ่งพากัน

  • Bzlmod

    ผู้เขียนโปรเจ็กต์ foo สามารถใช้ส่วนขยายโมดูลเพื่อแก้ไขข้อขัดแย้งได้ด้วย Bzlmod ตัวอย่างเช่น สมมติว่าควรเลือกเวอร์ชันสูงสุดของทรัพยากร Dependency ในโมดูล Bazel ทั้งหมดเสมอ

    ## extensions.bzl in foo
    load("//:repositories.bzl", "data_deps")
    
    data = tag_class(attrs={"version": attr.string()})
    
    def _data_deps_extension_impl(module_ctx):
        # Select the maximal required version in the dependency graph.
        version = "1.0"
        for mod in module_ctx.modules:
            for data in mod.tags.data:
                version = max(version, data.version)
        data_deps(version)
    
    data_deps_extension = module_extension(
        implementation = _data_deps_extension_impl,
        tag_classes = {"data": data},
    )
    
    ## MODULE.bazel in bar
    bazel_dep(name = "foo", version = "1.0")
    
    foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
    foo_data_deps.data(version = "3.0")
    use_repo(foo_data_deps, "data_file")
    
    ## MODULE.bazel in root module
    bazel_dep(name = "foo", version = "1.0")
    bazel_dep(name = "bar", version = "1.0")
    
    foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
    foo_data_deps.data(version = "2.0")
    use_repo(foo_data_deps, "data_file")
    

    ในกรณีนี้ โมดูลรูทต้องใช้ข้อมูลเวอร์ชัน 2.0 ส่วนข้อกำหนด bar ต้องใช้ 3.0 ส่วนขยายโมดูลใน foo จะแก้ไขความขัดแย้งนี้ได้อย่างถูกต้องและเลือกเวอร์ชัน 3.0 สำหรับการขึ้นต่อข้อมูลโดยอัตโนมัติ

ผสานรวมเครื่องมือจัดการแพ็กเกจของบุคคลที่สาม

ในส่วนสุดท้าย เนื่องจากส่วนขยายโมดูลมีวิธีเก็บรวบรวมข้อมูลจากกราฟทรัพยากร Dependency จะใช้ตรรกะที่กำหนดเองเพื่อแก้ไขการขึ้นต่อกันและกฎที่เก็บการเรียกใช้เพื่อแนะนำที่เก็บภายนอก ซึ่งเป็นวิธีที่ยอดเยี่ยมสำหรับผู้เขียนกฎในการปรับปรุงชุดกฎที่ผสานรวมเครื่องมือจัดการแพ็กเกจสำหรับบางภาษา

โปรดอ่านหน้าส่วนขยายโมดูลเพื่อเรียนรู้เพิ่มเติมเกี่ยวกับวิธีใช้ส่วนขยายโมดูล

ต่อไปนี้คือรายการชุดกฎที่ใช้ Bzlmod เพื่อดึงข้อมูลพึ่งพาจากเครื่องมือจัดการแพ็กเกจต่างๆ อยู่แล้ว

ตัวอย่างแบบมินิมอลที่ผสานรวมเครื่องมือจัดการแพ็กเกจจำลองมีอยู่ในที่เก็บรวบรวมตัวอย่าง

ตรวจหา Toolchain ในเครื่องโฮสต์

เมื่อกฎบิลด์ของ Bazel ต้องการตรวจหา Toolchain ที่พร้อมใช้งานในเครื่องของโฮสต์ กฎดังกล่าวจะใช้กฎที่เก็บเพื่อตรวจสอบเครื่องโฮสต์และสร้างข้อมูล Toolchain เป็นที่เก็บภายนอก

  • WORKSPACE

    กฎที่เก็บข้อมูลต่อไปนี้เพื่อตรวจหาชุดเครื่องมือเชลล์

    ## local_config_sh.bzl
    def _sh_config_rule_impl(repository_ctx):
        sh_path = get_sh_path_from_env("SH_BIN_PATH")
    
        if not sh_path:
            sh_path = detect_sh_from_path()
    
        if not sh_path:
            sh_path = "/shell/binary/not/found"
    
        repository_ctx.file("BUILD", """
    load("@bazel_tools//tools/sh:sh_toolchain.bzl", "sh_toolchain")
    sh_toolchain(
        name = "local_sh",
        path = "{sh_path}",
        visibility = ["//visibility:public"],
    )
    toolchain(
        name = "local_sh_toolchain",
        toolchain = ":local_sh",
        toolchain_type = "@bazel_tools//tools/sh:toolchain_type",
    )
    """.format(sh_path = sh_path))
    
    sh_config_rule = repository_rule(
        environ = ["SH_BIN_PATH"],
        local = True,
        implementation = _sh_config_rule_impl,
    )
    

    คุณโหลดกฎที่เก็บได้ใน WORKSPACE

    ## WORKSPACE
    load("//:local_config_sh.bzl", "sh_config_rule")
    sh_config_rule(name = "local_config_sh")
    
  • Bzlmod

    เมื่อใช้ Bzlmod คุณจะนํารีพอสิทอรี่เดียวกันมาใช้ได้โดยใช้ส่วนขยายโมดูล ซึ่งคล้ายกับการนํารีพอสิทอรี่ @data_file มาใช้ในส่วนสุดท้าย

    ## local_config_sh_extension.bzl
    load("//:local_config_sh.bzl", "sh_config_rule")
    
    sh_config_extension = module_extension(
        implementation = lambda ctx: sh_config_rule(name = "local_config_sh"),
    )
    

    จากนั้นใช้ส่วนขยายในไฟล์ MODULE.bazel

    ## MODULE.bazel
    sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
    use_repo(sh_config_ext, "local_config_sh")
    

ลงทะเบียนเครื่องมือและแพลตฟอร์มการดำเนินการ

หลังจากส่วนสุดท้าย หลังจากแนะนำข้อมูล Toolchain ของที่เก็บ (เช่น local_config_sh) คุณอาจต้องการลงทะเบียน Toolchain

  • พื้นที่ทำงาน

    เมื่อใช้ WORKSPACE คุณจะลงทะเบียนเครื่องมือทางเทคนิคได้ดังนี้

    1. คุณสามารถลงทะเบียนเครื่องมือชุดค่าผสมในไฟล์ .bzl และโหลดมาโครในไฟล์ WORKSPACE

      ## local_config_sh.bzl
      def sh_configure():
          sh_config_rule(name = "local_config_sh")
          native.register_toolchains("@local_config_sh//:local_sh_toolchain")
      
      ## WORKSPACE
      load("//:local_config_sh.bzl", "sh_configure")
      sh_configure()
      
    2. หรือลงทะเบียน Toolchain ในไฟล์ WORKSPACE โดยตรง

      ## WORKSPACE
      load("//:local_config_sh.bzl", "sh_config_rule")
      sh_config_rule(name = "local_config_sh")
      register_toolchains("@local_config_sh//:local_sh_toolchain")
      
  • Bzlmod

    เมื่อใช้ Bzlmod แล้ว API ของ register_toolchains และ register_execution_platforms จะพร้อมใช้งานในไฟล์ MODULE.bazel เท่านั้น คุณไม่สามารถเรียกใช้ native.register_toolchains ในส่วนขยายโมดูล

    ## MODULE.bazel
    sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
    use_repo(sh_config_ext, "local_config_sh")
    register_toolchains("@local_config_sh//:local_sh_toolchain")
    

Toolchain และแพลตฟอร์มการดำเนินการที่จดทะเบียนใน WORKSPACE, WORKSPACE.bzlmod และไฟล์ MODULE.bazel ของโมดูล Bazel แต่ละรายการจะมีลำดับความสําคัญเหนือกว่าระหว่างการเลือก Toolchain (จากมากไปน้อย) ดังนี้

  1. Toolchains และแพลตฟอร์มการดำเนินการที่ลงทะเบียนไว้ในไฟล์ MODULE.bazel ของโมดูลรูท
  2. Toolchains และแพลตฟอร์มการดำเนินการที่ลงทะเบียนในไฟล์ WORKSPACE หรือ WORKSPACE.bzlmod
  3. Toolchains และแพลตฟอร์มการดำเนินการที่ลงทะเบียนโดยโมดูลที่ขึ้นต่อกัน (แบบสับเปลี่ยน) ของโมดูลรูท
  4. เมื่อไม่ได้ใช้ WORKSPACE.bzlmod: เครื่องมือทางเทคนิคที่ลงทะเบียนในWORKSPACEส่วนต่อท้าย

แนะนำที่เก็บในเครื่อง

คุณอาจต้องแนะนำทรัพยากร Dependency เป็นที่เก็บภายในเครื่องเมื่อต้องการทรัพยากร Dependency ในเวอร์ชันในเครื่องสำหรับการแก้ไขข้อบกพร่อง หรือหากต้องการรวมไดเรกทอรีในพื้นที่ทำงานเป็นที่เก็บภายนอก

  • WORKSPACE

    การใช้ WORKSPACE ทำได้ตามกฎที่เก็บในเครื่อง 2 ข้อ ได้แก่ local_repository และ new_local_repository

    ## WORKSPACE
    local_repository(
        name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    
  • Bzlmod

    เมื่อใช้ Bzlmod คุณจะใช้ local_path_override เพื่อลบล้างโมดูลด้วยเส้นทางในเครื่องได้

    ## MODULE.bazel
    bazel_dep(name = "rules_java")
    local_path_override(
        module_name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    

    คุณอาจแนะนำที่เก็บในเครื่องที่มีส่วนขยายโมดูลได้ด้วย อย่างไรก็ตาม คุณจะเรียก native.local_repository ในส่วนขยายโมดูลไม่ได้ เรากําลังพยายามเปลี่ยนกฎของที่เก็บข้อมูลเดิมทั้งหมดให้เป็น Starlark (ดูความคืบหน้าที่ #18285) จากนั้นคุณจะเรียก Starlark local_repository ที่เกี่ยวข้องในส่วนขยายโมดูลได้ นอกจากนี้ คุณยังใช้กฎที่กําหนดเองของที่เก็บlocal_repositoryได้ง่ายๆ หากปัญหานี้ทําให้คุณไม่สามารถดำเนินการต่อได้

เชื่อมโยงเป้าหมาย

กฎ bind ใน WORKSPACE เลิกใช้งานแล้วและไม่รองรับใน Bzlmod มีการเปิดตัวเพื่อตั้งชื่ออีเมลแทนในแพ็กเกจ //external พิเศษ ผู้ใช้ทุกคนตามกรณีนี้ควรย้ายข้อมูลออก

เช่น หากคุณมีผู้ติดตาม

## WORKSPACE
bind(
    name = "openssl",
    actual = "@my-ssl//src:openssl-lib",
)

ซึ่งช่วยให้เป้าหมายอื่นๆ ขึ้นอยู่กับ //external:openssl ได้ คุณสามารถย้ายข้อมูล จากตรงนี้ได้โดยทำดังนี้

  • แทนที่การใช้ //external:openssl ทั้งหมดด้วย @my-ssl//src:openssl-lib

  • หรือใช้กฎการสร้าง alias

    • กําหนดเป้าหมายต่อไปนี้ในแพ็กเกจ (เช่น //third_party)

      ## third_party/BUILD
      alias(
          name = "openssl,
          actual = "@my-ssl//src:openssl-lib",
      )
      
    • แทนที่การใช้ //external:openssl ทั้งหมดด้วย //third_party:openssl-lib

การย้ายข้อมูล

ส่วนนี้จะให้ข้อมูลและคำแนะนำที่เป็นประโยชน์สำหรับกระบวนการย้ายข้อมูล Bzlmod

ทราบทรัพยากร Dependency ใน WORKSPACE

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

ตรวจสอบทรัพยากรภายนอกด้วยไฟล์ที่แก้ไขแล้วของพื้นที่ทำงาน

แต่โชคดีที่การแจ้งเตือน --experimental_repository_resolved_file ช่วยได้ โดยพื้นฐานแล้ว Flag นี้จะสร้าง "ไฟล์ล็อก" ของข้อกำหนดภายนอกทั้งหมดที่ดึงข้อมูลในคำสั่ง Bazel รายการล่าสุด ดูรายละเอียดเพิ่มเติมได้ในบล็อกโพสต์นี้

โดยใช้ได้ 2 วิธีดังนี้

  1. เพื่อดึงข้อมูลของทรัพยากร Dependency ภายนอกที่จำเป็นสำหรับการสร้างเป้าหมายบางรายการ

    bazel clean --expunge
    bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
    
  2. เพื่อดึงข้อมูลของ Dependency ภายนอกทั้งหมดที่กําหนดไว้ในไฟล์ WORKSPACE

    bazel clean --expunge
    bazel sync --experimental_repository_resolved_file=resolved.bzl
    

    คุณจะใช้คำสั่ง bazel sync เพื่อดึงข้อมูลทรัพยากร Dependency ทั้งหมดที่กำหนดไว้ในไฟล์ WORKSPACE ได้ ซึ่งประกอบด้วย

    • การใช้งาน bind
    • การใช้งาน register_toolchains และ register_execution_platforms

    อย่างไรก็ตาม หากโปรเจ็กต์เป็นแบบข้ามแพลตฟอร์ม การซิงค์ Bazel อาจใช้งานไม่ได้ในบางแพลตฟอร์ม เนื่องจากกฎของที่เก็บข้อมูลบางรายการอาจทำงานได้อย่างถูกต้องในแพลตฟอร์มที่รองรับเท่านั้น

หลังจากเรียกใช้คำสั่ง คุณควรมีข้อมูลการขึ้นต่อกันภายนอกในไฟล์ resolved.bzl

ตรวจสอบทรัพยากร Dependency ภายนอกด้วย bazel query

หรืออาจรู้ว่าใช้ bazel query เพื่อตรวจสอบกฎของที่เก็บได้ด้วย

bazel query --output=build //external:<repo name>

แม้ว่าจะสะดวกสบายกว่าและเร็วกว่ามาก แต่คำค้นหา Bazel อาจไม่ตรงกับเวอร์ชันของ Dependency ภายนอก ดังนั้นโปรดระวังการใช้งานด้วย การค้นหาและตรวจสอบการพึ่งพาภายนอกด้วย Bzlmod จะดำเนินการได้ด้วยคำสั่งย่อยใหม่

ทรัพยากร Dependency เริ่มต้นในตัว

หากตรวจสอบไฟล์ที่ --experimental_repository_resolved_file สร้างขึ้น คุณจะเห็นรายการที่ขึ้นต่อกันจำนวนมากที่ไม่ได้กำหนดไว้ใน WORKSPACE นั่นเป็นเพราะ Bazel เพิ่มคำนำหน้าและคำต่อท้ายให้กับเนื้อหาไฟล์ WORKSPACE ของผู้ใช้เพื่อแทรกทรัพยากร Dependency เริ่มต้นบางส่วน ซึ่งมักกำหนดโดยกฎของระบบ (เช่น @bazel_tools, @platforms และ @remote_java_tools) เมื่อใช้ Bzlmod ทรัพยากร Dependency เหล่านี้จะเริ่มใช้ด้วยโมดูลในตัว bazel_tools ซึ่งเป็นทรัพยากร Dependency เริ่มต้นสําหรับโมดูล Bazel ทั้งหมด

โหมดผสมสำหรับการทยอยย้ายข้อมูล

Bzlmod และ WORKSPACE สามารถทำงานควบคู่กันไปได้ ซึ่งจะทำให้การย้ายข้อมูลทรัพยากร Dependency จากไฟล์ WORKSPACE ไปยัง Bzlmod เป็นกระบวนการแบบค่อยเป็นค่อยไปได้

WORKSPACE.bzlmod

ในระหว่างการย้ายข้อมูล ผู้ใช้ Bazel อาจต้องสลับระหว่างบิลด์ที่เปิดใช้และไม่เปิดใช้ Bzlmod มีการสนับสนุน WORKSPACE.bzlmod เพื่อทำให้ กระบวนการราบรื่นยิ่งขึ้น

WORKSPACE.bzlmod มีไวยากรณ์เหมือนกับ WORKSPACE ทุกประการ เมื่อเปิดใช้ Bzlmod หากมีไฟล์ WORKSPACE.bzlmod ที่รูทของพื้นที่ทำงานด้วย ระบบจะดำเนินการดังนี้

การใช้ไฟล์ WORKSPACE.bzlmod จะช่วยให้การย้ายข้อมูลง่ายขึ้นเนื่องจากเหตุผลต่อไปนี้

  • เมื่อปิดใช้ Bzlmod คุณจะกลับไปดึงข้อมูลทรัพยากร Dependency จากไฟล์ WORKSPACE เดิม
  • เมื่อเปิดใช้ Bzlmod คุณจะติดตามรายการ Dependency ที่เหลือที่ต้องย้ายข้อมูลด้วย WORKSPACE.bzlmod ได้ดียิ่งขึ้น

ระดับการเข้าถึงที่เก็บ

Bzlmod ควบคุมได้ว่าจะให้ที่เก็บอื่นใดแสดงจากที่เก็บหนึ่งๆ ดูรายละเอียดเพิ่มเติมได้ที่ชื่อและรายละเอียดของที่เก็บ

ต่อไปนี้คือสรุประดับการเข้าถึงที่เก็บจากที่เก็บประเภทต่างๆ เมื่อนำ WORKSPACE มาพิจารณาด้วย

จากรีโปหลัก จากที่เก็บโมดูล Bazel จากที่เก็บส่วนขยายโมดูล จากที่เก็บของ WORKSPACE
ที่เก็บหลัก แสดง หากโมดูลรูทเป็นข้อกำหนดโดยตรง หากโมดูลรูทเป็นทรัพยากร Dependency โดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล แสดง
ที่เก็บโมดูล Bazel การเพิ่มขึ้นของเส้นตรง Dependency โดยตรง โมดูลที่โฮสต์ส่วนขยายของโมดูลนั้นๆ ช่วงโดยตรงของโมดูลรูท
ที่เก็บส่วนขยายโมดูล การเพิ่มขึ้นของเส้นตรง Dependency โดยตรง ช่วงเวลาโดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล + ที่เก็บทั้งหมดที่สร้างขึ้นโดยส่วนขยายโมดูลเดียวกัน ช่วงโดยตรงของโมดูลรูท
ที่เก็บใน Workspace มองเห็นทั้งหมด ไม่แสดง ไม่แสดง มองเห็นทั้งหมด

กระบวนการย้ายข้อมูล

กระบวนการย้ายข้อมูล Bzlmod ทั่วไปอาจมีลักษณะดังนี้

  1. ทำความเข้าใจสิ่งที่คุณพึ่งพาใน WORKSPACE
  2. เพิ่มไฟล์ MODULE.bazel ที่ว่างเปล่าที่รูทของโปรเจ็กต์
  3. เพิ่มไฟล์ WORKSPACE.bzlmod ที่ว่างเปล่าเพื่อลบล้างเนื้อหาไฟล์ WORKSPACE
  4. สร้างเป้าหมายโดยเปิดใช้ Bzlmod และดูว่าที่เก็บใดขาดหายไป
  5. ตรวจสอบคําจํากัดความของที่เก็บที่หายไปในไฟล์ข้อมูลพึ่งพาที่แก้ไขแล้ว
  6. เพิ่มข้อกำหนดเบื้องต้นที่ขาดหายไปเป็นโมดูล Bazel ผ่านส่วนขยายโมดูล หรือปล่อยไว้ใน WORKSPACE.bzlmod สำหรับการย้ายข้อมูลในภายหลัง
  7. กลับไปที่ 4 แล้วทำซ้ำจนกว่าจะมีทรัพยากรทั้งหมด

เครื่องมือย้ายข้อมูล

มีสคริปต์ตัวช่วยการย้ายข้อมูล Bzlmod แบบอินเทอร์แอกทีฟที่จะช่วยคุณเริ่มต้นใช้งาน

สคริปต์จะทําสิ่งต่อไปนี้

  • สร้างและแยกวิเคราะห์ไฟล์ที่แก้ไขแล้วของ WORKSPACE
  • พิมพ์ข้อมูลที่เก็บจากไฟล์ที่แก้ไขแล้วด้วยวิธีที่มนุษย์อ่านได้
  • เรียกใช้คําสั่ง bazel build, ตรวจหาข้อความแสดงข้อผิดพลาดที่รู้จัก และแนะนําวิธีย้ายข้อมูล
  • ตรวจสอบว่าทรัพยากร Dependency มีใน BCR อยู่แล้วหรือไม่
  • เพิ่มการพึ่งพาไปยังไฟล์ MODULE.bazel
  • เพิ่มข้อกําหนดผ่านส่วนขยายโมดูล
  • เพิ่มข้อกำหนดในไฟล์ WORKSPACE.bzlmod

หากต้องการใช้งาน ให้ตรวจสอบว่าคุณได้ติดตั้ง Bazel รุ่นล่าสุดแล้ว และเรียกใช้คำสั่งต่อไปนี้

git clone https://github.com/bazelbuild/bazel-central-registry.git
cd <your workspace root>
<BCR repo root>/tools/migrate_to_bzlmod.py -t <your build targets>

เผยแพร่โมดูล Bazel

หากโปรเจ็กต์ Bazel ของคุณเป็นทรัพยากร Dependency สำหรับโปรเจ็กต์อื่นๆ คุณจะเผยแพร่โปรเจ็กต์ใน Bazel Central Registry ได้

หากต้องการตรวจสอบโปรเจ็กต์ใน BCR คุณจะต้องมี URL ของที่เก็บถาวรต้นทางของโปรเจ็กต์ ข้อควรทราบบางประการเมื่อสร้างที่เก็บถาวรต้นทางมีดังนี้

  • ตรวจสอบว่าไฟล์ที่เก็บถาวรชี้ไปยังเวอร์ชันที่เจาะจง

    BCR ยอมรับเฉพาะที่เก็บซอร์สโค้ดที่มีเวอร์ชัน เนื่องจาก Bzlmod จำเป็นต้องทำการเปรียบเทียบเวอร์ชันระหว่างการแก้ไขข้อขัดข้องเกี่ยวกับทรัพยากร Dependency

  • ตรวจสอบว่า URL ของที่เก็บถาวรเป็นแบบคงที่

    Bazel ยืนยันเนื้อหาของที่เก็บถาวรโดยใช้ค่าแฮช ดังนั้นคุณควรตรวจสอบว่า Checksum ของไฟล์ที่ดาวน์โหลดไม่มีการเปลี่ยนแปลง หาก URL มาจาก GitHub โปรดสร้างและอัปโหลดไฟล์เก็บถาวรของรุ่นในหน้ารุ่น GitHub จะไม่รับประกันผลรวมตรวจสอบของที่เก็บถาวรต้นทางที่สร้างขึ้นตามคำขอ กล่าวโดยย่อคือ URL ในรูปแบบ https://github.com/<org>/<repo>/releases/download/... จะถือว่ามีเสถียรภาพ ส่วน https://github.com/<org>/<repo>/archive/... จะไม่เสถียร ดูบริบทเพิ่มเติมได้ในGitHub Checksum ของที่เก็บ ที่หยุดทำงาน

  • ตรวจสอบว่าโครงสร้างต้นทางเป็นไปตามเลย์เอาต์ของที่เก็บข้อมูลเดิม

    ในกรณีที่ที่เก็บข้อมูลมีขนาดใหญ่มากและคุณต้องการสร้างไฟล์เก็บถาวรสำหรับแจกจ่ายที่มีขนาดเล็กลงโดยการนําแหล่งที่มาที่ไม่จําเป็นออก โปรดตรวจสอบว่าต้นไม้แหล่งที่มาที่นําออกนั้นเป็นส่วนหนึ่งของต้นไม้แหล่งที่มาเดิม วิธีนี้ช่วยให้ผู้ใช้ปลายทางลบล้างโมดูลเป็นเวอร์ชันที่ยังไม่เปิดตัวด้วย archive_override และ git_override ได้ง่ายขึ้น

  • รวมโมดูลทดสอบในไดเรกทอรีย่อยที่ทดสอบ API ที่คุณใช้บ่อยที่สุด

    โมดูลทดสอบคือโปรเจ็กต์ Bazel ที่มีไฟล์ WORKSPACE และ MODULE.bazel ของตัวเองซึ่งอยู่ในไดเรกทอรีย่อยของที่เก็บถาวรต้นทางซึ่งจะขึ้นอยู่กับโมดูลจริงที่จะเผยแพร่ ซึ่งควรมีตัวอย่างหรือการทดสอบการผสานรวมบางส่วนที่ครอบคลุม API ที่คุณใช้บ่อยที่สุด โปรดดูวิธีตั้งค่าในข้อบังคับการทดสอบ

เมื่อคุณมี URL ของที่เก็บถาวรต้นทางพร้อมแล้ว ให้ทำตามหลักเกณฑ์การสนับสนุน BCR เพื่อส่งโมดูลไปยัง BCR ด้วยคำขอพุล GitHub

เราขอแนะนำเป็นอย่างยิ่งให้ตั้งค่าแอป GitHub เผยแพร่ไปยัง BCR สำหรับที่เก็บของคุณเพื่อทำให้กระบวนการส่งโมดูลไปยัง BCR เป็นแบบอัตโนมัติ

แนวทางปฏิบัติแนะนำ

ส่วนนี้จะอธิบายแนวทางปฏิบัติแนะนำบางประการที่คุณควรทำตามเพื่อจัดการทรัพยากรภายนอกให้ดียิ่งขึ้น

แยกเป้าหมายออกเป็นแพ็กเกจต่างๆ เพื่อหลีกเลี่ยงการดึงข้อมูลทรัพยากร Dependency ที่ไม่จำเป็น

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

ระบุทรัพยากร Dependency สําหรับนักพัฒนาซอฟต์แวร์

คุณสามารถตั้งค่าแอตทริบิวต์ dev_dependency เป็น "จริง" สําหรับคำสั่ง bazel_dep และ use_extension เพื่อไม่ให้คำสั่งดังกล่าวเผยแพร่ไปยังโปรเจ็กต์ที่เกี่ยวข้อง ในฐานะโมดูลรูท คุณสามารถใช้ Flag --ignore_dev_dependency เพื่อยืนยันว่าเป้าหมายยังคงสร้างได้โดยไม่ต้องใช้ Dependency และ Override ของนักพัฒนาซอฟต์แวร์หรือไม่

ความคืบหน้าของการย้ายข้อมูลชุมชน

คุณตรวจสอบ Bazel Central Registry เพื่อดูว่าทรัพยากร Dependency พร้อมใช้งานหรือไม่ หรือจะเข้าร่วมการสนทนาใน GitHub เพื่อกดโหวตหรือโพสต์เกี่ยวกับข้อกำหนดที่บล็อกการย้ายข้อมูลของคุณก็ได้

รายงานปัญหา

โปรดตรวจสอบรายการปัญหา GitHub ของ Bazel เพื่อดูปัญหาที่ทราบเกี่ยวกับ Bzlmod โปรดแจ้งปัญหาใหม่หรือส่งคำขอฟีเจอร์ที่จะช่วยแก้ปัญหาการย้ายข้อมูล