diff --git a/rules/select_file.bzl b/rules/select_file.bzl new file mode 100644 index 00000000..0ae08fa3 --- /dev/null +++ b/rules/select_file.bzl @@ -0,0 +1,40 @@ +""" +select_file() build rule implementation. + +Selects a single file from the outputs of some target by given relative path. +""" + +def _impl(ctx): + if ctx.attr.subpath and len(ctx.attr.subpath) == 0: + fail("Subpath can not be empty.") + + out = None + canonical = ctx.attr.subpath.replace("\\", "/") + for file_ in ctx.attr.srcs.files.to_list(): + if file_.path.replace("\\", "/").endswith(canonical): + out = file_ + break + if not out: + files_str = ",\n".join([ + str(f.path) + for f in ctx.attr.srcs.files.to_list() + ]) + fail("Can not find specified file in [%s]" % files_str) + return [DefaultInfo(files = depset([out]))] + +select_file = rule( + implementation = _impl, + doc = "Selects a single file from the outputs of some target \ +by given relative path", + attrs = { + "srcs": attr.label( + allow_files = True, + mandatory = True, + doc = "The target producing the file among other outputs", + ), + "subpath": attr.string( + mandatory = True, + doc = "Relative path to the file", + ), + }, +) diff --git a/tests/select_file/BUILD b/tests/select_file/BUILD new file mode 100644 index 00000000..e7955022 --- /dev/null +++ b/tests/select_file/BUILD @@ -0,0 +1,34 @@ +load("//rules:select_file.bzl", "select_file") +load("//rules:diff_test.bzl", "diff_test") + +filegroup( + name = "fg", + srcs = [ + "subdir/inner.txt", + ":select_me.txt", + ], +) + +select_file( + name = "select_me", + srcs = ":fg", + subpath = "select_me.txt", +) + +select_file( + name = "select_inner", + srcs = ":fg", + subpath = "subdir/inner.txt", +) + +diff_test( + name = "selected_me", + file1 = ":select_me", + file2 = ":select_me.txt", +) + +diff_test( + name = "selected_inner", + file1 = ":select_inner", + file2 = "subdir/inner.txt", +) diff --git a/tests/select_file/select_me.txt b/tests/select_file/select_me.txt new file mode 100644 index 00000000..4221a1e6 --- /dev/null +++ b/tests/select_file/select_me.txt @@ -0,0 +1 @@ +Outer diff --git a/tests/select_file/subdir/inner.txt b/tests/select_file/subdir/inner.txt new file mode 100644 index 00000000..d87e45af --- /dev/null +++ b/tests/select_file/subdir/inner.txt @@ -0,0 +1 @@ +Inner