blob: f1e39709308db218d980c0e7df875e041c79e383 [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>
21#include <vector>
22
Googlerebd28a92018-02-07 08:46:31 -080023#include "src/main/cpp/rc_file.h"
Julio Merino28774852016-09-14 16:59:46 +000024#include "src/main/cpp/startup_options.h"
Thiago Farina7f9357f2015-04-23 13:57:43 +000025#include "src/main/cpp/util/exit_code.h"
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010026
27namespace blaze {
28
Julio Merinoe3e3bfa2016-12-08 22:22:12 +000029class WorkspaceLayout;
30
ccalvarin1cbe62a2017-08-14 21:09:07 +020031// Broken down structure of the command line into logical components. The raw
32// arguments should not be referenced after this structure exists. This
33// breakdown should suffice to access the parts of the command line that the
34// client cares about, notably the binary and startup startup options.
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000035struct CommandLine {
36 const std::string path_to_binary;
37 const std::vector<std::string> startup_args;
38 const std::string command;
39 const std::vector<std::string> command_args;
40
41 CommandLine(const std::string& path_to_binary_arg,
42 const std::vector<std::string>& startup_args_arg,
43 const std::string& command_arg,
44 const std::vector<std::string>& command_args_arg)
45 : path_to_binary(path_to_binary_arg),
46 startup_args(startup_args_arg),
47 command(command_arg),
48 command_args(command_args_arg) {}
49};
50
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010051// This class is responsible for parsing the command line of the Blaze binary,
52// parsing blazerc files, and putting together the command that should be sent
53// to the server.
54class OptionProcessor {
55 public:
Julio Merinoe3e3bfa2016-12-08 22:22:12 +000056 OptionProcessor(const WorkspaceLayout* workspace_layout,
57 std::unique_ptr<StartupOptions> default_startup_options);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010058
Googlerebd28a92018-02-07 08:46:31 -080059 virtual ~OptionProcessor() {}
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010060
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000061 // Splits the arguments of a command line invocation.
62 //
63 // For instance:
64 // output/bazel --foo --bar=42 --bar blah build --myflag value :mytarget
65 //
66 // returns a CommandLine structure with the following values:
67 // result.path_to_binary = "output/bazel"
68 // result.startup_args = {"--foo", "--bar=42", "--bar=blah"}
69 // result.command = "build"
ccalvarin1cbe62a2017-08-14 21:09:07 +020070 // result.command_args = {"--myflag", "value", ":mytarget"}
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000071 //
72 // Note that result.startup_args is guaranteed to contain only valid
73 // startup options (w.r.t. StartupOptions::IsUnary and
74 // StartupOptions::IsNullary) and unary startup args of the form '--bar blah'
75 // are rewritten as '--bar=blah' for uniformity.
76 // In turn, the command and command args are not rewritten nor validated.
77 //
78 // If the method fails then error will contain the cause, otherwise error
79 // remains untouched.
lpinobc28fa62017-07-13 13:52:56 +020080 virtual std::unique_ptr<CommandLine> SplitCommandLine(
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000081 const std::vector<std::string>& args,
lpinoc00ba522017-07-10 19:17:40 +020082 std::string* error) const;
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000083
ccalvarind8dfd782018-04-19 08:47:28 -070084 // Parse a command line and the appropriate blazerc files and stores the
85 // results. This should be invoked only once per OptionProcessor object.
Thiago Farina80bb0f22016-10-17 15:57:13 +000086 blaze_exit_code::ExitCode ParseOptions(const std::vector<std::string>& args,
87 const std::string& workspace,
88 const std::string& cwd,
89 std::string* error);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010090
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010091 // Get the Blaze command to be executed.
92 // Returns an empty string if no command was found on the command line.
lpinoc00ba522017-07-10 19:17:40 +020093 std::string GetCommand() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010094
95 // Gets the arguments to the command. This is put together from the default
96 // options specified in the blazerc file(s), the command line, and various
97 // bits and pieces of information about the environment the blaze binary is
98 // executed in.
lpinoc00ba522017-07-10 19:17:40 +020099 std::vector<std::string> GetCommandArguments() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100100
lpino233b72d2017-07-05 11:08:40 -0400101 // Gets the arguments explicitly provided by the user's command line.
102 std::vector<std::string> GetExplicitCommandArguments() const;
103
lpino3e36d7a2017-07-11 22:14:42 +0200104 virtual StartupOptions* GetParsedStartupOptions() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100105
ccalvarin1cbe62a2017-08-14 21:09:07 +0200106 // Prints a message about the origin of startup options. This should be called
ccalvarind8dfd782018-04-19 08:47:28 -0700107 // if the server is not started or called, in case the options are related to
108 // the failure. Otherwise, the server will handle any required logging.
ccalvarin1cbe62a2017-08-14 21:09:07 +0200109 void PrintStartupOptionsProvenanceMessage() const;
110
Googlerebd28a92018-02-07 08:46:31 -0800111 // Constructs all synthetic command args that should be passed to the
112 // server to configure blazerc options and client environment.
lpinoc00ba522017-07-10 19:17:40 +0200113 static std::vector<std::string> GetBlazercAndEnvCommandArgs(
114 const std::string& cwd,
Googlerebd28a92018-02-07 08:46:31 -0800115 const std::vector<std::unique_ptr<RcFile>>& blazercs,
116 const std::vector<std::string>& env);
lpinoc00ba522017-07-10 19:17:40 +0200117
ccalvarin5e5ee0d2018-08-23 08:56:01 -0700118 // Finds and parses the appropriate RcFiles:
119 // - system rc (unless --nosystem_rc)
120 // - workspace, %workspace%/.bazelrc (unless --noworkspace_rc, or we aren't
121 // in a workspace directory, indicated by an empty workspace parameter)
122 // - user, $HOME/.bazelrc (unless --nohome_rc)
123 // - command-line provided, if a value is passed with --bazelrc.
ccalvarind8dfd782018-04-19 08:47:28 -0700124 virtual blaze_exit_code::ExitCode GetRcFiles(
125 const WorkspaceLayout* workspace_layout, const std::string& workspace,
126 const std::string& cwd, const CommandLine* cmd_line,
127 std::vector<std::unique_ptr<RcFile>>* result_rc_files,
128 std::string* error) const;
129
ccalvarind8dfd782018-04-19 08:47:28 -0700130 private:
jmmv64553792018-04-19 12:32:59 -0700131 blaze_exit_code::ExitCode ParseStartupOptions(
132 const std::vector<std::unique_ptr<RcFile>>& rc_files,
133 std::string* error);
lpinoc00ba522017-07-10 19:17:40 +0200134
135 // An ordered list of command args that contain information about the
136 // execution environment and the flags passed via the bazelrc files.
137 std::vector<std::string> blazerc_and_env_command_args_;
138
139 // The command line constructed after calling ParseOptions.
140 std::unique_ptr<CommandLine> cmd_line_;
141
Julio Merinoe3e3bfa2016-12-08 22:22:12 +0000142 const WorkspaceLayout* workspace_layout_;
lpinoc00ba522017-07-10 19:17:40 +0200143
lpinob379f652017-04-07 12:05:09 +0000144 // The startup options parsed from args, this field is initialized by
145 // ParseOptions.
Julio Merino28774852016-09-14 16:59:46 +0000146 std::unique_ptr<StartupOptions> parsed_startup_options_;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100147};
148
ccalvarind8dfd782018-04-19 08:47:28 -0700149// Parses and returns the contents of the rc file.
150blaze_exit_code::ExitCode ParseRcFile(const WorkspaceLayout* workspace_layout,
151 const std::string& workspace,
152 const std::string& rc_file_path,
153 std::unique_ptr<RcFile>* result_rc_file,
154 std::string* error);
155
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100156} // namespace blaze
Thiago Farina2e4c2aa2015-06-12 07:18:20 +0000157
Han-Wen Nienhuys0d56b6c2015-05-12 14:52:30 +0000158#endif // BAZEL_SRC_MAIN_CPP_OPTION_PROCESSOR_H_