| """output_files implementation |
| """ |
| |
| load("//lib:utils.bzl", _to_label = "to_label") |
| |
| def _output_files(ctx): |
| files = [] |
| files_depset = depset() |
| if ctx.attr.output_group: |
| if OutputGroupInfo not in ctx.attr.target: |
| msg = "%s output_group is specified but %s does not provide an OutputGroupInfo" % (ctx.attr.output_group, ctx.attr.target) |
| fail(msg) |
| if ctx.attr.output_group not in ctx.attr.target[OutputGroupInfo]: |
| msg = "%s output_group is specified but %s does not provide this output group" % (ctx.attr.output_group, ctx.attr.target) |
| fail(msg) |
| files_depset = ctx.attr.target[OutputGroupInfo][ctx.attr.output_group] |
| else: |
| files_depset = ctx.attr.target[DefaultInfo].files |
| |
| files_list = files_depset.to_list() |
| |
| for path in ctx.attr.paths: |
| file = _find_short_path_in_files_list(files_list, path) |
| if not file: |
| if ctx.attr.output_group: |
| msg = "%s file not found within the %s output group of %s" % (path, ctx.attr.output_group, ctx.attr.target) |
| else: |
| msg = "%s file not found within the DefaultInfo of %s" % (path, ctx.attr.target) |
| fail(msg) |
| files.append(file) |
| return [DefaultInfo( |
| files = depset(direct = files), |
| runfiles = ctx.runfiles(files = files), |
| )] |
| |
| output_files = rule( |
| doc = "A rule that provides file(s) specific via DefaultInfo from a given target's DefaultInfo or OutputGroupInfo", |
| implementation = _output_files, |
| attrs = { |
| "target": attr.label( |
| doc = "the target to look in for requested paths in its' DefaultInfo or OutputGroupInfo", |
| mandatory = True, |
| ), |
| "paths": attr.string_list( |
| doc = "the paths of the file(s), relative to their roots, to provide via DefaultInfo from the given target's DefaultInfo or OutputGroupInfo", |
| mandatory = True, |
| allow_empty = False, |
| ), |
| "output_group": attr.string( |
| doc = "if set, we look in the specified output group for paths instead of DefaultInfo", |
| ), |
| }, |
| provides = [DefaultInfo], |
| ) |
| |
| def make_output_files(name, target, paths, **kwargs): |
| """Helper function to generate a output_files target and return its label. |
| |
| Args: |
| name: unique name for the generated `output_files` target |
| target: `target` attribute passed to generated `output_files` target |
| paths: `paths` attribute passed to generated `output_files` target |
| **kwargs: parameters to pass to generated `output_files` target |
| |
| Returns: |
| The label `name` |
| """ |
| output_files( |
| name = name, |
| target = target, |
| paths = paths, |
| **kwargs |
| ) |
| return _to_label(name) |
| |
| def _find_short_path_in_files_list(files_list, short_path): |
| """Helper function find a file in a DefaultInfo by short path |
| |
| Args: |
| files_list: a list of files |
| short_path: the short path (path relative to root) to search for |
| Returns: |
| The File if found else None |
| """ |
| for file in files_list: |
| if file.short_path == short_path: |
| return file |
| return None |