blob: bfe2070f7f71fe703a46366368488ce586401849 [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
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000066 // Splits the arguments of a command line invocation.
67 //
68 // For instance:
69 // output/bazel --foo --bar=42 --bar blah build --myflag value :mytarget
70 //
71 // returns a CommandLine structure with the following values:
72 // result.path_to_binary = "output/bazel"
73 // result.startup_args = {"--foo", "--bar=42", "--bar=blah"}
74 // result.command = "build"
ccalvarin1cbe62a2017-08-14 21:09:07 +020075 // result.command_args = {"--myflag", "value", ":mytarget"}
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000076 //
77 // Note that result.startup_args is guaranteed to contain only valid
78 // startup options (w.r.t. StartupOptions::IsUnary and
79 // StartupOptions::IsNullary) and unary startup args of the form '--bar blah'
80 // are rewritten as '--bar=blah' for uniformity.
81 // In turn, the command and command args are not rewritten nor validated.
82 //
83 // If the method fails then error will contain the cause, otherwise error
84 // remains untouched.
lpinobc28fa62017-07-13 13:52:56 +020085 virtual std::unique_ptr<CommandLine> SplitCommandLine(
Googler9cda2ec2019-03-25 14:48:26 -070086 std::vector<std::string> args, std::string* error) const;
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000087
ccalvarind8dfd782018-04-19 08:47:28 -070088 // Parse a command line and the appropriate blazerc files and stores the
89 // results. This should be invoked only once per OptionProcessor object.
Thiago Farina80bb0f22016-10-17 15:57:13 +000090 blaze_exit_code::ExitCode ParseOptions(const std::vector<std::string>& args,
91 const std::string& workspace,
92 const std::string& cwd,
93 std::string* error);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010094
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010095 // Get the Blaze command to be executed.
96 // Returns an empty string if no command was found on the command line.
lpinoc00ba522017-07-10 19:17:40 +020097 std::string GetCommand() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010098
99 // Gets the arguments to the command. This is put together from the default
100 // options specified in the blazerc file(s), the command line, and various
101 // bits and pieces of information about the environment the blaze binary is
102 // executed in.
lpinoc00ba522017-07-10 19:17:40 +0200103 std::vector<std::string> GetCommandArguments() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100104
lpino233b72d2017-07-05 11:08:40 -0400105 // Gets the arguments explicitly provided by the user's command line.
106 std::vector<std::string> GetExplicitCommandArguments() const;
107
michajloeaf066b2019-05-15 14:12:57 -0700108 // Returns the underlying StartupOptions object with parsed values. Must
109 // only be called after ParseOptions.
lpino3e36d7a2017-07-11 22:14:42 +0200110 virtual StartupOptions* GetParsedStartupOptions() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100111
ccalvarin1cbe62a2017-08-14 21:09:07 +0200112 // Prints a message about the origin of startup options. This should be called
ccalvarind8dfd782018-04-19 08:47:28 -0700113 // if the server is not started or called, in case the options are related to
114 // the failure. Otherwise, the server will handle any required logging.
ccalvarin1cbe62a2017-08-14 21:09:07 +0200115 void PrintStartupOptionsProvenanceMessage() const;
116
Googlerebd28a92018-02-07 08:46:31 -0800117 // Constructs all synthetic command args that should be passed to the
118 // server to configure blazerc options and client environment.
lpinoc00ba522017-07-10 19:17:40 +0200119 static std::vector<std::string> GetBlazercAndEnvCommandArgs(
120 const std::string& cwd,
Googlerebd28a92018-02-07 08:46:31 -0800121 const std::vector<std::unique_ptr<RcFile>>& blazercs,
122 const std::vector<std::string>& env);
lpinoc00ba522017-07-10 19:17:40 +0200123
ccalvarin5e5ee0d2018-08-23 08:56:01 -0700124 // Finds and parses the appropriate RcFiles:
125 // - system rc (unless --nosystem_rc)
126 // - workspace, %workspace%/.bazelrc (unless --noworkspace_rc, or we aren't
127 // in a workspace directory, indicated by an empty workspace parameter)
128 // - user, $HOME/.bazelrc (unless --nohome_rc)
129 // - command-line provided, if a value is passed with --bazelrc.
ccalvarind8dfd782018-04-19 08:47:28 -0700130 virtual blaze_exit_code::ExitCode GetRcFiles(
131 const WorkspaceLayout* workspace_layout, const std::string& workspace,
132 const std::string& cwd, const CommandLine* cmd_line,
133 std::vector<std::unique_ptr<RcFile>>* result_rc_files,
134 std::string* error) const;
135
ccalvarind8dfd782018-04-19 08:47:28 -0700136 private:
jmmv64553792018-04-19 12:32:59 -0700137 blaze_exit_code::ExitCode ParseStartupOptions(
138 const std::vector<std::unique_ptr<RcFile>>& rc_files,
139 std::string* error);
lpinoc00ba522017-07-10 19:17:40 +0200140
141 // An ordered list of command args that contain information about the
142 // execution environment and the flags passed via the bazelrc files.
143 std::vector<std::string> blazerc_and_env_command_args_;
144
145 // The command line constructed after calling ParseOptions.
146 std::unique_ptr<CommandLine> cmd_line_;
147
Julio Merinoe3e3bfa2016-12-08 22:22:12 +0000148 const WorkspaceLayout* workspace_layout_;
lpinoc00ba522017-07-10 19:17:40 +0200149
michajloeaf066b2019-05-15 14:12:57 -0700150 // The StartupOptions object defining the startup options which are accepted,
151 // and, after ParseOptions has been called, their values.
152 const std::unique_ptr<StartupOptions> startup_options_;
153
154 // Whether or not ParseOptions has been called.
155 bool parse_options_called_;
Yannic Bonenberger45d52002018-09-14 16:11:36 -0700156
157 // Path to the system-wide bazelrc configuration file.
158 // This is configurable for testing purposes only.
159 const std::string system_bazelrc_path_;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100160};
161
ccalvarind8dfd782018-04-19 08:47:28 -0700162// Parses and returns the contents of the rc file.
163blaze_exit_code::ExitCode ParseRcFile(const WorkspaceLayout* workspace_layout,
164 const std::string& workspace,
165 const std::string& rc_file_path,
166 std::unique_ptr<RcFile>* result_rc_file,
167 std::string* error);
168
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100169} // namespace blaze
Thiago Farina2e4c2aa2015-06-12 07:18:20 +0000170
Han-Wen Nienhuys0d56b6c2015-05-12 14:52:30 +0000171#endif // BAZEL_SRC_MAIN_CPP_OPTION_PROCESSOR_H_