建立依赖于另一条规则的挡板规则

时间:2019-12-09 02:30:34

标签: node.js build bazel

我正在尝试使用graphql-codegen库为代码生成GraphQL类型建立一个bazel规则。

gqlgen规则的实现非常简单:

load("@bazel_skylib//lib:paths.bzl", "paths")
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")

_SCHEMA = """
  {types}:
    schema: {schema}
    plugins:
      - "typescript"
  {meta}:
    schema: {schema}
    plugins:
      - "introspection"
"""

_CONFIG = """
overwrite: true
generates:
  {instructions}
"""

def _gqlgen_impl(ctx):
    config_file = ctx.actions.declare_file(ctx.label.name + ".yml")

    out_files = []
    instructions = []
    for s in ctx.files.srcs:
        name = paths.basename(s.path)[:-len(".graphql")]
        types = ctx.actions.declare_file("types/{}.ts".format(name))
        meta = ctx.actions.declare_file("meta/{}.json".format(name))
        out_files.append(types)
        out_files.append(meta)
        instructions.append(_SCHEMA.format(schema = s.path, types = types.path, meta = meta.path))
    instructions = "\n".join(instructions)

    ctx.actions.write(
        content = _CONFIG.format(instructions = instructions),
        output = config_file,
    )

    ctx.actions.run_shell(
        tools = [ctx.executable._codegen],
        inputs = depset(ctx.files.srcs + [config_file]),
        outputs = out_files,
        command = "{gqlgen} --config {cfg}".format(
            gqlgen = ctx.executable._codegen.path,
            cfg = config_file.path,
        ),
    )

输入是一组*.graphql文件,而输出是一组相应的*.json*.ts文件。

我使用的是nodejs规则,并且由于graphql-codegen是节点模块,因此我要在gqlgen规则中为其声明一个规则:

def gqlgen(name, **kwargs):
    nodejs_binary(
        name = "gqlgen",
        data = ["@npm//:node_modules"],
        entry_point = "@npm//:node_modules/@graphql-codegen/cli/bin.js",
        install_source_map_support = False,
        visibility = ["//visibility:public"],
    )

    _gqlgen(
        name = name,
        **kwargs
    )

我的问题在于将这两件事联系在一起。我有以下内容:

_gqlgen = rule(
    implementation = _gqlgen_impl,
    attrs = {
        "srcs": attr.label_list(
            allow_files = [".graphql"],
        ),
        "_codegen": attr.label(
            cfg = "host",
            default = "//schemas:gqlgen",
            executable = True,
        ),
    },
)

但是请注意,对于_codegen属性,我将可执行文件指定为//schemas:gqlgen,这是错误的,因为我应该能够从任何软件包中使用gqlgen规则。

是否可以通过调用nodejs_binary来引用rule()

1 个答案:

答案 0 :(得分:1)

要回答我的问题,我可以简单地执行以下操作:

_gqlgen = rule(
    implementation = _gqlgen_impl,
    attrs = {
        "srcs": attr.label_list(
            allow_files = [".graphql"],
        ),
        "_codegen": attr.label(
            cfg = "host",
            executable = True,
        ),
    },
)

def gqlgen(name, **kwargs):
    nodejs_binary(
        name = "gqlgen",
        data = ["@npm//:node_modules"],
        entry_point = "@npm//:node_modules/@graphql-codegen/cli/bin.js",
        install_source_map_support = False,
        visibility = ["//visibility:public"],
    )

    _gqlgen(
        name = name,
        _codegen = "gqlgen",
        **kwargs
    )