Skip to content

Commit

Permalink
Bash,runfiles: add a runfiles library
Browse files Browse the repository at this point in the history
See bazelbuild#4460

Change-Id: Icf38b28ad492e7b7fc431844d31dc19e74ac663e
  • Loading branch information
laszlocsomor committed Mar 19, 2018
1 parent cd8eb70 commit 69c9c09
Show file tree
Hide file tree
Showing 15 changed files with 546 additions and 350 deletions.
70 changes: 41 additions & 29 deletions src/test/py/bazel/runfiles_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,20 +71,23 @@ def testJavaRunfilesLibraryInBazelToolsRepo(self):
self.assertEqual(lines[0], "world")

def _AssertPythonRunfilesLibraryInBazelToolsRepo(self, family, lang_name):
for s, t in [
("WORKSPACE.mock", "WORKSPACE"),
("foo/BUILD.mock", "foo/BUILD"),
("foo/runfiles.py", "foo/runfiles.py"),
("foo/datadep/hello.txt", "foo/datadep/hello.txt"),
("bar/BUILD.mock", "bar/BUILD"),
("bar/bar.py", "bar/bar.py"),
("bar/bar-py-data.txt", "bar/bar-py-data.txt"),
("bar/Bar.java", "bar/Bar.java"),
("bar/bar-java-data.txt", "bar/bar-java-data.txt"),
for s, t, exe in [
("WORKSPACE.mock", "WORKSPACE", False),
("foo/BUILD.mock", "foo/BUILD", False),
("foo/runfiles.py", "foo/runfiles.py", True),
("foo/foo.sh", "foo/foo.sh", True),
("foo/datadep/hello.txt", "foo/datadep/hello.txt", False),
("bar/BUILD.mock", "bar/BUILD", False),
("bar/bar.py", "bar/bar.py", True),
("bar/bar-py-data.txt", "bar/bar-py-data.txt", False),
("bar/Bar.java", "bar/Bar.java", False),
("bar/bar-java-data.txt", "bar/bar-java-data.txt", False),
("bar/bar.sh", "bar/bar.sh", True),
("bar/bar-sh-data.txt", "bar/bar-sh-data.txt", False),
]:
self.CopyFile(
self.Rlocation(
"io_bazel/src/test/py/bazel/testdata/runfiles_test/" + s), t)
"io_bazel/src/test/py/bazel/testdata/runfiles_test/" + s), t, exe)

exit_code, stdout, stderr = self.RunBazel(["info", "bazel-bin"])
self.AssertExitCode(exit_code, 0, stderr)
Expand All @@ -103,7 +106,7 @@ def _AssertPythonRunfilesLibraryInBazelToolsRepo(self, family, lang_name):
exit_code, stdout, stderr = self.RunProgram(
[bin_path], env_add={"TEST_SRCDIR": "__ignore_me__"})
self.AssertExitCode(exit_code, 0, stderr)
if len(stdout) != 6:
if len(stdout) != 8:
self.fail("stdout: %s" % stdout)

self.assertEqual(stdout[0], "Hello %s Foo!" % lang_name)
Expand All @@ -117,7 +120,8 @@ def _AssertPythonRunfilesLibraryInBazelToolsRepo(self, family, lang_name):
self.assertEqual(lines[0], "world")

i = 2
for lang in [("py", "Python", "bar.py"), ("java", "Java", "Bar.java")]:
for lang in [("py", "Python", "bar.py"), ("java", "Java", "Bar.java"),
("sh", "Bash", "bar.sh")]:
self.assertEqual(stdout[i], "Hello %s Bar!" % lang[1])
six.assertRegex(self, stdout[i + 1],
"^rloc=.*/bar/bar-%s-data.txt" % lang[0])
Expand All @@ -134,18 +138,23 @@ def _AssertPythonRunfilesLibraryInBazelToolsRepo(self, family, lang_name):
def testPythonRunfilesLibraryInBazelToolsRepo(self):
self._AssertPythonRunfilesLibraryInBazelToolsRepo("py", "Python")

def testBashRunfilesLibraryInBazelToolsRepo(self):
self._AssertPythonRunfilesLibraryInBazelToolsRepo("sh", "Bash")

def testRunfilesLibrariesFindRunfilesWithoutEnvvars(self):
for s, t in [
("WORKSPACE.mock", "WORKSPACE"),
("bar/BUILD.mock", "bar/BUILD"),
("bar/bar.py", "bar/bar.py"),
("bar/bar-py-data.txt", "bar/bar-py-data.txt"),
("bar/Bar.java", "bar/Bar.java"),
("bar/bar-java-data.txt", "bar/bar-java-data.txt"),
for s, t, exe in [
("WORKSPACE.mock", "WORKSPACE", False),
("bar/BUILD.mock", "bar/BUILD", False),
("bar/bar.py", "bar/bar.py", True),
("bar/bar-py-data.txt", "bar/bar-py-data.txt", False),
("bar/Bar.java", "bar/Bar.java", False),
("bar/bar-java-data.txt", "bar/bar-java-data.txt", False),
("bar/bar.sh", "bar/bar.sh", True),
("bar/bar-sh-data.txt", "bar/bar-sh-data.txt", False),
]:
self.CopyFile(
self.Rlocation(
"io_bazel/src/test/py/bazel/testdata/runfiles_test/" + s), t)
"io_bazel/src/test/py/bazel/testdata/runfiles_test/" + s), t, exe)

exit_code, stdout, stderr = self.RunBazel(["info", "bazel-bin"])
self.AssertExitCode(exit_code, 0, stderr)
Expand All @@ -154,7 +163,8 @@ def testRunfilesLibrariesFindRunfilesWithoutEnvvars(self):
exit_code, _, stderr = self.RunBazel(["build", "//bar:all"])
self.AssertExitCode(exit_code, 0, stderr)

for lang in [("py", "Python", "bar.py"), ("java", "Java", "Bar.java")]:
for lang in [("py", "Python", "bar.py"), ("java", "Java", "Bar.java"),
("sh", "Bash", "bar.sh")]:
if test_base.TestBase.IsWindows():
bin_path = os.path.join(bazel_bin, "bar/bar-%s.exe" % lang[0])
else:
Expand Down Expand Up @@ -185,25 +195,27 @@ def testRunfilesLibrariesFindRunfilesWithoutEnvvars(self):
self.assertEqual(lines[0], "data for " + lang[2])

def testRunfilesLibrariesFindRunfilesWithRunfilesManifestEnvvar(self):
for s, t in [
("WORKSPACE.mock", "WORKSPACE"),
("bar/BUILD.mock", "bar/BUILD"),
for s, t, exe in [
("WORKSPACE.mock", "WORKSPACE", False),
("bar/BUILD.mock", "bar/BUILD", False),
# Note: do not test Python here, because py_binary always needs a
# runfiles tree, even on Windows, because it needs __init__.py files in
# every directory where there may be importable modules, so Bazel always
# needs to create a runfiles tree for py_binary.
("bar/Bar.java", "bar/Bar.java"),
("bar/bar-java-data.txt", "bar/bar-java-data.txt"),
("bar/Bar.java", "bar/Bar.java", False),
("bar/bar-java-data.txt", "bar/bar-java-data.txt", False),
("bar/bar.sh", "bar/bar.sh", True),
("bar/bar-sh-data.txt", "bar/bar-sh-data.txt", False),
]:
self.CopyFile(
self.Rlocation(
"io_bazel/src/test/py/bazel/testdata/runfiles_test/" + s), t)
"io_bazel/src/test/py/bazel/testdata/runfiles_test/" + s), t, exe)

exit_code, stdout, stderr = self.RunBazel(["info", "bazel-bin"])
self.AssertExitCode(exit_code, 0, stderr)
bazel_bin = stdout[0]

for lang in [("java", "Java")]: # TODO(laszlocsomor): add "cc" when ready.
for lang in [("java", "Java"), ("sh", "Bash")]: # TODO(laszlocsomor): add "cc" when ready.
exit_code, _, stderr = self.RunBazel([
"build", "--experimental_enable_runfiles=no", "//bar:bar-" + lang[0]
])
Expand Down
7 changes: 7 additions & 0 deletions src/test/py/bazel/testdata/runfiles_test/bar/BUILD.mock
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ java_binary(
main_class = "Bar",
deps = ["@bazel_tools//tools/runfiles:java-runfiles"],
)

sh_binary(
name = "bar-sh",
srcs = ["bar.sh"],
data = ["bar-sh-data.txt"],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
data for bar.sh
39 changes: 39 additions & 0 deletions src/test/py/bazel/testdata/runfiles_test/bar/bar.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
# Copyright 2018 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.

set -euo pipefail
# --- begin runfiles.sh initialization ---
if [[ -z "${RUNFILES_MANIFEST_FILE:-}" && -z "${RUNFILES_DIR:-}" ]]; then
if [[ -f "$0.runfiles_manifest" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
elif [[ -f "$0.runfiles/MANIFEST" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
elif [[ -d "$0.runfiles" ]]; then
export RUNFILES_DIR="$0.runfiles"
fi
fi
if [[ -n "${RUNFILES_MANIFEST_FILE:-}" ]]; then
source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.sh " \
"${RUNFILES_MANIFEST_FILE}" | cut -d ' ' -f 2-)"
elif [[ -n "${RUNFILES_DIR:-}" ]]; then
source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.sh"
else
echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.sh"
exit 1
fi
# --- end runfiles.sh initialization ---

echo "Hello Bash Bar!"
echo "rloc=$(rlocation "foo_ws/bar/bar-sh-data.txt")"
15 changes: 14 additions & 1 deletion src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ py_binary(
srcs = ["runfiles.py"],
data = [
"datadep/hello.txt",
"//bar:bar-py",
"//bar:bar-java",
"//bar:bar-py",
"//bar:bar-sh",
],
main = "runfiles.py",
deps = ["@bazel_tools//tools/runfiles:py-runfiles"],
Expand All @@ -19,3 +20,15 @@ java_binary(
main_class = "Foo",
deps = ["@bazel_tools//tools/runfiles:java-runfiles"],
)

sh_binary(
name = "runfiles-sh",
srcs = ["foo.sh"],
data = [
"datadep/hello.txt",
"//bar:bar-java",
"//bar:bar-py",
"//bar:bar-sh",
],
deps = ["@bazel_tools//tools/bash/runfiles"],
)
81 changes: 81 additions & 0 deletions src/test/py/bazel/testdata/runfiles_test/foo/foo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/bin/bash
# Copyright 2018 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.

set -euo pipefail
# --- begin runfiles.sh initialization ---
if [[ -z "${RUNFILES_MANIFEST_FILE:-}" && -z "${RUNFILES_DIR:-}" ]]; then
if [[ -f "$0.runfiles_manifest" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
elif [[ -f "$0.runfiles/MANIFEST" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
elif [[ -d "$0.runfiles" ]]; then
export RUNFILES_DIR="$0.runfiles"
fi
fi
if [[ -n "${RUNFILES_MANIFEST_FILE:-}" ]]; then
source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.sh " \
"${RUNFILES_MANIFEST_FILE}" | cut -d ' ' -f 2-)"
elif [[ -n "${RUNFILES_DIR:-}" ]]; then
source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.sh"
else
echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.sh"
exit 1
fi
# --- end runfiles.sh initialization ---


if ! type rlocation >&/dev/null; then
echo >&2 "ERROR: rlocation is undefined"
exit 1
fi

case "$(uname -s | tr [:upper:] [:lower:])" in
msys*|mingw*|cygwin*)
function is_windows() { true ; }
;;
*)
function is_windows() { false ; }
;;
esac

function child_binary_name() {
local lang=$1
if is_windows; then
echo "foo_ws/bar/bar-${lang}.exe"
else
echo "foo_ws/bar/bar-${lang}"
fi
}

function main() {
echo "Hello Bash Foo!"
echo "rloc=$(rlocation "foo_ws/foo/datadep/hello.txt")"

# Run a subprocess, propagate the runfiles envvar to it. The subprocess will
# use this process's runfiles manifest or runfiles directory.
runfiles_export_envvars
if is_windows; then
export SYSTEMROOT="${SYSTEMROOT:-}"
fi
for lang in py java sh; do
child_bin="$(rlocation "$(child_binary_name $lang)")"
if ! "$child_bin"; then
echo >&2 "ERROR: error running bar-$lang"
exit 1
fi
done
}

main
2 changes: 1 addition & 1 deletion src/test/py/bazel/testdata/runfiles_test/foo/runfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def main():
else:
env = {}
env.update(r.EnvVars())
for lang in ["py", "java"]:
for lang in ["py", "java", "sh"]:
p = subprocess.Popen(
[r.Rlocation(ChildBinaryName(lang))],
env=env,
Expand Down
14 changes: 0 additions & 14 deletions src/tools/runfiles/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,6 @@ cc_test(
],
)

sh_library(
name = "runfiles_sh_lib",
srcs = ["runfiles.sh"],
)

sh_test(
name = "runfiles_sh_test",
srcs = select({
"//src/conditions:windows": ["runfiles_windows_test.sh"],
"//conditions:default": ["runfiles_posix_test.sh"],
}),
deps = [":runfiles_sh_lib"],
)

test_suite(
name = "windows_tests",
tags = [
Expand Down
2 changes: 1 addition & 1 deletion src/tools/runfiles/runfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def Rlocation(self, path):
raise TypeError()
if ".." in path:
raise ValueError("path contains uplevel references: \"%s\"" % path)
if path[0] == "\\":
if path[0] == "\\":
raise ValueError("path is absolute without a drive letter: \"%s\"" % path)
if os.path.isabs(path):
return path
Expand Down
Loading

0 comments on commit 69c9c09

Please sign in to comment.