Python: 2to3 is now a write_file, not sh_binary
Now py_* rules no longer depend on a sh_* rule, so
Bazel can analyze them even with
--shell_executable="".
Change-Id: I8e74d86daf385442df9e91c2dc2f7a27b7c4b236
Closes #8187.
Change-Id: I78057362c0f4e761362ae1d363eee9c52d3c1295
PiperOrigin-RevId: 245941481
diff --git a/scripts/bootstrap/compile.sh b/scripts/bootstrap/compile.sh
index db7be55..cd35202 100755
--- a/scripts/bootstrap/compile.sh
+++ b/scripts/bootstrap/compile.sh
@@ -226,7 +226,13 @@
cat <<EOF >${BAZEL_TOOLS_REPO}/WORKSPACE
workspace(name = 'bazel_tools')
EOF
- link_dir ${PWD}/src ${BAZEL_TOOLS_REPO}/src
+
+ mkdir -p "${BAZEL_TOOLS_REPO}/src/conditions"
+ link_file "${PWD}/src/conditions/BUILD.tools" \
+ "${BAZEL_TOOLS_REPO}/src/conditions/BUILD"
+ link_children "${PWD}" src/conditions "${BAZEL_TOOLS_REPO}"
+ link_children "${PWD}" src "${BAZEL_TOOLS_REPO}"
+
link_dir ${PWD}/third_party ${BAZEL_TOOLS_REPO}/third_party
# Create @bazel_tools//tools/cpp/runfiles
diff --git a/tools/python/2to3.sh b/tools/python/2to3.sh
deleted file mode 100755
index d87f29e..0000000
--- a/tools/python/2to3.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-exit 1
diff --git a/tools/python/BUILD.tools b/tools/python/BUILD.tools
index 5544e7d..d53871b 100644
--- a/tools/python/BUILD.tools
+++ b/tools/python/BUILD.tools
@@ -1,11 +1,34 @@
load(":python_version.bzl", "define_python_version_flag")
load(":toolchain.bzl", "define_autodetecting_toolchain")
+# Please do not use write_file.bzl outside of this package.
+# See https://groups.google.com/d/msg/bazel-dev/I8IvJyoyo-s/AttqDcnOCgAJ
+load(":write_file.bzl", "write_file")
+
package(default_visibility = ["//visibility:public"])
-sh_binary(
+write_file(
name = "2to3",
- srcs = ["2to3.sh"],
+ out = select({
+ "//src/conditions:host_windows": "2to3.bat",
+ "//conditions:default": "2to3.sh",
+ }),
+ content = select({
+ "//src/conditions:host_windows": [
+ "@echo >&2 ERROR: 2to3 is not implemented.",
+ "@echo >&2 Please either build this target for PY2 or else set srcs_version to PY2ONLY instead of PY2.",
+ "@echo >&2 See https://github.com/bazelbuild/bazel/issues/1393#issuecomment-431110617",
+ "@exit /B 1",
+ ],
+ "//conditions:default": [
+ "#!/bin/bash",
+ "echo >&2 'ERROR: 2to3 is not implemented.'",
+ "echo >&2 'Please either build this target for PY2 or else set srcs_version to PY2ONLY instead of PY2.'",
+ "echo >&2 'See https://github.com/bazelbuild/bazel/issues/1393#issuecomment-431110617'",
+ "exit 1",
+ ],
+ }),
+ is_executable = True,
)
# This target can be used to inspect the current Python major version. To use,
diff --git a/tools/python/write_file.bzl b/tools/python/write_file.bzl
new file mode 100644
index 0000000..45ec1b6
--- /dev/null
+++ b/tools/python/write_file.bzl
@@ -0,0 +1,95 @@
+# Copyright 2019 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.
+
+"""write_file() rule from bazel-skylib 0.8.0.
+
+This file is a copy of rules/private/write_file_private.bzl [1] with some edits:
+ - this DocString is different
+ - the rule's 'out' attribute does not create a label, so it is select()-able
+
+IMPORTANT: please do not use this rule outside of this package.
+Related discussion here [2].
+
+
+[1] https://github.com/bazelbuild/bazel-skylib/blob/3721d32c14d3639ff94320c780a60a6e658fb033/rules/private/write_file_private.bzl
+
+[2] https://groups.google.com/d/msg/bazel-dev/I8IvJyoyo-s/AttqDcnOCgAJ
+"""
+
+def _common_impl(ctx, is_executable):
+ # ctx.actions.write creates a FileWriteAction which uses UTF-8 encoding.
+ out = ctx.actions.declare_file(ctx.attr.out)
+ ctx.actions.write(
+ output = out,
+ content = "\n".join(ctx.attr.content) if ctx.attr.content else "",
+ is_executable = is_executable,
+ )
+ files = depset(direct = [out])
+ runfiles = ctx.runfiles(files = [out])
+ if is_executable:
+ return [DefaultInfo(files = files, runfiles = runfiles, executable = out)]
+ else:
+ return [DefaultInfo(files = files, runfiles = runfiles)]
+
+def _impl(ctx):
+ return _common_impl(ctx, False)
+
+def _ximpl(ctx):
+ return _common_impl(ctx, True)
+
+_ATTRS = {
+ "content": attr.string_list(mandatory = False, allow_empty = True),
+ "out": attr.string(mandatory = True),
+}
+
+_write_file = rule(
+ implementation = _impl,
+ provides = [DefaultInfo],
+ attrs = _ATTRS,
+)
+
+_write_xfile = rule(
+ implementation = _ximpl,
+ executable = True,
+ provides = [DefaultInfo],
+ attrs = _ATTRS,
+)
+
+def write_file(name, out, content = [], is_executable = False, **kwargs):
+ """Creates a UTF-8 encoded text file.
+
+ Args:
+ name: Name of the rule.
+ out: Path of the output file, relative to this package.
+ content: A list of strings. Lines of text, the contents of the file.
+ Newlines are added automatically after every line except the last one.
+ is_executable: A boolean. Whether to make the output file executable. When
+ True, the rule's output can be executed using `bazel run` and can be
+ in the srcs of binary and test rules that require executable sources.
+ **kwargs: further keyword arguments, e.g. `visibility`
+ """
+ if is_executable:
+ _write_xfile(
+ name = name,
+ content = content,
+ out = out,
+ **kwargs
+ )
+ else:
+ _write_file(
+ name = name,
+ content = content,
+ out = out,
+ **kwargs
+ )