abergmeier
abergmeier

Reputation: 14072

Emulate string to label dict

Since Bazel does not provide a way to map labels to strings, I am wondering how to work around this via Skylark.

Following my partial horrible "workaround".

First the statics:

_INDEX_COUNT = 50

def _build_label_mapping():
    lmap = {}

    for i in range(_INDEX_COUNT):
        lmap ["map_name%s" % i] = attr.string()
        lmap ["map_label%s" % i] = attr.label(allow_files = True)

    return lmap

_LABEL_MAPPING = _build_label_mapping()

And in the implementation:

    item_pairs = {}
    for i in range(_INDEX_COUNT):
        id = getattr(ctx.attr, "map_name%s" % i)

        if not id:
            continue

        mapl = getattr(ctx.attr, "map_label%s" % i)


        if len(mapl.files):
            item_pairs[id] = list(mapl.files)[0].path
        else:
            item_pairs[id] = ""

    if item_pairs:
        arguments += [
            "--map", str(item_pairs), # Pass json data
        ]

And then the rule:

_foo = rule(
    implementation = _impl,
    attrs = dict({
        "srcs": attr.label_list(allow_files = True, mandatory = True),
    }.items() + _LABEL_MAPPING.items()),

Which needs to be wrapped like:

def foo(map={}, **kwargs):

    map_args = {}

    # TODO: Check whether order of items is defined
    for i, item in enumerate(textures.items()):
        key, value = item
        map_args["map_name%s" % i] = key
        map_args["map_label%s" % i] = value

    return _foo(
        **dict(map_args.items() + kwargs.items())
    )

Is there a better way of doing that in Skylark?

Upvotes: 1

Views: 1198

Answers (1)

Laurent
Laurent

Reputation: 2999

To rephrase your question, you want to create a rule attribute mapping from string to label?

This is currently not supported (see list of attributes), but you can file a feature request for this.

Do you think using "label_keyed_string_dict" is a reasonable workaround? (it won't work if you have duplicated keys)

Upvotes: 1

Related Questions