-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
GenerateCodeMojo.java
115 lines (101 loc) · 5.03 KB
/
GenerateCodeMojo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package io.quarkus.maven;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.List;
import java.util.Properties;
import java.util.function.Consumer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import io.quarkus.bootstrap.app.CuratedApplication;
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.paths.PathCollection;
import io.quarkus.paths.PathList;
import io.quarkus.runtime.LaunchMode;
// in the PROCESS_RESOURCES phase because we want the config to be available
// by the time code gen providers are triggered (the resources plugin copies the config files
// to the destination location at the beginning of this phase)
@Mojo(name = "generate-code", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, threadSafe = true)
public class GenerateCodeMojo extends QuarkusBootstrapMojo {
/**
* Skip the execution of this mojo
*/
@Parameter(defaultValue = "false", property = "quarkus.generate-code.skip", alias = "quarkus.prepare.skip")
private boolean skipSourceGeneration = false;
@Parameter(defaultValue = "NORMAL", property = "launchMode")
String mode;
@Override
protected boolean beforeExecute() throws MojoExecutionException, MojoFailureException {
if (mavenProject().getPackaging().equals("pom")) {
getLog().info("Type of the artifact is POM, skipping build goal");
return false;
}
if (skipSourceGeneration) {
getLog().info("Skipping Quarkus code generation");
return false;
}
return true;
}
@Override
protected void doExecute() throws MojoExecutionException, MojoFailureException {
generateCode(getParentDirs(mavenProject().getCompileSourceRoots()),
path -> mavenProject().addCompileSourceRoot(path.toString()), false);
}
void generateCode(PathCollection sourceParents,
Consumer<Path> sourceRegistrar,
boolean test) throws MojoFailureException, MojoExecutionException {
final LaunchMode launchMode = test ? LaunchMode.TEST : LaunchMode.valueOf(mode);
if (getLog().isDebugEnabled()) {
getLog().debug("Bootstrapping Quarkus application in mode " + launchMode);
}
ClassLoader originalTccl = Thread.currentThread().getContextClassLoader();
CuratedApplication curatedApplication = null;
QuarkusClassLoader deploymentClassLoader = null;
try {
curatedApplication = bootstrapApplication(launchMode);
deploymentClassLoader = curatedApplication.createDeploymentClassLoader();
Thread.currentThread().setContextClassLoader(deploymentClassLoader);
final Class<?> codeGenerator = deploymentClassLoader.loadClass("io.quarkus.deployment.CodeGenerator");
final Method initAndRun = codeGenerator.getMethod("initAndRun", QuarkusClassLoader.class, PathCollection.class,
Path.class, Path.class,
Consumer.class, ApplicationModel.class, Properties.class, String.class,
boolean.class);
initAndRun.invoke(null, deploymentClassLoader, sourceParents,
generatedSourcesDir(test), buildDir().toPath(),
sourceRegistrar, curatedApplication.getApplicationModel(), mavenProject().getProperties(),
launchMode.name(),
test);
} catch (Exception any) {
throw new MojoExecutionException("Quarkus code generation phase has failed", any);
} finally {
// in case of test mode, we can't share the bootstrapped app with the testing plugins, so we are closing it right away
if (test && curatedApplication != null) {
curatedApplication.close();
}
Thread.currentThread().setContextClassLoader(originalTccl);
if (deploymentClassLoader != null) {
deploymentClassLoader.close();
}
}
}
protected PathCollection getParentDirs(List<String> sourceDirs) {
if (sourceDirs.size() == 1) {
return PathList.of(Path.of(sourceDirs.get(0)).getParent());
}
final PathList.Builder builder = PathList.builder();
for (int i = 0; i < sourceDirs.size(); ++i) {
final Path parentDir = Path.of(sourceDirs.get(i)).getParent();
if (!builder.contains(parentDir)) {
builder.add(parentDir);
}
}
return builder.build();
}
private Path generatedSourcesDir(boolean test) {
return test ? buildDir().toPath().resolve("generated-test-sources") : buildDir().toPath().resolve("generated-sources");
}
}