diff --git a/packages/rules_prerender/css/css_library.bzl b/packages/rules_prerender/css/css_library.bzl index 117d4ea7..225d583c 100644 --- a/packages/rules_prerender/css/css_library.bzl +++ b/packages/rules_prerender/css/css_library.bzl @@ -6,8 +6,18 @@ load(":css_providers.bzl", "CssInfo") visibility(["//", "//packages/rules_prerender/..."]) def _css_library_impl(ctx): - # Copy sources to bin so they are always available for downstream `js_binary()` - # tools. + if not ctx.files.srcs and not ctx.files.deps: + fail("Expected `srcs` and/or `deps` to be specified.") + + # If no `srcs`, re-export dependencies. + if not ctx.files.srcs: + return [ + _merge_default_infos([dep[DefaultInfo] for dep in ctx.attr.deps]), + _merge_css_infos([dep[CssInfo] for dep in ctx.attr.deps]), + ] + + # Copy sources to bin so they are always available for downstream + # `js_binary()` tools. copied = copy_files_to_bin_actions(ctx, ctx.files.srcs) return [ @@ -40,5 +50,25 @@ A library of CSS source files and their `@import` dependencies. This rule does not currently implement any form of strict dependencies, take care to manage your imports and dependencies. + +If no `srcs` are given, this target re-exports its `deps`. Any direct sources of +direct dependencies are treated like direct sources of this target. """.strip(), ) + +def _merge_default_infos(infos): + """Merges the list of `DefaultInfo` providers into a single one.""" + return DefaultInfo(files = depset( + direct = [], + transitive = [info.files for info in infos], + )) + +def _merge_css_infos(infos): + """Merges the given `CssInfo` providers into a single one.""" + return CssInfo( + direct_sources = [src for info in infos for src in info.direct_sources], + transitive_sources = depset( + direct = [], + transitive = [info.transitive_sources for info in infos], + ), + ) diff --git a/packages/rules_prerender/css/tests/reexport/BUILD.bazel b/packages/rules_prerender/css/tests/reexport/BUILD.bazel new file mode 100644 index 00000000..c2b5f34f --- /dev/null +++ b/packages/rules_prerender/css/tests/reexport/BUILD.bazel @@ -0,0 +1,5 @@ +load(":reexport_test.bzl", "reexport_test_suite") + +package(default_testonly = True) + +reexport_test_suite(name = "tests") diff --git a/packages/rules_prerender/css/tests/reexport/bar.css b/packages/rules_prerender/css/tests/reexport/bar.css new file mode 100644 index 00000000..f83c4540 --- /dev/null +++ b/packages/rules_prerender/css/tests/reexport/bar.css @@ -0,0 +1 @@ +.bar { color: green }; diff --git a/packages/rules_prerender/css/tests/reexport/baz.css b/packages/rules_prerender/css/tests/reexport/baz.css new file mode 100644 index 00000000..b03259f1 --- /dev/null +++ b/packages/rules_prerender/css/tests/reexport/baz.css @@ -0,0 +1,3 @@ +@import './dep.css'; + +.baz { color: var(--color); } diff --git a/packages/rules_prerender/css/tests/reexport/dep.css b/packages/rules_prerender/css/tests/reexport/dep.css new file mode 100644 index 00000000..e8a46756 --- /dev/null +++ b/packages/rules_prerender/css/tests/reexport/dep.css @@ -0,0 +1 @@ +:root { --color: blue; } diff --git a/packages/rules_prerender/css/tests/reexport/foo.css b/packages/rules_prerender/css/tests/reexport/foo.css new file mode 100644 index 00000000..2d130df9 --- /dev/null +++ b/packages/rules_prerender/css/tests/reexport/foo.css @@ -0,0 +1 @@ +.foo { color: red; } diff --git a/packages/rules_prerender/css/tests/reexport/reexport_test.bzl b/packages/rules_prerender/css/tests/reexport/reexport_test.bzl new file mode 100644 index 00000000..6ba2ab08 --- /dev/null +++ b/packages/rules_prerender/css/tests/reexport/reexport_test.bzl @@ -0,0 +1,107 @@ +load("@bazel_skylib//lib:sets.bzl", "sets") +load("@bazel_skylib//lib:unittest.bzl", "asserts", "analysistest") +load("//packages/rules_prerender/css:css_library.bzl", "css_library") +load("//packages/rules_prerender/css:css_providers.bzl", "CssInfo") + +visibility("private") + +def _reexport_test_impl(ctx): + env = analysistest.begin(ctx) + + default_info = analysistest.target_under_test(env)[DefaultInfo] + asserts.set_equals( + env, + sets.make([ + "packages/rules_prerender/css/tests/reexport/foo.css", + "packages/rules_prerender/css/tests/reexport/bar.css", + "packages/rules_prerender/css/tests/reexport/baz.css", + ]), + sets.make([file.short_path for file in default_info.files.to_list()]), + ) + + css_info = analysistest.target_under_test(env)[CssInfo] + asserts.set_equals( + env, + sets.make([ + "packages/rules_prerender/css/tests/reexport/foo.css", + "packages/rules_prerender/css/tests/reexport/bar.css", + "packages/rules_prerender/css/tests/reexport/baz.css", + ]), + sets.make([file.short_path for file in css_info.direct_sources]), + ) + asserts.set_equals( + env, + sets.make([ + "packages/rules_prerender/css/tests/reexport/foo.css", + "packages/rules_prerender/css/tests/reexport/bar.css", + "packages/rules_prerender/css/tests/reexport/baz.css", + "packages/rules_prerender/css/tests/reexport/dep.css", + ]), + sets.make([file.short_path + for file in css_info.transitive_sources.to_list()]), + ) + + return analysistest.end(env) + +_reexport_test = analysistest.make(_reexport_test_impl) + +def _test_reexport(name): + css_library( + name = "styles", + srcs = ["foo.css", "bar.css"], + ) + + css_library( + name = "dep", + srcs = ["dep.css"], + ) + + css_library( + name = "baz", + srcs = ["baz.css"], + deps = [":dep"], + ) + + css_library( + name = "reexport", + deps = [":styles", ":baz"], + ) + + _reexport_test( + name = name, + target_under_test = ":reexport", + size = "small", + ) + +def _empty_test_impl(ctx): + env = analysistest.begin(ctx) + + asserts.expect_failure(env, "Expected `srcs` and/or `deps`") + + return analysistest.end(env) + +_empty_test = analysistest.make(_empty_test_impl, expect_failure = True) + +def _test_empty(name): + css_library( + name = "empty", + tags = ["manual"], + ) + + _empty_test( + name = name, + target_under_test = ":empty", + size = "small", + ) + +def reexport_test_suite(name): + _test_reexport(name = "reexport_test") + _test_empty(name = "empty_test") + + native.test_suite( + name = name, + tests = [ + ":reexport_test", + ":empty_test", + ], + )