Skip to content

Commit 6130789

Browse files
committed
Add dist and variant attrs to bindist rules / extensions
This change should be backwards compatible, since the attrs are not mandatory and on Linux we choose the oldest Debian tarball if no dist / variant has been specified explicitly.
1 parent c83a740 commit 6130789

File tree

3 files changed

+67
-4
lines changed

3 files changed

+67
-4
lines changed

extensions/haskell_toolchains.bzl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ _bindists_tag = tag_class(
1414
"version": attr.string(
1515
doc = "[see rules_haskell_toolchains](toolchain.html#rules_haskell_toolchains-version)",
1616
),
17+
"dist": attr.string_dict(
18+
doc = "Select a specific `dist` of a GHC binary tarball (e.g. deb10, alpine312) for a platform",
19+
),
20+
"variant": attr.string_dict(
21+
doc = "Select a specific `variant` of a GHC binary tarball (e.g. dwarf, native_int) for a platform",
22+
),
1723
"ghcopts": attr.string_list(
1824
doc = "[see rules_haskell_toolchains](toolchain.html#rules_haskell_toolchains-ghcopts)",
1925
),
@@ -41,6 +47,12 @@ _bindist_tag = tag_class(
4147
mandatory = True,
4248
doc = "The desired GHC version",
4349
),
50+
"dist": attr.string_dict(
51+
doc = "Select a specific `dist` of a GHC binary tarball (e.g. deb10, alpine312) for a platform",
52+
),
53+
"variant": attr.string_dict(
54+
doc = "Select a specific `variant` of a GHC binary tarball (e.g. dwarf, native_int) for a platform",
55+
),
4456
"target": attr.string(
4557
mandatory = True,
4658
doc = "The desired architecture (See [ghc_bindist_generated.json](https://github.com/tweag/rules_haskell/blob/master/haskell/private/ghc_bindist_generated.json))",

haskell/ghc_bindist.bzl

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,46 @@ def _ghc_bindist_impl(ctx):
7171
if target not in bindist:
7272
fail("Operating system {0} does not have a bindist for GHC version {1}".format(ctx.os.name, ctx.attr.version))
7373
else:
74-
url, sha256 = bindist[target]
74+
bindists = bindist[target]
75+
dist = ctx.attr.dist.get(target)
76+
if dist:
77+
bindists = [bindist for bindist in bindists if bindist["dist"] == dist]
78+
if not bindists:
79+
fail("no GHC bindist found with specified `dist` of `{}`".format(dist))
80+
81+
variant = ctx.attr.variant.get(target)
82+
if variant:
83+
bindists = [bindist for bindist in bindists if bindist.get("variant") == variant]
84+
if not bindists:
85+
fail("no GHC bindist found with specified `dist` of `{}`".format(dist))
86+
87+
if len(bindists) > 1:
88+
dists = [bindist["dist"] for bindist in bindists]
89+
90+
if os.startswith("linux"):
91+
# for Linux, we use debian dists by default
92+
debian_dists = sorted([int(d[3:]) for d in dists if d.startswith("deb")])
93+
94+
if debian_dists:
95+
# prefer the oldest version by default
96+
deb_version = "deb{}".format(debian_dists[0])
97+
98+
bindists = [bindist for bindist in bindists if bindist["dist"] == deb_version]
99+
100+
if len(bindists) > 1:
101+
# prefer the one without a variant, but fail if ambiguous
102+
dists = [bindist for bindist in bindists if "variant" not in bindist]
103+
if len(dists) > 1:
104+
# we should never get here, for a given version, architecture and dist there can only be one
105+
# tarball without a variant
106+
fail("multiple non-variant entries for GHC {} {}:\n\n{}".format(version, target, bindists))
107+
if not dists:
108+
fail("multiple variant entries for GHC {} {}:\n\n{}\n\nSelect one explicitly using `variant = 'xyz'`".format(version, target, bindists))
109+
110+
bindist = bindists[0]
111+
112+
url = bindist["url"]
113+
sha256 = bindist["sha256"]
75114

76115
bindist_dir = ctx.path(".") # repo path
77116

@@ -286,6 +325,12 @@ _ghc_bindist = repository_rule(
286325
"haddock_flags": attr.string_list(),
287326
"repl_ghci_args": attr.string_list(),
288327
"cabalopts": attr.string_list(),
328+
"dist": attr.string_dict(
329+
doc = "Select a specific `dist` of a GHC binary tarball (e.g. deb10, alpine312) for a platform",
330+
),
331+
"variant": attr.string_dict(
332+
doc = "Select a specific `variant` of a GHC binary tarball (e.g. dwarf, native_int) for a platform",
333+
),
289334
"patches": attr.label_list(
290335
default = [],
291336
doc =
@@ -419,7 +464,8 @@ def ghc_bindist(
419464
repl_ghci_args = None,
420465
cabalopts = None,
421466
locale = None,
422-
register = True):
467+
register = True,
468+
**kwargs):
423469
"""Create a new repository from binary distributions of GHC.
424470
425471
The repository exports two targets:
@@ -469,6 +515,7 @@ def ghc_bindist(
469515
}.get(version)
470516

471517
extra_attrs = {"patches": patches, "patch_args": ["-p0"]} if patches else {}
518+
extra_attrs.update(kwargs)
472519

473520
# We want the toolchain definition to be tucked away in a separate
474521
# repository, that way `bazel build //...` will not match it (and
@@ -518,7 +565,8 @@ def haskell_register_ghc_bindists(
518565
cabalopts = None,
519566
locale = None,
520567
register = True,
521-
targets = _GHC_AVAILABLE_TARGETS):
568+
targets = _GHC_AVAILABLE_TARGETS,
569+
**kwargs):
522570
""" Register GHC binary distributions for all platforms as toolchains.
523571
524572
See [rules_haskell_toolchains](toolchain.html#rules_haskell_toolchains).
@@ -550,6 +598,7 @@ def haskell_register_ghc_bindists(
550598
cabalopts = cabalopts,
551599
locale = locale,
552600
register = register,
601+
**kwargs
553602
)
554603
local_sh_posix_repo_name = "rules_haskell_sh_posix_local"
555604
if local_sh_posix_repo_name not in native.existing_rules():

haskell/toolchain.bzl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,8 @@ def rules_haskell_toolchains(
721721
haddock_flags = None,
722722
repl_ghci_args = None,
723723
cabalopts = None,
724-
locale = None):
724+
locale = None,
725+
**kwargs):
725726
"""Register GHC binary distributions for all platforms as toolchains.
726727
727728
Toolchains can be used to compile Haskell code. This function
@@ -749,6 +750,7 @@ def rules_haskell_toolchains(
749750
repl_ghci_args = repl_ghci_args,
750751
cabalopts = cabalopts,
751752
locale = locale,
753+
**kwargs
752754
)
753755

754756
# Utility rules forwarding various toolchain providers.

0 commit comments

Comments
 (0)