From 0690187834d79f29d8faa0ef6d664a01b5869fa6 Mon Sep 17 00:00:00 2001 From: ichern Date: Fri, 27 Sep 2019 19:51:34 +0200 Subject: [PATCH 1/4] Create a helper rule for selecting a file from outputs of another rule or a filegroup by subpath --- rules/select_file.bzl | 34 ++++++++++++++++++++++++++++++ tests/select_file/BUILD | 21 ++++++++++++++++++ tests/select_file/select_me.txt | 0 tests/select_file/subdir/inner.txt | 0 4 files changed, 55 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 00000000..fe7f22c7 --- /dev/null +++ b/rules/select_file.bzl @@ -0,0 +1,34 @@ +""" +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: + fail("Can not find specified file in '%s'" % str(ctx.attr.srcs)) + print("Selected: " + str(out)) + 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, + doc = "The target producing the file \ +among other outputs", + ), + "subpath": attr.string(doc = "Relative path to the file"), + }, +) diff --git a/tests/select_file/BUILD b/tests/select_file/BUILD new file mode 100644 index 00000000..7af0cec2 --- /dev/null +++ b/tests/select_file/BUILD @@ -0,0 +1,21 @@ +load("//rules:select_file.bzl", "select_file") + +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 --git a/tests/select_file/select_me.txt b/tests/select_file/select_me.txt new file mode 100644 index 00000000..e69de29b diff --git a/tests/select_file/subdir/inner.txt b/tests/select_file/subdir/inner.txt new file mode 100644 index 00000000..e69de29b From 8ea1b9d34ff5c817b2cceb0319b20b8f9664a7a6 Mon Sep 17 00:00:00 2001 From: ichern Date: Sat, 15 Feb 2020 17:18:07 +0100 Subject: [PATCH 2/4] Add tests --- rules/select_file.bzl | 1 - tests/select_file/BUILD | 13 +++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/rules/select_file.bzl b/rules/select_file.bzl index fe7f22c7..a26f48d9 100644 --- a/rules/select_file.bzl +++ b/rules/select_file.bzl @@ -16,7 +16,6 @@ def _impl(ctx): break if not out: fail("Can not find specified file in '%s'" % str(ctx.attr.srcs)) - print("Selected: " + str(out)) return [DefaultInfo(files = depset([out]))] select_file = rule( diff --git a/tests/select_file/BUILD b/tests/select_file/BUILD index 7af0cec2..e7955022 100644 --- a/tests/select_file/BUILD +++ b/tests/select_file/BUILD @@ -1,4 +1,5 @@ load("//rules:select_file.bzl", "select_file") +load("//rules:diff_test.bzl", "diff_test") filegroup( name = "fg", @@ -19,3 +20,15 @@ select_file( 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", +) From 67db5a6e72c21682f4db51360f1f743cffb82ef0 Mon Sep 17 00:00:00 2001 From: ichern Date: Mon, 17 Feb 2020 17:28:08 +0100 Subject: [PATCH 3/4] Address code review comments --- rules/select_file.bzl | 13 ++++++++----- tests/select_file/select_me.txt | 1 + tests/select_file/subdir/inner.txt | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/rules/select_file.bzl b/rules/select_file.bzl index a26f48d9..eb17276b 100644 --- a/rules/select_file.bzl +++ b/rules/select_file.bzl @@ -15,7 +15,9 @@ def _impl(ctx): out = file_ break if not out: - fail("Can not find specified file in '%s'" % str(ctx.attr.srcs)) + 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( @@ -25,9 +27,10 @@ by given relative path", attrs = { "srcs": attr.label( allow_files = True, - doc = "The target producing the file \ -among other outputs", - ), - "subpath": attr.string(doc = "Relative path to the file"), + 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/select_me.txt b/tests/select_file/select_me.txt index e69de29b..4221a1e6 100644 --- a/tests/select_file/select_me.txt +++ 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 index e69de29b..d87e45af 100644 --- a/tests/select_file/subdir/inner.txt +++ b/tests/select_file/subdir/inner.txt @@ -0,0 +1 @@ +Inner From 385e64e7fbaf80fded735aebe101d49e28ff8adc Mon Sep 17 00:00:00 2001 From: ichern Date: Tue, 18 Feb 2020 08:59:51 +0100 Subject: [PATCH 4/4] + formatting --- rules/select_file.bzl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rules/select_file.bzl b/rules/select_file.bzl index eb17276b..0ae08fa3 100644 --- a/rules/select_file.bzl +++ b/rules/select_file.bzl @@ -15,8 +15,10 @@ def _impl(ctx): out = file_ break if not out: - files_str = ",\n".join([str(f.path) \ -for f in ctx.attr.srcs.files.to_list()]) + 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]))] @@ -28,9 +30,11 @@ by given relative path", "srcs": attr.label( allow_files = True, mandatory = True, - doc = "The target producing the file among other outputs"), + doc = "The target producing the file among other outputs", + ), "subpath": attr.string( mandatory = True, - doc = "Relative path to the file"), + doc = "Relative path to the file", + ), }, )