"""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 for path in ctx.attr.paths: file = _find_short_path_in_files_depset(files_depset, 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_depset(files_depset, short_path): """Helper function find a file in a DefaultInfo by short path Args: files_depset: a depset short_path: the short path (path relative to root) to search for Returns: The File if found else None """ if files_depset: for file in files_depset.to_list(): if file.short_path == short_path: return file return None