Skip to content

Commit

Permalink
runfiles,cc: merge strategies into Runfiles
Browse files Browse the repository at this point in the history
Merge the manifest- and directory-based runfiles
strategies into the Runfiles class. The resulting
Runfiles object can look up runfiles from the
manifest or from the filesystem, as needed.

Change-Id: Ifff4b76849ce67248bb9152901024e241aaea800

Closes bazelbuild#5251.

Change-Id: Ifff4b76849ce67248bb9152901024e241aaea800
PiperOrigin-RevId: 197863872
  • Loading branch information
laszlocsomor authored and Copybara-Service committed May 24, 2018
1 parent 7458a5f commit 72075bf
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 274 deletions.
128 changes: 53 additions & 75 deletions tools/cpp/runfiles/runfiles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ using std::vector;

namespace {

bool starts_with(const string& s, const string& prefix) {
if (prefix.empty()) {
bool starts_with(const string& s, const char* prefix) {
if (!prefix || !*prefix) {
return true;
}
if (s.empty()) {
Expand All @@ -54,8 +54,8 @@ bool starts_with(const string& s, const string& prefix) {
return s.find(prefix) == 0;
}

bool contains(const string& s, const string& substr) {
if (substr.empty()) {
bool contains(const string& s, const char* substr) {
if (!substr || !*substr) {
return true;
}
if (s.empty()) {
Expand All @@ -74,36 +74,6 @@ bool ends_with(const string& s, const string& suffix) {
return s.rfind(suffix) == s.size() - suffix.size();
}

class RunfilesImpl : public Runfiles {
public:
static Runfiles* Create(const string& argv0,
function<string(const string&)> env_lookup,
string* error);

string Rlocation(const string& path) const override;

const vector<pair<string, string> >& EnvVars() const override {
return envvars_;
}

protected:
RunfilesImpl(const map<string, string>&& runfiles_map,
const string&& directory,
const vector<pair<string, string> >&& envvars)
: runfiles_map_(std::move(runfiles_map)),
directory_(std::move(directory)),
envvars_(std::move(envvars)) {}
virtual ~RunfilesImpl() {}

private:
static bool ParseManifest(const string& path, map<string, string>* result,
string* error);

const map<string, string> runfiles_map_;
const string directory_;
const vector<pair<string, string> > envvars_;
};

bool IsReadableFile(const string& path) {
return std::ifstream(path).is_open();
}
Expand All @@ -119,22 +89,31 @@ bool IsDirectory(const string& path) {
#endif
}

Runfiles* RunfilesImpl::Create(const string& argv0,
function<string(const string&)> env_lookup,
string* error) {
bool PathsFrom(const std::string& argv0, std::string runfiles_manifest_file,
std::string runfiles_dir,
std::function<bool(const std::string&)> is_runfiles_manifest,
std::function<bool(const std::string&)> is_runfiles_directory,
std::string* out_manifest, std::string* out_directory);

bool ParseManifest(const string& path, map<string, string>* result,
string* error);

} // namespace

Runfiles* Runfiles::Create(const string& argv0,
const string& runfiles_manifest_file,
const string& runfiles_dir, string* error) {
string manifest, directory;
if (!Runfiles::PathsFrom(argv0, env_lookup("RUNFILES_MANIFEST_FILE"),
env_lookup("RUNFILES_DIR"),
[](const string& path) {
return (ends_with(path, "MANIFEST") ||
ends_with(path, ".runfiles_manifest")) &&
IsReadableFile(path);
},
[](const string& path) {
return ends_with(path, ".runfiles") &&
IsDirectory(path);
},
&manifest, &directory)) {
if (!PathsFrom(argv0, runfiles_manifest_file, runfiles_dir,
[](const string& path) {
return (ends_with(path, "MANIFEST") ||
ends_with(path, ".runfiles_manifest")) &&
IsReadableFile(path);
},
[](const string& path) {
return ends_with(path, ".runfiles") && IsDirectory(path);
},
&manifest, &directory)) {
if (error) {
std::ostringstream err;
err << "ERROR: " << __FILE__ << "(" << __LINE__
Expand All @@ -158,8 +137,8 @@ Runfiles* RunfilesImpl::Create(const string& argv0,
}
}

return new RunfilesImpl(std::move(runfiles), std::move(directory),
std::move(envvars));
return new Runfiles(std::move(runfiles), std::move(directory),
std::move(envvars));
}

bool IsAbsolute(const string& path) {
Expand All @@ -181,18 +160,18 @@ string GetEnv(const string& key) {
}
std::unique_ptr<char[]> value(new char[size]);
::GetEnvironmentVariableA(key.c_str(), value.get(), size);
return move(string(value.get()));
return std::move(string(value.get()));
#else
char* result = getenv(key.c_str());
return std::move((result == NULL) ? string() : string(result));
#endif
}

string RunfilesImpl::Rlocation(const string& path) const {
string Runfiles::Rlocation(const string& path) const {
if (path.empty() || starts_with(path, "../") || contains(path, "/..") ||
starts_with(path, "./") || contains(path, "/./") ||
ends_with(path, "/.") || contains(path, "//")) {
return std::move(string());
return string();
}
if (IsAbsolute(path)) {
return path;
Expand All @@ -207,8 +186,10 @@ string RunfilesImpl::Rlocation(const string& path) const {
return "";
}

bool RunfilesImpl::ParseManifest(const string& path,
map<string, string>* result, string* error) {
namespace {

bool ParseManifest(const string& path, map<string, string>* result,
string* error) {
std::ifstream stm(path);
if (!stm.is_open()) {
if (error) {
Expand Down Expand Up @@ -245,34 +226,29 @@ bool RunfilesImpl::ParseManifest(const string& path,

namespace testing {

Runfiles* TestOnly_CreateRunfiles(const std::string& argv0,
function<string(const string&)> env_lookup,
string* error) {
return RunfilesImpl::Create(argv0, env_lookup, error);
bool TestOnly_PathsFrom(const string& argv0, string mf, string dir,
function<bool(const string&)> is_runfiles_manifest,
function<bool(const string&)> is_runfiles_directory,
string* out_manifest, string* out_directory) {
return PathsFrom(argv0, mf, dir, is_runfiles_manifest, is_runfiles_directory,
out_manifest, out_directory);
}

bool TestOnly_IsAbsolute(const string& path) { return IsAbsolute(path); }

} // namespace testing

Runfiles* Runfiles::Create(const string& argv0, string* error) {
return RunfilesImpl::Create(
argv0,
[](const string& key) {
if (key == "RUNFILES_MANIFEST_FILE" || key == "RUNFILES_DIR") {
string val(GetEnv(key));
return std::move(val);
} else {
return std::move(string());
}
},
error);
return Runfiles::Create(argv0, GetEnv("RUNFILES_MANIFEST_FILE"),
GetEnv("RUNFILES_DIR"), error);
}

bool Runfiles::PathsFrom(const string& argv0, string mf, string dir,
function<bool(const string&)> is_runfiles_manifest,
function<bool(const string&)> is_runfiles_directory,
string* out_manifest, string* out_directory) {
namespace {

bool PathsFrom(const string& argv0, string mf, string dir,
function<bool(const string&)> is_runfiles_manifest,
function<bool(const string&)> is_runfiles_directory,
string* out_manifest, string* out_directory) {
out_manifest->clear();
out_directory->clear();

Expand Down Expand Up @@ -320,6 +296,8 @@ bool Runfiles::PathsFrom(const string& argv0, string mf, string dir,
return true;
}

} // namespace

} // namespace runfiles
} // namespace cpp
} // namespace tools
Expand Down
Loading

0 comments on commit 72075bf

Please sign in to comment.