aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/cpp/option_processor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/cpp/option_processor.cc')
-rw-r--r--src/main/cpp/option_processor.cc222
1 files changed, 152 insertions, 70 deletions
diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc
index 11da52a2cd..f4c246a9dc 100644
--- a/src/main/cpp/option_processor.cc
+++ b/src/main/cpp/option_processor.cc
@@ -13,6 +13,7 @@
// limitations under the License.
#include "src/main/cpp/option_processor.h"
+#include "src/main/cpp/option_processor-internal.h"
#include <stdio.h>
#include <stdlib.h>
@@ -45,6 +46,7 @@ using std::string;
using std::vector;
constexpr char WorkspaceLayout::WorkspacePrefix[];
+static constexpr const char* kRcBasename = ".bazelrc";
static std::vector<std::string> GetProcessedEnv();
// Path to the system-wide bazelrc configuration file.
@@ -135,51 +137,68 @@ std::unique_ptr<CommandLine> OptionProcessor::SplitCommandLine(
new CommandLine(path_to_binary, startup_args, command, command_args));
}
-blaze_exit_code::ExitCode OptionProcessor::FindUserBlazerc(
- const char* cmd_line_rc_file, const string& workspace,
- string* user_blazerc_file, string* error) const {
- const string rc_basename =
- "." + parsed_startup_options_->GetLowercaseProductName() + "rc";
+namespace internal {
+std::string FindLegacyUserBazelrc(const char* cmd_line_rc_file,
+ const std::string& workspace) {
if (cmd_line_rc_file != nullptr) {
string rcFile = blaze::AbsolutePathFromFlag(cmd_line_rc_file);
if (!blaze_util::CanReadFile(rcFile)) {
- blaze_util::StringPrintf(error,
- "Error: Unable to read %s file '%s'.", rc_basename.c_str(),
- rcFile.c_str());
- return blaze_exit_code::BAD_ARGV;
+ // The actual rc file reading will catch this - we ignore this here in the
+ // legacy version since this is just a warning. Exit eagerly though.
+ return "";
}
- *user_blazerc_file = rcFile;
- return blaze_exit_code::SUCCESS;
+ return rcFile;
}
- string workspaceRcFile = blaze_util::JoinPath(workspace, rc_basename);
+ string workspaceRcFile = blaze_util::JoinPath(workspace, kRcBasename);
if (blaze_util::CanReadFile(workspaceRcFile)) {
- *user_blazerc_file = workspaceRcFile;
- return blaze_exit_code::SUCCESS;
+ return workspaceRcFile;
}
string home = blaze::GetHomeDir();
if (!home.empty()) {
- string userRcFile = blaze_util::JoinPath(home, rc_basename);
+ string userRcFile = blaze_util::JoinPath(home, kRcBasename);
if (blaze_util::CanReadFile(userRcFile)) {
- *user_blazerc_file = userRcFile;
- return blaze_exit_code::SUCCESS;
+ return userRcFile;
}
}
-
- BAZEL_LOG(INFO) << "User provided no rc file.";
- *user_blazerc_file = "";
- return blaze_exit_code::SUCCESS;
+ return "";
}
-namespace internal {
+std::set<std::string> GetOldRcPaths(
+ const WorkspaceLayout* workspace_layout, const std::string& workspace,
+ const std::string& cwd, const std::string& path_to_binary,
+ const std::vector<std::string>& startup_args) {
+ // Find the old list of rc files that would have been loaded here, so we can
+ // provide a useful warning about old rc files that might no longer be read.
+ std::vector<std::string> candidate_bazelrc_paths;
+ if (SearchNullaryOption(startup_args, "master_bazelrc", true)) {
+ const std::string workspace_rc =
+ workspace_layout->GetWorkspaceRcPath(workspace, startup_args);
+ const std::string binary_rc =
+ internal::FindRcAlongsideBinary(cwd, path_to_binary);
+ const std::string system_rc = internal::FindSystemWideRc();
+ candidate_bazelrc_paths = {workspace_rc, binary_rc, system_rc};
+ }
+ const std::vector<std::string> deduped_blazerc_paths =
+ internal::DedupeBlazercPaths(candidate_bazelrc_paths);
+ std::set<std::string> old_rc_paths(deduped_blazerc_paths.begin(),
+ deduped_blazerc_paths.end());
+ string user_bazelrc_path = internal::FindLegacyUserBazelrc(
+ SearchUnaryOption(startup_args, "--bazelrc"), workspace);
+ if (!user_bazelrc_path.empty()) {
+ old_rc_paths.insert(user_bazelrc_path);
+ }
+ return old_rc_paths;
+}
-vector<string> DedupeBlazercPaths(const vector<string>& paths) {
- set<string> canonical_paths;
- vector<string> result;
- for (const string& path : paths) {
- const string canonical_path = blaze_util::MakeCanonical(path.c_str());
+std::vector<std::string> DedupeBlazercPaths(
+ const std::vector<std::string>& paths) {
+ std::set<std::string> canonical_paths;
+ std::vector<std::string> result;
+ for (const std::string& path : paths) {
+ const std::string canonical_path = blaze_util::MakeCanonical(path.c_str());
if (canonical_path.empty()) {
// MakeCanonical returns an empty string when it fails. We ignore this
// failure since blazerc paths may point to invalid locations.
@@ -191,26 +210,22 @@ vector<string> DedupeBlazercPaths(const vector<string>& paths) {
return result;
}
-string FindSystemWideRc() {
- // MakeAbsoluteAndResolveWindowsEnvvars will standardize the form of the
- // provided path. This also means we accept relative paths, which is
- // is convenient for testing.
- const string path = blaze_util::MakeAbsoluteAndResolveWindowsEnvvars(
- system_bazelrc_path);
+std::string FindSystemWideRc() {
+ const std::string path =
+ blaze_util::MakeAbsoluteAndResolveWindowsEnvvars(system_bazelrc_path);
if (blaze_util::CanReadFile(path)) {
return path;
}
- BAZEL_LOG(INFO) << "Looked for a system bazelrc at path '" << path
- << "', but none was found.";
return "";
}
-string FindRcAlongsideBinary(const string& cwd, const string& path_to_binary) {
- const string path = blaze_util::IsAbsolute(path_to_binary)
- ? path_to_binary
- : blaze_util::JoinPath(cwd, path_to_binary);
- const string base = blaze_util::Basename(path_to_binary);
- const string binary_blazerc_path = path + "." + base + "rc";
+std::string FindRcAlongsideBinary(const std::string& cwd,
+ const std::string& path_to_binary) {
+ const std::string path = blaze_util::IsAbsolute(path_to_binary)
+ ? path_to_binary
+ : blaze_util::JoinPath(cwd, path_to_binary);
+ const std::string base = blaze_util::Basename(path_to_binary);
+ const std::string binary_blazerc_path = path + "." + base + "rc";
if (blaze_util::CanReadFile(binary_blazerc_path)) {
return binary_blazerc_path;
}
@@ -243,41 +258,72 @@ blaze_exit_code::ExitCode OptionProcessor::GetRcFiles(
std::string* error) const {
assert(cmd_line != nullptr);
assert(result_rc_files != nullptr);
-
- // Find the master bazelrcs if requested. This list may contain duplicates.
- vector<string> candidate_bazelrc_paths;
- if (SearchNullaryOption(cmd_line->startup_args, "master_bazelrc", true)) {
- const string workspace_rc =
- workspace_layout->GetWorkspaceRcPath(workspace, cmd_line->startup_args);
- // TODO(b/36168162): Remove the alongside-binary rc file. (Part of GitHub
- // issue #4502)
- const string binary_rc =
- internal::FindRcAlongsideBinary(cwd, cmd_line->path_to_binary);
- // TODO(b/36168162): This is not the desired order, see
- // https://github.com/bazelbuild/bazel/issues/4502#issuecomment-372697374.
- const string system_rc = internal::FindSystemWideRc();
- BAZEL_LOG(INFO)
- << "Looking for master bazelrcs in the following three paths: "
- << workspace_rc << ", " << binary_rc << ", " << system_rc;
- candidate_bazelrc_paths = {workspace_rc, binary_rc, system_rc};
+ assert(!workspace.empty());
+
+ std::vector<std::string> rc_files;
+
+ // Get the system rc (unless --nosystem_rc).
+ if (SearchNullaryOption(cmd_line->startup_args, "system_rc", true)) {
+ // MakeAbsoluteAndResolveWindowsEnvvars will standardize the form of the
+ // provided path. This also means we accept relative paths, which is
+ // is convenient for testing.
+ const std::string system_rc =
+ blaze_util::MakeAbsoluteAndResolveWindowsEnvvars(system_bazelrc_path);
+ rc_files.push_back(system_rc);
}
- string user_bazelrc_path;
- blaze_exit_code::ExitCode find_bazelrc_exit_code =
- FindUserBlazerc(SearchUnaryOption(cmd_line->startup_args, "--bazelrc"),
- workspace, &user_bazelrc_path, error);
- if (find_bazelrc_exit_code != blaze_exit_code::SUCCESS) {
- return find_bazelrc_exit_code;
+ // Get the workspace rc: %workspace%/.bazelrc (unless --noworkspace_rc)
+ if (SearchNullaryOption(cmd_line->startup_args, "workspace_rc", true)) {
+ const std::string workspaceRcFile =
+ blaze_util::JoinPath(workspace, kRcBasename);
+ rc_files.push_back(workspaceRcFile);
}
- vector<string> deduped_blazerc_paths =
- internal::DedupeBlazercPaths(candidate_bazelrc_paths);
- deduped_blazerc_paths.push_back(user_bazelrc_path);
+ // Get the user rc: $HOME/.bazelrc (unless --nohome_rc)
+ if (SearchNullaryOption(cmd_line->startup_args, "home_rc", true)) {
+ const std::string home = blaze::GetHomeDir();
+ if (home.empty()) {
+ BAZEL_LOG(WARNING) << "The home directory is not defined, no home_rc "
+ "will be looked for.";
+ } else {
+ rc_files.push_back(blaze_util::JoinPath(home, kRcBasename));
+ }
+ }
- for (const auto& bazelrc_path : deduped_blazerc_paths) {
- if (bazelrc_path.empty()) {
- continue;
+ // Get the command-line provided rc, passed as --bazelrc or nothing if the
+ // flag is absent.
+ const char* cmd_line_rc_file =
+ SearchUnaryOption(cmd_line->startup_args, "--bazelrc");
+ if (cmd_line_rc_file != nullptr) {
+ string absolute_cmd_line_rc = blaze::AbsolutePathFromFlag(cmd_line_rc_file);
+ // Unlike the previous 3 paths, where we ignore it if the file does not
+ // exist or is unreadable, since this path is explicitly passed, this is an
+ // error. Check this condition here.
+ if (!blaze_util::CanReadFile(absolute_cmd_line_rc)) {
+ BAZEL_LOG(ERROR) << "Error: Unable to read .bazelrc file '"
+ << absolute_cmd_line_rc << "'.";
+ return blaze_exit_code::BAD_ARGV;
}
+ rc_files.push_back(absolute_cmd_line_rc);
+ }
+
+ // Log which files we're looking for before removing duplicates and
+ // non-existent files, so that this can serve to debug why a certain file is
+ // not being read. The final files which are read will be logged as they are
+ // parsed, and can be found using --announce_rc.
+ std::string joined_rcs;
+ blaze_util::JoinStrings(rc_files, ',', &joined_rcs);
+ BAZEL_LOG(INFO) << "Looking for the following rc files: " << joined_rcs;
+
+ // It's possible that workspace == home, that files are symlinks for each
+ // other, or that the --bazelrc flag is a duplicate. Dedupe them to minimize
+ // the likelihood of repeated options. Since bazelrcs can include one another,
+ // this isn't sufficient to prevent duplicate options, but it's good enough.
+ // This also has the effect of removing paths that don't point to real files.
+ rc_files = internal::DedupeBlazercPaths(rc_files);
+
+ // Parse these potential files, in priority order;
+ for (const auto& bazelrc_path : rc_files) {
std::unique_ptr<RcFile> parsed_rc;
blaze_exit_code::ExitCode parse_rcfile_exit_code = ParseRcFile(
workspace_layout, workspace, bazelrc_path, &parsed_rc, error);
@@ -287,6 +333,42 @@ blaze_exit_code::ExitCode OptionProcessor::GetRcFiles(
result_rc_files->push_back(std::move(parsed_rc));
}
+ // Provide a warning for any old file that might have been missed with the new
+ // expectations. This compares "canonical" paths to one another, so should not
+ // require additional transformation.
+ // TODO(b/36168162): Remove this warning along with
+ // internal::GetOldRcPaths and internal::FindLegacyUserBazelrc after
+ // the transition period has passed.
+ std::set<std::string> read_files;
+ for (auto& result_rc : *result_rc_files) {
+ const std::deque<std::string>& sources = result_rc->sources();
+ read_files.insert(sources.begin(), sources.end());
+ }
+
+ const std::set<std::string> old_files =
+ internal::GetOldRcPaths(workspace_layout, workspace, cwd,
+ cmd_line->path_to_binary, cmd_line->startup_args);
+
+ // std::vector<std::string> old_files = internal::GetOldRcPathsInOrder(
+ // workspace_layout, workspace, cwd, cmd_line->path_to_binary,
+ // cmd_line->startup_args);
+ //
+ // std::sort(old_files.begin(), old_files.end());
+ std::vector<std::string> lost_files(old_files.size());
+ std::vector<std::string>::iterator end_iter = std::set_difference(
+ old_files.begin(), old_files.end(), read_files.begin(), read_files.end(),
+ lost_files.begin());
+ lost_files.resize(end_iter - lost_files.begin());
+ if (!lost_files.empty()) {
+ std::string joined_lost_rcs;
+ blaze_util::JoinStrings(lost_files, '\n', &joined_lost_rcs);
+ BAZEL_LOG(WARNING)
+ << "The following rc files are no longer being read, please transfer "
+ "their contents or import their path into one of the standard rc "
+ "files:\n"
+ << joined_lost_rcs;
+ }
+
return blaze_exit_code::SUCCESS;
}