From 6970e21d290ceaa36502d0c94533b26e5ec18c0b Mon Sep 17 00:00:00 2001 From: irengrig Date: Thu, 27 Feb 2020 19:29:45 +0100 Subject: [PATCH] =?UTF-8?q?Create=20a=20helper=20rule=20for=20selecting=20?= =?UTF-8?q?a=20file=20from=20outputs=20of=20another=20rul=E2=80=A6=20(#233?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create a helper rule for selecting a file from outputs of another rule or a filegroup by subpath * Add tests * Address code review comments * + formatting Co-authored-by: c-parsons --- rules/select_file.bzl | 40 ++++++++++++++++++++++++++++++ tests/select_file/BUILD | 34 +++++++++++++++++++++++++ tests/select_file/select_me.txt | 1 + tests/select_file/subdir/inner.txt | 1 + 4 files changed, 76 insertions(+) create mode 100644 rules/select_file.bzl create mode 100644 tests/select_file/BUILD create mode 100644 tests/select_file/select_me.txt create mode 100644 tests/select_file/subdir/inner.txt diff --git a/rules/select_file.bzl b/rules/select_file.bzl new file mode 100644 index 0000000..0ae08fa --- /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 0000000..e795502 --- /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 0000000..4221a1e --- /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 0000000..d87e45a --- /dev/null +++ b/tests/select_file/subdir/inner.txt @@ -0,0 +1 @@ +Inner