1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.cling.invoker.mvn;
20  
21  import java.io.IOException;
22  import java.nio.charset.Charset;
23  import java.nio.file.Files;
24  import java.nio.file.Path;
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.stream.Stream;
28  
29  import org.apache.commons.cli.ParseException;
30  import org.apache.maven.api.cli.Options;
31  import org.apache.maven.api.cli.mvn.MavenOptions;
32  import org.apache.maven.cling.invoker.BaseParser;
33  
34  public class MavenParser extends BaseParser {
35      @Override
36      protected Options parseCliOptions(LocalContext context) {
37          ArrayList<MavenOptions> result = new ArrayList<>();
38          
39          MavenOptions cliOptions = parseMavenCliOptions(context.parserRequest.args());
40          result.add(cliOptions);
41          
42          if (cliOptions.atFile().isPresent()) {
43              Path file = context.cwd.resolve(cliOptions.atFile().orElseThrow());
44              if (Files.isRegularFile(file)) {
45                  result.add(parseMavenAtFileOptions(file));
46              } else {
47                  throw new IllegalArgumentException("Specified file does not exists (" + file + ")");
48              }
49          }
50          
51          Path mavenConfig = context.rootDirectory != null ? context.rootDirectory.resolve(".mvn/maven.config") : null;
52          if (mavenConfig != null && Files.isRegularFile(mavenConfig)) {
53              result.add(parseMavenConfigOptions(mavenConfig));
54          }
55          return LayeredMavenOptions.layerMavenOptions(result);
56      }
57  
58      protected MavenOptions parseMavenCliOptions(List<String> args) {
59          try {
60              return parseArgs(Options.SOURCE_CLI, args);
61          } catch (ParseException e) {
62              throw new IllegalArgumentException("Failed to parse CLI arguments: " + e.getMessage(), e.getCause());
63          }
64      }
65  
66      protected MavenOptions parseMavenAtFileOptions(Path atFile) {
67          try (Stream<String> lines = Files.lines(atFile, Charset.defaultCharset())) {
68              List<String> args =
69                      lines.filter(arg -> !arg.isEmpty() && !arg.startsWith("#")).toList();
70              return parseArgs("atFile", args);
71          } catch (ParseException e) {
72              throw new IllegalArgumentException(
73                      "Failed to parse arguments from file (" + atFile + "): " + e.getMessage(), e.getCause());
74          } catch (IOException e) {
75              throw new IllegalStateException("Error reading config file: " + atFile, e);
76          }
77      }
78  
79      protected MavenOptions parseMavenConfigOptions(Path configFile) {
80          try (Stream<String> lines = Files.lines(configFile, Charset.defaultCharset())) {
81              List<String> args =
82                      lines.filter(arg -> !arg.isEmpty() && !arg.startsWith("#")).toList();
83              MavenOptions options = parseArgs("maven.config", args);
84              if (options.goals().isPresent()) {
85                  
86                  throw new IllegalArgumentException("Unrecognized entries in maven.config (" + configFile + ") file: "
87                          + options.goals().get());
88              }
89              return options;
90          } catch (ParseException e) {
91              throw new IllegalArgumentException(
92                      "Failed to parse arguments from maven.config file (" + configFile + "): " + e.getMessage(),
93                      e.getCause());
94          } catch (IOException e) {
95              throw new IllegalStateException("Error reading config file: " + configFile, e);
96          }
97      }
98  
99      protected MavenOptions parseArgs(String source, List<String> args) throws ParseException {
100         return CommonsCliMavenOptions.parse(source, args.toArray(new String[0]));
101     }
102 }