모듈 확장 프로그램

문제 신고 소스 보기

모듈 확장 프로그램을 사용하면 사용자가 종속 항목 그래프에 걸쳐 모듈의 입력 데이터를 읽고 종속 항목 해결에 필요한 로직을 실행하며 마지막으로 저장소 규칙을 호출하여 저장소를 생성하여 모듈 시스템을 확장할 수 있습니다. 이러한 확장 프로그램에는 파일 I/O를 수행하고 네트워크 요청을 전송하는 등의 작업이 가능한 저장소 규칙과 유사한 기능이 있습니다. 무엇보다도 Bazel은 다른 패키지 관리 시스템과 상호작용할 수 있으며 Bazel 모듈로 빌드된 종속 항목 그래프를 준수합니다.

저장소 규칙과 마찬가지로 .bzl 파일에서 모듈 확장을 정의할 수 있습니다. 이러한 태그는 직접 호출되는 것이 아니라 확장 프로그램이 읽을 태그라고 하는 데이터 조각을 지정합니다. Bazel은 확장 프로그램을 평가하기 전에 모듈 확인을 실행합니다. 확장 프로그램은 전체 종속 항목 그래프에서 속한 모든 태그를 읽습니다.

확장 프로그램 사용

확장 프로그램은 Bazel 모듈 자체에서 호스팅됩니다. 모듈에서 확장 프로그램을 사용하려면 먼저 확장 프로그램을 호스팅하는 모듈에 bazel_dep를 추가한 후 use_extension 내장 함수를 호출하여 범위를 가져옵니다. 다음 예를 살펴보겠습니다. rules_jvm_external 모듈에 정의된 'maven' 확장 프로그램을 사용하는 MODULE.bazel 파일의 스니펫

bazel_dep(name = "rules_jvm_external", version = "4.5")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

이렇게 하면 use_extension의 반환 값이 변수에 결합되므로 사용자가 점 문법을 사용하여 확장 프로그램의 태그를 지정할 수 있습니다. 태그는 확장 프로그램 정의에 지정된 해당 태그 클래스로 정의된 스키마를 따라야 합니다. maven.installmaven.artifact 태그를 지정하는 예는 다음과 같습니다.

maven.install(artifacts = ["org.junit:junit:4.13.2"])
maven.artifact(group = "com.google.guava",
               artifact = "guava",
               version = "27.0-jre",
               exclusions = ["com.google.j2objc:j2objc-annotations"])

use_repo 지시문을 사용하여 확장 프로그램에서 생성한 저장소를 현재 모듈의 범위로 가져옵니다.

use_repo(maven, "maven")

확장 프로그램에 의해 생성된 저장소는 API의 일부입니다. 이 예시에서는 'maven' 모듈 확장 프로그램이 maven라는 저장소를 생성한다고 약속합니다. 위의 선언을 통해 확장 프로그램은 'maven' 확장 프로그램에서 생성된 저장소를 가리키도록 @maven//:org_junit_junit와 같은 라벨을 적절하게 확인합니다.

확장 프로그램 정의

module_extension 함수를 사용하여 저장소 규칙과 유사하게 모듈 확장을 정의할 수 있습니다. 저장소 저장소에는 다양한 속성이 있지만 모듈 확장 프로그램에는 각각 tag_class가 있으며 여러 속성이 있습니다. 태그 클래스는 이 확장에서 사용하는 태그의 스키마를 정의합니다. 예를 들어 위의 'maven' 확장 프로그램은 다음과 같이 정의할 수 있습니다.

# @rules_jvm_external//:extensions.bzl

_install = tag_class(attrs = {"artifacts": attr.string_list(), ...})
_artifact = tag_class(attrs = {"group": attr.string(), "artifact": attr.string(), ...})
maven = module_extension(
  implementation = _maven_impl,
  tag_classes = {"install": _install, "artifact": _artifact},
)

이러한 선언은 지정된 속성 스키마를 사용하여 maven.installmaven.artifact 태그를 지정할 수 있음을 보여줍니다.

모듈 확장 프로그램의 구현 함수는 확장 프로그램 및 모든 관련 태그를 사용하여 모든 모듈에 대한 액세스 권한을 부여하는 module_ctx 객체를 가져온다는 점을 제외하면 저장소 규칙과 유사합니다. 그런 다음 구현 함수는 저장소 규칙을 호출하여 저장소를 생성합니다.

# @rules_jvm_external//:extensions.bzl

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")  # a repo rule
def _maven_impl(ctx):
  # This is a fake implementation for demonstration purposes only

  # collect artifacts from across the dependency graph
  artifacts = []
  for mod in ctx.modules:
    for install in mod.tags.install:
      artifacts += install.artifacts
    artifacts += [_to_artifact(artifact) for artifact in mod.tags.artifact]

  # call out to the coursier CLI tool to resolve dependencies
  output = ctx.execute(["coursier", "resolve", artifacts])
  repo_attrs = _process_coursier_output(output)

  # call repo rules to generate repos
  for attrs in repo_attrs:
    http_file(**attrs)
  _generate_hub_repo(name = "maven", repo_attrs)

확장 프로그램 ID

모듈 확장 프로그램은 use_extension 호출에 표시되는 이름과 .bzl 파일로 식별됩니다. 다음 예에서 확장 프로그램 maven.bzl 파일 @rules_jvm_external//:extension.bzl 및 이름 maven로 식별됩니다.

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

다른 .bzl 파일에서 확장 프로그램을 다시 내보내면 새 ID가 부여되고 확장 프로그램의 두 버전이 모두 전이 모듈 그래프에 사용되는 경우 별도로 평가되며 해당 특정 ID와 연결된 태그만 표시됩니다.

확장 프로그램 작성자는 사용자가 단일 .bzl 파일에서만 모듈 확장 프로그램을 사용하도록 해야 합니다.

저장소 이름 및 공개 상태

확장자로 생성된 저장소는 module_repo_canonical_name~extension_name~repo_name 형식의 표준 이름을 갖습니다. 루트 모듈에서 호스팅되는 확장 프로그램의 경우 module_repo_canonical_name 부분이 _main 문자열로 대체됩니다. 표준 이름 형식은 반드시 사용해야 하는 API가 아니며 언제든지 변경될 수 있습니다.

이 이름 지정 정책은 각 확장 프로그램에 자체 '저장소 네임스페이스'가 있음을 의미합니다. 서로 다른 두 확장 프로그램은 충돌 없이 동일한 이름으로 저장소를 각각 정의할 수 있습니다. 또한 repository_ctx.name은 저장소의 표준 이름을 보고하며 이는 저장소 규칙 호출에 지정된 이름과 동일하지 않습니다.

모듈 확장 프로그램에서 생성한 저장소를 고려하기 위해 다음과 같은 몇 가지 저장소 공개 상태 규칙이 있습니다.

  • Bazel 모듈 저장소는 bazel_depuse_repo를 통해 MODULE.bazel 파일에 도입된 모든 저장소를 볼 수 있습니다.
  • 모듈 확장 프로그램에 의해 생성된 저장소는 확장 프로그램을 호스팅하는 모듈에 표시되는 모든 저장소와 동일한 모듈 확장 프로그램에 의해 생성된 다른 모든 저장소 (을 저장소 규칙에 지정된 이름을 외래 이름으로) 사용하여 볼 수 있습니다.
    • 이 경우 충돌이 발생할 수 있습니다. 모듈 저장소가 겉보기 이름 foo의 저장소를 볼 수 있고 확장 프로그램에서 지정된 이름 foo의 저장소를 생성하면 해당 확장 프로그램 foo로 생성된 모든 저장소는 전자를 의미합니다.

권장사항

이 섹션에서는 확장 프로그램을 바로 사용할 때 권장사항을 설명하고, 이를 바로 사용할 수 있고 유지 관리가 가능하며 시간이 지남에 따라 변화에 잘 맞게 조정합니다.

각 확장자를 별도의 파일에 넣기

확장 프로그램이 다른 파일에 있는 경우 한 확장 프로그램이 다른 확장 프로그램에서 생성한 저장소를 로드할 수 있습니다. 이 기능을 사용하지 않더라도 나중에 필요할 경우를 대비하여 별도의 파일에 배치하는 것이 가장 좋습니다. 확장 프로그램의 ID가 파일을 기반으로 하기 때문입니다. 따라서 확장 프로그램을 다른 파일로 이동하면 나중에 공개 API가 변경되고 사용자가 이전 버전과 호환되지 않게 변경됩니다.