diff --git a/src/test/py/bazel/runfiles_test.py b/src/test/py/bazel/runfiles_test.py index e3f697cc554753..2c6a9c9d698db0 100644 --- a/src/test/py/bazel/runfiles_test.py +++ b/src/test/py/bazel/runfiles_test.py @@ -79,6 +79,8 @@ def testPythonRunfilesLibraryInBazelToolsRepo(self): ("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"), ]: self.CopyFile( self.Rlocation( @@ -101,15 +103,21 @@ def testPythonRunfilesLibraryInBazelToolsRepo(self): exit_code, stdout, stderr = self.RunProgram( [bin_path], env_add={"TEST_SRCDIR": "__ignore_me__"}) self.AssertExitCode(exit_code, 0, stderr) - if len(stdout) < 4: + if len(stdout) != 6: self.fail("stdout: %s" % stdout) + self.assertEqual(stdout[0], "Hello Python Foo!") six.assertRegex(self, stdout[1], "^rloc=.*/foo/datadep/hello.txt") self.assertNotIn("__ignore_me__", stdout[1]) + self.assertEqual(stdout[2], "Hello Python Bar!") six.assertRegex(self, stdout[3], "^rloc=.*/bar/bar-py-data.txt") self.assertNotIn("__ignore_me__", stdout[3]) + self.assertEqual(stdout[4], "Hello Java Bar!") + six.assertRegex(self, stdout[5], "^rloc=.*/bar/bar-java-data.txt") + self.assertNotIn("__ignore_me__", stdout[5]) + with open(stdout[1].split("=", 1)[1], "r") as f: lines = [l.strip() for l in f.readlines()] if len(lines) != 1: @@ -122,6 +130,12 @@ def testPythonRunfilesLibraryInBazelToolsRepo(self): self.fail("lines: %s" % lines) self.assertEqual(lines[0], "data for bar.py") + with open(stdout[5].split("=", 1)[1], "r") as f: + lines = [l.strip() for l in f.readlines()] + if len(lines) != 1: + self.fail("lines: %s" % lines) + self.assertEqual(lines[0], "data for Bar.java") + def testRunfilesLibrariesFindRunfilesWithoutEnvvars(self): for s, t in [ ("WORKSPACE.mock", "WORKSPACE"), diff --git a/src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock b/src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock index 618ea723b972a4..15a3a7d467b3ad 100644 --- a/src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock +++ b/src/test/py/bazel/testdata/runfiles_test/foo/BUILD.mock @@ -4,6 +4,7 @@ py_binary( data = [ "datadep/hello.txt", "//bar:bar-py", + "//bar:bar-java", ], main = "runfiles.py", deps = ["@bazel_tools//tools/runfiles:py-runfiles"], diff --git a/src/test/py/bazel/testdata/runfiles_test/foo/runfiles.py b/src/test/py/bazel/testdata/runfiles_test/foo/runfiles.py index 1be07c4e8fca69..32100447e95c55 100644 --- a/src/test/py/bazel/testdata/runfiles_test/foo/runfiles.py +++ b/src/test/py/bazel/testdata/runfiles_test/foo/runfiles.py @@ -53,18 +53,20 @@ def main(): else: env = {} env.update(r.EnvVars()) - p = subprocess.Popen( - [r.Rlocation(ChildBinaryName("py"))], - env=env, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - out, err = p.communicate() - out = SplitToLines(out) - if len(out) >= 2: - print(out[0]) # e.g. "Hello Python Bar!" - print(out[1]) # e.g. "rloc=/tmp/foo_ws/bar/bar-py-data.txt" - else: - raise Exception("ERROR: error running bar-py: %s" % SplitToLines(err)) + for lang in ["py", "java"]: + p = subprocess.Popen( + [r.Rlocation(ChildBinaryName(lang))], + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = p.communicate() + out = SplitToLines(out) + if len(out) >= 2: + print(out[0]) # e.g. "Hello Python Bar!" + print(out[1]) # e.g. "rloc=/tmp/foo_ws/bar/bar-py-data.txt" + else: + raise Exception("ERROR: error running bar-%s: %s" % (lang, + SplitToLines(err))) if __name__ == "__main__": diff --git a/src/tools/runfiles/runfiles.py b/src/tools/runfiles/runfiles.py index 8b00539a008fd3..3e062034fb3ad0 100644 --- a/src/tools/runfiles/runfiles.py +++ b/src/tools/runfiles/runfiles.py @@ -175,8 +175,23 @@ def _LoadRunfiles(path): result[tokens[0]] = tokens[1] return result + def _GetRunfilesDir(self): + if self._path.endswith("/MANIFEST") or self._path.endswith("\\MANIFEST"): + return self._path[:-len("/MANIFEST")] + elif self._path.endswith(".runfiles_manifest"): + return self._path[:-len("_manifest")] + else: + return "" + def EnvVars(self): - return {"RUNFILES_MANIFEST_FILE": self._path} + directory = self._GetRunfilesDir() + return { + "RUNFILES_MANIFEST_FILE": self._path, + "RUNFILES_DIR": directory, + # TODO(laszlocsomor): remove JAVA_RUNFILES once the Java launcher can + # pick up RUNFILES_DIR. + "JAVA_RUNFILES": directory, + } class _DirectoryBased(object): @@ -196,4 +211,9 @@ def RlocationChecked(self, path): return posixpath.join(self._runfiles_root, path) def EnvVars(self): - return {"RUNFILES_DIR": self._runfiles_root} + return { + "RUNFILES_DIR": self._runfiles_root, + # TODO(laszlocsomor): remove JAVA_RUNFILES once the Java launcher can + # pick up RUNFILES_DIR. + "JAVA_RUNFILES": self._runfiles_root, + } diff --git a/src/tools/runfiles/runfiles_test.py b/src/tools/runfiles/runfiles_test.py index eb022a675c2117..e4715568ebda47 100644 --- a/src/tools/runfiles/runfiles_test.py +++ b/src/tools/runfiles/runfiles_test.py @@ -42,7 +42,7 @@ def testRlocationArgumentValidation(self): lambda: r.Rlocation("/foo")) def testCreatesManifestBasedRunfiles(self): - with _MockFile(["a/b c/d"]) as mf: + with _MockFile(contents=["a/b c/d"]) as mf: r = runfiles.Create({ "RUNFILES_MANIFEST_FILE": mf.Path(), "RUNFILES_DIR": "ignored when RUNFILES_MANIFEST_FILE has a value", @@ -50,7 +50,46 @@ def testCreatesManifestBasedRunfiles(self): }) self.assertEqual(r.Rlocation("a/b"), "c/d") self.assertIsNone(r.Rlocation("foo")) - self.assertDictEqual(r.EnvVars(), {"RUNFILES_MANIFEST_FILE": mf.Path()}) + + def testManifestBasedRunfilesEnvVars(self): + with _MockFile(name="MANIFEST") as mf: + r = runfiles.Create({ + "RUNFILES_MANIFEST_FILE": mf.Path(), + "TEST_SRCDIR": "always ignored", + }) + self.assertDictEqual( + r.EnvVars(), { + "RUNFILES_MANIFEST_FILE": mf.Path(), + "RUNFILES_DIR": mf.Path()[:-len("/MANIFEST")], + "JAVA_RUNFILES": mf.Path()[:-len("/MANIFEST")], + }) + + with _MockFile(name="foo.runfiles_manifest") as mf: + r = runfiles.Create({ + "RUNFILES_MANIFEST_FILE": mf.Path(), + "TEST_SRCDIR": "always ignored", + }) + self.assertDictEqual( + r.EnvVars(), { + "RUNFILES_MANIFEST_FILE": + mf.Path(), + "RUNFILES_DIR": ( + mf.Path()[:-len("foo.runfiles_manifest")] + "foo.runfiles"), + "JAVA_RUNFILES": ( + mf.Path()[:-len("foo.runfiles_manifest")] + "foo.runfiles"), + }) + + with _MockFile(name="x_manifest") as mf: + r = runfiles.Create({ + "RUNFILES_MANIFEST_FILE": mf.Path(), + "TEST_SRCDIR": "always ignored", + }) + self.assertDictEqual( + r.EnvVars(), { + "RUNFILES_MANIFEST_FILE": mf.Path(), + "RUNFILES_DIR": "", + "JAVA_RUNFILES": "", + }) def testCreatesDirectoryBasedRunfiles(self): r = runfiles.Create({ @@ -59,7 +98,16 @@ def testCreatesDirectoryBasedRunfiles(self): }) self.assertEqual(r.Rlocation("a/b"), "runfiles/dir/a/b") self.assertEqual(r.Rlocation("foo"), "runfiles/dir/foo") - self.assertDictEqual(r.EnvVars(), {"RUNFILES_DIR": "runfiles/dir"}) + + def testDirectoryBasedRunfilesEnvVars(self): + r = runfiles.Create({ + "RUNFILES_DIR": "runfiles/dir", + "TEST_SRCDIR": "always ignored", + }) + self.assertDictEqual(r.EnvVars(), { + "RUNFILES_DIR": "runfiles/dir", + "JAVA_RUNFILES": "runfiles/dir", + }) def testFailsToCreateManifestBasedBecauseManifestDoesNotExist(self): @@ -69,7 +117,7 @@ def _Run(): self.assertRaisesRegexp(IOError, "non-existing path", _Run) def testFailsToCreateAnyRunfilesBecauseEnvvarsAreNotDefined(self): - with _MockFile(["a b"]) as mf: + with _MockFile(contents=["a b"]) as mf: runfiles.Create({ "RUNFILES_MANIFEST_FILE": mf.Path(), "RUNFILES_DIR": "whatever", @@ -83,7 +131,7 @@ def testFailsToCreateAnyRunfilesBecauseEnvvarsAreNotDefined(self): self.assertIsNone(runfiles.Create({"FOO": "bar"})) def testManifestBasedRlocation(self): - with _MockFile([ + with _MockFile(contents=[ "Foo/runfile1", "Foo/runfile2 C:/Actual Path\\runfile2", "Foo/Bar/runfile3 D:\\the path\\run file 3.txt" ]) as mf: @@ -93,7 +141,6 @@ def testManifestBasedRlocation(self): self.assertEqual( r.Rlocation("Foo/Bar/runfile3"), "D:\\the path\\run file 3.txt") self.assertIsNone(r.Rlocation("unknown")) - self.assertDictEqual(r.EnvVars(), {"RUNFILES_MANIFEST_FILE": mf.Path()}) def testDirectoryBasedRlocation(self): # The _DirectoryBased strategy simply joins the runfiles directory and the @@ -101,7 +148,6 @@ def testDirectoryBasedRlocation(self): # nor does it check that the path exists. r = runfiles.CreateDirectoryBased("foo/bar baz//qux/") self.assertEqual(r.Rlocation("arg"), "foo/bar baz//qux/arg") - self.assertDictEqual(r.EnvVars(), {"RUNFILES_DIR": "foo/bar baz//qux/"}) @staticmethod def IsWindows(): @@ -110,13 +156,14 @@ def IsWindows(): class _MockFile(object): - def __init__(self, contents): - self._contents = contents + def __init__(self, name=None, contents=None): + self._contents = contents or [] + self._name = name or "x" self._path = None def __enter__(self): tmpdir = os.environ.get("TEST_TMPDIR") - self._path = os.path.join(tempfile.mkdtemp(dir=tmpdir), "x") + self._path = os.path.join(tempfile.mkdtemp(dir=tmpdir), self._name) with open(self._path, "wt") as f: f.writelines(l + "\n" for l in self._contents) return self