@@ -126,21 +126,6 @@ main = defaultMain
126
126
127
127
_CABAL_TOOLS = ["alex" , "c2hs" , "cpphs" , "doctest" , "happy" ]
128
128
129
- # Some old packages are empty compatibility shims. Empty packages
130
- # cause Cabal to not produce the outputs it normally produces. Instead
131
- # of detecting that, we blacklist the offending packages, on the
132
- # assumption that such packages are old and rare.
133
- #
134
- # TODO: replace this with a more general solution.
135
- _EMPTY_PACKAGES_BLACKLIST = [
136
- "bytestring-builder" ,
137
- "fail" ,
138
- "ghc-byteorder" ,
139
- "haskell-gi-overloading" ,
140
- "mtl-compat" ,
141
- "nats" ,
142
- ]
143
-
144
129
def _cabal_tool_flag (tool ):
145
130
"""Return a --with-PROG=PATH flag if input is a recognized Cabal tool. None otherwise."""
146
131
if tool .basename in _CABAL_TOOLS :
@@ -1166,6 +1151,16 @@ _default_components = {
1166
1151
"cpphs" : struct (lib = True , exe = ["cpphs" ], sublibs = []),
1167
1152
"doctest" : struct (lib = True , exe = ["doctest" ], sublibs = []),
1168
1153
"happy" : struct (lib = False , exe = ["happy" ], sublibs = []),
1154
+ # Below are compatibility libraries that produce an empty cabal library.
1155
+ }
1156
+
1157
+ _default_components_args = {
1158
+ "bytestring-builder:lib:bytestring-builder" : "@rules_haskell//tools/cabal_args:empty_library" ,
1159
+ "fail:lib:fail" : "@rules_haskell//tools/cabal_args:empty_library" ,
1160
+ "ghc-byteorder:lib:ghc-byteorder" : "@rules_haskell//tools/cabal_args:empty_library" ,
1161
+ "haskell-gi-overloading:lib:haskell-gi-overloading" : "@rules_haskell//tools/cabal_args:empty_library" ,
1162
+ "mtl-compat:lib:mtl-compat" : "@rules_haskell//tools/cabal_args:empty_library" ,
1163
+ "nats:lib:nats" : "@rules_haskell//tools/cabal_args:empty_library" ,
1169
1164
}
1170
1165
1171
1166
def _get_components (components , package ):
@@ -1177,6 +1172,9 @@ def _get_components(components, package):
1177
1172
"""
1178
1173
return components .get (package , _default_components .get (package , struct (lib = True , exe = [], sublibs = [])))
1179
1174
1175
+ def _get_components_args (components_args , component ):
1176
+ return components_args .get (component , _default_components_args .get (component , None ))
1177
+
1180
1178
def _parse_json_field (json , field , ty , errmsg ):
1181
1179
"""Read and type-check a field from a JSON object.
1182
1180
@@ -1202,6 +1200,17 @@ def _parse_json_field(json, field, ty, errmsg):
1202
1200
)))
1203
1201
return json [field ]
1204
1202
1203
+ def _parse_components_args_key (component ):
1204
+ pieces = component .split (':' )
1205
+ if len (pieces ) == 1 :
1206
+ component = '{}:lib:{}' .format (component , component )
1207
+ elif len (pieces ) == 2 or (len (pieces ) == 3 and pieces [2 ] == '' ):
1208
+ if pieces [1 ] == 'lib' or pieces [1 ] == 'exe' :
1209
+ component = '{}:{}:{}' .format (pieces [0 ], pieces [1 ], pieces [0 ])
1210
+ else :
1211
+ component = '{}:lib:{}' .format (pieces [0 ], pieces [1 ])
1212
+ return component
1213
+
1205
1214
def _parse_package_spec (package_spec , enable_custom_toolchain_libraries , custom_toolchain_libraries ):
1206
1215
"""Parse a package description from `stack ls dependencies json`.
1207
1216
@@ -1997,6 +2006,10 @@ def _stack_snapshot_impl(repository_ctx):
1997
2006
for (name , components ) in repository_ctx .attr .components .items ()
1998
2007
}
1999
2008
all_components = {}
2009
+ user_components_args = {
2010
+ _parse_components_args_key (component ): args
2011
+ for (component , args ) in repository_ctx .attr .components_args .items ()
2012
+ }
2000
2013
for (name , spec ) in resolved .items ():
2001
2014
all_components [name ] = _get_components (user_components , name )
2002
2015
user_components .pop (name , None )
@@ -2075,20 +2088,6 @@ alias(name = "{name}", actual = "{actual}", visibility = {visibility})
2075
2088
haskell_toolchain_library(name = "{name}", visibility = {visibility})
2076
2089
""" .format (name = name , visibility = visibility ),
2077
2090
)
2078
- elif name in _EMPTY_PACKAGES_BLACKLIST :
2079
- build_file_builder .append (
2080
- """
2081
- haskell_library(
2082
- name = "{name}",
2083
- version = "{version}",
2084
- visibility = {visibility},
2085
- )
2086
- """ .format (
2087
- name = name ,
2088
- version = version ,
2089
- visibility = visibility ,
2090
- ),
2091
- )
2092
2091
else :
2093
2092
library_deps = [
2094
2093
dep
@@ -2119,6 +2118,12 @@ haskell_library(
2119
2118
)).relative (label ))
2120
2119
for label in repository_ctx .attr .setup_deps .get (name , [])
2121
2120
]
2121
+
2122
+ lib_args = _get_components_args (user_components_args , '{}:lib:{}' .format (name , name ))
2123
+ cabal_args = ""
2124
+ if lib_args != None :
2125
+ cabal_args = "cabal_args = \" {}\" ," .format (lib_args )
2126
+
2122
2127
if all_components [name ].lib :
2123
2128
build_file_builder .append (
2124
2129
"""
@@ -2134,6 +2139,7 @@ haskell_cabal_library(
2134
2139
visibility = {visibility},
2135
2140
cabalopts = ["--ghc-option=-w", "--ghc-option=-optF=-w"],
2136
2141
verbose = {verbose},
2142
+ {cabal_args}
2137
2143
unique_name = True,
2138
2144
)
2139
2145
""" .format (
@@ -2147,6 +2153,7 @@ haskell_cabal_library(
2147
2153
tools = library_tools ,
2148
2154
visibility = visibility ,
2149
2155
verbose = repr (repository_ctx .attr .verbose ),
2156
+ cabal_args = cabal_args
2150
2157
),
2151
2158
)
2152
2159
build_file_builder .append (
@@ -2162,6 +2169,10 @@ haskell_cabal_library(
2162
2169
for comp in ["exe:{}" .format (exe )] + (["exe" ] if exe == name else [])
2163
2170
for comp_dep in package_components_dependencies .get (comp , [])
2164
2171
]
2172
+ exe_args = _get_components_args (user_components_args , '{}:exe:{}' .format (name , exe ))
2173
+ cabal_args = ""
2174
+ if exe_args != None :
2175
+ cabal_args = "cabal_args = \" {}\" ," .format (lib_args )
2165
2176
build_file_builder .append (
2166
2177
"""
2167
2178
haskell_cabal_binary(
@@ -2174,6 +2185,7 @@ haskell_cabal_binary(
2174
2185
tools = {tools},
2175
2186
visibility = ["@{workspace}-exe//{name}:__pkg__"],
2176
2187
cabalopts = ["--ghc-option=-w", "--ghc-option=-optF=-w", "--ghc-option=-static"],
2188
+ {cabal_args}
2177
2189
verbose = {verbose},
2178
2190
)
2179
2191
""" .format (
@@ -2185,6 +2197,7 @@ haskell_cabal_binary(
2185
2197
deps = library_deps + exe_component_deps + ([name ] if all_components [name ].lib else []),
2186
2198
setup_deps = setup_deps ,
2187
2199
tools = library_tools ,
2200
+ cabal_args = cabal_args ,
2188
2201
verbose = repr (repository_ctx .attr .verbose ),
2189
2202
),
2190
2203
)
@@ -2193,6 +2206,10 @@ haskell_cabal_binary(
2193
2206
_resolve_component_target_name (name , c )
2194
2207
for c in package_components_dependencies .get ("lib:{}" .format (sublib ), [])
2195
2208
]
2209
+ lib_args = _get_components_args (user_components_args , '{}:lib:{}' .format (name , sublib ))
2210
+ cabal_args = ""
2211
+ if lib_args != None :
2212
+ cabal_args = "cabal_args = \" {}\" ," .format (lib_args )
2196
2213
build_file_builder .append (
2197
2214
"""
2198
2215
haskell_cabal_library(
@@ -2208,6 +2225,7 @@ haskell_cabal_library(
2208
2225
tools = {tools},
2209
2226
visibility = {visibility},
2210
2227
cabalopts = ["--ghc-option=-w", "--ghc-option=-optF=-w"],
2228
+ {cabal_args}
2211
2229
verbose = {verbose},
2212
2230
)
2213
2231
""" .format (
@@ -2222,8 +2240,10 @@ haskell_cabal_library(
2222
2240
tools = library_tools ,
2223
2241
verbose = repr (repository_ctx .attr .verbose ),
2224
2242
visibility = visibility ,
2243
+ cabal_args = cabal_args ,
2225
2244
),
2226
2245
)
2246
+
2227
2247
build_file_content = "\n " .join (build_file_builder )
2228
2248
repository_ctx .file ("BUILD.bazel" , build_file_content , executable = False )
2229
2249
@@ -2273,6 +2293,7 @@ _stack_snapshot = repository_rule(
2273
2293
"verbose" : attr .bool (default = False ),
2274
2294
"custom_toolchain_libraries" : attr .string_list (default = []),
2275
2295
"enable_custom_toolchain_libraries" : attr .bool (default = False ),
2296
+ "components_args" : attr .string_dict (),
2276
2297
},
2277
2298
)
2278
2299
@@ -2484,6 +2505,7 @@ def stack_snapshot(
2484
2505
netrc = "" ,
2485
2506
toolchain_libraries = None ,
2486
2507
setup_stack = True ,
2508
+ components_args = {},
2487
2509
label_builder = lambda l : Label (l ),
2488
2510
** kwargs ):
2489
2511
"""Use Stack to download and extract Cabal source distributions.
@@ -2743,6 +2765,7 @@ def stack_snapshot(
2743
2765
tools = tools ,
2744
2766
components = components ,
2745
2767
components_dependencies = components_dependencies ,
2768
+ components_args = components_args ,
2746
2769
verbose = verbose ,
2747
2770
custom_toolchain_libraries = toolchain_libraries ,
2748
2771
enable_custom_toolchain_libraries = toolchain_libraries != None ,
0 commit comments