Skip to content

Commit 2f24d82

Browse files
committed
Use _repo_mapping in C++ runfiles library
Work towards #16124 Closes #16701. PiperOrigin-RevId: 487806351 Change-Id: I3b04fef84d817b0875bfd71c65efe6db13468b13
1 parent a4a6b59 commit 2f24d82

File tree

4 files changed

+130
-161
lines changed

4 files changed

+130
-161
lines changed

src/test/py/bazel/bzlmod/bazel_module_test.py

+55-8
Original file line numberDiff line numberDiff line change
@@ -749,17 +749,64 @@ def testJavaRunfilesLibraryRepoMapping(self):
749749
self.ScratchFile('WORKSPACE')
750750

751751
# Run sandboxed on Linux and macOS.
752-
exit_code, stderr, stdout = self.RunBazel([
753-
'test', '@test//:test', '--test_output=errors',
754-
'--test_env=RUNFILES_LIB_DEBUG=1'
755-
],
756-
allow_failure=True)
752+
exit_code, stderr, stdout = self.RunBazel(
753+
['test', '@test//:test', '--test_output=errors'], allow_failure=True)
757754
self.AssertExitCode(exit_code, 0, stderr, stdout)
758755
# Run unsandboxed on all platforms.
756+
exit_code, stderr, stdout = self.RunBazel(['run', '@test//:test'],
757+
allow_failure=True, )
758+
self.AssertExitCode(exit_code, 0, stderr, stdout)
759+
760+
def testCppRunfilesLibraryRepoMapping(self):
761+
self.main_registry.setModuleBasePath('projects')
762+
projects_dir = self.main_registry.projects
763+
764+
self.main_registry.createLocalPathModule('data', '1.0', 'data')
765+
projects_dir.joinpath('data').mkdir(exist_ok=True)
766+
scratchFile(projects_dir.joinpath('data', 'WORKSPACE'))
767+
scratchFile(projects_dir.joinpath('data', 'foo.txt'), ['hello'])
768+
scratchFile(
769+
projects_dir.joinpath('data', 'BUILD'), ['exports_files(["foo.txt"])'])
770+
771+
self.main_registry.createLocalPathModule('test', '1.0', 'test',
772+
{'data': '1.0'})
773+
projects_dir.joinpath('test').mkdir(exist_ok=True)
774+
scratchFile(projects_dir.joinpath('test', 'WORKSPACE'))
775+
scratchFile(
776+
projects_dir.joinpath('test', 'BUILD'), [
777+
'cc_test(',
778+
' name = "test",',
779+
' srcs = ["test.cpp"],',
780+
' data = ["@data//:foo.txt"],',
781+
' args = ["$(rlocationpath @data//:foo.txt)"],',
782+
' deps = ["@bazel_tools//tools/cpp/runfiles"],',
783+
')',
784+
])
785+
scratchFile(
786+
projects_dir.joinpath('test', 'test.cpp'), [
787+
'#include <cstdlib>',
788+
'#include <fstream>',
789+
'#include "tools/cpp/runfiles/runfiles.h"',
790+
'using bazel::tools::cpp::runfiles::Runfiles;',
791+
'int main(int argc, char** argv) {',
792+
' Runfiles* runfiles = Runfiles::Create(argv[0], BAZEL_CURRENT_REPOSITORY);',
793+
' std::ifstream f1(runfiles->Rlocation(argv[1]));',
794+
' if (!f1.good()) std::exit(1);',
795+
' std::ifstream f2(runfiles->Rlocation("data/foo.txt"));',
796+
' if (!f2.good()) std::exit(2);',
797+
'}',
798+
])
799+
800+
self.ScratchFile('MODULE.bazel', ['bazel_dep(name="test",version="1.0")'])
801+
self.ScratchFile('WORKSPACE')
802+
803+
# Run sandboxed on Linux and macOS.
759804
exit_code, stderr, stdout = self.RunBazel(
760-
['run', '@test//:test'],
761-
allow_failure=True,
762-
env_add={'RUNFILES_LIB_DEBUG': '1'})
805+
['test', '@test//:test', '--test_output=errors'], allow_failure=True)
806+
self.AssertExitCode(exit_code, 0, stderr, stdout)
807+
# Run unsandboxed on all platforms.
808+
exit_code, stderr, stdout = self.RunBazel(['run', '@test//:test'],
809+
allow_failure=True)
763810
self.AssertExitCode(exit_code, 0, stderr, stdout)
764811

765812
if __name__ == '__main__':

tools/cpp/runfiles/runfiles_src.cc

+29-63
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,13 @@ bool IsDirectory(const string& path) {
9696

9797
bool PathsFrom(const std::string& argv0, std::string runfiles_manifest_file,
9898
std::string runfiles_dir, std::string* out_manifest,
99-
std::string* out_directory, std::string* out_repo_mapping);
99+
std::string* out_directory);
100100

101101
bool PathsFrom(const std::string& argv0, std::string runfiles_manifest_file,
102102
std::string runfiles_dir,
103103
std::function<bool(const std::string&)> is_runfiles_manifest,
104104
std::function<bool(const std::string&)> is_runfiles_directory,
105-
std::function<bool(const std::string&)> is_repo_mapping,
106-
std::string* out_manifest, std::string* out_directory,
107-
std::string* out_repo_mapping);
105+
std::string* out_manifest, std::string* out_directory);
108106

109107
bool ParseManifest(const string& path, map<string, string>* result,
110108
string* error);
@@ -117,9 +115,9 @@ Runfiles* Runfiles::Create(const string& argv0,
117115
const string& runfiles_manifest_file,
118116
const string& runfiles_dir,
119117
const string& source_repository, string* error) {
120-
string manifest, directory, repo_mapping;
118+
string manifest, directory;
121119
if (!PathsFrom(argv0, runfiles_manifest_file, runfiles_dir, &manifest,
122-
&directory, &repo_mapping)) {
120+
&directory)) {
123121
if (error) {
124122
std::ostringstream err;
125123
err << "ERROR: " << __FILE__ << "(" << __LINE__
@@ -144,10 +142,10 @@ Runfiles* Runfiles::Create(const string& argv0,
144142
}
145143

146144
map<pair<string, string>, string> mapping;
147-
if (!repo_mapping.empty()) {
148-
if (!ParseRepoMapping(repo_mapping, &mapping, error)) {
149-
return nullptr;
150-
}
145+
if (!ParseRepoMapping(
146+
RlocationUnchecked("_repo_mapping", runfiles, directory), &mapping,
147+
error)) {
148+
return nullptr;
151149
}
152150

153151
return new Runfiles(std::move(runfiles), std::move(directory),
@@ -196,28 +194,28 @@ string Runfiles::Rlocation(const string& path,
196194
return path;
197195
}
198196

199-
if (repo_mapping_.empty()) {
200-
return RlocationUnchecked(path);
201-
}
202197
string::size_type first_slash = path.find_first_of('/');
203198
if (first_slash == string::npos) {
204-
return RlocationUnchecked(path);
199+
return RlocationUnchecked(path, runfiles_map_, directory_);
205200
}
206201
string target_apparent = path.substr(0, first_slash);
207202
auto target =
208203
repo_mapping_.find(std::make_pair(source_repo, target_apparent));
209204
if (target == repo_mapping_.cend()) {
210-
return RlocationUnchecked(path);
205+
return RlocationUnchecked(path, runfiles_map_, directory_);
211206
}
212-
return RlocationUnchecked(target->second + path.substr(first_slash));
207+
return RlocationUnchecked(target->second + path.substr(first_slash),
208+
runfiles_map_, directory_);
213209
}
214210

215-
string Runfiles::RlocationUnchecked(const string& path) const {
216-
const auto exact_match = runfiles_map_.find(path);
217-
if (exact_match != runfiles_map_.end()) {
211+
string Runfiles::RlocationUnchecked(const string& path,
212+
const map<string, string>& runfiles_map,
213+
const string& directory) {
214+
const auto exact_match = runfiles_map.find(path);
215+
if (exact_match != runfiles_map.end()) {
218216
return exact_match->second;
219217
}
220-
if (!runfiles_map_.empty()) {
218+
if (!runfiles_map.empty()) {
221219
// If path references a runfile that lies under a directory that itself is a
222220
// runfile, then only the directory is listed in the manifest. Look up all
223221
// prefixes of path in the manifest and append the relative path from the
@@ -226,14 +224,14 @@ string Runfiles::RlocationUnchecked(const string& path) const {
226224
while ((prefix_end = path.find_last_of('/', prefix_end - 1)) !=
227225
string::npos) {
228226
const string prefix = path.substr(0, prefix_end);
229-
const auto prefix_match = runfiles_map_.find(prefix);
230-
if (prefix_match != runfiles_map_.end()) {
227+
const auto prefix_match = runfiles_map.find(prefix);
228+
if (prefix_match != runfiles_map.end()) {
231229
return prefix_match->second + "/" + path.substr(prefix_end + 1);
232230
}
233231
}
234232
}
235-
if (!directory_.empty()) {
236-
return directory_ + "/" + path;
233+
if (!directory.empty()) {
234+
return directory + "/" + path;
237235
}
238236
return "";
239237
}
@@ -279,13 +277,7 @@ bool ParseRepoMapping(const string& path,
279277
string* error) {
280278
std::ifstream stm(path);
281279
if (!stm.is_open()) {
282-
if (error) {
283-
std::ostringstream err;
284-
err << "ERROR: " << __FILE__ << "(" << __LINE__
285-
<< "): cannot open repository mapping \"" << path << "\"";
286-
*error = err.str();
287-
}
288-
return false;
280+
return true;
289281
}
290282
string line;
291283
std::getline(stm, line);
@@ -333,12 +325,9 @@ namespace testing {
333325
bool TestOnly_PathsFrom(const string& argv0, string mf, string dir,
334326
function<bool(const string&)> is_runfiles_manifest,
335327
function<bool(const string&)> is_runfiles_directory,
336-
function<bool(const string&)> is_repo_mapping,
337-
string* out_manifest, string* out_directory,
338-
string* out_repo_mapping) {
328+
string* out_manifest, string* out_directory) {
339329
return PathsFrom(argv0, mf, dir, is_runfiles_manifest, is_runfiles_directory,
340-
is_repo_mapping, out_manifest, out_directory,
341-
out_repo_mapping);
330+
out_manifest, out_directory);
342331
}
343332

344333
bool TestOnly_IsAbsolute(const string& path) { return IsAbsolute(path); }
@@ -376,23 +365,19 @@ Runfiles* Runfiles::CreateForTest(std::string* error) {
376365
namespace {
377366

378367
bool PathsFrom(const string& argv0, string mf, string dir, string* out_manifest,
379-
string* out_directory, string* out_repo_mapping) {
368+
string* out_directory) {
380369
return PathsFrom(
381370
argv0, mf, dir, [](const string& path) { return IsReadableFile(path); },
382-
[](const string& path) { return IsDirectory(path); },
383-
[](const string& path) { return IsReadableFile(path); }, out_manifest,
384-
out_directory, out_repo_mapping);
371+
[](const string& path) { return IsDirectory(path); }, out_manifest,
372+
out_directory);
385373
}
386374

387375
bool PathsFrom(const string& argv0, string mf, string dir,
388376
function<bool(const string&)> is_runfiles_manifest,
389377
function<bool(const string&)> is_runfiles_directory,
390-
function<bool(const string&)> is_repo_mapping,
391-
string* out_manifest, string* out_directory,
392-
string* out_repo_mapping) {
378+
string* out_manifest, string* out_directory) {
393379
out_manifest->clear();
394380
out_directory->clear();
395-
out_repo_mapping->clear();
396381

397382
bool mfValid = is_runfiles_manifest(mf);
398383
bool dirValid = is_runfiles_directory(dir);
@@ -428,21 +413,6 @@ bool PathsFrom(const string& argv0, string mf, string dir,
428413
dirValid = is_runfiles_directory(dir);
429414
}
430415

431-
string rm;
432-
bool rmValid = false;
433-
434-
if (dirValid && ends_with(dir, ".runfiles")) {
435-
rm = dir.substr(0, dir.size() - 9) + ".repo_mapping";
436-
rmValid = is_repo_mapping(rm);
437-
}
438-
439-
if (!rmValid && mfValid &&
440-
(ends_with(mf, ".runfiles_manifest") ||
441-
ends_with(mf, ".runfiles/MANIFEST"))) {
442-
rm = mf.substr(0, mf.size() - 18) + ".repo_mapping";
443-
rmValid = is_repo_mapping(rm);
444-
}
445-
446416
if (mfValid) {
447417
*out_manifest = mf;
448418
}
@@ -451,10 +421,6 @@ bool PathsFrom(const string& argv0, string mf, string dir,
451421
*out_directory = dir;
452422
}
453423

454-
if (rmValid) {
455-
*out_repo_mapping = rm;
456-
}
457-
458424
return true;
459425
}
460426

tools/cpp/runfiles/runfiles_src.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -206,14 +206,17 @@ class Runfiles {
206206
Runfiles& operator=(const Runfiles&) = delete;
207207
Runfiles& operator=(Runfiles&&) = delete;
208208

209+
static std::string RlocationUnchecked(
210+
const std::string& path,
211+
const std::map<std::string, std::string>& runfiles_map,
212+
const std::string& directory);
213+
209214
const std::map<std::string, std::string> runfiles_map_;
210215
const std::string directory_;
211216
const std::map<std::pair<std::string, std::string>, std::string>
212217
repo_mapping_;
213218
const std::vector<std::pair<std::string, std::string> > envvars_;
214219
const std::string source_repository_;
215-
216-
std::string RlocationUnchecked(const std::string& path) const;
217220
};
218221

219222
// The "testing" namespace contains functions that allow unit testing the code.
@@ -243,9 +246,7 @@ bool TestOnly_PathsFrom(
243246
std::string runfiles_dir,
244247
std::function<bool(const std::string&)> is_runfiles_manifest,
245248
std::function<bool(const std::string&)> is_runfiles_directory,
246-
std::function<bool(const std::string&)> is_repo_mapping,
247-
std::string* out_manifest, std::string* out_directory,
248-
std::string* out_repo_mapping);
249+
std::string* out_manifest, std::string* out_directory);
249250

250251
// For testing only.
251252
// Returns true if `path` is an absolute Unix or Windows path.

0 commit comments

Comments
 (0)