runfiles libraries: fix tests and comments
- Update all runfiles libraries to have the same
header comment format, including the build rule
to depend on the namespace / header / module to
import
- Fix runfiles_test.cc to include the right files
(recent refactoring commit has split
src/main/cpp/util/path.cc from
file_[platform].cc)
- Change exported variable
_rlocation_isabs_pattern in runfiles.bash to be
upper-case, so it is visibly a variable and not
a function.
See https://github.com/bazelbuild/bazel/issues/4460
Change-Id: I17e18308506ab9f5c9f410ef6bc6b9df912d42a9
Closes #5481.
Change-Id: I17e18308506ab9f5c9f410ef6bc6b9df912d42a9
PiperOrigin-RevId: 202291629
diff --git a/src/tools/runfiles/java/com/google/devtools/build/runfiles/Runfiles.java b/src/tools/runfiles/java/com/google/devtools/build/runfiles/Runfiles.java
index 8b62773..3c9eef3 100644
--- a/src/tools/runfiles/java/com/google/devtools/build/runfiles/Runfiles.java
+++ b/src/tools/runfiles/java/com/google/devtools/build/runfiles/Runfiles.java
@@ -25,13 +25,33 @@
import java.util.Map;
/**
- * Returns the runtime location of runfiles (data-dependencies of Bazel-built binaries and tests).
+ * Runfiles lookup library for Bazel-built Java binaries and tests.
*
- * <p>Usage:
+ * <p>USAGE:
+ *
+ * <p>1. Depend on this runfiles library from your build rule:
*
* <pre>
- * Runfiles runfiles = Runfiles.create();
- * File p = new File(runfiles.rlocation("io_bazel/src/bazel"));
+ * java_binary(
+ * name = "my_binary",
+ * ...
+ * deps = ["@bazel_tools//tools/runfiles:java-runfiles"],
+ * )
+ * </pre>
+ *
+ * <p>2. Import the runfiles library.
+ *
+ * <pre>
+ * import com.google.devtools.build.runfiles.Runfiles;
+ * </pre>
+ *
+ * <p>3. Create a Runfiles object and use rlocation to look up runfile paths:
+ *
+ * <pre>
+ * public void myFunction() {
+ * Runfiles runfiles = Runfiles.create();
+ * String path = runfiles.rlocation("my_workspace/path/to/my/data.txt");
+ * ...
* </pre>
*
* <p>If you want to start subprocesses that also need runfiles, you need to set the right
diff --git a/tools/bash/runfiles/runfiles.bash b/tools/bash/runfiles/runfiles.bash
index cba75ab..b8bb7b2 100644
--- a/tools/bash/runfiles/runfiles.bash
+++ b/tools/bash/runfiles/runfiles.bash
@@ -12,59 +12,64 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# This Bash script defines functions to handle sh_binary/sh_test runfiles.
+# Runfiles lookup library for Bazel-built Bash binaries and tests.
#
-# REQUIREMENTS:
-# - At least one of RUNFILES_MANIFEST_FILE and RUNFILES_DIR environment
-# variables must be set, to the absolute path of the runfiles manifest or the
-# <rulename>.runfiles directory respectively.
+# ENVIRONMENT:
+# - Use the example code provided below. It initializes the environment
+# variables required by this script.
# - If RUNFILES_LIB_DEBUG=1 is set, the script will print diagnostic messages to
# stderr.
#
# USAGE:
-# 1. Depend on this runfiles library from your build rule:
+# 1. Depend on this runfiles library from your build rule:
#
-# sh_binary(
-# name = "my_binary",
-# ...
-# deps = ["@bazel_tools//tools/bash/runfiles"],
-# )
+# sh_binary(
+# name = "my_binary",
+# ...
+# deps = ["@bazel_tools//tools/bash/runfiles"],
+# )
#
-# 2. Source the runfiles library.
-# The runfiles library itself defines rlocation which you would need to look
-# up the library's runtime location, thus we have a chicken-and-egg problem.
-# Insert the following code snippet to the top of your main script:
+# 2. Source the runfiles library.
#
-# set -euo pipefail
-# # --- begin runfiles.bash initialization ---
-# if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; 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 [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
-# export RUNFILES_DIR="$0.runfiles"
-# fi
-# fi
-# if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
-# source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
-# elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
-# source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
-# "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
-# else
-# echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
-# exit 1
-# fi
-# # --- end runfiles.bash initialization ---
+# The runfiles library itself defines rlocation which you would need to look
+# up the library's runtime location, thus we have a chicken-and-egg problem.
+# Insert the following code snippet to the top of your main script:
+#
+# set -euo pipefail
+# # --- begin runfiles.bash initialization ---
+# if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; 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 [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+# export RUNFILES_DIR="$0.runfiles"
+# fi
+# fi
+# if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+# source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
+# elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+# source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
+# "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
+# else
+# echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
+# exit 1
+# fi
+# # --- end runfiles.bash initialization ---
+#
+# 3. Use rlocation to look up runfile paths:
+#
+# cat "$(rlocation my_workspace/path/to/my/data.txt)"
+#
case "$(uname -s | tr [:upper:] [:lower:])" in
msys*|mingw*|cygwin*)
# matches an absolute Windows path
- export _rlocation_isabs_pattern="^[a-zA-Z]:[/\\]"
+ export _RLOCATION_ISABS_PATTERN="^[a-zA-Z]:[/\\]"
;;
*)
# matches an absolute Unix path
- export _rlocation_isabs_pattern="^/[^/].*"
+ export _RLOCATION_ISABS_PATTERN="^/[^/].*"
;;
esac
@@ -73,7 +78,7 @@
if [[ "${RUNFILES_LIB_DEBUG:-}" == 1 ]]; then
echo >&2 "INFO[runfiles.bash]: rlocation($1): start"
fi
- if [[ "$1" =~ $_rlocation_isabs_pattern ]]; then
+ if [[ "$1" =~ $_RLOCATION_ISABS_PATTERN ]]; then
if [[ "${RUNFILES_LIB_DEBUG:-}" == 1 ]]; then
echo >&2 "INFO[runfiles.bash]: rlocation($1): absolute path, return"
fi
diff --git a/tools/cpp/runfiles/runfiles.h b/tools/cpp/runfiles/runfiles.h
index b2bfe30..cfb1f30 100644
--- a/tools/cpp/runfiles/runfiles.h
+++ b/tools/cpp/runfiles/runfiles.h
@@ -14,30 +14,39 @@
// Runfiles lookup library for Bazel-built C++ binaries and tests.
//
-// Usage:
+// USAGE:
+// 1. Depend on this runfiles library from your build rule:
//
-// #include "tools/cpp/runfiles/runfiles.h"
+// cc_binary(
+// name = "my_binary",
+// ...
+// deps = ["@bazel_tools//tools/cpp/runfiles"],
+// )
//
-// using bazel::tools::cpp::runfiles::Runfiles;
+// 2. Include the runfiles library.
//
-// int main(int argc, char** argv) {
-// std::string error;
-// std::unique_ptr<Runfiles> runfiles(Runfiles::Create(argv[0], &error));
-// if (runfiles == nullptr) {
-// ... // error handling
-// }
-// std::string path = runfiles->Rlocation("io_bazel/src/bazel");
-// if (!path.empty()) {
-// std::ifstream data(path);
-// if (data.is_open()) {
-// ... // use the runfile
+// #include "tools/cpp/runfiles/runfiles.h"
//
-// The code above creates a Runfiles object and retrieves a runfile path.
+// using bazel::tools::cpp::runfiles::Runfiles;
//
-// The Runfiles::Create function uses the runfiles manifest and the runfiles
-// directory from the RUNFILES_MANIFEST_FILE and RUNFILES_DIR environment
-// variables. If not present, the function looks for the manifest and directory
-// near argv[0], the path of the main program.
+// 3. Create a Runfiles object and use rlocation to look up runfile paths:
+//
+// int main(int argc, char** argv) {
+// std::string error;
+// std::unique_ptr<Runfiles> runfiles(Runfiles::Create(argv[0],
+// &error)); if (runfiles == nullptr) {
+// ... // error handling
+// }
+// std::string path =
+// runfiles->Rlocation("my_workspace/path/to/my/data.txt");
+// ...
+//
+// The code above creates a Runfiles object and retrieves a runfile path.
+//
+// The Runfiles::Create function uses the runfiles manifest and the
+// runfiles directory from the RUNFILES_MANIFEST_FILE and RUNFILES_DIR
+// environment variables. If not present, the function looks for the
+// manifest and directory near argv[0], the path of the main program.
//
// To start child processes that also need runfiles, you need to set the right
// environment variables for them:
diff --git a/tools/cpp/runfiles/runfiles_test.cc b/tools/cpp/runfiles/runfiles_test.cc
index 17c1d42..d6ecac9 100644
--- a/tools/cpp/runfiles/runfiles_test.cc
+++ b/tools/cpp/runfiles/runfiles_test.cc
@@ -25,10 +25,11 @@
#include "gtest/gtest.h"
#include "src/main/cpp/util/file.h"
+#include "src/main/cpp/util/path.h"
-#define _T(x) #x
-#define T(x) _T(x)
-#define LINE() T(__LINE__)
+#define RUNFILES_TEST_TOSTRING_HELPER(x) #x
+#define RUNFILES_TEST_TOSTRING(x) RUNFILES_TEST_TOSTRING_HELPER(x)
+#define LINE_AS_STRING() RUNFILES_TEST_TOSTRING(__LINE__)
namespace bazel {
namespace tools {
@@ -145,8 +146,8 @@
RunfilesTest::MockFile::~MockFile() { std::remove(path_.c_str()); }
TEST_F(RunfilesTest, CreatesManifestBasedRunfilesFromManifestNextToBinary) {
- unique_ptr<MockFile> mf(
- MockFile::Create("foo" LINE() ".runfiles_manifest", {"a/b c/d"}));
+ unique_ptr<MockFile> mf(MockFile::Create(
+ "foo" LINE_AS_STRING() ".runfiles_manifest", {"a/b c/d"}));
EXPECT_TRUE(mf != nullptr);
string argv0(mf->Path().substr(
0, mf->Path().size() - string(".runfiles_manifest").size()));
@@ -164,8 +165,8 @@
TEST_F(RunfilesTest,
CreatesManifestBasedRunfilesFromManifestInRunfilesDirectory) {
- unique_ptr<MockFile> mf(
- MockFile::Create("foo" LINE() ".runfiles/MANIFEST", {"a/b c/d"}));
+ unique_ptr<MockFile> mf(MockFile::Create(
+ "foo" LINE_AS_STRING() ".runfiles/MANIFEST", {"a/b c/d"}));
EXPECT_TRUE(mf != nullptr);
string argv0(mf->Path().substr(
0, mf->Path().size() - string(".runfiles/MANIFEST").size()));
@@ -180,8 +181,8 @@
}
TEST_F(RunfilesTest, CreatesManifestBasedRunfilesFromEnvvar) {
- unique_ptr<MockFile> mf(
- MockFile::Create("foo" LINE() ".runfiles_manifest", {"a/b c/d"}));
+ unique_ptr<MockFile> mf(MockFile::Create(
+ "foo" LINE_AS_STRING() ".runfiles_manifest", {"a/b c/d"}));
EXPECT_TRUE(mf != nullptr);
string error;
@@ -197,8 +198,8 @@
}
TEST_F(RunfilesTest, CannotCreateManifestBasedRunfilesDueToBadManifest) {
- unique_ptr<MockFile> mf(
- MockFile::Create("foo" LINE() ".runfiles_manifest", {"a b", "nospace"}));
+ unique_ptr<MockFile> mf(MockFile::Create(
+ "foo" LINE_AS_STRING() ".runfiles_manifest", {"a b", "nospace"}));
EXPECT_TRUE(mf != nullptr);
string error;
@@ -210,8 +211,8 @@
}
TEST_F(RunfilesTest, ManifestBasedRunfilesRlocationAndEnvVars) {
- unique_ptr<MockFile> mf(
- MockFile::Create("foo" LINE() ".runfiles_manifest", {"a/b c/d"}));
+ unique_ptr<MockFile> mf(MockFile::Create(
+ "foo" LINE_AS_STRING() ".runfiles_manifest", {"a/b c/d"}));
EXPECT_TRUE(mf != nullptr);
string error;
@@ -242,7 +243,7 @@
TEST_F(RunfilesTest, DirectoryBasedRunfilesRlocationAndEnvVars) {
unique_ptr<MockFile> dummy(
- MockFile::Create("foo" LINE() ".runfiles/dummy", {"a/b c/d"}));
+ MockFile::Create("foo" LINE_AS_STRING() ".runfiles/dummy", {"a/b c/d"}));
EXPECT_TRUE(dummy != nullptr);
string dir = dummy->DirName();
@@ -273,8 +274,8 @@
}
TEST_F(RunfilesTest, ManifestAndDirectoryBasedRunfilesRlocationAndEnvVars) {
- unique_ptr<MockFile> mf(
- MockFile::Create("foo" LINE() ".runfiles/MANIFEST", {"a/b c/d"}));
+ unique_ptr<MockFile> mf(MockFile::Create(
+ "foo" LINE_AS_STRING() ".runfiles/MANIFEST", {"a/b c/d"}));
EXPECT_TRUE(mf != nullptr);
string dir = mf->DirName();
@@ -311,7 +312,7 @@
".txt"});
for (vector<string>::size_type i = 0; i < suffixes.size(); ++i) {
unique_ptr<MockFile> mf(
- MockFile::Create(string("foo" LINE()) + suffixes[i]));
+ MockFile::Create(string("foo" LINE_AS_STRING()) + suffixes[i]));
EXPECT_TRUE(mf != nullptr) << " (suffix=\"" << suffixes[i] << "\")";
string error;
@@ -334,7 +335,7 @@
TEST_F(RunfilesTest, CreatesDirectoryBasedRunfilesFromDirectoryNextToBinary) {
// We create a directory as a side-effect of creating a mock file.
unique_ptr<MockFile> mf(
- MockFile::Create(string("foo" LINE() ".runfiles/dummy")));
+ MockFile::Create(string("foo" LINE_AS_STRING() ".runfiles/dummy")));
string argv0(mf->Path().substr(
0, mf->Path().size() - string(".runfiles/dummy").size()));
@@ -353,7 +354,7 @@
TEST_F(RunfilesTest, CreatesDirectoryBasedRunfilesFromEnvvar) {
// We create a directory as a side-effect of creating a mock file.
unique_ptr<MockFile> mf(
- MockFile::Create(string("foo" LINE() ".runfiles/dummy")));
+ MockFile::Create(string("foo" LINE_AS_STRING() ".runfiles/dummy")));
string dir = mf->DirName();
string error;
@@ -371,7 +372,7 @@
TEST_F(RunfilesTest, FailsToCreateAnyRunfilesBecauseEnvvarsAreNotDefined) {
unique_ptr<MockFile> mf(
- MockFile::Create(string("foo" LINE() ".runfiles/MANIFEST")));
+ MockFile::Create(string("foo" LINE_AS_STRING() ".runfiles/MANIFEST")));
EXPECT_TRUE(mf != nullptr);
string error;
@@ -381,7 +382,7 @@
EXPECT_TRUE(error.empty());
// We create a directory as a side-effect of creating a mock file.
- mf.reset(MockFile::Create(string("foo" LINE() ".runfiles/dummy")));
+ mf.reset(MockFile::Create(string("foo" LINE_AS_STRING() ".runfiles/dummy")));
r.reset(Runfiles::Create("ignore-argv0", "", mf->DirName(), &error));
ASSERT_NE(r, nullptr);
EXPECT_TRUE(error.empty());
@@ -393,23 +394,43 @@
TEST_F(RunfilesTest, MockFileTest) {
{
- unique_ptr<MockFile> mf(MockFile::Create(string("foo" LINE() "/..")));
+ unique_ptr<MockFile> mf(
+ MockFile::Create(string("foo" LINE_AS_STRING() "/..")));
EXPECT_TRUE(mf == nullptr);
}
{
- unique_ptr<MockFile> mf(MockFile::Create(string("/Foo" LINE())));
+ unique_ptr<MockFile> mf(MockFile::Create(string("/Foo" LINE_AS_STRING())));
EXPECT_TRUE(mf == nullptr);
}
{
- unique_ptr<MockFile> mf(MockFile::Create(string("C:/Foo" LINE())));
+ unique_ptr<MockFile> mf(
+ MockFile::Create(string("C:/Foo" LINE_AS_STRING())));
EXPECT_TRUE(mf == nullptr);
}
string path;
{
- unique_ptr<MockFile> mf(MockFile::Create(string("foo" LINE() "/bar1/qux")));
+ unique_ptr<MockFile> mf(
+ MockFile::Create(string("foo" LINE_AS_STRING() "/bar1/qux")));
+ EXPECT_TRUE(mf != nullptr);
+ path = mf->Path();
+
+ std::ifstream stm(path);
+ EXPECT_TRUE(stm.good());
+ string actual;
+ stm >> actual;
+ EXPECT_TRUE(actual.empty());
+ }
+ {
+ std::ifstream stm(path);
+ EXPECT_FALSE(stm.good());
+ }
+
+ {
+ unique_ptr<MockFile> mf(MockFile::Create(
+ string("foo" LINE_AS_STRING() "/bar2/qux"), vector<string>()));
EXPECT_TRUE(mf != nullptr);
path = mf->Path();
@@ -426,24 +447,7 @@
{
unique_ptr<MockFile> mf(
- MockFile::Create(string("foo" LINE() "/bar2/qux"), vector<string>()));
- EXPECT_TRUE(mf != nullptr);
- path = mf->Path();
-
- std::ifstream stm(path);
- EXPECT_TRUE(stm.good());
- string actual;
- stm >> actual;
- EXPECT_TRUE(actual.empty());
- }
- {
- std::ifstream stm(path);
- EXPECT_FALSE(stm.good());
- }
-
- {
- unique_ptr<MockFile> mf(
- MockFile::Create(string("foo" LINE() "/bar3/qux"),
+ MockFile::Create(string("foo" LINE_AS_STRING() "/bar3/qux"),
{"hello world", "you are beautiful"}));
EXPECT_TRUE(mf != nullptr);
path = mf->Path();
diff --git a/tools/python/runfiles/runfiles.py b/tools/python/runfiles/runfiles.py
index e80a7d1..cdf62b6 100644
--- a/tools/python/runfiles/runfiles.py
+++ b/tools/python/runfiles/runfiles.py
@@ -13,35 +13,49 @@
# limitations under the License.
"""Runfiles lookup library for Bazel-built Python binaries and tests.
-Usage:
+USAGE:
-from bazel_tools.tools.python.runfiles import runfiles
+1. Depend on this runfiles library from your build rule:
-r = runfiles.Create()
-with open(r.Rlocation("io_bazel/foo/bar.txt"), "r") as f:
- contents = f.readlines()
+ py_binary(
+ name = "my_binary",
+ ...
+ deps = ["@bazel_tools//tools/python/runfiles"],
+ )
-The code above creates a manifest- or directory-based implementations based on
-the environment variables in os.environ. See `Create()` for more info.
+2. Import the runfiles library.
-If you want to explicitly create a manifest- or directory-based
-implementations, you can do so as follows:
+ from bazel_tools.tools.python.runfiles import runfiles
- r1 = runfiles.CreateManifestBased("path/to/foo.runfiles_manifest")
+3. Create a Runfiles object and use rlocation to look up runfile paths:
- r2 = runfiles.CreateDirectoryBased("path/to/foo.runfiles/")
+ r = runfiles.Create()
+ ...
+ with open(r.Rlocation("my_workspace/path/to/my/data.txt"), "r") as f:
+ contents = f.readlines()
+ ...
-If you want to start subprocesses that also need runfiles, you need to set the
-right environment variables for them:
+ The code above creates a manifest- or directory-based implementations based
+ on the environment variables in os.environ. See `Create()` for more info.
- import subprocess
- from bazel_tools.tools.python.runfiles import runfiles
+ If you want to explicitly create a manifest- or directory-based
+ implementations, you can do so as follows:
- r = runfiles.Create()
- env = {}
- ...
- env.update(r.EnvVars())
- p = subprocess.Popen([r.Rlocation("path/to/binary")], env, ...)
+ r1 = runfiles.CreateManifestBased("path/to/foo.runfiles_manifest")
+
+ r2 = runfiles.CreateDirectoryBased("path/to/foo.runfiles/")
+
+ If you want to start subprocesses that also need runfiles, you need to set
+ the right environment variables for them:
+
+ import subprocess
+ from bazel_tools.tools.python.runfiles import runfiles
+
+ r = runfiles.Create()
+ env = {}
+ ...
+ env.update(r.EnvVars())
+ p = subprocess.Popen([r.Rlocation("path/to/binary")], env, ...)
"""
import os