Add the bazel target :package-generic-unix

Which can be used to build the artifact with bazel
This commit is contained in:
Philip Kuryloski 2021-09-30 15:49:08 +02:00
parent eaa1370dc8
commit 11fd866247
7 changed files with 419 additions and 83 deletions

View File

@ -1,9 +1,12 @@
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("@bazel-erlang//:dialyze.bzl", "plt")
load("@bazel-erlang//:shell.bzl", "shell")
load("elixir_home.bzl", "elixir_home")
load(":rabbitmq_home.bzl", "rabbitmq_home")
load(":rabbitmq_run.bzl", "rabbitmq_run", "rabbitmq_run_command")
load(":rabbitmqctl.bzl", "rabbitmqctl")
load(":rabbitmq.bzl", "ALL_PLUGINS", "APP_VERSION")
load(":dist.bzl", "collect_licenses", "versioned_rabbitmq_home")
exports_files([
"scripts/bazel/rabbitmq-run.sh",
@ -37,42 +40,6 @@ plt(
visibility = ["//visibility:public"],
)
ALL_PLUGINS = [
"//deps/rabbit:bazel_erlang_lib",
"//deps/rabbitmq_amqp1_0:bazel_erlang_lib",
"//deps/rabbitmq_auth_backend_cache:bazel_erlang_lib",
"//deps/rabbitmq_auth_backend_http:bazel_erlang_lib",
"//deps/rabbitmq_auth_backend_ldap:bazel_erlang_lib",
"//deps/rabbitmq_auth_backend_oauth2:bazel_erlang_lib",
"//deps/rabbitmq_auth_mechanism_ssl:bazel_erlang_lib",
"//deps/rabbitmq_consistent_hash_exchange:bazel_erlang_lib",
"//deps/rabbitmq_event_exchange:bazel_erlang_lib",
"//deps/rabbitmq_federation:bazel_erlang_lib",
"//deps/rabbitmq_federation_management:bazel_erlang_lib",
"//deps/rabbitmq_jms_topic_exchange:bazel_erlang_lib",
"//deps/rabbitmq_management:bazel_erlang_lib",
"//deps/rabbitmq_mqtt:bazel_erlang_lib",
"//deps/rabbitmq_peer_discovery_aws:bazel_erlang_lib",
"//deps/rabbitmq_peer_discovery_consul:bazel_erlang_lib",
"//deps/rabbitmq_peer_discovery_etcd:bazel_erlang_lib",
"//deps/rabbitmq_peer_discovery_k8s:bazel_erlang_lib",
"//deps/rabbitmq_prometheus:bazel_erlang_lib",
"//deps/rabbitmq_random_exchange:bazel_erlang_lib",
"//deps/rabbitmq_recent_history_exchange:bazel_erlang_lib",
"//deps/rabbitmq_sharding:bazel_erlang_lib",
"//deps/rabbitmq_shovel:bazel_erlang_lib",
"//deps/rabbitmq_shovel_management:bazel_erlang_lib",
"//deps/rabbitmq_stomp:bazel_erlang_lib",
"//deps/rabbitmq_stream:bazel_erlang_lib",
"//deps/rabbitmq_stream_management:bazel_erlang_lib",
"//deps/rabbitmq_top:bazel_erlang_lib",
"//deps/rabbitmq_tracing:bazel_erlang_lib",
"//deps/rabbitmq_trust_store:bazel_erlang_lib",
"//deps/rabbitmq_web_dispatch:bazel_erlang_lib",
"//deps/rabbitmq_web_mqtt:bazel_erlang_lib",
"//deps/rabbitmq_web_stomp:bazel_erlang_lib",
]
rabbitmq_home(
name = "broker-home",
plugins = ALL_PLUGINS,
@ -132,3 +99,70 @@ shell(
name = "repl",
deps = ALL_PLUGINS,
)
collect_licenses(
name = "licenses",
srcs = glob(
["LICENSE*"],
exclude = [
"LICENSE.md",
"LICENSE.txt",
],
),
deps = ALL_PLUGINS,
)
versioned_rabbitmq_home(
name = "dist-home",
plugins = ALL_PLUGINS,
)
# need to add the INSTALL file
pkg_tar(
name = "license-files",
srcs = [
":licenses",
"//deps/rabbit:INSTALL",
],
visibility = ["//visibility:public"],
)
pkg_tar(
name = "scripts",
srcs = [
"scripts/bash_autocomplete.sh",
"scripts/rabbitmq-script-wrapper",
"scripts/rabbitmqctl-autocomplete.sh",
"scripts/zsh_autocomplete.sh",
],
package_dir = "scripts",
visibility = ["//visibility:public"],
)
pkg_tar(
name = "release-notes",
srcs = glob([
"release-notes/*.md",
"release-notes/*.txt",
]),
package_dir = "release-notes",
visibility = ["//visibility:public"],
)
pkg_tar(
name = "package-generic-unix",
srcs = [
":dist-home",
],
extension = "tar.xz",
package_dir = "rabbitmq_server-{}".format(APP_VERSION),
strip_prefix = "dist-home",
visibility = ["//visibility:public"],
deps = [
":license-files",
":release-notes",
":scripts",
"//deps/rabbit:manpages-dir",
],
)

View File

@ -1,6 +1,19 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
http_archive(
name = "rules_pkg",
sha256 = "038f1caa773a7e35b3663865ffb003169c6a71dc995e39bf4815792f385d837d",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.4.0/rules_pkg-0.4.0.tar.gz",
"https://github.com/bazelbuild/rules_pkg/releases/download/0.4.0/rules_pkg-0.4.0.tar.gz",
],
)
load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
rules_pkg_dependencies()
http_archive(
name = "io_buildbuddy_buildbuddy_toolchain",
sha256 = "48546946879b1fd2dcba327ba15776c822f2ce9a9ef1077be9bf3ecadcc1564a",

View File

@ -23,6 +23,7 @@ exports_files([
"scripts/rabbitmq-queues",
"scripts/rabbitmq-server",
"scripts/rabbitmqctl",
"INSTALL",
])
_APP_ENV = """[
@ -997,3 +998,72 @@ assert_suites(
suites,
glob(["test/**/*_SUITE.erl"]),
)
filegroup(
name = "manpages",
srcs = glob([
"docs/*.1",
"docs/*.2",
"docs/*.3",
"docs/*.4",
"docs/*.5",
"docs/*.6",
"docs/*.7",
"docs/*.8",
"docs/*.9",
]),
)
genrule(
name = "manpages-dir",
srcs = [":manpages"],
outs = ["manpages.tar"],
cmd = """set -euo pipefail
DESTDIR=manpages-tmp/share/man
mkdir -p $${DESTDIR}
for mp in $(SRCS); do
section=$${mp##*.}
mkdir -p $${DESTDIR}/man$$section
gzip < $$mp \\
> $${DESTDIR}/man$$section/$$(basename $$mp).gz
done
tar --strip-components 1 -cf $@ manpages-tmp/*
rm -dr manpages-tmp
""",
visibility = ["//visibility:public"],
)
genrule(
name = "web-manpages",
srcs = [":manpages"],
outs = ["web-manpages.tar"],
cmd = """set -euo pipefail
mkdir web-manpages-tmp
for mp in $(SRCS); do
d=web-manpages-tmp/$$(basename $${mp}).html
echo "Converting $$mp to $$d..."
mandoc -T html -O 'fragment,man=%N.%S.html' "$$mp" | \\
awk '\\
/^<table class="head">$$/ { remove_table=1; next; } \\
/^<table class="foot">$$/ { remove_table=1; next; } \\
/^<\\/table>$$/ { if (remove_table) { remove_table=0; next; } } \\
{ if (!remove_table) { \\
line=$$0; \\
gsub(/<h2/, "<h3", line); \\
gsub(/<\\/h2>/, "</h3>", line); \\
gsub(/<h1/, "<h2", line); \\
gsub(/<\\/h1>/, "</h2>", line); \\
gsub(/class="D1"/, "class=\"D1 lang-bash\"", line); \\
gsub(/class="Bd Bd-indent"/, "class=\"Bd Bd-indent lang-bash\"", line); \\
gsub(/&#[xX]201[cCdD];/, "\\&quot;", line); \\
print line; \\
} } \\
' > "$$d"
done
tar --strip-components 1 -cf $@ web-manpages-tmp/*
rm -dr web-manpages-tmp
""",
visibility = ["//visibility:public"],
)

View File

@ -1,4 +1,3 @@
load("@bazel-erlang//:bazel_erlang_lib.bzl", "erlang_lib", "test_erlang_lib")
load("@bazel-erlang//:xref.bzl", "xref")
load("@bazel-erlang//:dialyze.bzl", "dialyze", "plt")
load("//:rabbitmq_home.bzl", "rabbitmq_home")
@ -9,6 +8,7 @@ load(
"RABBITMQ_DIALYZER_OPTS",
"assert_suites",
"rabbitmq_integration_suite",
"rabbitmq_lib",
"rabbitmq_suite",
)
@ -28,16 +28,7 @@ DEPS = [
"@cowboy//:bazel_erlang_lib",
]
erlang_lib(
app_description = APP_DESCRIPTION,
app_module = APP_MODULE,
app_name = APP_NAME,
app_version = APP_VERSION,
extra_apps = EXTRA_APPS,
deps = DEPS,
)
test_erlang_lib(
rabbitmq_lib(
app_description = APP_DESCRIPTION,
app_module = APP_MODULE,
app_name = APP_NAME,

199
dist.bzl Normal file
View File

@ -0,0 +1,199 @@
load("@bazel-erlang//:erlang_home.bzl", "ErlangHomeProvider")
load("@bazel-erlang//:bazel_erlang_lib.bzl", "ErlangLibInfo", "flat_deps", "path_join")
load("@bazel-erlang//:ct.bzl", "additional_file_dest_relative_path")
load(
":rabbitmq_home.bzl",
"RABBITMQ_HOME_ATTRS",
"RabbitmqHomeInfo",
"flatten",
"link_escript",
"unique_versions",
)
def _collect_licenses_impl(ctx):
srcs = ctx.files.srcs + flatten([
d[ErlangLibInfo].license_files
for d in flat_deps(ctx.attr.deps)
])
outs = {}
for src in srcs:
name = src.basename
if name not in outs:
dest = ctx.actions.declare_file(name)
ctx.actions.run(
inputs = [src],
outputs = [dest],
executable = "cp",
arguments = [
src.path,
dest.path,
],
)
outs[name] = dest
return [
DefaultInfo(
files = depset(sorted(outs.values())),
),
]
collect_licenses = rule(
implementation = _collect_licenses_impl,
attrs = {
"srcs": attr.label_list(allow_files = True),
"deps": attr.label_list(providers = [ErlangLibInfo]),
},
)
def _copy_script(ctx, script):
dest = ctx.actions.declare_file(path_join(ctx.label.name, "sbin", script.basename))
ctx.actions.expand_template(
template = script,
output = dest,
substitutions = {
"SYS_PREFIX=": "SYS_PREFIX=${RABBITMQ_HOME}",
},
)
return dest
def _extract_version(p):
return "erl -eval '{ok, [{application, _, AppInfo}]} = file:consult(\"" + p + "\"), Version = proplists:get_value(vsn, AppInfo), io:fwrite(Version), halt().' -noshell"
def _app_file(plugin_lib_info):
for f in plugin_lib_info.beam:
if f.basename.endswith(".app"):
return f
fail(".app file not found in {}".format(plugin_lib_info))
def _plugins_dir(ctx, plugins):
plugins_dir = ctx.actions.declare_directory(path_join(ctx.label.name, "plugins"))
erlang_home = ctx.attr._erlang_home[ErlangHomeProvider].path
inputs = []
commands = ["set -euo pipefail", ""]
for plugin in plugins:
lib_info = plugin[ErlangLibInfo]
app_file = _app_file(lib_info)
extract_version = _extract_version(app_file.path)
commands.append("PLUGIN_VERSION=$({erlang_home}/bin/{extract_version})".format(erlang_home = erlang_home, extract_version = extract_version))
commands.append(
"echo \"Assembling {lib_name}-$PLUGIN_VERSION...\"".format(
lib_name = lib_info.lib_name,
),
)
commands.append(
"mkdir -p {plugins_dir}/{lib_name}-$PLUGIN_VERSION/include".format(
plugins_dir = plugins_dir.path,
lib_name = lib_info.lib_name,
),
)
for f in lib_info.include:
commands.append(
"cp {src} {plugins_dir}/{lib_name}-$PLUGIN_VERSION/include/{dest}".format(
src = f.path,
plugins_dir = plugins_dir.path,
lib_name = lib_info.lib_name,
dest = f.basename,
),
)
inputs.extend(lib_info.include)
commands.append(
"mkdir -p {plugins_dir}/{lib_name}-$PLUGIN_VERSION/ebin".format(
plugins_dir = plugins_dir.path,
lib_name = lib_info.lib_name,
),
)
for f in lib_info.beam:
if f.is_directory:
if f.basename != "ebin":
fail("{} contains a directory in 'beam' that is not an ebin dir".format(lib_info.lib_name))
commands.append(
"cp -R {src} {plugins_dir}/{lib_name}-$PLUGIN_VERSION".format(
src = f.path,
plugins_dir = plugins_dir.path,
lib_name = lib_info.lib_name,
),
)
else:
commands.append(
"cp {src} {plugins_dir}/{lib_name}-$PLUGIN_VERSION/ebin/{dest}".format(
src = f.path,
plugins_dir = plugins_dir.path,
lib_name = lib_info.lib_name,
dest = f.basename,
),
)
inputs.extend(lib_info.beam)
for f in lib_info.priv:
p = additional_file_dest_relative_path(plugin.label, f)
commands.append(
"mkdir -p $(dirname {plugins_dir}/{lib_name}-$PLUGIN_VERSION/{dest}) && cp {src} {plugins_dir}/{lib_name}-$PLUGIN_VERSION/{dest}".format(
src = f.path,
plugins_dir = plugins_dir.path,
lib_name = lib_info.lib_name,
dest = p,
),
)
inputs.extend(lib_info.priv)
commands.append("")
ctx.actions.run_shell(
inputs = inputs,
outputs = [plugins_dir],
command = "\n".join(commands),
)
return plugins_dir
def _versioned_rabbitmq_home_impl(ctx):
plugins = flat_deps(ctx.attr.plugins)
erlang_versions = unique_versions(plugins)
if len(erlang_versions) > 1:
fail("plugins do not have a unified erlang version", erlang_versions)
scripts = [_copy_script(ctx, script) for script in ctx.files._scripts]
rabbitmq_ctl_copies = [
"rabbitmq-diagnostics",
"rabbitmq-plugins",
"rabbitmq-queues",
"rabbitmq-streams",
"rabbitmq-upgrade",
"rabbitmqctl",
]
escripts = [link_escript(ctx, escript) for escript in rabbitmq_ctl_copies]
plugins_dir = _plugins_dir(ctx, plugins)
rabbitmqctl = None
for script in scripts:
if script.basename == "rabbitmqctl":
rabbitmqctl = script
if rabbitmqctl == None:
fail("could not find rabbitmqct among", scripts)
return [
RabbitmqHomeInfo(
rabbitmqctl = rabbitmqctl,
),
DefaultInfo(
files = depset(scripts + escripts + [plugins_dir]),
),
]
versioned_rabbitmq_home = rule(
implementation = _versioned_rabbitmq_home_impl,
attrs = dict(RABBITMQ_HOME_ATTRS.items() + {
"_erlang_home": attr.label(default = "@bazel-erlang//:erlang_home"),
}.items()),
)

View File

@ -22,6 +22,42 @@ RABBITMQ_DIALYZER_OPTS = [
APP_VERSION = "3.10.0"
ALL_PLUGINS = [
"//deps/rabbit:bazel_erlang_lib",
"//deps/rabbitmq_amqp1_0:bazel_erlang_lib",
"//deps/rabbitmq_auth_backend_cache:bazel_erlang_lib",
"//deps/rabbitmq_auth_backend_http:bazel_erlang_lib",
"//deps/rabbitmq_auth_backend_ldap:bazel_erlang_lib",
"//deps/rabbitmq_auth_backend_oauth2:bazel_erlang_lib",
"//deps/rabbitmq_auth_mechanism_ssl:bazel_erlang_lib",
"//deps/rabbitmq_consistent_hash_exchange:bazel_erlang_lib",
"//deps/rabbitmq_event_exchange:bazel_erlang_lib",
"//deps/rabbitmq_federation:bazel_erlang_lib",
"//deps/rabbitmq_federation_management:bazel_erlang_lib",
"//deps/rabbitmq_jms_topic_exchange:bazel_erlang_lib",
"//deps/rabbitmq_management:bazel_erlang_lib",
"//deps/rabbitmq_mqtt:bazel_erlang_lib",
"//deps/rabbitmq_peer_discovery_aws:bazel_erlang_lib",
"//deps/rabbitmq_peer_discovery_consul:bazel_erlang_lib",
"//deps/rabbitmq_peer_discovery_etcd:bazel_erlang_lib",
"//deps/rabbitmq_peer_discovery_k8s:bazel_erlang_lib",
"//deps/rabbitmq_prometheus:bazel_erlang_lib",
"//deps/rabbitmq_random_exchange:bazel_erlang_lib",
"//deps/rabbitmq_recent_history_exchange:bazel_erlang_lib",
"//deps/rabbitmq_sharding:bazel_erlang_lib",
"//deps/rabbitmq_shovel:bazel_erlang_lib",
"//deps/rabbitmq_shovel_management:bazel_erlang_lib",
"//deps/rabbitmq_stomp:bazel_erlang_lib",
"//deps/rabbitmq_stream:bazel_erlang_lib",
"//deps/rabbitmq_stream_management:bazel_erlang_lib",
"//deps/rabbitmq_top:bazel_erlang_lib",
"//deps/rabbitmq_tracing:bazel_erlang_lib",
"//deps/rabbitmq_trust_store:bazel_erlang_lib",
"//deps/rabbitmq_web_dispatch:bazel_erlang_lib",
"//deps/rabbitmq_web_mqtt:bazel_erlang_lib",
"//deps/rabbitmq_web_stomp:bazel_erlang_lib",
]
LABELS_WITH_TEST_VERSIONS = [
"//deps/amqp10_common:bazel_erlang_lib",
"//deps/rabbit_common:bazel_erlang_lib",
@ -29,6 +65,9 @@ LABELS_WITH_TEST_VERSIONS = [
"//deps/rabbit/apps/rabbitmq_prelaunch:bazel_erlang_lib",
]
def all_plugins(rabbitmq_workspace = "@rabbitmq-server"):
return [rabbitmq_workspace + p for p in ALL_PLUGINS]
def with_test_versions(deps):
r = []
for d in deps:

View File

@ -1,4 +1,5 @@
load("@bazel-erlang//:bazel_erlang_lib.bzl", "ErlangLibInfo", "flat_deps", "path_join")
load("@bazel-erlang//:ct.bzl", "additional_file_dest_relative_path")
RabbitmqHomeInfo = provider(
doc = "An assembled RABBITMQ_HOME dir",
@ -19,7 +20,7 @@ def _copy_script(ctx, script):
)
return dest
def _link_escript(ctx, escript):
def link_escript(ctx, escript):
e = ctx.attr._rabbitmqctl_escript.files_to_run.executable
s = ctx.actions.declare_file(path_join(ctx.label.name, "escript", escript))
ctx.actions.symlink(
@ -28,19 +29,6 @@ def _link_escript(ctx, escript):
)
return s
def _priv_file_dest_relative_path(plugin_label, f):
if plugin_label.workspace_root != "":
if plugin_label.package != "":
rel_base = path_join(plugin_label.workspace_root, plugin_label.package)
else:
rel_base = plugin_label.workspace_root
else:
rel_base = plugin_label.package
if rel_base != "":
return f.path.replace(rel_base + "/", "")
else:
return f.path
def _plugins_dir_links(ctx, plugin):
lib_info = plugin[ErlangLibInfo]
plugin_path = path_join(
@ -72,7 +60,7 @@ def _plugins_dir_links(ctx, plugin):
links.append(o)
for f in lib_info.priv:
p = _priv_file_dest_relative_path(plugin.label, f)
p = additional_file_dest_relative_path(plugin.label, f)
o = ctx.actions.declare_file(path_join(plugin_path, p))
ctx.actions.symlink(
output = o,
@ -82,7 +70,7 @@ def _plugins_dir_links(ctx, plugin):
return links
def _unique_versions(plugins):
def unique_versions(plugins):
erlang_versions = []
for plugin in plugins:
erlang_version = plugin[ErlangLibInfo].erlang_version
@ -90,13 +78,13 @@ def _unique_versions(plugins):
erlang_versions.append(erlang_version)
return erlang_versions
def _flatten(list_of_lists):
def flatten(list_of_lists):
return [item for sublist in list_of_lists for item in sublist]
def _impl(ctx):
plugins = flat_deps(ctx.attr.plugins)
erlang_versions = _unique_versions(plugins)
erlang_versions = unique_versions(plugins)
if len(erlang_versions) > 1:
fail("plugins do not have a unified erlang version", erlang_versions)
@ -110,9 +98,9 @@ def _impl(ctx):
"rabbitmq-upgrade",
"rabbitmqctl",
]
escripts = [_link_escript(ctx, escript) for escript in rabbitmq_ctl_copies]
escripts = [link_escript(ctx, escript) for escript in rabbitmq_ctl_copies]
plugins = _flatten([_plugins_dir_links(ctx, plugin) for plugin in plugins])
plugins = flatten([_plugins_dir_links(ctx, plugin) for plugin in plugins])
rabbitmqctl = None
for script in scripts:
@ -130,24 +118,26 @@ def _impl(ctx):
),
]
RABBITMQ_HOME_ATTRS = {
"_scripts": attr.label_list(
default = [
"//deps/rabbit:scripts/rabbitmq-defaults",
"//deps/rabbit:scripts/rabbitmq-diagnostics",
"//deps/rabbit:scripts/rabbitmq-env",
"//deps/rabbit:scripts/rabbitmq-plugins",
"//deps/rabbit:scripts/rabbitmq-queues",
"//deps/rabbit:scripts/rabbitmq-server",
"//deps/rabbit:scripts/rabbitmqctl",
],
allow_files = True,
),
"_rabbitmqctl_escript": attr.label(default = "//deps/rabbitmq_cli:rabbitmqctl"),
"plugins": attr.label_list(providers = [ErlangLibInfo]),
}
rabbitmq_home = rule(
implementation = _impl,
attrs = {
"_scripts": attr.label_list(
default = [
"//deps/rabbit:scripts/rabbitmq-defaults",
"//deps/rabbit:scripts/rabbitmq-diagnostics",
"//deps/rabbit:scripts/rabbitmq-env",
"//deps/rabbit:scripts/rabbitmq-plugins",
"//deps/rabbit:scripts/rabbitmq-queues",
"//deps/rabbit:scripts/rabbitmq-server",
"//deps/rabbit:scripts/rabbitmqctl",
],
allow_files = True,
),
"_rabbitmqctl_escript": attr.label(default = "//deps/rabbitmq_cli:rabbitmqctl"),
"plugins": attr.label_list(),
},
attrs = RABBITMQ_HOME_ATTRS,
)
def _dirname(p):