View Javadoc
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.cling.invoker.mvn;
20  
21  import java.io.ByteArrayOutputStream;
22  import java.nio.file.Files;
23  import java.nio.file.Path;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collection;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  import eu.maveniverse.maven.mimir.testing.MimirInfuser;
32  import org.apache.maven.api.cli.Invoker;
33  import org.apache.maven.api.cli.InvokerException;
34  import org.apache.maven.api.cli.Parser;
35  import org.apache.maven.api.cli.ParserRequest;
36  import org.apache.maven.jline.JLineMessageBuilderFactory;
37  import org.codehaus.plexus.classworlds.ClassWorld;
38  
39  import static org.junit.jupiter.api.Assertions.assertEquals;
40  
41  public abstract class MavenInvokerTestSupport {
42      static {
43          System.setProperty(
44                  "library.jline.path",
45                  Path.of("target/dependency/org/jline/nativ").toAbsolutePath().toString());
46      }
47  
48      public static final String POM_STRING = """
49                  <?xml version="1.0" encoding="UTF-8"?>
50                  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
51                           xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
52  
53                      <modelVersion>4.0.0</modelVersion>
54  
55                      <groupId>org.apache.maven.samples</groupId>
56                      <artifactId>sample</artifactId>
57                      <version>1.0.0</version>
58  
59                      <dependencyManagement>
60                        <dependencies>
61                          <dependency>
62                            <groupId>org.junit</groupId>
63                            <artifactId>junit-bom</artifactId>
64                            <version>5.11.1</version>
65                            <type>pom</type>
66                            <scope>import</scope>
67                          </dependency>
68                        </dependencies>
69                      </dependencyManagement>
70  
71                      <dependencies>
72                        <dependency>
73                          <groupId>org.junit.jupiter</groupId>
74                          <artifactId>junit-jupiter-api</artifactId>
75                          <scope>test</scope>
76                        </dependency>
77                      </dependencies>
78  
79                  </project>
80                  """;
81  
82      public static final String APP_JAVA_STRING = """
83              package org.apache.maven.samples.sample;
84  
85              public class App {
86                  public static void main(String... args) {
87                      System.out.println("Hello World!");
88                  }
89              }
90              """;
91  
92      protected Map<String, String> invoke(Path cwd, Path userHome, Collection<String> goals, Collection<String> args)
93              throws Exception {
94          Files.createDirectories(cwd.resolve(".mvn"));
95          Path pom = cwd.resolve("pom.xml").toAbsolutePath();
96          Files.writeString(pom, POM_STRING);
97          Path appJava = cwd.resolve("src/main/java/org/apache/maven/samples/sample/App.java");
98          Files.createDirectories(appJava.getParent());
99          Files.writeString(appJava, APP_JAVA_STRING);
100 
101         if (MimirInfuser.isMimirPresentUW()) {
102             MimirInfuser.doInfuseUW(userHome);
103             MimirInfuser.preseedItselfIntoInnerUserHome(userHome);
104         }
105 
106         HashMap<String, String> logs = new HashMap<>();
107         Parser parser = createParser();
108         try (ClassWorld classWorld = createClassWorld();
109                 Invoker invoker = createInvoker(classWorld)) {
110             for (String goal : goals) {
111                 ByteArrayOutputStream stdout = new ByteArrayOutputStream();
112                 ByteArrayOutputStream stderr = new ByteArrayOutputStream();
113                 List<String> mvnArgs = new ArrayList<>(args);
114                 mvnArgs.add("-Daether.remoteRepositoryFilter.prefixes=false");
115                 mvnArgs.add(goal);
116                 int exitCode = -1;
117                 Exception exception = null;
118                 try {
119                     exitCode = invoker.invoke(
120                             parser.parseInvocation(ParserRequest.mvn(mvnArgs, new JLineMessageBuilderFactory())
121                                     .cwd(cwd)
122                                     .userHome(userHome)
123                                     .stdOut(stdout)
124                                     .stdErr(stderr)
125                                     .embedded(true)
126                                     .build()));
127                 } catch (InvokerException.ExitException e) {
128                     exitCode = e.getExitCode();
129                     exception = e;
130                 } catch (Exception e) {
131                     exception = e;
132                 }
133 
134                 // dump things out
135                 System.out.println("===================================================");
136                 System.out.println("args: " + Arrays.toString(mvnArgs.toArray()));
137                 System.out.println("===================================================");
138                 System.out.println("stdout: " + stdout);
139                 System.out.println("===================================================");
140 
141                 System.err.println("===================================================");
142                 System.err.println("args: " + Arrays.toString(mvnArgs.toArray()));
143                 System.err.println("===================================================");
144                 System.err.println("stderr: " + stderr);
145                 System.err.println("===================================================");
146 
147                 logs.put(goal, stdout.toString());
148                 if (exception != null) {
149                     throw exception;
150                 } else {
151                     assertEquals(0, exitCode, "OUT:" + stdout + "\nERR:" + stderr);
152                 }
153             }
154         }
155         return logs;
156     }
157 
158     protected ClassWorld createClassWorld() {
159         return new ClassWorld("plexus.core", ClassLoader.getSystemClassLoader());
160     }
161 
162     protected abstract Invoker createInvoker(ClassWorld classWorld);
163 
164     protected abstract Parser createParser();
165 }