1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.api.cli;
20
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.nio.file.Path;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Optional;
27
28 import org.apache.maven.api.annotations.Experimental;
29 import org.apache.maven.api.annotations.Immutable;
30 import org.apache.maven.api.annotations.Nonnull;
31 import org.apache.maven.api.cli.cisupport.CIInfo;
32 import org.apache.maven.api.services.Lookup;
33 import org.apache.maven.api.services.MessageBuilderFactory;
34
35 /**
36 * Represents a Maven invocation request, encapsulating all necessary information
37 * for invoking a Maven build or command. Arguments are parsed and exposed via methods.
38 *
39 * @since 4.0.0
40 */
41 @Immutable
42 @Experimental
43 public interface InvokerRequest {
44 /**
45 * The parser request this instance was created from.
46 */
47 @Nonnull
48 ParserRequest parserRequest();
49
50 /**
51 * Flag representing parser processing result: if there were some fatal errors during
52 * {@link Parser#parseInvocation(ParserRequest)} this method will return {@code true} and invoker should
53 * handle this request as "early failure". In these cases, {@link #options()} usually is absent.
54 */
55 boolean parsingFailed();
56
57 /**
58 * Returns {@code true} if this call happens in "embedded" mode.
59 *
60 * @see ParserRequest#embedded()
61 */
62 default boolean embedded() {
63 return parserRequest().embedded();
64 }
65
66 /**
67 * Returns the current working directory for the Maven execution.
68 * This is typically the directory from which Maven was invoked.
69 *
70 * @return the current working directory path
71 */
72 @Nonnull
73 Path cwd();
74
75 /**
76 * Returns the Maven installation directory.
77 * This is usually set by the Maven launcher script using the "maven.home" system property.
78 *
79 * @return the Maven installation directory path
80 */
81 @Nonnull
82 Path installationDirectory();
83
84 /**
85 * Returns the user's home directory.
86 * This is typically obtained from the "user.home" system property.
87 *
88 * @return the user's home directory path
89 */
90 @Nonnull
91 Path userHomeDirectory();
92
93 /**
94 * Shorthand for {@link MessageBuilderFactory}.
95 */
96 default MessageBuilderFactory messageBuilderFactory() {
97 return parserRequest().messageBuilderFactory();
98 }
99
100 /**
101 * Shorthand for {@link Lookup}.
102 */
103 default Lookup lookup() {
104 return parserRequest().lookup();
105 }
106
107 /**
108 * Returns a map of user-defined properties for the Maven execution.
109 * These properties can be set using the -D command-line option.
110 *
111 * @return an unmodifiable map of user properties
112 */
113 @Nonnull
114 Map<String, String> userProperties();
115
116 /**
117 * Returns a map of system properties for the Maven execution.
118 * These include both Java system properties and Maven-specific system properties.
119 *
120 * @return an unmodifiable map of system properties
121 */
122 @Nonnull
123 Map<String, String> systemProperties();
124
125 /**
126 * Returns the top-level directory of the Maven invocation.
127 * This is typically the directory containing the POM file being executed.
128 *
129 * @return the top-level directory path
130 */
131 @Nonnull
132 Path topDirectory();
133
134 /**
135 * Returns the root directory of the Maven invocation, if found. This is determined by the presence of a
136 * {@code .mvn} directory or a POM with the root="true" property but is not always applicable (ie invocation
137 * from outside a checkout).
138 *
139 * @return the root directory path, if present
140 */
141 @Nonnull
142 Optional<Path> rootDirectory();
143
144 /**
145 * Returns the input stream for the Maven execution, if running in embedded mode.
146 *
147 * @return an {@link Optional} containing the input stream, or empty if not applicable
148 */
149 @Nonnull
150 default Optional<InputStream> stdIn() {
151 return Optional.ofNullable(parserRequest().stdIn());
152 }
153
154 /**
155 * Returns the output stream for the Maven execution, if running in embedded mode.
156 *
157 * @return an {@link Optional} containing the output stream, or empty if not applicable
158 */
159 @Nonnull
160 default Optional<OutputStream> stdOut() {
161 return Optional.ofNullable(parserRequest().stdOut());
162 }
163
164 /**
165 * Returns the error stream for the Maven execution, if running in embedded mode.
166 *
167 * @return an {@link Optional} containing the error stream, or empty if not applicable
168 */
169 @Nonnull
170 default Optional<OutputStream> stdErr() {
171 return Optional.ofNullable(parserRequest().stdErr());
172 }
173
174 /**
175 * Returns a list of core extensions from all sources, that were discovered and loaded. Each instance of
176 * {@link CoreExtensions} is validated, but the list elements may have overlapping elements, that requires
177 * some logic to sort out (like precedence).
178 * <p>
179 * The list of {@link CoreExtensions} if present, is in precedence order.
180 *
181 * @return an {@link Optional} containing the {@link CoreExtensions}, or empty if not configured
182 */
183 @Nonnull
184 Optional<List<CoreExtensions>> coreExtensions();
185
186 /**
187 * Returns detected CI system, if any.
188 *
189 * @return an {@link Optional} containing the {@link CIInfo} collected from CI system. or empty if CI not
190 * detected.
191 */
192 @Nonnull
193 Optional<CIInfo> ciInfo();
194
195 /**
196 * Returns the options associated with this invocation request.
197 *
198 * @return the options optional. It will be absent if {@link #parsingFailed()} return {@code true}.
199 */
200 @Nonnull
201 Optional<Options> options();
202
203 /**
204 * This method returns "verbose" option value derived from multiple places: CLI options, but also CI detection,
205 * if applicable.
206 */
207 default boolean effectiveVerbose() {
208 return options().isPresent() && options().orElseThrow().verbose().orElse(false)
209 || ciInfo().isPresent() && ciInfo().orElseThrow().isVerbose();
210 }
211 }