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

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

เนื่องจากข้อบกพร่องของ 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 ช่วยให้คุณตั้งค่า Flag ที่มีผลทุกครั้งที่เรียกใช้ Bazel หากต้องการเปิดใช้ Bzlmod ให้ใช้ Flag --enable_bzlmod กับคำสั่ง common เพื่อให้มีผลกับทุกคำสั่ง

  • .bazelrc

    # Enable Bzlmod for every Bazel command
    common --enable_bzlmod
    

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

  • WORKSPACE

    ใช้ฟังก์ชัน 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 คุณควรใช้ Dependency ดังกล่าวเป็นโมดูล Bazel ได้เมื่อโปรเจ็กต์ดังกล่าวใช้ Bzlmod ด้วย

  • WORKSPACE

    เมื่อใช้ 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()
    

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

  • WORKSPACE

    ดาวน์โหลดไฟล์โดยใช้กฎที่เก็บ 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",
    )
    

    การดำเนินการนี้ทำงานอยู่เบื้องหลังโดยใช้ส่วนขยายโมดูล หากต้องการใช้ตรรกะที่ซับซ้อนกว่าการเรียกใช้กฎของ repo คุณยังติดตั้งใช้งานส่วนขยายโมดูลด้วยตนเองได้ด้วย คุณจะต้องย้ายคําจํากัดความไปไว้ในไฟล์ .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",
        )
    

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

    ## 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")
    

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

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

สมมติว่าโปรเจ็กต์ 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

    เมื่อใช้ Bzlmod ผู้เขียนโปรเจ็กต์ foo จะใช้ส่วนขยายโมดูลเพื่อแก้ไขข้อขัดแย้งได้ ตัวอย่างเช่น สมมติว่าการเลือกเวอร์ชันสูงสุดของข้อมูลที่ต้องพึ่งพาในโมดูล 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 ให้กับข้อกําหนดของข้อมูลโดยอัตโนมัติ

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

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

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

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

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

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

เมื่อกฎการสร้าง 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")
    

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

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

  • WORKSPACE

    เมื่อใช้ 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. หรือลงทะเบียนเครื่องมือทางเทคนิคในไฟล์ 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")
    

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

  1. เครื่องมือและแพลตฟอร์มการดําเนินการที่ลงทะเบียนไว้ในไฟล์ MODULE.bazel ของโมดูลรูท
  2. เครื่องมือและแพลตฟอร์มการเรียกใช้ที่ลงทะเบียนในไฟล์ WORKSPACE หรือ WORKSPACE.bzlmod
  3. เครื่องมือและแพลตฟอร์มการดําเนินการที่ลงทะเบียนโดยโมดูลที่เป็นทรัพยากร Dependency (แบบเปลี่ยนผ่าน) ของโมดูลรูท
  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

ขั้นตอนแรกของการย้ายข้อมูลคือการทําความเข้าใจว่าคุณต้องพึ่งพาอะไรบ้าง การระบุการพึ่งพาที่แน่นอนในไฟล์ 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 คุณจะดึงข้อมูลทรัพยากรทั้งหมดที่กําหนดไว้ในไฟล์ WORKSPACE ได้ ซึ่งรวมถึงรายการต่อไปนี้

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

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

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

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

นอกจากนี้ คุณยังทราบว่า bazel query สามารถใช้ในการตรวจสอบกฎของที่เก็บได้ด้วย

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

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

Dependency เริ่มต้นในตัว

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

โหมดผสมสำหรับการย้ายข้อมูลแบบค่อยเป็นค่อยไป

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

WORKSPACE.bzlmod

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • สร้างและแยกวิเคราะห์ไฟล์ที่แก้ไขแล้วของ WORKSPACE
  • พิมพ์ข้อมูลพื้นที่เก็บข้อมูลจากไฟล์ที่แก้ไขแล้วในรูปแบบที่มนุษย์อ่านได้
  • เรียกใช้คําสั่ง bazel build, ตรวจหาข้อความแสดงข้อผิดพลาดที่รู้จัก และแนะนําวิธีย้ายข้อมูล
  • ตรวจสอบว่ารายการที่เกี่ยวข้องมีอยู่ใน 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 ของคุณเป็นข้อกำหนดของโปรเจ็กต์อื่นๆ คุณสามารถเผยแพร่โปรเจ็กต์ใน Bazel Central Registry

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

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

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

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

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

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

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

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

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

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

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

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

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

รายงานปัญหา

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