diff --git a/scripts/bash_completion_test.sh b/scripts/bash_completion_test.sh index 7029137a376fa6..2a7bef24e9a49b 100755 --- a/scripts/bash_completion_test.sh +++ b/scripts/bash_completion_test.sh @@ -406,9 +406,9 @@ test_basic_subcommand_expansion() { 'shutdown ' } -test_common_startup_options() { - # 'Test common startup option completion' - assert_expansion '--hos' \ +test_common_options() { + # 'Test common option completion' + assert_expansion '--h' \ '--host_jvm_' assert_expansion '--host_jvm_a' \ '--host_jvm_args=' diff --git a/site/docs/user-manual.html b/site/docs/user-manual.html index 0fbbe1924daffe..854b925bc199b3 100644 --- a/site/docs/user-manual.html +++ b/site/docs/user-manual.html @@ -135,43 +135,41 @@

Bazel allows you to specify options in a configuration file.

- -

Where are the .bazelrc files?

+

Where are .bazelrc files?

Bazel looks for an optional configuration file in the following locations, - in the order shown below. The options are interpreted in this order, so - options in later files can override a value from an earlier file if a - conflict arises. All options to control which of these files are loaded are - startup options, which means they much occur after bazel and - before the command (build, etc). + in order. It will stop searching once it has successfully found a file.

  1. - Unless the --nosystem_rc is present, Bazel looks for - the system .bazelrc file: on Unix, it lives at /etc/bazel.bazelrc, - and on Windows at %%ProgramData%%/bazel.bazelrc. - - If another system-specified location is required, this value can be - changed by setting BAZEL_SYSTEM_BAZELRC_PATH in - src/main/cpp:option_processor and using this custom Bazel binary. + The path specified by the --bazelrc=file + startup option. If specified, this option must appear before the + command name (e.g. build)
  2. - Unless the --noworkspace_rc is present, Bazel looks - for the .bazelrc file in your workspace directory. -
  3. -
  4. - Unless the --nohome_rc is present, Bazel looks for - the home, or user, bazelrc: the file .bazelrc in your home - directory. + A file named .bazelrc in your base workspace directory
  5. - An additional .rc file can be specified by the - --bazelrc=file startup option. If this - option is not present, no additional file is loaded. Unlike in the three - default locations specified above, an incorrect path or non-existent file - will fail if passed explicitly. + A file named .bazelrc in your home directory
+

+ The option --bazelrc=/dev/null effectively disables the + use of a configuration file. We strongly recommend that you use + this option when performing release builds, or automated tests that + invoke Bazel. +

+ +

+ Aside from the optional configuration file described above, Bazel also looks + for a master rc file named bazel.bazelrc next to the binary, in + the workspace at tools/bazel.rc or system-wide at + /etc/bazel.bazelrc. These files are here to support + installation-wide options or options shared between users. These files do not + override one another; if all of these files exist, all of them will be loaded. + Reading of these files can be disabled using the + --nomaster_bazelrc option. +

.bazelrc syntax and semantics

Like all UNIX "rc" files, the .bazelrc file is a text file with diff --git a/src/main/cpp/bazel_startup_options.cc b/src/main/cpp/bazel_startup_options.cc index 2ec8c8c4f57354..950647e55dac9e 100644 --- a/src/main/cpp/bazel_startup_options.cc +++ b/src/main/cpp/bazel_startup_options.cc @@ -25,14 +25,8 @@ 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"); } @@ -48,48 +42,6 @@ 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."; @@ -119,19 +71,9 @@ void BazelStartupOptions::MaybeLogStartupOptionWarnings() const { BAZEL_LOG(WARNING) << "Value of --bazelrc is ignored, since " "--ignore_all_rc_files is on."; } - 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 " + if ((use_master_bazelrc_) && + option_sources.find("blazerc") != option_sources.end()) { + BAZEL_LOG(WARNING) << "Explicit value of --master_bazelrc 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 d84cfd2d3849a4..b27aaef613845d 100644 --- a/src/main/cpp/bazel_startup_options.h +++ b/src/main/cpp/bazel_startup_options.h @@ -34,10 +34,6 @@ 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 b25db9c92996c6..47f0df4d167302 100644 --- a/src/main/cpp/option_processor-internal.h +++ b/src/main/cpp/option_processor-internal.h @@ -16,7 +16,6 @@ #define BAZEL_SRC_MAIN_CPP_OPTION_PROCESSOR_INTERNAL_H_ #include -#include #include "src/main/cpp/rc_file.h" #include "src/main/cpp/util/exit_code.h" @@ -31,24 +30,6 @@ namespace internal { std::vector DedupeBlazercPaths( const std::vector& paths); -// Given the set of already-ready files, warns if any of the newly loaded_rcs -// are duplicates. All paths are expected to be canonical. -void WarnAboutDuplicateRcFiles(const std::set& read_files, - const std::deque& loaded_rcs); - -// 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 GetOldRcPaths( - const WorkspaceLayout* workspace_layout, const std::string& workspace, - const std::string& cwd, const std::string& path_to_binary, - const std::vector& 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 07f67929664400..6f17614e69a834 100644 --- a/src/main/cpp/option_processor.cc +++ b/src/main/cpp/option_processor.cc @@ -13,7 +13,6 @@ // limitations under the License. #include "src/main/cpp/option_processor.h" -#include "src/main/cpp/option_processor-internal.h" #include #include @@ -46,7 +45,6 @@ using std::string; using std::vector; constexpr char WorkspaceLayout::WorkspacePrefix[]; -static constexpr const char* kRcBasename = ".bazelrc"; static std::vector GetProcessedEnv(); // Path to the system-wide bazelrc configuration file. @@ -137,68 +135,51 @@ std::unique_ptr OptionProcessor::SplitCommandLine( new CommandLine(path_to_binary, startup_args, command, command_args)); } -namespace internal { +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"; -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)) { - // 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 ""; + blaze_util::StringPrintf(error, + "Error: Unable to read %s file '%s'.", rc_basename.c_str(), + rcFile.c_str()); + return blaze_exit_code::BAD_ARGV; } - return rcFile; + *user_blazerc_file = rcFile; + return blaze_exit_code::SUCCESS; } - string workspaceRcFile = blaze_util::JoinPath(workspace, kRcBasename); + string workspaceRcFile = blaze_util::JoinPath(workspace, rc_basename); if (blaze_util::CanReadFile(workspaceRcFile)) { - return workspaceRcFile; + *user_blazerc_file = workspaceRcFile; + return blaze_exit_code::SUCCESS; } string home = blaze::GetHomeDir(); if (!home.empty()) { - string userRcFile = blaze_util::JoinPath(home, kRcBasename); + string userRcFile = blaze_util::JoinPath(home, rc_basename); if (blaze_util::CanReadFile(userRcFile)) { - return userRcFile; + *user_blazerc_file = userRcFile; + return blaze_exit_code::SUCCESS; } } - return ""; -} -std::set GetOldRcPaths( - const WorkspaceLayout* workspace_layout, const std::string& workspace, - const std::string& cwd, const std::string& path_to_binary, - const std::vector& 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 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 deduped_blazerc_paths = - internal::DedupeBlazercPaths(candidate_bazelrc_paths); - std::set 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; + BAZEL_LOG(INFO) << "User provided no rc file."; + *user_blazerc_file = ""; + return blaze_exit_code::SUCCESS; } -std::vector DedupeBlazercPaths( - const std::vector& paths) { - std::set canonical_paths; - std::vector result; - for (const std::string& path : paths) { - const std::string canonical_path = blaze_util::MakeCanonical(path.c_str()); +namespace internal { + +vector DedupeBlazercPaths(const vector& paths) { + set canonical_paths; + vector result; + for (const string& path : paths) { + const 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. @@ -210,22 +191,26 @@ std::vector DedupeBlazercPaths( return result; } -std::string FindSystemWideRc() { - const std::string path = - blaze_util::MakeAbsoluteAndResolveWindowsEnvvars(system_bazelrc_path); +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); if (blaze_util::CanReadFile(path)) { return path; } + BAZEL_LOG(INFO) << "Looked for a system bazelrc at path '" << path + << "', but none was found."; return ""; } -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"; +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"; if (blaze_util::CanReadFile(binary_blazerc_path)) { return binary_blazerc_path; } @@ -237,12 +222,7 @@ blaze_exit_code::ExitCode ParseErrorToExitCode(RcFile::ParseError parse_error) { case RcFile::ParseError::NONE: return blaze_exit_code::SUCCESS; case RcFile::ParseError::UNREADABLE_FILE: - // We check readability before parsing, so this is unexpected for - // top-level rc files, so is an INTERNAL_ERROR. It can happen for imported - // files, however, which should be BAD_ARGV, but we don't currently - // differentiate. - // TODO(bazel-team): fix RcFile to reclassify unreadable files that were - // read from a recursive call due to a malformed import. + // We check readability before parsing, so this is unexpected. return blaze_exit_code::INTERNAL_ERROR; case RcFile::ParseError::INVALID_FORMAT: case RcFile::ParseError::IMPORT_LOOP: @@ -252,41 +232,6 @@ blaze_exit_code::ExitCode ParseErrorToExitCode(RcFile::ParseError parse_error) { } } -void WarnAboutDuplicateRcFiles(const std::set& read_files, - const std::deque& loaded_rcs) { - // The first rc file in the queue is the top-level one, the one that would - // have imported all the others in the queue. The top-level rc is one of the - // default locations (system, workspace, home) or the explicit path passed by - // --bazelrc. - const std::string& top_level_rc = loaded_rcs.front(); - - const std::set unique_loaded_rcs(loaded_rcs.begin(), - loaded_rcs.end()); - // First check if each of the newly loaded rc files was already read. - for (const std::string& loaded_rc : unique_loaded_rcs) { - if (read_files.count(loaded_rc) > 0) { - if (loaded_rc == top_level_rc) { - BAZEL_LOG(WARNING) - << "Duplicate rc file: " << loaded_rc - << " is read multiple times, it is a standard rc file location " - "but must have been unnecessarilly imported earlier."; - } else { - BAZEL_LOG(WARNING) - << "Duplicate rc file: " << loaded_rc - << " is read multiple times, most recently imported from " - << top_level_rc; - } - } - // Now check if the top-level rc file loads up its own duplicates (it can't - // be a cycle, since that would be an error and we would have already - // exited, but it could have a diamond dependency of some sort.) - if (std::count(loaded_rcs.begin(), loaded_rcs.end(), loaded_rc) > 1) { - BAZEL_LOG(WARNING) << "Duplicate rc file: " << loaded_rc - << " is imported multiple times from " << top_level_rc; - } - } -} - } // namespace internal // TODO(#4502) Consider simplifying result_rc_files to a vector of RcFiles, no @@ -299,120 +244,49 @@ blaze_exit_code::ExitCode OptionProcessor::GetRcFiles( assert(cmd_line != nullptr); assert(result_rc_files != nullptr); - std::vector 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); + // Find the master bazelrcs if requested. This list may contain duplicates. + vector 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}; } - // Get the workspace rc: %workspace%/.bazelrc (unless --noworkspace_rc), but - // only if we are in a workspace: invoking commands like "help" from outside - // a workspace should work. - if (!workspace.empty() && - SearchNullaryOption(cmd_line->startup_args, "workspace_rc", true)) { - const std::string workspaceRcFile = - blaze_util::JoinPath(workspace, kRcBasename); - rc_files.push_back(workspaceRcFile); + 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 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)); - } - } + vector deduped_blazerc_paths = + internal::DedupeBlazercPaths(candidate_bazelrc_paths); + deduped_blazerc_paths.push_back(user_bazelrc_path); - // 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; + for (const auto& bazelrc_path : deduped_blazerc_paths) { + if (bazelrc_path.empty()) { + continue; } - 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, so we also warn if we - // discover duplicate loads later. This also has the effect of removing paths - // that don't point to real files. - rc_files = internal::DedupeBlazercPaths(rc_files); - - std::set read_files; - // Parse these potential files, in priority order; - for (const std::string& top_level_bazelrc_path : rc_files) { std::unique_ptr parsed_rc; blaze_exit_code::ExitCode parse_rcfile_exit_code = ParseRcFile( - workspace_layout, workspace, top_level_bazelrc_path, &parsed_rc, error); + workspace_layout, workspace, bazelrc_path, &parsed_rc, error); if (parse_rcfile_exit_code != blaze_exit_code::SUCCESS) { return parse_rcfile_exit_code; } - - // Check that none of the rc files loaded this time are duplicate. - const std::deque& sources = parsed_rc->sources(); - internal::WarnAboutDuplicateRcFiles(read_files, sources); - read_files.insert(sources.begin(), sources.end()); - 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. - const std::set old_files = - internal::GetOldRcPaths(workspace_layout, workspace, cwd, - cmd_line->path_to_binary, cmd_line->startup_args); - - // std::vector 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 lost_files(old_files.size()); - std::vector::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 f1e39709308db2..2ae1798f859361 100644 --- a/src/main/cpp/option_processor.h +++ b/src/main/cpp/option_processor.h @@ -115,18 +115,24 @@ class OptionProcessor { const std::vector>& blazercs, const std::vector& env); - // Finds and parses the appropriate RcFiles: - // - system rc (unless --nosystem_rc) - // - workspace, %workspace%/.bazelrc (unless --noworkspace_rc, or we aren't - // in a workspace directory, indicated by an empty workspace parameter) - // - user, $HOME/.bazelrc (unless --nohome_rc) - // - command-line provided, if a value is passed with --bazelrc. + // Finds and parses the appropriate RcFiles. + // TODO(#4502) Change where the bazelrcs are read from. virtual blaze_exit_code::ExitCode GetRcFiles( const WorkspaceLayout* workspace_layout, const std::string& workspace, const std::string& cwd, const CommandLine* cmd_line, std::vector>* 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>& rc_files, diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelStartupOptionsModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelStartupOptionsModule.java index da2f9038f65bbd..fa0d66ee5f94f1 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BazelStartupOptionsModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelStartupOptionsModule.java @@ -23,7 +23,6 @@ import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionDocumentationCategory; import com.google.devtools.common.options.OptionEffectTag; -import com.google.devtools.common.options.OptionMetadataTag; import com.google.devtools.common.options.OptionsBase; /** Provides Bazel startup flags. */ @@ -44,47 +43,17 @@ public static final class Options extends OptionsBase { + "release builds.") public String blazerc; - // TODO(b/36168162): Remove this after the transition period is ower. This now only serves to - // provide accurate warnings about which old files are being missed. @Option( name = "master_bazelrc", defaultValue = "true", // NOTE: purely decorative, rc files are read by the client. - documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, - effectTags = {OptionEffectTag.NO_OP}, - metadataTags = {OptionMetadataTag.DEPRECATED}, + documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS, + effectTags = {OptionEffectTag.CHANGES_INPUTS}, help = "If this option is false, the master bazelrcs are not read. Otherwise, Bazel looks for " + "master rcs in three locations, reading them all, in order: " + "$workspace/tools/bazel.rc, a .bazelrc file near the bazel binary, and the " + "global rc, /etc/bazel.bazelrc.") public boolean masterBlazerc; - - // For the system_rc, it can be /etc/bazel.bazelrc, or a special Windows value, or can be - // custom-set by the Bazel distributor. We don't list a known path in the help output in order - // to avoid misdocumentation here. - @Option( - name = "system_rc", - defaultValue = "true", // NOTE: purely decorative, rc files are read by the client. - documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS, - effectTags = {OptionEffectTag.CHANGES_INPUTS}, - help = "Whether or not to look for the system-wide bazelrc.") - public boolean systemRc; - - @Option( - name = "workspace_rc", - defaultValue = "true", // NOTE: purely decorative, rc files are read by the client. - documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS, - effectTags = {OptionEffectTag.CHANGES_INPUTS}, - help = "Whether or not to look for the workspace bazelrc file at $workspace/.bazelrc") - public boolean workspaceRc; - - @Option( - name = "home_rc", - defaultValue = "true", // NOTE: purely decorative, rc files are read by the client. - documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS, - effectTags = {OptionEffectTag.CHANGES_INPUTS}, - help = "Whether or not to look for the home bazelrc file at $HOME/.bazelrc") - public boolean homeRc; } @Override diff --git a/src/test/cpp/bazel_startup_options_test.cc b/src/test/cpp/bazel_startup_options_test.cc index 3e372e4a88038a..4f0e460693a7ee 100644 --- a/src/test/cpp/bazel_startup_options_test.cc +++ b/src/test/cpp/bazel_startup_options_test.cc @@ -85,13 +85,10 @@ TEST_F(BazelStartupOptionsTest, ValidStartupFlags) { ExpectIsNullaryOption(options, "deep_execroot"); ExpectIsNullaryOption(options, "experimental_oom_more_eagerly"); ExpectIsNullaryOption(options, "fatal_event_bus_exceptions"); - ExpectIsNullaryOption(options, "home_rc"); ExpectIsNullaryOption(options, "host_jvm_debug"); ExpectIsNullaryOption(options, "ignore_all_rc_files"); ExpectIsNullaryOption(options, "master_bazelrc"); - ExpectIsNullaryOption(options, "system_rc"); ExpectIsNullaryOption(options, "watchfs"); - ExpectIsNullaryOption(options, "workspace_rc"); ExpectIsNullaryOption(options, "write_command_log"); ExpectIsUnaryOption(options, "bazelrc"); ExpectIsUnaryOption(options, "command_port"); @@ -131,28 +128,28 @@ TEST_F(BazelStartupOptionsTest, IgnoredBazelrcFlagWarnsWhenAfterIgnore) { "on.\n"); } -TEST_F(BazelStartupOptionsTest, IgnoredWorkspaceRcFlagWarns) { +TEST_F(BazelStartupOptionsTest, IgnoredMasterBazelrcFlagWarns) { ParseStartupOptionsAndExpectWarning( - startup_options_.get(), {"--workspace_rc", "--ignore_all_rc_files"}, - "WARNING: Explicit value of --workspace_rc is ignored, " + startup_options_.get(), {"--master_bazelrc", "--ignore_all_rc_files"}, + "WARNING: Explicit value of --master_bazelrc is ignored, " "since --ignore_all_rc_files is on.\n"); } -TEST_F(BazelStartupOptionsTest, IgnoredWorkspaceRcFlagWarnsAfterIgnore) { +TEST_F(BazelStartupOptionsTest, IgnoredMasterBazelrcFlagWarnsAfterIgnore) { ParseStartupOptionsAndExpectWarning( - startup_options_.get(), {"--ignore_all_rc_files", "--workspace_rc"}, - "WARNING: Explicit value of --workspace_rc is ignored, " + startup_options_.get(), {"--ignore_all_rc_files", "--master_bazelrc"}, + "WARNING: Explicit value of --master_bazelrc is ignored, " "since --ignore_all_rc_files is on.\n"); } TEST_F(BazelStartupOptionsTest, MultipleIgnoredRcFlagsWarnOnceEach) { ParseStartupOptionsAndExpectWarning( startup_options_.get(), - {"--workspace_rc", "--bazelrc=somefile", "--ignore_all_rc_files", - "--bazelrc=thefinalfile", "--workspace_rc"}, + {"--master_bazelrc", "--bazelrc=somefile", "--ignore_all_rc_files", + "--bazelrc=thefinalfile", "--master_bazelrc"}, "WARNING: Value of --bazelrc is ignored, " "since --ignore_all_rc_files is on.\n" - "WARNING: Explicit value of --workspace_rc is ignored, " + "WARNING: Explicit value of --master_bazelrc is ignored, " "since --ignore_all_rc_files is on.\n"); } diff --git a/src/test/cpp/option_processor_test.cc b/src/test/cpp/option_processor_test.cc index f008d035c98ee2..6048b80b00f891 100644 --- a/src/test/cpp/option_processor_test.cc +++ b/src/test/cpp/option_processor_test.cc @@ -310,12 +310,6 @@ TEST_F(OptionProcessorTest, TestDedupePathsOmitsInvalidPath) { ASSERT_EQ(expected, internal::DedupeBlazercPaths(input)); } -TEST_F(OptionProcessorTest, TestDedupePathsOmitsEmptyPath) { - std::vector input = {""}; - std::vector expected = {}; - ASSERT_EQ(expected, internal::DedupeBlazercPaths(input)); -} - TEST_F(OptionProcessorTest, TestDedupePathsWithDifferentFiles) { std::string foo_path = blaze_util::JoinPath(workspace_, "foo"); std::string bar_path = blaze_util::JoinPath(workspace_, "bar"); diff --git a/src/test/cpp/rc_file_test.cc b/src/test/cpp/rc_file_test.cc index af7254d0deb1d2..e46d039a7aca8a 100644 --- a/src/test/cpp/rc_file_test.cc +++ b/src/test/cpp/rc_file_test.cc @@ -28,7 +28,6 @@ #include "googletest/include/gtest/gtest.h" namespace blaze { -using ::testing::ContainsRegex; using ::testing::HasSubstr; using ::testing::MatchesRegex; @@ -44,7 +43,7 @@ class RcFileTest : public ::testing::Test { protected: RcFileTest() : workspace_( - blaze_util::JoinPath(blaze::GetEnv("TEST_TMPDIR"), "workspace")), + blaze_util::JoinPath(blaze::GetEnv("TEST_TMPDIR"), "testdir")), cwd_(blaze_util::JoinPath(blaze::GetEnv("TEST_TMPDIR"), "cwd")), binary_dir_( blaze_util::JoinPath(blaze::GetEnv("TEST_TMPDIR"), "bazeldir")), @@ -105,34 +104,20 @@ class RcFileTest : public ::testing::Test { system_bazelrc_path = old_system_bazelrc_path_.c_str(); } - bool SetUpSystemRcFile(const std::string& contents, + bool SetUpGlobalRcFile(const std::string& contents, std::string* rcfile_path) const { - const std::string system_rc_path = + const std::string global_rc_path = blaze_util::ConvertPath(blaze_util::JoinPath(cwd_, "bazel.bazelrc")); - if (blaze_util::WriteFile(contents, system_rc_path, 0755)) { - *rcfile_path = system_rc_path; + if (blaze_util::WriteFile(contents, global_rc_path, 0755)) { + *rcfile_path = global_rc_path; return true; } return false; } - bool SetUpWorkspaceRcFile(const std::string& contents, - std::string* rcfile_path) const { - const std::string workspace_user_rc_path = - blaze_util::JoinPath(workspace_, ".bazelrc"); - if (blaze_util::WriteFile(contents, workspace_user_rc_path, 0755)) { - *rcfile_path = workspace_user_rc_path; - return true; - } - return false; - } - - // TODO(b/36168162): Make it possible to configure the home directory so we - // can test --home_rc as well. - - bool SetUpLegacyMasterRcFileInWorkspace(const std::string& contents, - std::string* rcfile_path) const { + bool SetUpMasterRcFileInWorkspace(const std::string& contents, + std::string* rcfile_path) const { const std::string tools_dir = blaze_util::JoinPath(workspace_, "tools"); const std::string workspace_rc_path = blaze_util::JoinPath(tools_dir, "bazel.rc"); @@ -144,8 +129,8 @@ class RcFileTest : public ::testing::Test { return false; } - bool SetUpLegacyMasterRcFileAlongsideBinary(const std::string& contents, - std::string* rcfile_path) const { + bool SetUpMasterRcFileAlongsideBinary(const std::string& contents, + std::string* rcfile_path) const { const std::string binary_rc_path = blaze_util::JoinPath(binary_dir_, "bazel.bazelrc"); if (blaze_util::WriteFile(contents, binary_rc_path, 0755)) { @@ -155,20 +140,16 @@ class RcFileTest : public ::testing::Test { return false; } - void ParseOptionsAndCheckOutput( - const std::vector& args, - const blaze_exit_code::ExitCode expected_exit_code, - const std::string& expected_error_regex, - const std::string& expected_output_regex) { - std::string error; - testing::internal::CaptureStderr(); - const blaze_exit_code::ExitCode exit_code = - option_processor_->ParseOptions(args, workspace_, cwd_, &error); - const std::string& output = testing::internal::GetCapturedStderr(); - - ASSERT_EQ(expected_exit_code, exit_code) << error; - ASSERT_THAT(error, ContainsRegex(expected_error_regex)); - ASSERT_THAT(output, ContainsRegex(expected_output_regex)); + // This file is looked for if no --bazelrc is explicitly provided. + bool SetUpUserRcFileInWorkspace(const std::string& contents, + std::string* rcfile_path) const { + const std::string workspace_user_rc_path = + blaze_util::JoinPath(workspace_, ".bazelrc"); + if (blaze_util::WriteFile(contents, workspace_user_rc_path, 0755)) { + *rcfile_path = workspace_user_rc_path; + return true; + } + return false; } const std::string workspace_; @@ -182,38 +163,16 @@ class RcFileTest : public ::testing::Test { using GetRcFileTest = RcFileTest; -TEST_F(GetRcFileTest, GetRcFilesLoadsAllDefaultBazelrcs) { - std::string system_rc; - ASSERT_TRUE(SetUpSystemRcFile("", &system_rc)); +TEST_F(GetRcFileTest, GetRcFilesLoadsAllMasterBazelrcs) { std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("", &workspace_rc)); - - const CommandLine cmd_line = CommandLine(binary_path_, {}, "build", {}); - std::string error = "check that this string is not modified"; - std::vector> parsed_rcs; - const blaze_exit_code::ExitCode exit_code = - option_processor_->GetRcFiles(workspace_layout_.get(), workspace_, cwd_, - &cmd_line, &parsed_rcs, &error); - EXPECT_EQ(blaze_exit_code::SUCCESS, exit_code); - EXPECT_EQ("check that this string is not modified", error); - - // There should be 2 rc files: the system one and the workspace one. --bazelrc - // is not passed and therefore is not relevant. - ASSERT_EQ(2, parsed_rcs.size()); - const std::deque expected_system_rc_que = {system_rc}; - const std::deque expected_workspace_rc_que = {workspace_rc}; - EXPECT_EQ(expected_system_rc_que, parsed_rcs[0].get()->sources()); - EXPECT_EQ(expected_workspace_rc_que, parsed_rcs[1].get()->sources()); -} - -TEST_F(GetRcFileTest, GetRcFilesRespectsNoSystemRc) { - std::string system_rc; - ASSERT_TRUE(SetUpSystemRcFile("", &system_rc)); - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("", &workspace_rc)); + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("", &workspace_rc)); + std::string binary_rc; + ASSERT_TRUE(SetUpMasterRcFileAlongsideBinary("", &binary_rc)); + std::string global_rc; + ASSERT_TRUE(SetUpGlobalRcFile("", &global_rc)); const CommandLine cmd_line = - CommandLine(binary_path_, {"--nosystem_rc"}, "build", {}); + CommandLine(binary_path_, {"--bazelrc=/dev/null"}, "build", {}); std::string error = "check that this string is not modified"; std::vector> parsed_rcs; const blaze_exit_code::ExitCode exit_code = @@ -222,110 +181,43 @@ TEST_F(GetRcFileTest, GetRcFilesRespectsNoSystemRc) { EXPECT_EQ(blaze_exit_code::SUCCESS, exit_code); EXPECT_EQ("check that this string is not modified", error); - ASSERT_EQ(1, parsed_rcs.size()); + // There should be 4 rc files, since "/dev/null" does count along with the 3 + // master rcs. + ASSERT_EQ(4, parsed_rcs.size()); const std::deque expected_workspace_rc_que = {workspace_rc}; + const std::deque expected_binary_rc_que = {binary_rc}; + const std::deque expected_global_rc_que = {global_rc}; + const std::deque expected_user_rc_que = {kNullDevice}; EXPECT_EQ(expected_workspace_rc_que, parsed_rcs[0].get()->sources()); + EXPECT_EQ(expected_binary_rc_que, parsed_rcs[1].get()->sources()); + EXPECT_EQ(expected_global_rc_que, parsed_rcs[2].get()->sources()); + EXPECT_EQ(expected_user_rc_que, parsed_rcs[3].get()->sources()); } -TEST_F(GetRcFileTest, GetRcFilesRespectsNoWorkspaceRc) { - std::string system_rc; - ASSERT_TRUE(SetUpSystemRcFile("", &system_rc)); - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("", &workspace_rc)); - - const CommandLine cmd_line = - CommandLine(binary_path_, {"--noworkspace_rc"}, "build", {}); - std::string error = "check that this string is not modified"; - std::vector> parsed_rcs; - const blaze_exit_code::ExitCode exit_code = - option_processor_->GetRcFiles(workspace_layout_.get(), workspace_, cwd_, - &cmd_line, &parsed_rcs, &error); - EXPECT_EQ(blaze_exit_code::SUCCESS, exit_code); - EXPECT_EQ("check that this string is not modified", error); - - ASSERT_EQ(1, parsed_rcs.size()); - const std::deque expected_system_rc_que = {system_rc}; - EXPECT_EQ(expected_system_rc_que, parsed_rcs[0].get()->sources()); -} - -TEST_F(GetRcFileTest, GetRcFilesRespectsNoWorkspaceRcAndNoSystemCombined) { - std::string system_rc; - ASSERT_TRUE(SetUpSystemRcFile("", &system_rc)); +TEST_F(GetRcFileTest, GetRcFilesRespectsNoMasterBazelrc) { std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("", &workspace_rc)); - - const CommandLine cmd_line = CommandLine( - binary_path_, {"--noworkspace_rc", "--nosystem_rc"}, "build", {}); - std::string error = "check that this string is not modified"; - std::vector> parsed_rcs; - const blaze_exit_code::ExitCode exit_code = - option_processor_->GetRcFiles(workspace_layout_.get(), workspace_, cwd_, - &cmd_line, &parsed_rcs, &error); - EXPECT_EQ(blaze_exit_code::SUCCESS, exit_code); - EXPECT_EQ("check that this string is not modified", error); - - ASSERT_EQ(0, parsed_rcs.size()); -} - -TEST_F(GetRcFileTest, GetRcFilesWarnsAboutIgnoredMasterRcFiles) { - std::string workspace_rc; - ASSERT_TRUE(SetUpLegacyMasterRcFileInWorkspace("", &workspace_rc)); - std::string binary_rc; - ASSERT_TRUE(SetUpLegacyMasterRcFileAlongsideBinary("", &binary_rc)); - - const CommandLine cmd_line = CommandLine(binary_path_, {}, "build", {}); - std::string error = "check that this string is not modified"; - std::vector> parsed_rcs; - - testing::internal::CaptureStderr(); - const blaze_exit_code::ExitCode exit_code = - option_processor_->GetRcFiles(workspace_layout_.get(), workspace_, cwd_, - &cmd_line, &parsed_rcs, &error); - const std::string& output = testing::internal::GetCapturedStderr(); - - EXPECT_EQ(blaze_exit_code::SUCCESS, exit_code); - EXPECT_EQ("check that this string is not modified", error); - - // Expect that GetRcFiles outputs a warning about these files that are not - // read as expected. - EXPECT_THAT(output, - HasSubstr("The following rc files are no longer being read")); - EXPECT_THAT(output, HasSubstr(workspace_rc)); - EXPECT_THAT(output, HasSubstr(binary_rc)); -} - -TEST_F( - GetRcFileTest, - GetRcFilesDoesNotWarnAboutIgnoredMasterRcFilesWhenNoMasterBazelrcIsPassed) { - std::string workspace_rc; - ASSERT_TRUE(SetUpLegacyMasterRcFileInWorkspace("", &workspace_rc)); + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("", &workspace_rc)); std::string binary_rc; - ASSERT_TRUE(SetUpLegacyMasterRcFileAlongsideBinary("", &binary_rc)); + ASSERT_TRUE(SetUpMasterRcFileAlongsideBinary("", &binary_rc)); + std::string global_rc; + ASSERT_TRUE(SetUpGlobalRcFile("", &global_rc)); - const CommandLine cmd_line = - CommandLine(binary_path_, {"--nomaster_bazelrc"}, "build", {}); + const CommandLine cmd_line = CommandLine( + binary_path_, {"--nomaster_bazelrc", "--bazelrc=/dev/null"}, "build", {}); std::string error = "check that this string is not modified"; std::vector> parsed_rcs; - - testing::internal::CaptureStderr(); const blaze_exit_code::ExitCode exit_code = option_processor_->GetRcFiles(workspace_layout_.get(), workspace_, cwd_, &cmd_line, &parsed_rcs, &error); - const std::string& output = testing::internal::GetCapturedStderr(); - EXPECT_EQ(blaze_exit_code::SUCCESS, exit_code); EXPECT_EQ("check that this string is not modified", error); - // Expect that nothing is logged to stderr about ignored rc files when these - // files are disabled. - EXPECT_THAT( - output, - Not(HasSubstr("The following rc files are no longer being read"))); - EXPECT_THAT(output, Not(HasSubstr(workspace_rc))); - EXPECT_THAT(output, Not(HasSubstr(binary_rc))); + // /dev/null is technically a file, but no master rcs should have been loaded. + const std::deque expected_user_rc_que = {kNullDevice}; + EXPECT_EQ(expected_user_rc_que, parsed_rcs[0].get()->sources()); } -TEST_F(GetRcFileTest, GetRcFilesReadsCommandLineRc) { +TEST_F(GetRcFileTest, GetRcFilesReadsCommandLineUserRc) { const std::string cmdline_rc_path = blaze_util::JoinPath(workspace_, "mybazelrc"); ASSERT_TRUE( @@ -350,24 +242,25 @@ TEST_F(GetRcFileTest, GetRcFilesReadsCommandLineRc) { EXPECT_THAT(parsed_rcs[0].get()->sources().front(), HasSubstr("mybazelrc")); } -TEST_F(GetRcFileTest, GetRcFilesAcceptsNullCommandLineRc) { +TEST_F(GetRcFileTest, GetRcFilesReadsUserRcInWorkspace) { + // We expect the user rc to be read when from the workspace if no alternative + // --bazelrc is provided. + std::string user_workspace_rc; + ASSERT_TRUE(SetUpUserRcFileInWorkspace("", &user_workspace_rc)); + const CommandLine cmd_line = - CommandLine(binary_path_, - {"--nosystem_rc", "--noworkspace_rc", "--nohome_rc", - "--bazelrc=/dev/null"}, - "build", {}); + CommandLine(binary_path_, {"--nomaster_bazelrc"}, "build", {}); std::string error = "check that this string is not modified"; std::vector> parsed_rcs; const blaze_exit_code::ExitCode exit_code = option_processor_->GetRcFiles(workspace_layout_.get(), workspace_, cwd_, &cmd_line, &parsed_rcs, &error); - // /dev/null is not an error EXPECT_EQ(blaze_exit_code::SUCCESS, exit_code); EXPECT_EQ("check that this string is not modified", error); - // but it does technically count as a file + + const std::deque expected_user_rc_que = {user_workspace_rc}; ASSERT_EQ(1, parsed_rcs.size()); - const std::deque expected_rc_que = {kNullDevice}; - EXPECT_EQ(expected_rc_que, parsed_rcs[0].get()->sources()); + EXPECT_EQ(expected_user_rc_que, parsed_rcs[0].get()->sources()); } using ParseOptionsTest = RcFileTest; @@ -375,15 +268,17 @@ using ParseOptionsTest = RcFileTest; TEST_F(ParseOptionsTest, IgnoreAllRcFilesIgnoresAllMasterAndUserRcFiles) { // Put fake options in different expected rc files, to check that none of them // are read. - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("startup --workspacefoo", &workspace_rc)); - std::string system_rc; - ASSERT_TRUE(SetUpSystemRcFile("startup --systemfoo", &system_rc)); - const std::string cmdline_rc_path = - blaze_util::JoinPath(workspace_, "mybazelrc"); + std::string user_workspace_rc; ASSERT_TRUE( - blaze_util::MakeDirectories(blaze_util::Dirname(cmdline_rc_path), 0755)); - ASSERT_TRUE(blaze_util::WriteFile("startup --myfoo", cmdline_rc_path, 0755)); + SetUpUserRcFileInWorkspace("startup --userfoo", &user_workspace_rc)); + std::string workspace_rc; + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("startup --workspacemasterfoo", + &workspace_rc)); + std::string binary_rc; + ASSERT_TRUE(SetUpMasterRcFileAlongsideBinary("startup --binarymasterfoo", + &binary_rc)); + std::string global_rc; + ASSERT_TRUE(SetUpGlobalRcFile("startup --globalmasterfoo", &global_rc)); const std::vector args = {binary_path_, "--ignore_all_rc_files", "build"}; @@ -402,9 +297,10 @@ TEST_F(ParseOptionsTest, IgnoreAllRcFilesIgnoresAllMasterAndUserRcFiles) { EXPECT_EQ(output, ""); } -TEST_F(ParseOptionsTest, LaterIgnoreAllRcFilesValueWins) { +TEST_F(ParseOptionsTest, LaterIgnoreRcFileValueWins) { std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("startup --workspacefoo", &workspace_rc)); + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("startup --workspacemasterfoo", + &workspace_rc)); const std::vector args = {binary_path_, "--ignore_all_rc_files", "--noignore_all_rc_files", "build"}; @@ -412,7 +308,7 @@ TEST_F(ParseOptionsTest, LaterIgnoreAllRcFilesValueWins) { EXPECT_EQ(blaze_exit_code::BAD_ARGV, option_processor_->ParseOptions(args, workspace_, cwd_, &error)); ASSERT_EQ( - "Unknown startup option: '--workspacefoo'.\n For more info, run " + "Unknown startup option: '--workspacemasterfoo'.\n For more info, run " "'bazel help startup_options'.", error); @@ -422,26 +318,28 @@ TEST_F(ParseOptionsTest, LaterIgnoreAllRcFilesValueWins) { option_processor_->PrintStartupOptionsProvenanceMessage(); const std::string& output = testing::internal::GetCapturedStderr(); - EXPECT_THAT( - output, - MatchesRegex("INFO: Reading 'startup' options from .*workspace.*bazelrc: " - "--workspacefoo\n")); + EXPECT_THAT(output, + MatchesRegex("INFO: Reading 'startup' options from .*bazel.rc: " + "--workspacemasterfoo\n")); } TEST_F(ParseOptionsTest, IgnoreAllRcFilesIgnoresCommandLineRcFileToo) { // Put fake options in different expected rc files, to check that none of them // are read. std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("startup --workspacefoo", &workspace_rc)); - std::string system_rc; - ASSERT_TRUE(SetUpSystemRcFile("startup --systemfoo", &system_rc)); - + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("startup --workspacemasterfoo", + &workspace_rc)); + std::string binary_rc; + ASSERT_TRUE(SetUpMasterRcFileAlongsideBinary("startup --binarymasterfoo", + &binary_rc)); + std::string global_rc; + ASSERT_TRUE(SetUpGlobalRcFile("startup --globalmasterfoo", &global_rc)); const std::string cmdline_rc_path = blaze_util::JoinPath(workspace_, "mybazelrc"); ASSERT_TRUE( blaze_util::MakeDirectories(blaze_util::Dirname(cmdline_rc_path), 0755)); ASSERT_TRUE( - blaze_util::WriteFile("startup --cmdlinefoo", cmdline_rc_path, 0755)); + blaze_util::WriteFile("startup --userfoo", cmdline_rc_path, 0755)); const std::vector args = {binary_path_, "--ignore_all_rc_files", "--bazelrc=" + cmdline_rc_path, @@ -492,9 +390,9 @@ TEST_F(ParseOptionsTest, CommandLineBazelrcHasUnknownOption) { "INFO: Reading 'startup' options from .*mybazelrc: --foo\n")); } -TEST_F(ParseOptionsTest, BazelrcHasUnknownOption) { +TEST_F(ParseOptionsTest, MasterBazelrcHasUnknownOption) { std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("startup --foo", &workspace_rc)); + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("startup --foo", &workspace_rc)); const std::vector args = {binary_path_, "build"}; @@ -513,16 +411,20 @@ TEST_F(ParseOptionsTest, BazelrcHasUnknownOption) { option_processor_->PrintStartupOptionsProvenanceMessage(); const std::string& output = testing::internal::GetCapturedStderr(); - EXPECT_THAT(output, MatchesRegex("INFO: Reading 'startup' options from " - ".*workspace.*bazelrc: --foo\n")); + EXPECT_THAT( + output, + MatchesRegex( + "INFO: Reading 'startup' options from .*tools.bazel.rc: --foo\n")); } TEST_F(ParseOptionsTest, - IncorrectWorkspaceBazelrcIgnoredWhenNoWorkspaceRcIsPresent) { + IncorrectMasterBazelrcIgnoredWhenNoMasterBazelrcIsPresent) { std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("startup --foo", &workspace_rc)); + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("startup --foo", &workspace_rc)); + std::string global_rc; + ASSERT_TRUE(SetUpGlobalRcFile("startup --globalfoo", &global_rc)); - const std::vector args = {binary_path_, "--noworkspace_rc", + const std::vector args = {binary_path_, "--nomaster_bazelrc", "build"}; // Expect no error due to the incorrect --foo. @@ -540,15 +442,47 @@ TEST_F(ParseOptionsTest, EXPECT_EQ(output, ""); } -TEST_F(ParseOptionsTest, PositiveOptionOverridesNegativeOption) { - std::string workspace_rc; +TEST_F(ParseOptionsTest, UserBazelrcHasPriorityOverMasterBazelrc) { + std::string user_rc; ASSERT_TRUE( - SetUpWorkspaceRcFile("startup --max_idle_secs=123", &workspace_rc)); + SetUpUserRcFileInWorkspace("startup --max_idle_secs=123", &user_rc)); + std::string workspace_rc; + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("startup --max_idle_secs=42", + &workspace_rc)); + + const std::vector args = {binary_path_, "build"}; + std::string error; + ASSERT_EQ(blaze_exit_code::SUCCESS, + option_processor_->ParseOptions(args, workspace_, cwd_, &error)) + << error; + + EXPECT_EQ(123, option_processor_->GetParsedStartupOptions()->max_idle_secs); + + // Check that the startup options' provenance message contains the correct + // information for the provided rc, and prints nothing for the master bazelrc. + testing::internal::CaptureStderr(); + option_processor_->PrintStartupOptionsProvenanceMessage(); + const std::string& output = testing::internal::GetCapturedStderr(); - const std::vector args = {"bazel", "--noworkspace_rc", - "--workspace_rc", "build"}; - ParseOptionsAndCheckOutput(args, blaze_exit_code::SUCCESS, "", ""); + const std::string expected_message = "INFO: Reading 'startup' options from " + + workspace_rc + + ": --max_idle_secs=42\n" + "INFO: Reading 'startup' options from " + + user_rc + ": --max_idle_secs=123\n"; + EXPECT_EQ(output, expected_message); +} + +TEST_F(ParseOptionsTest, MasterBazelrcOverridesNoMasterBazelrc) { + std::string workspace_rc; + ASSERT_TRUE(SetUpMasterRcFileInWorkspace("startup --max_idle_secs=123", + &workspace_rc)); + const std::vector args = {"bazel", "--nomaster_bazelrc", + "--master_bazelrc", "build"}; + std::string error; + ASSERT_EQ(blaze_exit_code::SUCCESS, + option_processor_->ParseOptions(args, workspace_, cwd_, &error)) + << error; EXPECT_EQ(123, option_processor_->GetParsedStartupOptions()->max_idle_secs); // Check that the startup options' provenance message contains the correct @@ -557,19 +491,22 @@ TEST_F(ParseOptionsTest, PositiveOptionOverridesNegativeOption) { option_processor_->PrintStartupOptionsProvenanceMessage(); const std::string& output = testing::internal::GetCapturedStderr(); - EXPECT_THAT(output, - MatchesRegex("INFO: Reading 'startup' options from " - ".*workspace.*bazelrc: --max_idle_secs=123\n")); + EXPECT_THAT(output, MatchesRegex("INFO: Reading 'startup' options from " + ".*tools.bazel.rc: --max_idle_secs=123\n")); } TEST_F(ParseOptionsTest, MultipleStartupArgsInMasterBazelrcWorksCorrectly) { // Add startup flags to the master bazelrc. - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile( - "startup --max_idle_secs=42\nstartup --io_nice_level=6", &workspace_rc)); + std::string master_rc_path; + ASSERT_TRUE(SetUpMasterRcFileInWorkspace( + "startup --max_idle_secs=42\nstartup --io_nice_level=6", + &master_rc_path)); const std::vector args = {binary_path_, "build"}; - ParseOptionsAndCheckOutput(args, blaze_exit_code::SUCCESS, "", ""); + std::string error; + ASSERT_EQ(blaze_exit_code::SUCCESS, + option_processor_->ParseOptions(args, workspace_, cwd_, &error)) + << error; EXPECT_EQ(42, option_processor_->GetParsedStartupOptions()->max_idle_secs); EXPECT_EQ(6, option_processor_->GetParsedStartupOptions()->io_nice_level); @@ -582,15 +519,16 @@ TEST_F(ParseOptionsTest, MultipleStartupArgsInMasterBazelrcWorksCorrectly) { EXPECT_THAT( output, - MatchesRegex("INFO: Reading 'startup' options from .*workspace.*bazelrc: " + MatchesRegex("INFO: Reading 'startup' options from .*tools.bazel.rc: " "--max_idle_secs=42 --io_nice_level=6\n")); } -TEST_F(ParseOptionsTest, CommandLineBazelrcHasPriorityOverDefaultBazelrc) { - // Add startup flags to the workspace bazelrc. - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile( - "startup --max_idle_secs=42\nstartup --io_nice_level=6", &workspace_rc)); +TEST_F(ParseOptionsTest, CustomBazelrcOverridesMasterBazelrc) { + // Add startup flags to the master bazelrc. + std::string master_rc_path; + ASSERT_TRUE(SetUpMasterRcFileInWorkspace( + "startup --max_idle_secs=42\nstartup --io_nice_level=6", + &master_rc_path)); // Override one of the master bazelrc's flags in the commandline rc. const std::string cmdline_rc_path = @@ -602,7 +540,10 @@ TEST_F(ParseOptionsTest, CommandLineBazelrcHasPriorityOverDefaultBazelrc) { const std::vector args = { "bazel", "--bazelrc=" + cmdline_rc_path, "build"}; - ParseOptionsAndCheckOutput(args, blaze_exit_code::SUCCESS, "", ""); + std::string error; + ASSERT_EQ(blaze_exit_code::SUCCESS, + option_processor_->ParseOptions(args, workspace_, cwd_, &error)) + << error; EXPECT_EQ(123, option_processor_->GetParsedStartupOptions()->max_idle_secs); EXPECT_EQ(6, option_processor_->GetParsedStartupOptions()->io_nice_level); @@ -615,7 +556,7 @@ TEST_F(ParseOptionsTest, CommandLineBazelrcHasPriorityOverDefaultBazelrc) { EXPECT_THAT( output, - MatchesRegex("INFO: Reading 'startup' options from .*workspace.*bazelrc: " + MatchesRegex("INFO: Reading 'startup' options from .*tools.*bazel.rc: " "--max_idle_secs=42 --io_nice_level=6\n" "INFO: Reading 'startup' options from .*mybazelrc: " "--max_idle_secs=123\n")); @@ -632,14 +573,17 @@ TEST_F(ParseOptionsTest, BazelRcImportsMaintainsFlagOrdering) { imported_rc_path, 0755)); // Add startup flags the imported bazelrc. - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("startup --max_idle_secs=42\nimport " + - imported_rc_path + - "\nstartup --io_nice_level=6", - &workspace_rc)); + std::string master_rc_path; + ASSERT_TRUE(SetUpMasterRcFileInWorkspace( + "startup --max_idle_secs=42\nimport " + imported_rc_path + + "\nstartup --io_nice_level=6", + &master_rc_path)); const std::vector args = {"bazel", "build"}; - ParseOptionsAndCheckOutput(args, blaze_exit_code::SUCCESS, "", ""); + std::string error; + ASSERT_EQ(blaze_exit_code::SUCCESS, + option_processor_->ParseOptions(args, workspace_, cwd_, &error)) + << error; EXPECT_EQ(123, option_processor_->GetParsedStartupOptions()->max_idle_secs); EXPECT_EQ(6, option_processor_->GetParsedStartupOptions()->io_nice_level); @@ -652,144 +596,12 @@ TEST_F(ParseOptionsTest, BazelRcImportsMaintainsFlagOrdering) { EXPECT_THAT( output, - MatchesRegex("INFO: Reading 'startup' options from .*workspace.*bazelrc: " + MatchesRegex("INFO: Reading 'startup' options from .*tools.*bazel.rc: " "--max_idle_secs=42\n" "INFO: Reading 'startup' options from .*myimportedbazelrc: " "--max_idle_secs=123 --io_nice_level=4\n" - "INFO: Reading 'startup' options from .*workspace.*bazelrc: " + "INFO: Reading 'startup' options from .*tools.*bazel.rc: " "--io_nice_level=6\n")); } -TEST_F(ParseOptionsTest, BazelRcImportFailsForMissingFile) { - const std::string missing_imported_rc_path = - blaze_util::JoinPath(workspace_, "myimportedbazelrc"); - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("import " + missing_imported_rc_path, - &workspace_rc)); - - const std::vector args = {"bazel", "build"}; - ParseOptionsAndCheckOutput( - args, blaze_exit_code::INTERNAL_ERROR, - "Unexpected error reading .blazerc file '.*myimportedbazelrc'", ""); -} - -TEST_F(ParseOptionsTest, DoubleImportsCauseAWarning) { - const std::string imported_rc_path = - blaze_util::JoinPath(workspace_, "myimportedbazelrc"); - ASSERT_TRUE( - blaze_util::MakeDirectories(blaze_util::Dirname(imported_rc_path), 0755)); - ASSERT_TRUE(blaze_util::WriteFile("", imported_rc_path, 0755)); - - // Import the custom location twice. - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile( - "import " + imported_rc_path + "\n" - "import " + imported_rc_path + "\n", - &workspace_rc)); - - const std::vector args = {"bazel", "build"}; - ParseOptionsAndCheckOutput( - args, blaze_exit_code::SUCCESS, "", - "WARNING: Duplicate rc file: .*myimportedbazelrc is imported multiple " - "times from .*workspace.*bazelrc\n"); -} - -TEST_F(ParseOptionsTest, DeepDoubleImportCausesAWarning) { - const std::string dual_imported_rc_path = - blaze_util::JoinPath(workspace_, "dual_imported.bazelrc"); - ASSERT_TRUE(blaze_util::MakeDirectories( - blaze_util::Dirname(dual_imported_rc_path), 0755)); - ASSERT_TRUE(blaze_util::WriteFile("", dual_imported_rc_path, 0755)); - - const std::string intermediate_import_1 = - blaze_util::JoinPath(workspace_, "intermediate_import_1"); - ASSERT_TRUE(blaze_util::MakeDirectories( - blaze_util::Dirname(intermediate_import_1), 0755)); - ASSERT_TRUE(blaze_util::WriteFile("import " + dual_imported_rc_path, - intermediate_import_1, 0755)); - - const std::string intermediate_import_2 = - blaze_util::JoinPath(workspace_, "intermediate_import_2"); - ASSERT_TRUE(blaze_util::MakeDirectories( - blaze_util::Dirname(intermediate_import_2), 0755)); - ASSERT_TRUE(blaze_util::WriteFile("import " + dual_imported_rc_path, - intermediate_import_2, 0755)); - - // Import the custom location twice. - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile( - "import " + intermediate_import_1 + "\n" - "import " + intermediate_import_2 + "\n", - &workspace_rc)); - - const std::vector args = {"bazel", "build"}; - ParseOptionsAndCheckOutput(args, blaze_exit_code::SUCCESS, "", - "WARNING: Duplicate rc file: " - ".*dual_imported.bazelrc is imported multiple " - "times from .*workspace.*bazelrc\n"); -} - -// TODO(b/112908763): C:/ and c:\\ paths don't compare well, making this fail on -// Windows. Adding all the conversions necessary to get around this is probably -// not the right approach either, so leaving this coverage out for Windows. We -// should not be using string equality for path comparisons, but have a path -// type which handles these differences for the correct platform. Fix this and -// enable this test. -#if !defined(_WIN32) && !defined(__CYGWIN__) -TEST_F(ParseOptionsTest, ImportingAFileAndPassingItInCausesAWarning) { - const std::string imported_rc_path = - blaze_util::JoinPath(workspace_, "myimportedbazelrc"); - ASSERT_TRUE( - blaze_util::MakeDirectories(blaze_util::Dirname(imported_rc_path), 0755)); - ASSERT_TRUE(blaze_util::WriteFile("", imported_rc_path, 0755)); - - // Import the custom location, and pass it in by flag. - std::string workspace_rc; - ASSERT_TRUE( - SetUpWorkspaceRcFile("import " + imported_rc_path, &workspace_rc)); - - const std::vector args = { - "bazel", "--bazelrc=" + imported_rc_path, "build"}; - ParseOptionsAndCheckOutput( - args, blaze_exit_code::SUCCESS, "", - "WARNING: Duplicate rc file: .*myimportedbazelrc is read multiple times, " - "it is a standard rc file location but must have been unnecessarilly " - "imported earlier.\n"); -} - -TEST_F(ParseOptionsTest, ImportingAPreviouslyLoadedStandardRcCausesAWarning) { - std::string system_rc; - ASSERT_TRUE(SetUpSystemRcFile("", &system_rc)); - - // Import the system_rc extraneously. - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("import " + system_rc, &workspace_rc)); - - const std::vector args = {"bazel", "build"}; - std::string output; - - ParseOptionsAndCheckOutput( - args, blaze_exit_code::SUCCESS, "", - "WARNING: Duplicate rc file: .*bazel.bazelrc is read multiple " - "times, most recently imported from .*workspace.*bazelrc\n"); -} -#endif // !defined(_WIN32) && !defined(__CYGWIN__) - -TEST_F(ParseOptionsTest, ImportingStandardRcBeforeItIsLoadedCausesAWarning) { - std::string workspace_rc; - ASSERT_TRUE(SetUpWorkspaceRcFile("", &workspace_rc)); - - // Import the workspace_rc extraneously. - std::string system_rc; - ASSERT_TRUE(SetUpSystemRcFile("import " + workspace_rc, &system_rc)); - - const std::vector args = {"bazel", "build"}; - std::string output; - ParseOptionsAndCheckOutput( - args, blaze_exit_code::SUCCESS, "", - "WARNING: Duplicate rc file: .*workspace.*bazelrc is read multiple " - "times, it is a standard rc file location but must have been " - "unnecessarilly imported earlier.\n"); -} - } // namespace blaze diff --git a/src/test/java/com/google/devtools/build/lib/packages/BazelDocumentationTest.java b/src/test/java/com/google/devtools/build/lib/packages/BazelDocumentationTest.java index 8d3f7b3dfc95c7..79d4eea62b35d8 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/BazelDocumentationTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/BazelDocumentationTest.java @@ -16,7 +16,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.common.collect.ImmutableSet; import com.google.common.io.Files; import com.google.devtools.build.lib.bazel.Bazel; import com.google.devtools.build.lib.bazel.rules.BazelRuleClassProvider; @@ -47,7 +46,6 @@ public void testBazelUserManual() throws Exception { DocumentationTestUtil.validateUserManual( Bazel.BAZEL_MODULES, BazelRuleClassProvider.create(), - Files.asCharSource(documentationFile, UTF_8).read(), - ImmutableSet.of()); + Files.asCharSource(documentationFile, UTF_8).read()); } } diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/DocumentationTestUtil.java b/src/test/java/com/google/devtools/build/lib/packages/util/DocumentationTestUtil.java index fafefe98a01e3f..ca5ecb32b0980d 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/util/DocumentationTestUtil.java +++ b/src/test/java/com/google/devtools/build/lib/packages/util/DocumentationTestUtil.java @@ -57,8 +57,7 @@ private DocumentationTestUtil() {} public static void validateUserManual( List> modules, ConfiguredRuleClassProvider ruleClassProvider, - String documentationSource, - Set extraValidOptions) + String documentationSource) throws Exception { // if there is a class missing, one can find it using // find . -name "*.java" -exec grep -Hn "@Option(name = " {} \; | grep "xxx" @@ -72,7 +71,9 @@ public static void validateUserManual( BlazeCommandUtils.getStartupOptions(blazeModules)) { validOptions.addAll(Options.getDefaults(optionsClass).asMap().keySet()); } - validOptions.addAll(extraValidOptions); + // --bazelrc and --master_bazelrc are aliases for blaze equivalents. Add these explicitly. + validOptions.add("bazelrc"); + validOptions.add("master_bazelrc"); // collect all command options ServerBuilder serverBuilder = new ServerBuilder(); diff --git a/src/test/shell/integration/bazel_command_log_test.sh b/src/test/shell/integration/bazel_command_log_test.sh index 63796016315f47..8094e65a197914 100755 --- a/src/test/shell/integration/bazel_command_log_test.sh +++ b/src/test/shell/integration/bazel_command_log_test.sh @@ -44,7 +44,6 @@ function strip_lines_from_bazel_cc() { -e '/server needs to be killed, because the startup options are different/d' \ -e '/^WARNING: Waiting for server process to terminate (waited 5 seconds, waiting at most 60)$/d' \ -e '/^WARNING: The startup option --host_javabase is deprecated; prefer --server_javabase.$/d' \ - -e '/^WARNING: The home directory is not defined, no home_rc will be looked for.$/d' \ $TEST_log) echo "$clean_log" > $TEST_log