Fall back to native rules if possible (#10)
Provides compatibility with Bazel versions before 7.4.0.
Also requires adding `bazel_skylib` to the dependency macro.
Fixes #9
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 4ca63d2..d499c80 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -5,8 +5,7 @@
platform:
- ubuntu2004
- macos
- # TODO: Enable Windows once the private API it allowlists rules_shell.
- # - windows
+ - windows
tasks:
test_module_bzlmod:
@@ -39,6 +38,15 @@
- "--enable_workspace"
test_targets:
- "//..."
+ test_module_workspace_bazel6:
+ name: "Test module (Bazel 6.5.0, WORKSPACE)"
+ working_directory: "tests/bcr"
+ bazel: 6.5.0
+ platform: ${{ platform }}
+ build_targets:
+ - "//..."
+ test_targets:
+ - "//..."
test_module_head:
name: "Test module (Bazel@HEAD, Bzlmod)"
working_directory: "tests/bcr"
diff --git a/shell/private/BUILD b/shell/private/BUILD
index 59632c1..d0eebed 100644
--- a/shell/private/BUILD
+++ b/shell/private/BUILD
@@ -2,6 +2,11 @@
bzl_library(
name = "private_bzl",
- srcs = ["sh_executable.bzl"],
+ srcs = [
+ "sh_binary.bzl",
+ "sh_executable.bzl",
+ "sh_library.bzl",
+ "sh_test.bzl",
+ ],
visibility = ["//shell:__pkg__"],
)
diff --git a/shell/private/sh_binary.bzl b/shell/private/sh_binary.bzl
new file mode 100644
index 0000000..eec109a
--- /dev/null
+++ b/shell/private/sh_binary.bzl
@@ -0,0 +1,22 @@
+# Copyright 2024 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""sh_binary rule definition."""
+
+load(":sh_executable.bzl", "make_sh_executable_rule")
+
+# For doc generation only.
+visibility("public")
+
+sh_binary = make_sh_executable_rule(executable = True)
diff --git a/shell/private/sh_library.bzl b/shell/private/sh_library.bzl
new file mode 100644
index 0000000..2f3613c
--- /dev/null
+++ b/shell/private/sh_library.bzl
@@ -0,0 +1,118 @@
+# Copyright 2024 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""sh_library rule definition."""
+
+# For doc generation only.
+visibility("public")
+
+def _sh_library_impl(ctx):
+ transitive_files = []
+ for target in ctx.attr.srcs:
+ transitive_files.append(target[DefaultInfo].files)
+ for target in ctx.attr.deps:
+ transitive_files.append(target[DefaultInfo].files)
+ for target in ctx.attr.data:
+ transitive_files.append(target[DefaultInfo].files)
+ files = depset(transitive = transitive_files)
+
+ runfiles = ctx.runfiles(transitive_files = files, collect_default = True)
+
+ instrumented_files_info = coverage_common.instrumented_files_info(
+ ctx,
+ source_attributes = ["srcs"],
+ dependency_attributes = ["deps", "data"],
+ )
+
+ return [
+ DefaultInfo(
+ files = files,
+ runfiles = runfiles,
+ ),
+ instrumented_files_info,
+ ]
+
+sh_library = rule(
+ _sh_library_impl,
+ doc = """
+<p>
+ The main use for this rule is to aggregate together a logical
+ "library" consisting of related scripts—programs in an
+ interpreted language that does not require compilation or linking,
+ such as the Bourne shell—and any data those programs need at
+ run-time. Such "libraries" can then be used from
+ the <code>data</code> attribute of one or
+ more <code>sh_binary</code> rules.
+</p>
+
+<p>
+ You can use the <a href="${link filegroup}"><code>filegroup</code></a> rule to aggregate data
+ files.
+</p>
+
+<p>
+ In interpreted programming languages, there's not always a clear
+ distinction between "code" and "data": after all, the program is
+ just "data" from the interpreter's point of view. For this reason
+ this rule has three attributes which are all essentially equivalent:
+ <code>srcs</code>, <code>deps</code> and <code>data</code>.
+ The current implementation does not distinguish between the elements of these lists.
+ All three attributes accept rules, source files and generated files.
+ It is however good practice to use the attributes for their usual purpose (as with other rules).
+</p>
+
+<h4 id="sh_library_examples">Examples</h4>
+
+<pre class="code">
+sh_library(
+ name = "foo",
+ data = [
+ ":foo_service_script", # an sh_binary with srcs
+ ":deploy_foo", # another sh_binary with srcs
+ ],
+)
+</pre>
+""",
+ attrs = {
+ "srcs": attr.label_list(
+ allow_files = True,
+ doc = """
+The list of input files.
+<p>
+ This attribute should be used to list shell script source files that belong to
+ this library. Scripts can load other scripts using the shell's <code>source</code>
+ or <code>.</code> command.
+</p>
+""",
+ ),
+ "data": attr.label_list(
+ allow_files = True,
+ flags = ["SKIP_CONSTRAINTS_OVERRIDE"],
+ ),
+ "deps": attr.label_list(
+ allow_rules = ["sh_library"],
+ doc = """
+The list of "library" targets to be aggregated into this target.
+See general comments about <code>deps</code>
+at <a href="${link common-definitions#typical.deps}">Typical attributes defined by
+most build rules</a>.
+<p>
+ This attribute should be used to list other <code>sh_library</code> rules that provide
+ interpreted program source code depended on by the code in <code>srcs</code>. The files
+ provided by these rules will be present among the <code>runfiles</code> of this target.
+</p>
+""",
+ ),
+ },
+)
diff --git a/shell/private/sh_test.bzl b/shell/private/sh_test.bzl
new file mode 100644
index 0000000..c12622a
--- /dev/null
+++ b/shell/private/sh_test.bzl
@@ -0,0 +1,39 @@
+# Copyright 2024 The Bazel Authors. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""sh_test rule definition."""
+
+load(":sh_executable.bzl", "make_sh_executable_rule")
+
+# For doc generation only.
+visibility("public")
+
+sh_test = make_sh_executable_rule(
+ test = True,
+ fragments = ["coverage"],
+ extra_attrs = {
+ "_lcov_merger": attr.label(
+ cfg = "exec",
+ default = configuration_field(fragment = "coverage", name = "output_generator"),
+ executable = True,
+ ),
+ # Add the script as an attribute in order for sh_test to output code coverage results for
+ # code covered by CC binaries invocations.
+ "_collect_cc_coverage": attr.label(
+ cfg = "exec",
+ default = "@bazel_tools//tools/test:collect_cc_coverage",
+ executable = True,
+ ),
+ },
+)
diff --git a/shell/repositories.bzl b/shell/repositories.bzl
index 81b1cc0..62a0ff1 100644
--- a/shell/repositories.bzl
+++ b/shell/repositories.bzl
@@ -14,6 +14,8 @@
"""WORKSPACE dependency macros for the shell rules."""
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("//shell/private/repositories:sh_config.bzl", "sh_config")
visibility("public")
@@ -21,7 +23,15 @@
# buildifier: disable=unnamed-macro
def rules_shell_dependencies():
"""Instantiates repositories required by rules_shell."""
- pass
+ maybe(
+ http_archive,
+ name = "bazel_skylib",
+ sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
+ "https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz",
+ ],
+ )
# buildifier: disable=unnamed-macro
def rules_shell_toolchains():
diff --git a/shell/sh_binary.bzl b/shell/sh_binary.bzl
index 5e3a422..9e4a30d 100644
--- a/shell/sh_binary.bzl
+++ b/shell/sh_binary.bzl
@@ -14,8 +14,8 @@
"""sh_binary rule definition."""
-load("//shell/private:sh_executable.bzl", "make_sh_executable_rule")
+load("//shell/private:sh_binary.bzl", _sh_binary = "sh_binary")
visibility("public")
-sh_binary = make_sh_executable_rule(executable = True)
+sh_binary = getattr(native, "sh_binary", _sh_binary)
diff --git a/shell/sh_library.bzl b/shell/sh_library.bzl
index fd6aef9..b51aeaa 100644
--- a/shell/sh_library.bzl
+++ b/shell/sh_library.bzl
@@ -14,104 +14,8 @@
"""sh_library rule definition."""
+load("//shell/private:sh_library.bzl", _sh_library = "sh_library")
+
visibility("public")
-def _sh_library_impl(ctx):
- transitive_files = []
- for target in ctx.attr.srcs:
- transitive_files.append(target[DefaultInfo].files)
- for target in ctx.attr.deps:
- transitive_files.append(target[DefaultInfo].files)
- for target in ctx.attr.data:
- transitive_files.append(target[DefaultInfo].files)
- files = depset(transitive = transitive_files)
-
- runfiles = ctx.runfiles(transitive_files = files, collect_default = True)
-
- instrumented_files_info = coverage_common.instrumented_files_info(
- ctx,
- source_attributes = ["srcs"],
- dependency_attributes = ["deps", "data"],
- )
-
- return [
- DefaultInfo(
- files = files,
- runfiles = runfiles,
- ),
- instrumented_files_info,
- ]
-
-sh_library = rule(
- _sh_library_impl,
- doc = """
-<p>
- The main use for this rule is to aggregate together a logical
- "library" consisting of related scripts—programs in an
- interpreted language that does not require compilation or linking,
- such as the Bourne shell—and any data those programs need at
- run-time. Such "libraries" can then be used from
- the <code>data</code> attribute of one or
- more <code>sh_binary</code> rules.
-</p>
-
-<p>
- You can use the <a href="${link filegroup}"><code>filegroup</code></a> rule to aggregate data
- files.
-</p>
-
-<p>
- In interpreted programming languages, there's not always a clear
- distinction between "code" and "data": after all, the program is
- just "data" from the interpreter's point of view. For this reason
- this rule has three attributes which are all essentially equivalent:
- <code>srcs</code>, <code>deps</code> and <code>data</code>.
- The current implementation does not distinguish between the elements of these lists.
- All three attributes accept rules, source files and generated files.
- It is however good practice to use the attributes for their usual purpose (as with other rules).
-</p>
-
-<h4 id="sh_library_examples">Examples</h4>
-
-<pre class="code">
-sh_library(
- name = "foo",
- data = [
- ":foo_service_script", # an sh_binary with srcs
- ":deploy_foo", # another sh_binary with srcs
- ],
-)
-</pre>
-""",
- attrs = {
- "srcs": attr.label_list(
- allow_files = True,
- doc = """
-The list of input files.
-<p>
- This attribute should be used to list shell script source files that belong to
- this library. Scripts can load other scripts using the shell's <code>source</code>
- or <code>.</code> command.
-</p>
-""",
- ),
- "data": attr.label_list(
- allow_files = True,
- flags = ["SKIP_CONSTRAINTS_OVERRIDE"],
- ),
- "deps": attr.label_list(
- allow_rules = ["sh_library"],
- doc = """
-The list of "library" targets to be aggregated into this target.
-See general comments about <code>deps</code>
-at <a href="${link common-definitions#typical.deps}">Typical attributes defined by
-most build rules</a>.
-<p>
- This attribute should be used to list other <code>sh_library</code> rules that provide
- interpreted program source code depended on by the code in <code>srcs</code>. The files
- provided by these rules will be present among the <code>runfiles</code> of this target.
-</p>
-""",
- ),
- },
-)
+sh_library = getattr(native, "sh_library", _sh_library)
diff --git a/shell/sh_test.bzl b/shell/sh_test.bzl
index ea5b5a9..272d193 100644
--- a/shell/sh_test.bzl
+++ b/shell/sh_test.bzl
@@ -14,25 +14,8 @@
"""sh_test rule definition."""
-load("//shell/private:sh_executable.bzl", "make_sh_executable_rule")
+load("//shell/private:sh_test.bzl", _sh_test = "sh_test")
visibility("public")
-sh_test = make_sh_executable_rule(
- test = True,
- fragments = ["coverage"],
- extra_attrs = {
- "_lcov_merger": attr.label(
- cfg = "exec",
- default = configuration_field(fragment = "coverage", name = "output_generator"),
- executable = True,
- ),
- # Add the script as an attribute in order for sh_test to output code coverage results for
- # code covered by CC binaries invocations.
- "_collect_cc_coverage": attr.label(
- cfg = "exec",
- default = "@bazel_tools//tools/test:collect_cc_coverage",
- executable = True,
- ),
- },
-)
+sh_test = getattr(native, "sh_test", _sh_test)