version: implement Go tooling
These two packages implement respectively:
1. A companion Go library to access data from //version/spec
Protobuf data.
2. A Go code generator and related Bazel build infrastructure to convert
Bazel build status data into an embedded //version/spec Protobuf
Version message.
The two allow for stamping Go artifacts with a generated spec.Version
proto, and allows Go code to work with said messages.
The two systems are split to allow decoupling stamping build artifacts
from processing such version messages. This is so that eg. a Metropolis
client tool can receive a server's Version field, and then show that
field to the user.
Change-Id: I82fbfa6bc2418edc979cdc6e1fdee60ee75a88b7
Reviewed-on: https://review.monogon.dev/c/monogon/+/2332
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
Tested-by: Jenkins CI
diff --git a/version/defs.bzl b/version/defs.bzl
new file mode 100644
index 0000000..d0e439b
--- /dev/null
+++ b/version/defs.bzl
@@ -0,0 +1,79 @@
+load(
+ "@io_bazel_rules_go//go:def.bzl",
+ "GoLibrary",
+ "go_context",
+ "go_library",
+)
+
+def _go_version_library_impl(ctx):
+ output = ctx.actions.declare_file(ctx.attr.name + "_generated.go")
+
+ ctx.actions.run(
+ mnemonic = "GenVersion",
+ progress_message = "Generating version file",
+ inputs = [ctx.info_file],
+ outputs = [output],
+ executable = ctx.executable._genversion,
+ arguments = [
+ "-importpath",
+ ctx.attr.importpath,
+ "-product",
+ ctx.attr.product,
+ "-status_file",
+ ctx.info_file.path,
+ "-out_file",
+ output.path,
+ ],
+ )
+
+ go = go_context(ctx)
+ source_files = [output]
+ library = go.new_library(
+ go,
+ srcs = source_files,
+ )
+ source = go.library_to_source(go, ctx.attr, library, False)
+ providers = [library, source]
+ output_groups = {
+ "go_generated_srcs": source_files,
+ }
+ return providers + [OutputGroupInfo(**output_groups)]
+
+go_version_library = rule(
+ doc = """
+ Generate a Go library target which can be further embedded/depended upon
+ by other Go code. This library contains a Version proto field which will
+ be automatically populated with version based on build state data.
+ """,
+ implementation = _go_version_library_impl,
+ attrs = {
+ "importpath": attr.string(
+ mandatory = True,
+ ),
+ "product": attr.string(
+ mandatory = True,
+ doc = """
+ Name of Monogon product that for which this version library will
+ be generated. This must correspond to the product name as used in
+ Git tags, which in turn is used to extract a release version
+ during a build.
+ """,
+ ),
+ "_genversion": attr.label(
+ default = Label("//version/stampgo"),
+ cfg = "host",
+ executable = True,
+ allow_files = True,
+ ),
+ "_go_context_data": attr.label(
+ default = "@io_bazel_rules_go//:go_context_data",
+ ),
+ "deps": attr.label_list(
+ default = [
+ "@org_golang_google_protobuf//proto",
+ "//version/spec",
+ ],
+ ),
+ },
+ toolchains = ["@io_bazel_rules_go//go:toolchain"],
+)