Использование Базела для построения полиглотов

У меня есть проект JVM Kotlin, который запускает некоторый JavaScript в собственной среде выполнения. В настоящее время источники на разных языках определены в отдельных репозиториях, а файл JS упакован в Интернет и упакован как JAR, который должен быть указан как зависимость проекта JVM. Это нормально работает, но я хочу объединить два репозитория, поскольку они по сути связаны. Я подумал, что вместо того, чтобы поддерживать множество различных инструментов для сборки, это была бы хорошая возможность изучить и использовать систему сборки полиглота, такую ​​как Bazel.

Текущая структура:

По сути, я пытаюсь создать два основных пакета. Веб-пакет строится правильно, и я могу просматривать запакованные через Интернет вывод через командную строку. Включая ИнтернетBUILD файл для полного изображения:

load("@npm_bazel_typescript//:index.bzl", "ts_library")

ts_library(
    name = "compileCore",
    srcs = ["index.ts"],
    tsconfig = "tsconfig.json",
)

filegroup(
    name = "internalCore",
    srcs = ["compileCore"],
    output_group = "es5_sources",
)

load("@npm//webpack-cli:index.bzl", webpack = "webpack_cli")

webpack(
    name = "bundle",
    outs = ["bundle.prod.js"],
    args = [
        "--mode production",
        "$(execpath internalCore)",
        "--config",
        "$(execpath webpack.config.js)",
        "-o",
        "$@",
    ],
    data = [
        "internalCore",
        "webpack.config.js",
        "@npm//:node_modules",
    ],
    visibility = ["//visibility:public"],
)

Другой важный пакет - вложенный //jvm/src/main/java/com/example/bazel/pluginпакет. По сути, это окончательный результат, которым должен быть JAR с выходными данными веб-пакета, включенными в качестве ресурсов.

load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")

kt_jvm_library(
    name = "plugin",
    srcs = glob(["*.kt"]),
    deps = [
        # ... some deps
    ],
    resources = ["//web:bundle"],
    visibility = ["//visibility:public"],
)

Это вроде бы просто, но при сборке возникают ошибки:

❯ bazel build //jvm/src/...
INFO: Analyzed target //jvm/src/main/java/com/example/bazel/plugin:plugin (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: /Users/jzucker/dev/GitHub/plugin-example-bazel/jvm/src/main/java/com/example/bazel/plugin/BUILD:12:15: error executing shell command: '/bin/bash -c external/bazel_tools/tools/zip/zipper/zipper c bazel-out/darwin-fastbuild/bin/jvm/src/main/java/com/example/bazel/plugin/plugin-resources.jar @bazel-out/darwin-fastbuild/bin/jvm/src/ma...' failed (Exit 255) bash failed: error executing command /bin/bash -c ... (remaining 1 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
File web/bundle.prod.js does not seem to exist.Target //jvm/src/main/java/com/example/bazel/plugin:plugin failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 0.402s, Critical Path: 0.05s
INFO: 0 processes.
FAILED: Build did NOT complete successfully

После некоторых экспериментов, похоже, это проблема попытки связать сгенерированные выходные данные в качестве ресурсов для kt_jvm_library. Если ресурсы ссылаются на реальный исходный файл из другого пакета, он работает нормально. Главный вопрос здесь в том, подходит ли это шаблон для Bazel или я пытаюсь злоупотребить этой технологией. Это кажется относительно простым вариантом использования, но в документации есть строка, которая меня беспокоит больше всего:

Инвариант всех правил состоит в том, что файлы, созданные правилом, всегда принадлежат тому же пакету, что и само правило; невозможно сгенерировать файлы в другой пакет. Однако нередки случаи, когда входные данные правила поступают из другого пакета.

С https://docs.bazel.build/versions/master/build-ref.html

Приветствуется любое понимание.

1 ответ

Решение

На самом деле это ошибка в наборе правил Bazel Kotlin: github.com/bazelbuild/rules_kotlin/issues/281

Пока это не будет исправлено, вы можете упаковать ресурсы в java_library и включите это как resource_jars.

java_library(
    name = "resources",
    resources = ["//web:bundle"],
    resource_strip_prefix = "web",
)

load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")

kt_jvm_library(
    name = "plugin",
    srcs = glob(["*.kt"]),
    deps = [
        # ... some deps
    ],
    resource_jars = ["resources"],
    visibility = ["//visibility:public"],
)
Другие вопросы по тегам