aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/cpp
diff options
context:
space:
mode:
authorGravatar ccalvarin <ccalvarin@google.com>2018-08-02 16:49:56 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-08-02 16:51:24 -0700
commitec83598cb6ee4136166bb562a24dc5dfa58921db (patch)
treeda003f48a11b4e3e8f56c5aea2673c49f84d3407 /src/main/cpp
parent1ae4fc24164a4131ac9f177f3e91170ae4e721bc (diff)
Change the list of rc files accepted.
The old list was, in order: - %workspace%/tools/bazel.rc (unless --nomaster_bazelrc) - %binary_dir%/bazel.bazelrc (unless --nomaster_bazelrc) - system rc, /etc/bazel.bazelrc or in %ProgramData% for Windows (unless --nomaster_bazelrc) - the first of the following gets called the "user" bazelrc - path passed by flag --bazelrc - %workspace%/.bazelrc - $HOME/.bazelrc The new list is hopefully a bit more consistent, as: - system rc (unless --nosystem_rc) - workspace, %workspace%/.bazelrc (unless --noworkspace_rc) - user, $HOME/.bazelrc (unless --nohome_rc) - command-line provided, passed as --bazelrc or nothing if the flag is absent. This list removes two less than useful locations, duplication in the Workspace directory, and the rc next to the bazel binary. This location made sense at Google but is generally nonsensical elsewhere so we are removing it. It also stops the user local rc file from being overriden by passing in a custom file in --bazelrc. In both old and new, --ignore_all_rc_files disables all of the above. For a transition period, any file that you would have loaded but was not read will cause a WARNING to be printed. If you want the old file to still be read without moving its location, you can always import it into one of the new standard locations, or create a symlink. Closes #4502, except for cleanup to remove the warning after a transition period of 1 Bazel version has passed. RELNOTES[INC]: New bazelrc file list. PiperOrigin-RevId: 207189212
Diffstat (limited to 'src/main/cpp')
-rw-r--r--src/main/cpp/bazel_startup_options.cc64
-rw-r--r--src/main/cpp/bazel_startup_options.h4
-rw-r--r--src/main/cpp/option_processor-internal.h14
-rw-r--r--src/main/cpp/option_processor.cc222
-rw-r--r--src/main/cpp/option_processor.h17
5 files changed, 236 insertions, 85 deletions
diff --git a/src/main/cpp/bazel_startup_options.cc b/src/main/cpp/bazel_startup_options.cc
index 950647e55d..2ec8c8c4f5 100644
--- a/src/main/cpp/bazel_startup_options.cc
+++ b/src/main/cpp/bazel_startup_options.cc
@@ -25,8 +25,14 @@ BazelStartupOptions::BazelStartupOptions(
const WorkspaceLayout *workspace_layout)
: StartupOptions("Bazel", workspace_layout),
user_bazelrc_(""),
+ use_system_rc(true),
+ use_workspace_rc(true),
+ use_home_rc(true),
use_master_bazelrc_(true) {
+ RegisterNullaryStartupFlag("home_rc");
RegisterNullaryStartupFlag("master_bazelrc");
+ RegisterNullaryStartupFlag("system_rc");
+ RegisterNullaryStartupFlag("workspace_rc");
RegisterUnaryStartupFlag("bazelrc");
}
@@ -42,6 +48,48 @@ blaze_exit_code::ExitCode BazelStartupOptions::ProcessArgExtra(
return blaze_exit_code::BAD_ARGV;
}
user_bazelrc_ = *value;
+ } else if (GetNullaryOption(arg, "--system_rc")) {
+ if (!rcfile.empty()) {
+ *error = "Can't specify --system_rc in .bazelrc file.";
+ return blaze_exit_code::BAD_ARGV;
+ }
+ use_system_rc = true;
+ option_sources["system_rc"] = rcfile;
+ } else if (GetNullaryOption(arg, "--nosystem_rc")) {
+ if (!rcfile.empty()) {
+ *error = "Can't specify --nosystem_rc in .bazelrc file.";
+ return blaze_exit_code::BAD_ARGV;
+ }
+ use_system_rc = false;
+ option_sources["system_rc"] = rcfile;
+ } else if (GetNullaryOption(arg, "--workspace_rc")) {
+ if (!rcfile.empty()) {
+ *error = "Can't specify --workspace_rc in .bazelrc file.";
+ return blaze_exit_code::BAD_ARGV;
+ }
+ use_workspace_rc = true;
+ option_sources["workspace_rc"] = rcfile;
+ } else if (GetNullaryOption(arg, "--noworkspace_rc")) {
+ if (!rcfile.empty()) {
+ *error = "Can't specify --noworkspace_rc in .bazelrc file.";
+ return blaze_exit_code::BAD_ARGV;
+ }
+ use_workspace_rc = false;
+ option_sources["workspace_rc"] = rcfile;
+ } else if (GetNullaryOption(arg, "--home_rc")) {
+ if (!rcfile.empty()) {
+ *error = "Can't specify --home_rc in .bazelrc file.";
+ return blaze_exit_code::BAD_ARGV;
+ }
+ use_home_rc = true;
+ option_sources["home_rc"] = rcfile;
+ } else if (GetNullaryOption(arg, "--nohome_rc")) {
+ if (!rcfile.empty()) {
+ *error = "Can't specify --nohome_rc in .bazelrc file.";
+ return blaze_exit_code::BAD_ARGV;
+ }
+ use_home_rc = false;
+ option_sources["home_rc"] = rcfile;
} else if (GetNullaryOption(arg, "--master_bazelrc")) {
if (!rcfile.empty()) {
*error = "Can't specify --master_bazelrc in .bazelrc file.";
@@ -71,9 +119,19 @@ void BazelStartupOptions::MaybeLogStartupOptionWarnings() const {
BAZEL_LOG(WARNING) << "Value of --bazelrc is ignored, since "
"--ignore_all_rc_files is on.";
}
- if ((use_master_bazelrc_) &&
- option_sources.find("blazerc") != option_sources.end()) {
- BAZEL_LOG(WARNING) << "Explicit value of --master_bazelrc is "
+ if ((use_home_rc) &&
+ option_sources.find("home_rc") != option_sources.end()) {
+ BAZEL_LOG(WARNING) << "Explicit value of --home_rc is "
+ "ignored, since --ignore_all_rc_files is on.";
+ }
+ if ((use_system_rc) &&
+ option_sources.find("system_rc") != option_sources.end()) {
+ BAZEL_LOG(WARNING) << "Explicit value of --system_rc is "
+ "ignored, since --ignore_all_rc_files is on.";
+ }
+ if ((use_workspace_rc) &&
+ option_sources.find("workspace_rc") != option_sources.end()) {
+ BAZEL_LOG(WARNING) << "Explicit value of --workspace_rc is "
"ignored, since --ignore_all_rc_files is on.";
}
}
diff --git a/src/main/cpp/bazel_startup_options.h b/src/main/cpp/bazel_startup_options.h
index b27aaef613..d84cfd2d38 100644
--- a/src/main/cpp/bazel_startup_options.h
+++ b/src/main/cpp/bazel_startup_options.h
@@ -34,6 +34,10 @@ class BazelStartupOptions : public StartupOptions {
private:
std::string user_bazelrc_;
+ bool use_system_rc;
+ bool use_workspace_rc;
+ bool use_home_rc;
+ // TODO(b/36168162): Remove the master rc flag.
bool use_master_bazelrc_;
};
diff --git a/src/main/cpp/option_processor-internal.h b/src/main/cpp/option_processor-internal.h
index 47f0df4d16..c552db4e38 100644
--- a/src/main/cpp/option_processor-internal.h
+++ b/src/main/cpp/option_processor-internal.h
@@ -16,6 +16,7 @@
#define BAZEL_SRC_MAIN_CPP_OPTION_PROCESSOR_INTERNAL_H_
#include <algorithm>
+#include <set>
#include "src/main/cpp/rc_file.h"
#include "src/main/cpp/util/exit_code.h"
@@ -30,6 +31,19 @@ namespace internal {
std::vector<std::string> DedupeBlazercPaths(
const std::vector<std::string>& paths);
+// Get the legacy list of rc files that would have been loaded - this is to
+// provide a useful warning if files are being ignored that were loaded in a
+// previous version of Bazel.
+// TODO(b/3616816): Remove this once the warning is no longer useful.
+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);
+
+// Returns what the "user bazelrc" would have been in the legacy rc list.
+std::string FindLegacyUserBazelrc(const char* cmd_line_rc_file,
+ const std::string& workspace);
+
std::string FindSystemWideRc();
std::string FindRcAlongsideBinary(const std::string& cwd,
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;
}
diff --git a/src/main/cpp/option_processor.h b/src/main/cpp/option_processor.h
index 2ae1798f85..0d7277fb96 100644
--- a/src/main/cpp/option_processor.h
+++ b/src/main/cpp/option_processor.h
@@ -115,24 +115,17 @@ class OptionProcessor {
const std::vector<std::unique_ptr<RcFile>>& blazercs,
const std::vector<std::string>& env);
- // Finds and parses the appropriate RcFiles.
- // TODO(#4502) Change where the bazelrcs are read from.
+ // Finds and parses the appropriate RcFiles:
+ // - system rc (unless --nosystem_rc)
+ // - workspace, %workspace%/.bazelrc (unless --noworkspace_rc)
+ // - user, $HOME/.bazelrc (unless --nohome_rc)
+ // - command-line provided, if a value is passed with --bazelrc.
virtual blaze_exit_code::ExitCode GetRcFiles(
const WorkspaceLayout* workspace_layout, const std::string& workspace,
const std::string& cwd, const CommandLine* cmd_line,
std::vector<std::unique_ptr<RcFile>>* result_rc_files,
std::string* error) const;
- protected:
- // Return the path to the user's rc file. If cmd_line_rc_file != NULL,
- // use it, dying if it is not readable. Otherwise, return the first
- // readable file called rc_basename from [workspace, $HOME]
- //
- // If no readable .blazerc file is found, return the empty string.
- virtual blaze_exit_code::ExitCode FindUserBlazerc(
- const char* cmd_line_rc_file, const std::string& workspace,
- std::string* user_blazerc_file, std::string* error) const;
-
private:
blaze_exit_code::ExitCode ParseStartupOptions(
const std::vector<std::unique_ptr<RcFile>>& rc_files,