From e3681d1fb21efd7d0c597965c3642647649b417c Mon Sep 17 00:00:00 2001 From: Googler Date: Wed, 2 Dec 2015 22:26:59 +0000 Subject: Allow workspace-relative imports in .bazelrc RELNOTES[NEW]: .bazelrc allows workspace-relative imports as "import %workspace%/path/to/rcfile" -- MOS_MIGRATED_REVID=109237460 --- src/main/cpp/blaze_startup_options.cc | 10 ++++++++++ src/main/cpp/blaze_startup_options.h | 13 ++++++++++++- src/main/cpp/option_processor.cc | 27 ++++++++++++++++++--------- src/main/cpp/option_processor.h | 4 +++- 4 files changed, 43 insertions(+), 11 deletions(-) (limited to 'src/main') diff --git a/src/main/cpp/blaze_startup_options.cc b/src/main/cpp/blaze_startup_options.cc index efceba37dd..641d6cd026 100644 --- a/src/main/cpp/blaze_startup_options.cc +++ b/src/main/cpp/blaze_startup_options.cc @@ -173,6 +173,16 @@ void BlazeStartupOptions::WorkspaceRcFileSearchPath( candidates->push_back("tools/bazel.rc"); } +bool BlazeStartupOptions::WorkspaceRelativizeRcFilePath(const string &workspace, + string *path_fragment) { + // Strip off the "%workspace%/" prefix and prepend the true workspace path. + // In theory this could use alternate search paths for blazerc files. + path_fragment->assign( + blaze_util::JoinPath(workspace, + path_fragment->substr(WorkspacePrefixLength))); + return true; +} + string BlazeStartupOptions::SystemWideRcPath() { return "/etc/bazel.bazelrc"; } diff --git a/src/main/cpp/blaze_startup_options.h b/src/main/cpp/blaze_startup_options.h index e61af4b47d..ca52c27c87 100644 --- a/src/main/cpp/blaze_startup_options.h +++ b/src/main/cpp/blaze_startup_options.h @@ -190,9 +190,20 @@ class BlazeStartupOptions { // Returns the path for the system-wide rc file. static string SystemWideRcPath(); - // Returns the search paths for the RC file in the workspace. + // Returns the candidate pathnames for the RC file in the workspace, + // the first readable one of which will be chosen. + // It is ok if no usable candidate exists. static void WorkspaceRcFileSearchPath(std::vector* candidates); + // Turn a %workspace%-relative import into its true name in the filesystem. + // path_fragment is modified in place. + // Unlike WorkspaceRcFileSearchPath, it is an error if no import file exists. + static bool WorkspaceRelativizeRcFilePath(const string &workspace, + string *path_fragment); + + static constexpr char WorkspacePrefix[] = "%workspace%/"; + static const int WorkspacePrefixLength = sizeof WorkspacePrefix - 1; + // Returns the GetHostJavabase. This should be called after parsing // the --host_javabase option. string GetHostJavabase(); diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc index f08f4fe144..209c9a08fb 100644 --- a/src/main/cpp/option_processor.cc +++ b/src/main/cpp/option_processor.cc @@ -36,6 +36,8 @@ extern char **environ; namespace blaze { +constexpr char BlazeStartupOptions::WorkspacePrefix[]; + OptionProcessor::RcOption::RcOption(int rcfile_index, const string& option) : rcfile_index_(rcfile_index), option_(option) { } @@ -45,16 +47,19 @@ OptionProcessor::RcFile::RcFile(const string& filename, int index) } blaze_exit_code::ExitCode OptionProcessor::RcFile::Parse( + const string& workspace, vector* rcfiles, map >* rcoptions, string* error) { list initial_import_stack; initial_import_stack.push_back(filename_); return Parse( - filename_, index_, rcfiles, rcoptions, &initial_import_stack, error); + workspace, filename_, index_, rcfiles, rcoptions, &initial_import_stack, + error); } blaze_exit_code::ExitCode OptionProcessor::RcFile::Parse( + const string& workspace, const string& filename_ref, const int index, vector* rcfiles, @@ -101,13 +106,16 @@ blaze_exit_code::ExitCode OptionProcessor::RcFile::Parse( string command = words[0]; if (command == "import") { - if (words.size() != 2) { + if (words.size() != 2 + || (words[1].compare(0, BlazeStartupOptions::WorkspacePrefixLength, + BlazeStartupOptions::WorkspacePrefix) == 0 + && !BlazeStartupOptions::WorkspaceRelativizeRcFilePath( + workspace, &words[1]))) { blaze_util::StringPrintf(error, "Invalid import declaration in .blazerc file '%s': '%s'", filename.c_str(), lines[line].c_str()); return blaze_exit_code::BAD_ARGV; } - if (std::find(import_stack->begin(), import_stack->end(), words[1]) != import_stack->end()) { string loop; @@ -123,8 +131,9 @@ blaze_exit_code::ExitCode OptionProcessor::RcFile::Parse( rcfiles->push_back(new RcFile(words[1], rcfiles->size())); import_stack->push_back(words[1]); blaze_exit_code::ExitCode parse_exit_code = - RcFile::Parse(rcfiles->back()->Filename(), rcfiles->back()->Index(), - rcfiles, rcoptions, import_stack, error); + RcFile::Parse(workspace, rcfiles->back()->Filename(), + rcfiles->back()->Index(), + rcfiles, rcoptions, import_stack, error); if (parse_exit_code != blaze_exit_code::SUCCESS) { return parse_exit_code; } @@ -276,7 +285,7 @@ blaze_exit_code::ExitCode OptionProcessor::ParseOptions( if (!depot_blazerc_path.empty()) { blazercs_.push_back(new RcFile(depot_blazerc_path, blazercs_.size())); blaze_exit_code::ExitCode parse_exit_code = - blazercs_.back()->Parse(&blazercs_, &rcoptions_, error); + blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error); if (parse_exit_code != blaze_exit_code::SUCCESS) { return parse_exit_code; } @@ -286,7 +295,7 @@ blaze_exit_code::ExitCode OptionProcessor::ParseOptions( blazercs_.push_back(new RcFile(alongside_binary_blazerc, blazercs_.size())); blaze_exit_code::ExitCode parse_exit_code = - blazercs_.back()->Parse(&blazercs_, &rcoptions_, error); + blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error); if (parse_exit_code != blaze_exit_code::SUCCESS) { return parse_exit_code; } @@ -295,7 +304,7 @@ blaze_exit_code::ExitCode OptionProcessor::ParseOptions( if (!system_wide_blazerc.empty()) { blazercs_.push_back(new RcFile(system_wide_blazerc, blazercs_.size())); blaze_exit_code::ExitCode parse_exit_code = - blazercs_.back()->Parse(&blazercs_, &rcoptions_, error); + blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error); if (parse_exit_code != blaze_exit_code::SUCCESS) { return parse_exit_code; } @@ -312,7 +321,7 @@ blaze_exit_code::ExitCode OptionProcessor::ParseOptions( if (!user_blazerc_path.empty()) { blazercs_.push_back(new RcFile(user_blazerc_path, blazercs_.size())); blaze_exit_code::ExitCode parse_exit_code = - blazercs_.back()->Parse(&blazercs_, &rcoptions_, error); + blazercs_.back()->Parse(workspace, &blazercs_, &rcoptions_, error); if (parse_exit_code != blaze_exit_code::SUCCESS) { return parse_exit_code; } diff --git a/src/main/cpp/option_processor.h b/src/main/cpp/option_processor.h index 7efea67e77..0888c8e892 100644 --- a/src/main/cpp/option_processor.h +++ b/src/main/cpp/option_processor.h @@ -88,6 +88,7 @@ class OptionProcessor { public: RcFile(const string& filename, int index); blaze_exit_code::ExitCode Parse( + const string& workspace, std::vector* rcfiles, std::map >* rcoptions, string* error); @@ -95,7 +96,8 @@ class OptionProcessor { const int Index() const { return index_; } private: - static blaze_exit_code::ExitCode Parse(const string& filename, + static blaze_exit_code::ExitCode Parse(const string& workspace, + const string& filename, const int index, std::vector* rcfiles, std::map