From 502730b32d8157b11662939814c795698d498134 Mon Sep 17 00:00:00 2001 From: Rin Kuryloski Date: Tue, 27 Sep 2022 16:45:26 +0200 Subject: [PATCH] Apply the @erlang_config pattern for elixir via the WORKSPACE and use rules_erlang 3.7.0 --- .github/workflows/oci.yaml | 10 +- .github/workflows/update-elixir-patches.yaml | 27 ++- MODULE.bazel | 43 +++- WORKSPACE | 45 +++- bazel/bzlmod/extensions.bzl | 90 ++++++++ bazel/elixir/elixir.bzl | 65 ++++++ bazel/elixir/elixir_build.bzl | 5 +- bazel/platforms/BUILD.bazel | 39 +--- bazel/repositories/BUILD.bazel | 0 bazel/repositories/BUILD_external.tpl | 33 +++ bazel/repositories/BUILD_internal.tpl | 35 +++ bazel/repositories/defaults.bzl.tpl | 6 + bazel/repositories/elixir_config.bzl | 224 +++++++++++++++++++ bazel/toolchains/BUILD.bazel | 31 --- user-template.bazelrc | 2 - 15 files changed, 556 insertions(+), 99 deletions(-) create mode 100644 bazel/repositories/BUILD.bazel create mode 100644 bazel/repositories/BUILD_external.tpl create mode 100644 bazel/repositories/BUILD_internal.tpl create mode 100644 bazel/repositories/defaults.bzl.tpl create mode 100644 bazel/repositories/elixir_config.bzl delete mode 100644 bazel/toolchains/BUILD.bazel diff --git a/.github/workflows/oci.yaml b/.github/workflows/oci.yaml index 3b80d2a29ffb..43b1e3d7c5c1 100644 --- a/.github/workflows/oci.yaml +++ b/.github/workflows/oci.yaml @@ -84,22 +84,17 @@ jobs: otp-version: ${{ steps.load-info.outputs.otp }} elixir-version: ${{ steps.load-info.outputs.elixir }} - - name: Further Configure Bazel - run: | - ELIXIR_HOME="$(dirname $(dirname $(which iex)))" - cat << EOF >> user.bazelrc - build --elixir_home=${ELIXIR_HOME} - EOF - - name: Build run: | export ERLANG_HOME="$(dirname $(dirname $(which erl)))" + export ELIXIR_HOME="$(dirname $(dirname $(which iex)))" bazelisk build //packaging/docker-image:rabbitmq \ --config=buildbuddy - name: Test run: | export ERLANG_HOME="$(dirname $(dirname $(which erl)))" + export ELIXIR_HOME="$(dirname $(dirname $(which iex)))" OCI_TESTS=$(bazel query 'tests(//packaging/docker-image/...)') bazelisk test ${OCI_TESTS} \ --config=buildbuddy @@ -107,6 +102,7 @@ jobs: - name: Load run: | export ERLANG_HOME="$(dirname $(dirname $(which erl)))" + export ELIXIR_HOME="$(dirname $(dirname $(which iex)))" bazelisk run //packaging/docker-image:rabbitmq \ --config=buildbuddy diff --git a/.github/workflows/update-elixir-patches.yaml b/.github/workflows/update-elixir-patches.yaml index d2112f9357c0..92e040ba6c73 100644 --- a/.github/workflows/update-elixir-patches.yaml +++ b/.github/workflows/update-elixir-patches.yaml @@ -13,13 +13,13 @@ jobs: matrix: include: - elixir_version: "1.10" - name_suffix: '_1_10' + name: '1_10' - elixir_version: "1.12" - name_suffix: '_1_12' + name: '1_12' - elixir_version: "1.13" - name_suffix: '_1_13' + name: '1_13' - elixir_version: "1.14" - name_suffix: '_1_14' + name: '1_14' timeout-minutes: 10 steps: - name: CHECKOUT REPOSITORY @@ -30,7 +30,7 @@ jobs: set +e git ls-remote --exit-code --heads origin bump-elixir-${{ matrix.elixir_version }} echo "::set-output name=c::$?" - - name: DETERMINE LATEST PATCH + - name: DETERMINE LATEST PATCH & SHA if: steps.check-for-branch.outputs.c != 0 id: fetch-version run: | @@ -42,7 +42,8 @@ jobs: exit 1 fi - wget --continue --quiet --output-document="/tmp/elixir.tar.gz" "https://github.com/elixir-lang/elixir/archive/${TAG_NAME}.tar.gz" && \ + ARCHIVE_URL="https://github.com/elixir-lang/elixir/archive/${TAG_NAME}.tar.gz" + wget --continue --quiet --output-document="/tmp/elixir.tar.gz" "${ARCHIVE_URL}" && \ SHA="$(shasum -a 256 "/tmp/elixir.tar.gz" | awk '{print $1}')" if [[ -z "${SHA}" ]]; then @@ -57,13 +58,15 @@ jobs: run: | sudo npm install --global --silent @bazel/buildozer - LINE=$(grep -n 'name_suffix = "${{ matrix.name_suffix }}",' bazel/toolchains/BUILD.bazel | awk -F ":" '{print $1}') - LINE=$(($LINE-1)) + OLD_SHA="$(cat MODULE.bazel | buildozer 'print sha256' -:${{ matrix.name }})" + OLD_VERSION="$(cat MODULE.bazel | buildozer 'print version' -:${{ matrix.name }})" - buildozer 'set sha256 "${{ steps.fetch-version.outputs.SHA }}"' \ - //bazel/toolchains:%${LINE} || test $? -eq 3 - buildozer 'set version "${{ steps.fetch-version.outputs.VERSION }}"' \ - //bazel/toolchains:%${LINE} || test $? -eq 3 + echo "$(cat MODULE.bazel | buildozer 'set sha256 "${{ steps.fetch-version.outputs.SHA }}"' -:${{ matrix.name }})" > MODULE.bazel + echo "$(cat MODULE.bazel | buildozer 'set version "${{ steps.fetch-version.outputs.VERSION }}"' -:${{ matrix.name }})" > MODULE.bazel + + sed -i"_orig" "s/${OLD_SHA}/${{ steps.fetch-version.outputs.SHA }}/" WORKSPACE + sed -i"_orig" "s/${OLD_VERSION}/${{ steps.fetch-version.outputs.VERSION }}/" WORKSPACE + rm *_orig set -x git diff diff --git a/MODULE.bazel b/MODULE.bazel index d37f36d07984..3b306ef4f61a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -25,7 +25,7 @@ bazel_dep( bazel_dep( name = "rules_erlang", - version = "3.6.3", + version = "3.7.0", ) erlang_config = use_extension( @@ -63,16 +63,48 @@ use_repo( "erlang_config", ) +elixir_config = use_extension( + "//bazel/bzlmod:extensions.bzl", + "elixir_config", +) + +elixir_config.internal_elixir_from_github_release( + name = "1_10", + sha256 = "8518c78f43fe36315dbe0d623823c2c1b7a025c114f3f4adbb48e04ef63f1d9f", + version = "1.10.4", +) +elixir_config.internal_elixir_from_github_release( + name = "1_12", + sha256 = "c5affa97defafa1fd89c81656464d61da8f76ccfec2ea80c8a528decd5cb04ad", + version = "1.12.3", +) +elixir_config.internal_elixir_from_github_release( + name = "1_13", + sha256 = "95daf2dd3052e6ca7d4d849457eaaba09de52d65ca38d6933c65bc1cdf6b8579", + version = "1.13.4", +) +elixir_config.internal_elixir_from_github_release( + name = "1_14", + sha256 = "ac129e266a1e04cdc389551843ec3dbdf36086bb2174d3d7e7936e820735003b", + version = "1.14.0", +) + +use_repo( + elixir_config, + "elixir_config", +) + register_toolchains( "@erlang_config//external:toolchain", "@erlang_config//23:toolchain", "@erlang_config//24:toolchain", "@erlang_config//25:toolchain", "@erlang_config//git_master:toolchain", - "//bazel/toolchains:elixir_toolchain_external", - "//bazel/toolchains:elixir_toolchain_1_10", - "//bazel/toolchains:elixir_toolchain_1_12", - "//bazel/toolchains:elixir_toolchain_1_13", + "@elixir_config//external:toolchain", + "@elixir_config//1_10:toolchain", + "@elixir_config//1_12:toolchain", + "@elixir_config//1_13:toolchain", + "@elixir_config//1_14:toolchain", ) erlang_package = use_extension( @@ -378,6 +410,7 @@ use_repo( secondary_umbrella = use_extension( "//bazel/bzlmod:extensions.bzl", "secondary_umbrella", + dev_dependency = True, ) use_repo( diff --git a/WORKSPACE b/WORKSPACE index 61bbccc87065..ea740bb9e4d9 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -112,7 +112,7 @@ git_repository( git_repository( name = "rules_erlang", remote = "https://github.com/rabbitmq/rules_erlang.git", - tag = "3.6.3", + tag = "3.7.0", ) load( @@ -155,14 +155,45 @@ load("@erlang_config//:defaults.bzl", "register_defaults") register_defaults() -register_toolchains( - "//bazel/toolchains:elixir_toolchain_external", - "//bazel/toolchains:elixir_toolchain_1_10", - "//bazel/toolchains:elixir_toolchain_1_12", - "//bazel/toolchains:elixir_toolchain_1_13", - "//bazel/toolchains:elixir_toolchain_1_14", +load( + "//bazel/elixir:elixir.bzl", + "elixir_config", + "internal_elixir_from_github_release", +) + +elixir_config( + internal_elixir_configs = [ + internal_elixir_from_github_release( + name = "1_10", + sha256 = "8518c78f43fe36315dbe0d623823c2c1b7a025c114f3f4adbb48e04ef63f1d9f", + version = "1.10.4", + ), + internal_elixir_from_github_release( + name = "1_12", + sha256 = "c5affa97defafa1fd89c81656464d61da8f76ccfec2ea80c8a528decd5cb04ad", + version = "1.12.3", + ), + internal_elixir_from_github_release( + name = "1_13", + sha256 = "95daf2dd3052e6ca7d4d849457eaaba09de52d65ca38d6933c65bc1cdf6b8579", + version = "1.13.4", + ), + internal_elixir_from_github_release( + name = "1_14", + sha256 = "ac129e266a1e04cdc389551843ec3dbdf36086bb2174d3d7e7936e820735003b", + version = "1.14.0", + ), + ], + rabbitmq_server_workspace = "@", +) + +load( + "@elixir_config//:defaults.bzl", + register_elixir_defaults = "register_defaults", ) +register_elixir_defaults() + load("//:workspace_helpers.bzl", "rabbitmq_external_deps") rabbitmq_external_deps(rabbitmq_workspace = "@") diff --git a/bazel/bzlmod/extensions.bzl b/bazel/bzlmod/extensions.bzl index 340765392549..ddc10c8ef876 100644 --- a/bazel/bzlmod/extensions.bzl +++ b/bazel/bzlmod/extensions.bzl @@ -3,6 +3,96 @@ load( ":secondary_umbrella.bzl", fetch_secondary_umbrella = "secondary_umbrella", ) +load( + "//bazel/repositories:elixir_config.bzl", + "INSTALLATION_TYPE_EXTERNAL", + "INSTALLATION_TYPE_INTERNAL", + _elixir_config_rule = "elixir_config", +) +load( + "//bazel/elixir:elixir.bzl", + "DEFAULT_ELIXIR_SHA256", + "DEFAULT_ELIXIR_VERSION", +) + +def _elixir_config(ctx): + types = {} + versions = {} + urls = {} + strip_prefixs = {} + sha256s = {} + elixir_homes = {} + + for mod in ctx.modules: + for elixir in mod.tags.external_elixir_from_path: + types[elixir.name] = INSTALLATION_TYPE_EXTERNAL + versions[elixir.name] = elixir.version + elixir_homes[elixir.name] = elixir.elixir_home + + for elixir in mod.tags.internal_elixir_from_http_archive: + types[elixir.name] = INSTALLATION_TYPE_INTERNAL + versions[elixir.name] = elixir.version + urls[elixir.name] = elixir.url + strip_prefixs[elixir.name] = elixir.strip_prefix + sha256s[elixir.name] = elixir.sha256 + + for elixir in mod.tags.internal_elixir_from_github_release: + url = "https://github.com/elixir-lang/elixir/archive/refs/tags/v{}.tar.gz".format( + elixir.version, + ) + strip_prefix = "elixir-{}".format(elixir.version) + + types[elixir.name] = INSTALLATION_TYPE_INTERNAL + versions[elixir.name] = elixir.version + urls[elixir.name] = url + strip_prefixs[elixir.name] = strip_prefix + sha256s[elixir.name] = elixir.sha256 + + _elixir_config_rule( + name = "elixir_config", + rabbitmq_server_workspace = "@rabbitmq-server", + types = types, + versions = versions, + urls = urls, + strip_prefixs = strip_prefixs, + sha256s = sha256s, + elixir_homes = elixir_homes, + ) + +external_elixir_from_path = tag_class(attrs = { + "name": attr.string(), + "version": attr.string(), + "elixir_home": attr.string(), +}) + +internal_elixir_from_http_archive = tag_class(attrs = { + "name": attr.string(), + "version": attr.string(), + "url": attr.string(), + "strip_prefix": attr.string(), + "sha256": attr.string(), +}) + +internal_elixir_from_github_release = tag_class(attrs = { + "name": attr.string( + default = "internal", + ), + "version": attr.string( + default = DEFAULT_ELIXIR_VERSION, + ), + "sha256": attr.string( + default = DEFAULT_ELIXIR_SHA256, + ), +}) + +elixir_config = module_extension( + implementation = _elixir_config, + tag_classes = { + "external_elixir_from_path": external_elixir_from_path, + "internal_elixir_from_http_archive": internal_elixir_from_http_archive, + "internal_elixir_from_github_release": internal_elixir_from_github_release, + }, +) def _rbe(ctx): rbe_repo_props = [] diff --git a/bazel/elixir/elixir.bzl b/bazel/elixir/elixir.bzl index d369dd1ee062..d36240a9a862 100644 --- a/bazel/elixir/elixir.bzl +++ b/bazel/elixir/elixir.bzl @@ -7,8 +7,15 @@ load( ":elixir_toolchain.bzl", "elixir_toolchain", ) +load( + "//bazel/repositories:elixir_config.bzl", + "INSTALLATION_TYPE_INTERNAL", + _elixir_config = "elixir_config", +) def elixir_toolchain_external(): + """DEPRECATED""" + elixir_external( name = "external_elixir_installation_ref", target_compatible_with = [ @@ -40,6 +47,8 @@ def elixir_toolchain_from_http_archive( strip_prefix = None, sha256 = None, elixir_constraints = None): + """DEPRECATED""" + elixir_build( name = "elixir_build{}".format(name_suffix), url = url, @@ -68,6 +77,8 @@ def elixir_toolchain_from_github_release( name_suffix = "_default", version = None, sha256 = None): + """DEPRECATED""" + [major, minor, patch] = version.split(".") elixir_constraints = [ Label("//bazel/platforms:elixir_{}_{}".format(major, minor)), @@ -80,3 +91,57 @@ def elixir_toolchain_from_github_release( sha256 = sha256, elixir_constraints = elixir_constraints, ) + +DEFAULT_ELIXIR_VERSION = "1.13.4" +DEFAULT_ELIXIR_SHA256 = "95daf2dd3052e6ca7d4d849457eaaba09de52d65ca38d6933c65bc1cdf6b8579" + +# Generates the @elixir_config repository, which contains erlang +# toolchains and platform defintions +def elixir_config( + rabbitmq_server_workspace = "@rabbitmq-server", + internal_elixir_configs = []): + types = {c.name: INSTALLATION_TYPE_INTERNAL for c in internal_elixir_configs} + versions = {c.name: c.version for c in internal_elixir_configs} + urls = {c.name: c.url for c in internal_elixir_configs} + strip_prefixs = {c.name: c.strip_prefix for c in internal_elixir_configs if c.strip_prefix} + sha256s = {c.name: c.sha256 for c in internal_elixir_configs if c.sha256} + + _elixir_config( + name = "elixir_config", + rabbitmq_server_workspace = rabbitmq_server_workspace, + types = types, + versions = versions, + urls = urls, + strip_prefixs = strip_prefixs, + sha256s = sha256s, + ) + +def internal_elixir_from_http_archive( + name = None, + version = None, + url = None, + strip_prefix = None, + sha256 = None): + return struct( + name = name, + version = version, + url = url, + strip_prefix = strip_prefix, + sha256 = sha256, + ) + +def internal_elixir_from_github_release( + name = "internal", + version = DEFAULT_ELIXIR_VERSION, + sha256 = DEFAULT_ELIXIR_SHA256): + url = "https://github.com/elixir-lang/elixir/archive/refs/tags/v{}.tar.gz".format( + version, + ) + + return internal_elixir_from_http_archive( + name = name, + version = version, + url = url, + strip_prefix = "elixir-{}".format(version), + sha256 = sha256, + ) diff --git a/bazel/elixir/elixir_build.bzl b/bazel/elixir/elixir_build.bzl index 7745945e31d1..5b4d622216b0 100644 --- a/bazel/elixir/elixir_build.bzl +++ b/bazel/elixir/elixir_build.bzl @@ -121,7 +121,9 @@ elixir_build = rule( ) def _elixir_external_impl(ctx): - elixir_home = ctx.attr._elixir_home[BuildSettingInfo].value + elixir_home = ctx.attr.elixir_home + if elixir_home == "": + elixir_home = ctx.attr._elixir_home[BuildSettingInfo].value version_file = ctx.actions.declare_file(ctx.label.name + "_version") @@ -163,6 +165,7 @@ elixir_external = rule( implementation = _elixir_external_impl, attrs = { "_elixir_home": attr.label(default = Label("//:elixir_home")), + "elixir_home": attr.string(), }, toolchains = ["@rules_erlang//tools:toolchain_type"], ) diff --git a/bazel/platforms/BUILD.bazel b/bazel/platforms/BUILD.bazel index de9d9966e041..7a3e07131fe6 100644 --- a/bazel/platforms/BUILD.bazel +++ b/bazel/platforms/BUILD.bazel @@ -2,40 +2,11 @@ package( default_visibility = ["//visibility:public"], ) -constraint_setting( - name = "elixir_version", - default_constraint_value = ":elixir_external", -) - -constraint_value( - name = "elixir_external", - constraint_setting = ":elixir_version", -) - -constraint_value( - name = "elixir_1_10", - constraint_setting = ":elixir_version", -) - -constraint_value( - name = "elixir_1_12", - constraint_setting = ":elixir_version", -) - -constraint_value( - name = "elixir_1_13", - constraint_setting = ":elixir_version", -) - -constraint_value( - name = "elixir_1_14", - constraint_setting = ":elixir_version", -) - platform( name = "erlang_internal_platform", constraint_values = [ "@erlang_config//:erlang_internal", + "@elixir_config//:elixir_internal", ], parents = ["@rbe//config:platform"], ) @@ -44,7 +15,7 @@ platform( name = "erlang_linux_23_platform", constraint_values = [ "@erlang_config//:erlang_23", - ":elixir_1_10", + "@elixir_config//:elixir_1_10", ], parents = ["@rbe//config:platform"], ) @@ -53,7 +24,7 @@ platform( name = "erlang_linux_24_platform", constraint_values = [ "@erlang_config//:erlang_24", - ":elixir_1_12", + "@elixir_config//:elixir_1_12", ], parents = ["@rbe//config:platform"], ) @@ -62,7 +33,7 @@ platform( name = "erlang_linux_25_platform", constraint_values = [ "@erlang_config//:erlang_25", - ":elixir_1_14", + "@elixir_config//:elixir_1_14", ], parents = ["@rbe//config:platform"], ) @@ -71,7 +42,7 @@ platform( name = "erlang_linux_git_master_platform", constraint_values = [ "@erlang_config//:erlang_26", - ":elixir_1_14", + "@elixir_config//:elixir_1_14", ], parents = ["@rbe//config:platform"], ) diff --git a/bazel/repositories/BUILD.bazel b/bazel/repositories/BUILD.bazel new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/bazel/repositories/BUILD_external.tpl b/bazel/repositories/BUILD_external.tpl new file mode 100644 index 000000000000..b85df759242a --- /dev/null +++ b/bazel/repositories/BUILD_external.tpl @@ -0,0 +1,33 @@ +# This file is generated by rabbitmq-server via the elixir_config macro + +load( + "%{RABBITMQ_SERVER_WORKSPACE}//bazel/elixir:elixir_build.bzl", + "elixir_external", +) +load( + "%{RABBITMQ_SERVER_WORKSPACE}//bazel/elixir:elixir_toolchain.bzl", + "elixir_toolchain", +) + +elixir_external( + name = "elixir_external", + elixir_home = "%{ELIXIR_HOME}", +) + +elixir_toolchain( + name = "elixir", + elixir = ":elixir_external", + visibility = ["//visibility:public"], +) + +toolchain( + name = "toolchain", + exec_compatible_with = [ + "//:elixir_external", + ], + target_compatible_with = [%{TARGET_COMPATIBLE_WITH} + ], + toolchain = ":elixir", + toolchain_type = "%{RABBITMQ_SERVER_WORKSPACE}//bazel/elixir:toolchain_type", + visibility = ["//visibility:public"], +) diff --git a/bazel/repositories/BUILD_internal.tpl b/bazel/repositories/BUILD_internal.tpl new file mode 100644 index 000000000000..96758b58d93e --- /dev/null +++ b/bazel/repositories/BUILD_internal.tpl @@ -0,0 +1,35 @@ +# This file is generated by rabbitmq-server via the elixir_config macro + +load( + "%{RABBITMQ_SERVER_WORKSPACE}//bazel/elixir:elixir_build.bzl", + "elixir_build", +) +load( + "%{RABBITMQ_SERVER_WORKSPACE}//bazel/elixir:elixir_toolchain.bzl", + "elixir_toolchain", +) + +elixir_build( + name = "elixir_build", + url = "%{URL}", + strip_prefix = "%{STRIP_PREFIX}", + sha256 = "%{SHA_256}", +) + +elixir_toolchain( + name = "elixir", + elixir = ":elixir_build", + visibility = ["//visibility:public"], +) + +toolchain( + name = "toolchain", + exec_compatible_with = [ + "//:elixir_internal", + ], + target_compatible_with = [%{TARGET_COMPATIBLE_WITH} + ], + toolchain = ":elixir", + toolchain_type = "%{RABBITMQ_SERVER_WORKSPACE}//bazel/elixir:toolchain_type", + visibility = ["//visibility:public"], +) diff --git a/bazel/repositories/defaults.bzl.tpl b/bazel/repositories/defaults.bzl.tpl new file mode 100644 index 000000000000..f4822fd9d078 --- /dev/null +++ b/bazel/repositories/defaults.bzl.tpl @@ -0,0 +1,6 @@ +# This file is generated by rabbitmq-server via the elixir_config macro + +def register_defaults(): + native.register_toolchains( +%{TOOLCHAINS} + ) diff --git a/bazel/repositories/elixir_config.bzl b/bazel/repositories/elixir_config.bzl new file mode 100644 index 000000000000..3f6dfb36ea79 --- /dev/null +++ b/bazel/repositories/elixir_config.bzl @@ -0,0 +1,224 @@ +load( + "@rules_erlang//:util.bzl", + "path_join", +) + +ELIXIR_HOME_ENV_VAR = "ELIXIR_HOME" +DEFAULT_IEX_PATH = "/usr/local/bin/iex" + +_DEFAULT_EXTERNAL_ELIXIR_PACKAGE_NAME = "external" +_ELIXIR_VERSION_UNKNOWN = "UNKNOWN" + +INSTALLATION_TYPE_EXTERNAL = "external" +INSTALLATION_TYPE_INTERNAL = "internal" + +def _version_identifier(version_string): + parts = version_string.split(".", 2) + if len(parts) > 1: + return "{}_{}".format(parts[0], parts[1]) + else: + return parts[0] + +def _impl(repository_ctx): + rabbitmq_server_workspace = repository_ctx.attr.rabbitmq_server_workspace + + elixir_installations = _default_elixir_dict(repository_ctx) + for name in repository_ctx.attr.types.keys(): + if name == _DEFAULT_EXTERNAL_ELIXIR_PACKAGE_NAME: + fail("'{}' is reserved as an elixir name".format( + _DEFAULT_EXTERNAL_ELIXIR_PACKAGE_NAME, + )) + version = repository_ctx.attr.versions[name] + identifier = _version_identifier(version) + elixir_installations[name] = struct( + type = repository_ctx.attr.types[name], + version = version, + identifier = identifier, + url = repository_ctx.attr.urls.get(name, None), + strip_prefix = repository_ctx.attr.strip_prefixs.get(name, None), + sha256 = repository_ctx.attr.sha256s.get(name, None), + elixir_home = repository_ctx.attr.elixir_homes.get(name, None), + ) + + for (name, props) in elixir_installations.items(): + target_compatible_with = [ + "//:elixir_{}".format(props.identifier), + ] + + target_compatible_with = "".join([ + "\n \"%s\"," % c + for c in target_compatible_with + ]) + + if props.type == INSTALLATION_TYPE_EXTERNAL: + repository_ctx.template( + "{}/BUILD.bazel".format(name), + Label("//bazel/repositories:BUILD_external.tpl"), + { + "%{ELIXIR_HOME}": props.elixir_home, + "%{TARGET_COMPATIBLE_WITH}": target_compatible_with, + "%{RABBITMQ_SERVER_WORKSPACE}": rabbitmq_server_workspace, + }, + False, + ) + else: + repository_ctx.template( + "{}/BUILD.bazel".format(name), + Label("//bazel/repositories:BUILD_internal.tpl"), + { + "%{ELIXIR_VERSION}": props.version, + "%{URL}": props.url, + "%{STRIP_PREFIX}": props.strip_prefix or "", + "%{SHA_256}": props.sha256 or "", + "%{TARGET_COMPATIBLE_WITH}": target_compatible_with, + "%{RABBITMQ_SERVER_WORKSPACE}": rabbitmq_server_workspace, + }, + False, + ) + + if len(elixir_installations) == 0: + fail("No elixir installations configured") + + repository_ctx.file( + "BUILD.bazel", + _build_file_content(elixir_installations), + False, + ) + + toolchains = [ + "@{}//{}:toolchain".format(repository_ctx.name, name) + for name in elixir_installations.keys() + ] + + repository_ctx.template( + "defaults.bzl", + Label("//bazel/repositories:defaults.bzl.tpl"), + { + "%{TOOLCHAINS}": "\n".join([ + ' "%s",' % t + for t in toolchains + ]), + }, + False, + ) + +elixir_config = repository_rule( + implementation = _impl, + attrs = { + "rabbitmq_server_workspace": attr.string(), + "types": attr.string_dict(), + "versions": attr.string_dict(), + "urls": attr.string_dict(), + "strip_prefixs": attr.string_dict(), + "sha256s": attr.string_dict(), + "elixir_homes": attr.string_dict(), + }, + environ = [ + "ELIXIR_HOME", + ], +) + +def _default_elixir_dict(repository_ctx): + if ELIXIR_HOME_ENV_VAR in repository_ctx.os.environ: + elixir_home = repository_ctx.os.environ[ELIXIR_HOME_ENV_VAR] + else: + if repository_ctx.os.name.find("windows") > 0: + iex_path = repository_ctx.which("iex.exe") + else: + iex_path = repository_ctx.which("iex") + if iex_path == None: + iex_path = repository_ctx.path(DEFAULT_IEX_PATH) + elixir_home = str(iex_path.dirname.dirname) + + version = repository_ctx.execute( + [ + path_join(elixir_home, "bin", "elixir"), + "-e", + "IO.puts System.version()", + ], + timeout = 10, + ) + if version.return_code == 0: + version = version.stdout.strip("\n") + identifier = _version_identifier(version) + return { + _DEFAULT_EXTERNAL_ELIXIR_PACKAGE_NAME: struct( + type = INSTALLATION_TYPE_EXTERNAL, + version = version, + identifier = identifier, + elixir_home = elixir_home, + ), + } + else: + return { + _DEFAULT_EXTERNAL_ELIXIR_PACKAGE_NAME: struct( + type = INSTALLATION_TYPE_EXTERNAL, + version = _ELIXIR_VERSION_UNKNOWN, + identifier = _ELIXIR_VERSION_UNKNOWN.lower(), + elixir_home = elixir_home, + ), + } + +def _build_file_content(elixir_installations): + default_installation = elixir_installations[_DEFAULT_EXTERNAL_ELIXIR_PACKAGE_NAME] + + build_file_content = """\ +package( + default_visibility = ["//visibility:public"], +) + +constraint_setting( + name = "elixir_internal_external", + default_constraint_value = ":elixir_external", +) + +constraint_setting( + name = "elixir_version", + default_constraint_value = ":elixir_{default_identifier}", +) + +constraint_value( + name = "elixir_external", + constraint_setting = ":elixir_internal_external", +) + +""".format( + default_identifier = default_installation.identifier, + ) + + external_installations = { + name: props + for (name, props) in elixir_installations.items() + if props.type == INSTALLATION_TYPE_EXTERNAL + } + if len(elixir_installations) > len(external_installations): + build_file_content += """\ +constraint_value( + name = "elixir_internal", + constraint_setting = ":elixir_internal_external", +) + +""" + + unique_identifiers = { + props.identifier: name + for (name, props) in elixir_installations.items() + }.keys() + + for identifier in unique_identifiers: + build_file_content += """\ +constraint_value( + name = "elixir_{identifier}", + constraint_setting = ":elixir_version", +) + +platform( + name = "elixir_{identifier}_platform", + constraint_values = [ + ":elixir_{identifier}", + ], +) + +""".format(identifier = identifier) + + return build_file_content diff --git a/bazel/toolchains/BUILD.bazel b/bazel/toolchains/BUILD.bazel deleted file mode 100644 index 2db6f8e4e739..000000000000 --- a/bazel/toolchains/BUILD.bazel +++ /dev/null @@ -1,31 +0,0 @@ -load( - "//bazel/elixir:elixir.bzl", - "elixir_toolchain_external", - "elixir_toolchain_from_github_release", -) - -elixir_toolchain_external() - -elixir_toolchain_from_github_release( - name_suffix = "_1_10", - sha256 = "8518c78f43fe36315dbe0d623823c2c1b7a025c114f3f4adbb48e04ef63f1d9f", - version = "1.10.4", -) - -elixir_toolchain_from_github_release( - name_suffix = "_1_12", - sha256 = "c5affa97defafa1fd89c81656464d61da8f76ccfec2ea80c8a528decd5cb04ad", - version = "1.12.3", -) - -elixir_toolchain_from_github_release( - name_suffix = "_1_13", - sha256 = "95daf2dd3052e6ca7d4d849457eaaba09de52d65ca38d6933c65bc1cdf6b8579", - version = "1.13.4", -) - -elixir_toolchain_from_github_release( - name_suffix = "_1_14", - sha256 = "ac129e266a1e04cdc389551843ec3dbdf36086bb2174d3d7e7936e820735003b", - version = "1.14.0", -) diff --git a/user-template.bazelrc b/user-template.bazelrc index d50ea5e62676..e452af4d515b 100644 --- a/user-template.bazelrc +++ b/user-template.bazelrc @@ -1,5 +1,3 @@ -build --elixir_home=/Users/rabbitmq/.kiex/elixirs/elixir-1.14.0/lib/elixir - # rabbitmqctl wait shells out to 'ps', which is broken in the bazel macOS # sandbox (https://github.com/bazelbuild/bazel/issues/7448) # adding "--spawn_strategy=local" to the invocation is a workaround