尝试编写自定义规则
Trying to write a custom rule
我正在尝试为 gqlgen 编写自定义规则。这个想法是 运行 它从 GraphQL 模式生成 Go 代码。
我的预期用途是:
gqlgen(
name = "gql-gen-foo",
schemas = ["schemas/schema.graphql"],
visibility = ["//visibility:public"],
)
"name"是规则的名称,我希望其他规则依赖于它; "schemas" 是一组输入文件。
到目前为止我有:
load(
"@io_bazel_rules_go//go:def.bzl",
_go_context = "go_context",
_go_rule = "go_rule",
)
def _gqlgen_impl(ctx):
go = _go_context(ctx)
args = ["run github.com/99designs/gqlgen --config"] + [ctx.attr.config]
ctx.actions.run(
inputs = ctx.attr.schemas,
outputs = [ctx.actions.declare_file(ctx.attr.name)],
arguments = args,
progress_message = "Generating GraphQL models and runtime from %s" % ctx.attr.config,
executable = go.go,
)
_gqlgen = _go_rule(
implementation = _gqlgen_impl,
attrs = {
"config": attr.string(
default = "gqlgen.yml",
doc = "The gqlgen filename",
),
"schemas": attr.label_list(
allow_files = [".graphql"],
doc = "The schema file location",
),
},
executable = True,
)
def gqlgen(**kwargs):
tags = kwargs.get("tags", [])
if "manual" not in tags:
tags.append("manual")
kwargs["tags"] = tags
_gqlgen(**kwargs)
我的直接问题是 Bazel 抱怨模式不是 Files
:
expected type 'File' for 'inputs' element but got type 'Target' instead
指定输入文件的正确方法是什么?
这是生成执行命令的规则的正确方法吗?
最后,输出文件不存在于文件系统中是否可以,而是作为其他规则可以依赖的标签?
而不是:
ctx.actions.run(
inputs = ctx.attr.schemas,
使用:
ctx.actions.run(
inputs = ctx.files.schemas,
Is this the right approach to generate a rule that executes a command?
这看起来是正确的,只要 gqlgen
使用正确的输出名称 (outputs = [ctx.actions.declare_file(ctx.attr.name)]
) 创建文件。
generated_go_file = ctx.actions.declare_file(ctx.attr.name + ".go")
# ..
ctx.actions.run(
outputs = [generated_go_file],
args = ["run", "...", "--output", generated_go_file.short_path],
# ..
)
Finally, is it okay to have the output file not exist in the filesystem, but rather be a label on which other rules can depend?
需要创建输出文件,只要在DefaultInfo
provider中的规则执行结束时返回,其他规则就可以依赖于文件标签(例如//my/package:foo-gqlgen.go
).
我正在尝试为 gqlgen 编写自定义规则。这个想法是 运行 它从 GraphQL 模式生成 Go 代码。
我的预期用途是:
gqlgen(
name = "gql-gen-foo",
schemas = ["schemas/schema.graphql"],
visibility = ["//visibility:public"],
)
"name"是规则的名称,我希望其他规则依赖于它; "schemas" 是一组输入文件。
到目前为止我有:
load(
"@io_bazel_rules_go//go:def.bzl",
_go_context = "go_context",
_go_rule = "go_rule",
)
def _gqlgen_impl(ctx):
go = _go_context(ctx)
args = ["run github.com/99designs/gqlgen --config"] + [ctx.attr.config]
ctx.actions.run(
inputs = ctx.attr.schemas,
outputs = [ctx.actions.declare_file(ctx.attr.name)],
arguments = args,
progress_message = "Generating GraphQL models and runtime from %s" % ctx.attr.config,
executable = go.go,
)
_gqlgen = _go_rule(
implementation = _gqlgen_impl,
attrs = {
"config": attr.string(
default = "gqlgen.yml",
doc = "The gqlgen filename",
),
"schemas": attr.label_list(
allow_files = [".graphql"],
doc = "The schema file location",
),
},
executable = True,
)
def gqlgen(**kwargs):
tags = kwargs.get("tags", [])
if "manual" not in tags:
tags.append("manual")
kwargs["tags"] = tags
_gqlgen(**kwargs)
我的直接问题是 Bazel 抱怨模式不是 Files
:
expected type 'File' for 'inputs' element but got type 'Target' instead
指定输入文件的正确方法是什么?
这是生成执行命令的规则的正确方法吗?
最后,输出文件不存在于文件系统中是否可以,而是作为其他规则可以依赖的标签?
而不是:
ctx.actions.run(
inputs = ctx.attr.schemas,
使用:
ctx.actions.run(
inputs = ctx.files.schemas,
Is this the right approach to generate a rule that executes a command?
这看起来是正确的,只要 gqlgen
使用正确的输出名称 (outputs = [ctx.actions.declare_file(ctx.attr.name)]
) 创建文件。
generated_go_file = ctx.actions.declare_file(ctx.attr.name + ".go")
# ..
ctx.actions.run(
outputs = [generated_go_file],
args = ["run", "...", "--output", generated_go_file.short_path],
# ..
)
Finally, is it okay to have the output file not exist in the filesystem, but rather be a label on which other rules can depend?
需要创建输出文件,只要在DefaultInfo
provider中的规则执行结束时返回,其他规则就可以依赖于文件标签(例如//my/package:foo-gqlgen.go
).