Skip to content

Commit

Permalink
refactor: use bazel-skylib for creating hub repo aliases (#1855)
Browse files Browse the repository at this point in the history
With this PR the code becomes more maintainable and easier to inspect.
Since bazel-skylib is already a dependency of rules_python, this is
a backwards compatible change.

Skipping the CHANGELOG notes because it should not be an externally
visible change.

Work towards #735.
  • Loading branch information
aignas authored Apr 29, 2024
1 parent 397c1b1 commit ced8cc6
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 33 deletions.
26 changes: 18 additions & 8 deletions python/private/render_pkg_aliases.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def _render_whl_library_alias(
*,
name,
default_version,
aliases):
aliases,
**kwargs):
"""Render an alias for common targets."""
if len(aliases) == 1 and not aliases[0].version:
alias = aliases[0]
Expand All @@ -56,27 +57,36 @@ def _render_whl_library_alias(
# whls that are based on a specific version of Python.
selects = {}
no_match_error = "_NO_MATCH_ERROR"
default = None
for alias in sorted(aliases, key = lambda x: x.version):
actual = "@{repo}//:{name}".format(repo = alias.repo, name = name)
selects[alias.config_setting] = actual
selects.setdefault(actual, []).append(alias.config_setting)
if alias.version == default_version:
default = actual
selects[actual].append("//conditions:default")
no_match_error = None

if default:
selects["//conditions:default"] = default

return render.alias(
name = name,
actual = render.select(
selects,
{
tuple(sorted(
conditions,
# Group `is_python` and other conditions for easier reading
# when looking at the generated files.
key = lambda condition: ("is_python" not in condition, condition),
)): target
for target, conditions in sorted(selects.items())
},
no_match_error = no_match_error,
# This key_repr is used to render selects.with_or keys
key_repr = lambda x: repr(x[0]) if len(x) == 1 else render.tuple(x),
name = "selects.with_or",
),
**kwargs
)

def _render_common_aliases(*, name, aliases, default_version = None):
lines = [
"""load("@bazel_skylib//lib:selects.bzl", "selects")""",
"""package(default_visibility = ["//visibility:public"])""",
]

Expand Down
27 changes: 22 additions & 5 deletions python/private/text_util.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ def _render_alias(name, actual, *, visibility = None):
")",
])

def _render_dict(d, *, value_repr = repr):
def _render_dict(d, *, key_repr = repr, value_repr = repr):
return "\n".join([
"{",
_indent("\n".join([
"{}: {},".format(repr(k), value_repr(v))
"{}: {},".format(key_repr(k), value_repr(v))
for k, v in d.items()
])),
"}",
])

def _render_select(selects, *, no_match_error = None, value_repr = repr):
dict_str = _render_dict(selects, value_repr = value_repr) + ","
def _render_select(selects, *, no_match_error = None, key_repr = repr, value_repr = repr, name = "select"):
dict_str = _render_dict(selects, key_repr = key_repr, value_repr = value_repr) + ","

if no_match_error:
args = "\n".join([
Expand All @@ -62,7 +62,7 @@ def _render_select(selects, *, no_match_error = None, value_repr = repr):
"",
])

return "select({})".format(args)
return "{}({})".format(name, args)

def _render_list(items):
if not items:
Expand All @@ -80,10 +80,27 @@ def _render_list(items):
"]",
])

def _render_tuple(items, *, value_repr = repr):
if not items:
return "tuple()"

if len(items) == 1:
return "({},)".format(value_repr(items[0]))

return "\n".join([
"(",
_indent("\n".join([
"{},".format(value_repr(item))
for item in items
])),
")",
])

render = struct(
alias = _render_alias,
dict = _render_dict,
indent = _indent,
list = _render_list,
select = _render_select,
tuple = _render_tuple,
)
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ def _test_legacy_aliases(env):

want_key = "foo/BUILD.bazel"
want_content = """\
load("@bazel_skylib//lib:selects.bzl", "selects")
package(default_visibility = ["//visibility:public"])
alias(
Expand Down Expand Up @@ -108,6 +110,8 @@ def _test_bzlmod_aliases(env):

want_key = "bar_baz/BUILD.bazel"
want_content = """\
load("@bazel_skylib//lib:selects.bzl", "selects")
package(default_visibility = ["//visibility:public"])
alias(
Expand All @@ -117,40 +121,48 @@ alias(
alias(
name = "pkg",
actual = select(
actual = selects.with_or(
{
"//:my_config_setting": "@pypi_32_bar_baz//:pkg",
"//conditions:default": "@pypi_32_bar_baz//:pkg",
(
"//:my_config_setting",
"//conditions:default",
): "@pypi_32_bar_baz//:pkg",
},
),
)
alias(
name = "whl",
actual = select(
actual = selects.with_or(
{
"//:my_config_setting": "@pypi_32_bar_baz//:whl",
"//conditions:default": "@pypi_32_bar_baz//:whl",
(
"//:my_config_setting",
"//conditions:default",
): "@pypi_32_bar_baz//:whl",
},
),
)
alias(
name = "data",
actual = select(
actual = selects.with_or(
{
"//:my_config_setting": "@pypi_32_bar_baz//:data",
"//conditions:default": "@pypi_32_bar_baz//:data",
(
"//:my_config_setting",
"//conditions:default",
): "@pypi_32_bar_baz//:data",
},
),
)
alias(
name = "dist_info",
actual = select(
actual = selects.with_or(
{
"//:my_config_setting": "@pypi_32_bar_baz//:dist_info",
"//conditions:default": "@pypi_32_bar_baz//:dist_info",
(
"//:my_config_setting",
"//conditions:default",
): "@pypi_32_bar_baz//:dist_info",
},
),
)"""
Expand Down Expand Up @@ -178,6 +190,8 @@ def _test_bzlmod_aliases_with_no_default_version(env):

want_key = "bar_baz/BUILD.bazel"
want_content = """\
load("@bazel_skylib//lib:selects.bzl", "selects")
package(default_visibility = ["//visibility:public"])
_NO_MATCH_ERROR = \"\"\"\\
Expand Down Expand Up @@ -206,7 +220,7 @@ alias(
alias(
name = "pkg",
actual = select(
actual = selects.with_or(
{
"@@//python/config_settings:is_python_3.1": "@pypi_31_bar_baz//:pkg",
"@@//python/config_settings:is_python_3.2": "@pypi_32_bar_baz//:pkg",
Expand All @@ -217,7 +231,7 @@ alias(
alias(
name = "whl",
actual = select(
actual = selects.with_or(
{
"@@//python/config_settings:is_python_3.1": "@pypi_31_bar_baz//:whl",
"@@//python/config_settings:is_python_3.2": "@pypi_32_bar_baz//:whl",
Expand All @@ -228,7 +242,7 @@ alias(
alias(
name = "data",
actual = select(
actual = selects.with_or(
{
"@@//python/config_settings:is_python_3.1": "@pypi_31_bar_baz//:data",
"@@//python/config_settings:is_python_3.2": "@pypi_32_bar_baz//:data",
Expand All @@ -239,7 +253,7 @@ alias(
alias(
name = "dist_info",
actual = select(
actual = selects.with_or(
{
"@@//python/config_settings:is_python_3.1": "@pypi_31_bar_baz//:dist_info",
"@@//python/config_settings:is_python_3.2": "@pypi_32_bar_baz//:dist_info",
Expand Down Expand Up @@ -273,6 +287,8 @@ def _test_bzlmod_aliases_for_non_root_modules(env):

want_key = "bar_baz/BUILD.bazel"
want_content = """\
load("@bazel_skylib//lib:selects.bzl", "selects")
package(default_visibility = ["//visibility:public"])
_NO_MATCH_ERROR = \"\"\"\\
Expand Down Expand Up @@ -301,7 +317,7 @@ alias(
alias(
name = "pkg",
actual = select(
actual = selects.with_or(
{
"@@//python/config_settings:is_python_3.1": "@pypi_31_bar_baz//:pkg",
"@@//python/config_settings:is_python_3.2": "@pypi_32_bar_baz//:pkg",
Expand All @@ -312,7 +328,7 @@ alias(
alias(
name = "whl",
actual = select(
actual = selects.with_or(
{
"@@//python/config_settings:is_python_3.1": "@pypi_31_bar_baz//:whl",
"@@//python/config_settings:is_python_3.2": "@pypi_32_bar_baz//:whl",
Expand All @@ -323,7 +339,7 @@ alias(
alias(
name = "data",
actual = select(
actual = selects.with_or(
{
"@@//python/config_settings:is_python_3.1": "@pypi_31_bar_baz//:data",
"@@//python/config_settings:is_python_3.2": "@pypi_32_bar_baz//:data",
Expand All @@ -334,7 +350,7 @@ alias(
alias(
name = "dist_info",
actual = select(
actual = selects.with_or(
{
"@@//python/config_settings:is_python_3.1": "@pypi_31_bar_baz//:dist_info",
"@@//python/config_settings:is_python_3.2": "@pypi_32_bar_baz//:dist_info",
Expand Down
19 changes: 19 additions & 0 deletions tests/private/text_util/render_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,25 @@ def _test_render_alias(env):

_tests.append(_test_render_alias)

def _test_render_tuple_dict(env):
got = render.dict(
{
("foo", "bar"): "baz",
("foo",): "bar",
},
key_repr = render.tuple,
)
env.expect.that_str(got).equals("""\
{
(
"foo",
"bar",
): "baz",
("foo",): "bar",
}""")

_tests.append(_test_render_tuple_dict)

def render_test_suite(name):
"""Create the test suite.
Expand Down

0 comments on commit ced8cc6

Please sign in to comment.