blob: 4692b0d59d84226a55e68ae3dd0a5868a84b7341 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Han-Wen Nienhuys0d56b6c2015-05-12 14:52:30 +000015#ifndef BAZEL_SRC_MAIN_CPP_OPTION_PROCESSOR_H_
16#define BAZEL_SRC_MAIN_CPP_OPTION_PROCESSOR_H_
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010017
18#include <list>
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010019#include <memory>
20#include <string>
Googler9cda2ec2019-03-25 14:48:26 -070021#include <utility>
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010022#include <vector>
23
Googlerebd28a92018-02-07 08:46:31 -080024#include "src/main/cpp/rc_file.h"
Julio Merino28774852016-09-14 16:59:46 +000025#include "src/main/cpp/startup_options.h"
Thiago Farina7f9357f2015-04-23 13:57:43 +000026#include "src/main/cpp/util/exit_code.h"
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010027
28namespace blaze {
29
Julio Merinoe3e3bfa2016-12-08 22:22:12 +000030class WorkspaceLayout;
31
ccalvarin1cbe62a2017-08-14 21:09:07 +020032// Broken down structure of the command line into logical components. The raw
33// arguments should not be referenced after this structure exists. This
34// breakdown should suffice to access the parts of the command line that the
35// client cares about, notably the binary and startup startup options.
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000036struct CommandLine {
Googler9cda2ec2019-03-25 14:48:26 -070037 std::string path_to_binary;
38 std::vector<std::string> startup_args;
39 std::string command;
40 std::vector<std::string> command_args;
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000041
Googler9cda2ec2019-03-25 14:48:26 -070042 CommandLine(std::string path_to_binary_arg,
43 std::vector<std::string> startup_args_arg,
44 std::string command_arg,
45 std::vector<std::string> command_args_arg)
46 : path_to_binary(std::move(path_to_binary_arg)),
47 startup_args(std::move(startup_args_arg)),
48 command(std::move(command_arg)),
49 command_args(std::move(command_args_arg)) {}
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000050};
51
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010052// This class is responsible for parsing the command line of the Blaze binary,
53// parsing blazerc files, and putting together the command that should be sent
54// to the server.
55class OptionProcessor {
56 public:
Julio Merinoe3e3bfa2016-12-08 22:22:12 +000057 OptionProcessor(const WorkspaceLayout* workspace_layout,
58 std::unique_ptr<StartupOptions> default_startup_options);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010059
Yannic Bonenberger45d52002018-09-14 16:11:36 -070060 OptionProcessor(const WorkspaceLayout* workspace_layout,
61 std::unique_ptr<StartupOptions> default_startup_options,
62 const std::string& system_bazelrc_path);
63
Googlerebd28a92018-02-07 08:46:31 -080064 virtual ~OptionProcessor() {}
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010065
michajlo371a2e32019-05-23 13:14:39 -070066 // Returns the lower-case product name associated with this options processor.
67 std::string GetLowercaseProductName() const;
68
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000069 // Splits the arguments of a command line invocation.
70 //
71 // For instance:
72 // output/bazel --foo --bar=42 --bar blah build --myflag value :mytarget
73 //
74 // returns a CommandLine structure with the following values:
75 // result.path_to_binary = "output/bazel"
76 // result.startup_args = {"--foo", "--bar=42", "--bar=blah"}
77 // result.command = "build"
ccalvarin1cbe62a2017-08-14 21:09:07 +020078 // result.command_args = {"--myflag", "value", ":mytarget"}
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000079 //
80 // Note that result.startup_args is guaranteed to contain only valid
81 // startup options (w.r.t. StartupOptions::IsUnary and
82 // StartupOptions::IsNullary) and unary startup args of the form '--bar blah'
83 // are rewritten as '--bar=blah' for uniformity.
84 // In turn, the command and command args are not rewritten nor validated.
85 //
86 // If the method fails then error will contain the cause, otherwise error
87 // remains untouched.
lpinobc28fa62017-07-13 13:52:56 +020088 virtual std::unique_ptr<CommandLine> SplitCommandLine(
Googler9cda2ec2019-03-25 14:48:26 -070089 std::vector<std::string> args, std::string* error) const;
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000090
ccalvarind8dfd782018-04-19 08:47:28 -070091 // Parse a command line and the appropriate blazerc files and stores the
92 // results. This should be invoked only once per OptionProcessor object.
Thiago Farina80bb0f22016-10-17 15:57:13 +000093 blaze_exit_code::ExitCode ParseOptions(const std::vector<std::string>& args,
94 const std::string& workspace,
95 const std::string& cwd,
96 std::string* error);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010097
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010098 // Get the Blaze command to be executed.
99 // Returns an empty string if no command was found on the command line.
lpinoc00ba522017-07-10 19:17:40 +0200100 std::string GetCommand() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100101
102 // Gets the arguments to the command. This is put together from the default
103 // options specified in the blazerc file(s), the command line, and various
104 // bits and pieces of information about the environment the blaze binary is
105 // executed in.
lpinoc00ba522017-07-10 19:17:40 +0200106 std::vector<std::string> GetCommandArguments() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100107
lpino233b72d2017-07-05 11:08:40 -0400108 // Gets the arguments explicitly provided by the user's command line.
109 std::vector<std::string> GetExplicitCommandArguments() const;
110
michajloeaf066b2019-05-15 14:12:57 -0700111 // Returns the underlying StartupOptions object with parsed values. Must
112 // only be called after ParseOptions.
lpino3e36d7a2017-07-11 22:14:42 +0200113 virtual StartupOptions* GetParsedStartupOptions() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100114
ccalvarin1cbe62a2017-08-14 21:09:07 +0200115 // Prints a message about the origin of startup options. This should be called
ccalvarind8dfd782018-04-19 08:47:28 -0700116 // if the server is not started or called, in case the options are related to
117 // the failure. Otherwise, the server will handle any required logging.
ccalvarin1cbe62a2017-08-14 21:09:07 +0200118 void PrintStartupOptionsProvenanceMessage() const;
119
Googlerebd28a92018-02-07 08:46:31 -0800120 // Constructs all synthetic command args that should be passed to the
121 // server to configure blazerc options and client environment.
lpinoc00ba522017-07-10 19:17:40 +0200122 static std::vector<std::string> GetBlazercAndEnvCommandArgs(
123 const std::string& cwd,
Googlerebd28a92018-02-07 08:46:31 -0800124 const std::vector<std::unique_ptr<RcFile>>& blazercs,
125 const std::vector<std::string>& env);
lpinoc00ba522017-07-10 19:17:40 +0200126
ccalvarin5e5ee0d2018-08-23 08:56:01 -0700127 // Finds and parses the appropriate RcFiles:
128 // - system rc (unless --nosystem_rc)
129 // - workspace, %workspace%/.bazelrc (unless --noworkspace_rc, or we aren't
130 // in a workspace directory, indicated by an empty workspace parameter)
131 // - user, $HOME/.bazelrc (unless --nohome_rc)
132 // - command-line provided, if a value is passed with --bazelrc.
ccalvarind8dfd782018-04-19 08:47:28 -0700133 virtual blaze_exit_code::ExitCode GetRcFiles(
134 const WorkspaceLayout* workspace_layout, const std::string& workspace,
135 const std::string& cwd, const CommandLine* cmd_line,
136 std::vector<std::unique_ptr<RcFile>>* result_rc_files,
137 std::string* error) const;
138
ccalvarind8dfd782018-04-19 08:47:28 -0700139 private:
jmmv64553792018-04-19 12:32:59 -0700140 blaze_exit_code::ExitCode ParseStartupOptions(
141 const std::vector<std::unique_ptr<RcFile>>& rc_files,
142 std::string* error);
lpinoc00ba522017-07-10 19:17:40 +0200143
144 // An ordered list of command args that contain information about the
145 // execution environment and the flags passed via the bazelrc files.
146 std::vector<std::string> blazerc_and_env_command_args_;
147
148 // The command line constructed after calling ParseOptions.
149 std::unique_ptr<CommandLine> cmd_line_;
150
Julio Merinoe3e3bfa2016-12-08 22:22:12 +0000151 const WorkspaceLayout* workspace_layout_;
lpinoc00ba522017-07-10 19:17:40 +0200152
michajloeaf066b2019-05-15 14:12:57 -0700153 // The StartupOptions object defining the startup options which are accepted,
154 // and, after ParseOptions has been called, their values.
155 const std::unique_ptr<StartupOptions> startup_options_;
156
157 // Whether or not ParseOptions has been called.
158 bool parse_options_called_;
Yannic Bonenberger45d52002018-09-14 16:11:36 -0700159
160 // Path to the system-wide bazelrc configuration file.
161 // This is configurable for testing purposes only.
162 const std::string system_bazelrc_path_;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100163};
164
ccalvarind8dfd782018-04-19 08:47:28 -0700165// Parses and returns the contents of the rc file.
166blaze_exit_code::ExitCode ParseRcFile(const WorkspaceLayout* workspace_layout,
167 const std::string& workspace,
168 const std::string& rc_file_path,
169 std::unique_ptr<RcFile>* result_rc_file,
170 std::string* error);
171
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100172} // namespace blaze
Thiago Farina2e4c2aa2015-06-12 07:18:20 +0000173
Han-Wen Nienhuys0d56b6c2015-05-12 14:52:30 +0000174#endif // BAZEL_SRC_MAIN_CPP_OPTION_PROCESSOR_H_