blob: 1281e77ed7ae96b21d32b8a8cac264ea78771906 [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>
19#include <map>
20#include <memory>
21#include <string>
22#include <vector>
23
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
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000029struct CommandLine {
30 const std::string path_to_binary;
31 const std::vector<std::string> startup_args;
32 const std::string command;
33 const std::vector<std::string> command_args;
34
35 CommandLine(const std::string& path_to_binary_arg,
36 const std::vector<std::string>& startup_args_arg,
37 const std::string& command_arg,
38 const std::vector<std::string>& command_args_arg)
39 : path_to_binary(path_to_binary_arg),
40 startup_args(startup_args_arg),
41 command(command_arg),
42 command_args(command_args_arg) {}
43};
44
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010045// This class is responsible for parsing the command line of the Blaze binary,
46// parsing blazerc files, and putting together the command that should be sent
47// to the server.
48class OptionProcessor {
49 public:
Julio Merino28774852016-09-14 16:59:46 +000050 OptionProcessor(std::unique_ptr<StartupOptions> default_startup_options);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010051
Han-Wen Nienhuys255cf092015-05-22 14:38:59 +000052 virtual ~OptionProcessor();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010053
Luis Fernando Pino Duque0311fc52016-11-21 13:20:50 +000054 // Splits the arguments of a command line invocation.
55 //
56 // For instance:
57 // output/bazel --foo --bar=42 --bar blah build --myflag value :mytarget
58 //
59 // returns a CommandLine structure with the following values:
60 // result.path_to_binary = "output/bazel"
61 // result.startup_args = {"--foo", "--bar=42", "--bar=blah"}
62 // result.command = "build"
63 // result.command_args = {"--some_flag", "value", ":mytarget"}
64 //
65 // Note that result.startup_args is guaranteed to contain only valid
66 // startup options (w.r.t. StartupOptions::IsUnary and
67 // StartupOptions::IsNullary) and unary startup args of the form '--bar blah'
68 // are rewritten as '--bar=blah' for uniformity.
69 // In turn, the command and command args are not rewritten nor validated.
70 //
71 // If the method fails then error will contain the cause, otherwise error
72 // remains untouched.
73 std::unique_ptr<CommandLine> SplitCommandLine(
74 const std::vector<std::string>& args,
75 std::string* error);
76
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010077 // Parse a command line and the appropriate blazerc files. This should be
78 // invoked only once per OptionProcessor object.
Thiago Farina80bb0f22016-10-17 15:57:13 +000079 blaze_exit_code::ExitCode ParseOptions(const std::vector<std::string>& args,
80 const std::string& workspace,
81 const std::string& cwd,
82 std::string* error);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010083
84 blaze_exit_code::ExitCode ParseOptions(int argc, const char* argv[],
Thiago Farina80bb0f22016-10-17 15:57:13 +000085 const std::string& workspace,
86 const std::string& cwd,
87 std::string* error);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010088
89 // Get the Blaze command to be executed.
90 // Returns an empty string if no command was found on the command line.
Thiago Farina80bb0f22016-10-17 15:57:13 +000091 const std::string& GetCommand() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010092
93 // Gets the arguments to the command. This is put together from the default
94 // options specified in the blazerc file(s), the command line, and various
95 // bits and pieces of information about the environment the blaze binary is
96 // executed in.
Thiago Farina80bb0f22016-10-17 15:57:13 +000097 void GetCommandArguments(std::vector<std::string>* result) const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010098
Julio Merino28774852016-09-14 16:59:46 +000099 StartupOptions* GetParsedStartupOptions() const;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100100
Thiago Farina80bb0f22016-10-17 15:57:13 +0000101 virtual blaze_exit_code::ExitCode FindUserBlazerc(
102 const char* cmdLineRcFile, const std::string& rc_basename,
103 const std::string& workspace, std::string* user_blazerc_file,
104 std::string* error);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100105
106 private:
107 class RcOption {
108 public:
Thiago Farina80bb0f22016-10-17 15:57:13 +0000109 RcOption(int rcfile_index, const std::string& option);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100110
111 const int rcfile_index() const { return rcfile_index_; }
Thiago Farina80bb0f22016-10-17 15:57:13 +0000112 const std::string& option() const { return option_; }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100113
114 private:
115 int rcfile_index_;
Thiago Farina80bb0f22016-10-17 15:57:13 +0000116 std::string option_;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100117 };
118
119 class RcFile {
120 public:
Thiago Farina80bb0f22016-10-17 15:57:13 +0000121 RcFile(const std::string& filename, int index);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100122 blaze_exit_code::ExitCode Parse(
Thiago Farina80bb0f22016-10-17 15:57:13 +0000123 const std::string& workspace, std::vector<RcFile*>* rcfiles,
124 std::map<std::string, std::vector<RcOption> >* rcoptions,
125 std::string* error);
126 const std::string& Filename() const { return filename_; }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100127 const int Index() const { return index_; }
128
129 private:
Thiago Farina80bb0f22016-10-17 15:57:13 +0000130 static blaze_exit_code::ExitCode Parse(
131 const std::string& workspace, const std::string& filename,
132 const int index, std::vector<RcFile*>* rcfiles,
133 std::map<std::string, std::vector<RcOption> >* rcoptions,
134 std::list<std::string>* import_stack, std::string* error);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100135
Thiago Farina80bb0f22016-10-17 15:57:13 +0000136 std::string filename_;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100137 int index_;
138 };
139
Thiago Farina80bb0f22016-10-17 15:57:13 +0000140 void AddRcfileArgsAndOptions(bool batch, const std::string& cwd);
141 blaze_exit_code::ExitCode ParseStartupOptions(std::string* error);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100142
Han-Wen Nienhuys255cf092015-05-22 14:38:59 +0000143 std::vector<RcFile*> blazercs_;
Thiago Farina80bb0f22016-10-17 15:57:13 +0000144 std::map<std::string, std::vector<RcOption> > rcoptions_;
145 std::vector<std::string> args_;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100146 unsigned int startup_args_;
Thiago Farina80bb0f22016-10-17 15:57:13 +0000147 std::string command_;
148 std::vector<std::string> command_arguments_;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100149 bool initialized_;
Julio Merino28774852016-09-14 16:59:46 +0000150 std::unique_ptr<StartupOptions> parsed_startup_options_;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100151};
152
153} // namespace blaze
Thiago Farina2e4c2aa2015-06-12 07:18:20 +0000154
Han-Wen Nienhuys0d56b6c2015-05-12 14:52:30 +0000155#endif // BAZEL_SRC_MAIN_CPP_OPTION_PROCESSOR_H_