diff --git a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenContext.java b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenContext.java index d901f56d74a8d..76c312af8b5a8 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenContext.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenContext.java @@ -1,11 +1,10 @@ package io.quarkus.deployment; import java.nio.file.Path; -import java.util.Map; -import io.quarkus.bootstrap.model.AppModel; +import org.eclipse.microprofile.config.Config; + import io.quarkus.bootstrap.model.ApplicationModel; -import io.quarkus.bootstrap.util.BootstrapUtils; public class CodeGenContext { private final ApplicationModel model; @@ -13,25 +12,15 @@ public class CodeGenContext { private final Path workDir; private final Path inputDir; private final boolean redirectIO; - private final Map properties; + private final Config config; - public CodeGenContext(ApplicationModel model, Path outDir, Path workDir, Path inputDir, boolean redirectIO, - Map properties) { + public CodeGenContext(ApplicationModel model, Path outDir, Path workDir, Path inputDir, boolean redirectIO, Config config) { this.model = model; this.outDir = outDir; this.workDir = workDir; this.inputDir = inputDir; this.redirectIO = redirectIO; - this.properties = properties; - } - - /** - * @deprecated in favor of {@link #applicationModel()} - * @return - */ - @Deprecated - public AppModel appModel() { - return BootstrapUtils.convert(model); + this.config = config; } public ApplicationModel applicationModel() { @@ -54,7 +43,7 @@ public boolean shouldRedirectIO() { return redirectIO; } - public Map properties() { - return properties; + public Config config() { + return config; } } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java index b6fe63616c2f9..112b5fe661a7f 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/CodeGenerator.java @@ -5,7 +5,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.Properties; import java.util.ServiceLoader; import java.util.function.Consumer; @@ -13,21 +13,25 @@ import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.bootstrap.prebuild.CodeGenException; import io.quarkus.deployment.codegen.CodeGenData; +import io.quarkus.runtime.LaunchMode; +import io.quarkus.runtime.configuration.ConfigUtils; +import io.smallrye.config.PropertiesConfigSource; +import io.smallrye.config.SmallRyeConfig; /** * A set of methods to initialize and execute {@link CodeGenProvider}s. */ public class CodeGenerator { - // used by Gradle + // used by Gradle and Maven public static void initAndRun(ClassLoader classLoader, PathsCollection sourceParentDirs, Path generatedSourcesDir, Path buildDir, - Consumer sourceRegistrar, - ApplicationModel appModel, Map properties) throws CodeGenException { + Consumer sourceRegistrar, ApplicationModel appModel, Properties properties, + String launchMode) throws CodeGenException { List generators = init(classLoader, sourceParentDirs, generatedSourcesDir, buildDir, sourceRegistrar); for (CodeGenData generator : generators) { generator.setRedirectIO(true); - trigger(classLoader, generator, appModel, properties); + trigger(classLoader, generator, appModel, properties, LaunchMode.valueOf(launchMode)); } } @@ -82,14 +86,21 @@ private static T callWithClassloader(ClassLoader deploymentClassLoader, Code public static boolean trigger(ClassLoader deploymentClassLoader, CodeGenData data, ApplicationModel appModel, - Map properties) throws CodeGenException { + Properties properties, + LaunchMode launchMode) throws CodeGenException { return callWithClassloader(deploymentClassLoader, () -> { - CodeGenProvider provider = data.provider; + final PropertiesConfigSource pcs = new PropertiesConfigSource(properties, "Build system"); + + final SmallRyeConfig config = ConfigUtils.configBuilder(false, launchMode) + .withProfile(launchMode.getDefaultProfile()) + .withSources(pcs) + .build(); + + CodeGenProvider provider = data.provider; return Files.isDirectory(data.sourceDir) && provider.trigger( - new CodeGenContext(appModel, data.outPath, data.buildDir, data.sourceDir, data.redirectIO, - properties)); + new CodeGenContext(appModel, data.outPath, data.buildDir, data.sourceDir, data.redirectIO, config)); }); } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java index bf62d68499827..c0e0c458bab36 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/dev/IsolatedDevModeMain.java @@ -17,6 +17,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.CountDownLatch; @@ -59,6 +60,7 @@ import io.quarkus.dev.spi.HotReplacementSetup; import io.quarkus.runner.bootstrap.AugmentActionImpl; import io.quarkus.runtime.ApplicationLifecycleManager; +import io.quarkus.runtime.LaunchMode; import io.quarkus.runtime.configuration.QuarkusConfigFactory; import io.quarkus.runtime.logging.LoggingSetupRecorder; @@ -186,16 +188,18 @@ public void accept(String args) { } private void startCodeGenWatcher(QuarkusClassLoader classLoader, List codeGens, - Map properties) { + Map propertyMap) { Collection watchers = new ArrayList<>(); + Properties properties = new Properties(); + properties.putAll(propertyMap); for (CodeGenData codeGen : codeGens) { watchers.add(new FSWatchUtil.Watcher(codeGen.sourceDir, codeGen.provider.inputExtension(), modifiedPaths -> { try { CodeGenerator.trigger(classLoader, codeGen, - curatedApplication.getApplicationModel(), properties); + curatedApplication.getApplicationModel(), properties, LaunchMode.DEVELOPMENT); } catch (Exception any) { log.warn("Code generation failed", any); } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java index 9218b176aa98a..26f0633e89f29 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/QuarkusPlugin.java @@ -61,6 +61,7 @@ public class QuarkusPlugin implements Plugin { public static final String ADD_EXTENSION_TASK_NAME = "addExtension"; public static final String REMOVE_EXTENSION_TASK_NAME = "removeExtension"; public static final String QUARKUS_GENERATE_CODE_TASK_NAME = "quarkusGenerateCode"; + public static final String QUARKUS_GENERATE_CODE_DEV_TASK_NAME = "quarkusGenerateCodeDev"; public static final String QUARKUS_GENERATE_CODE_TESTS_TASK_NAME = "quarkusGenerateCodeTests"; public static final String QUARKUS_BUILD_TASK_NAME = "quarkusBuild"; public static final String QUARKUS_DEV_TASK_NAME = "quarkusDev"; @@ -106,6 +107,9 @@ private void registerTasks(Project project, QuarkusPluginExtension quarkusExt) { tasks.create(REMOVE_EXTENSION_TASK_NAME, QuarkusRemoveExtension.class); QuarkusGenerateCode quarkusGenerateCode = tasks.create(QUARKUS_GENERATE_CODE_TASK_NAME, QuarkusGenerateCode.class); + QuarkusGenerateCode quarkusGenerateCodeDev = tasks.create(QUARKUS_GENERATE_CODE_DEV_TASK_NAME, + QuarkusGenerateCode.class); + quarkusGenerateCodeDev.setDevMode(true); QuarkusGenerateCode quarkusGenerateCodeTests = tasks.create(QUARKUS_GENERATE_CODE_TESTS_TASK_NAME, QuarkusGenerateCode.class); quarkusGenerateCodeTests.setTest(true); @@ -148,8 +152,8 @@ public void execute(Task test) { project.afterEvaluate(this::afterEvaluate); ConfigurationContainer configurations = project.getConfigurations(); JavaCompile compileJavaTask = (JavaCompile) tasks.getByName(JavaPlugin.COMPILE_JAVA_TASK_NAME); - - compileJavaTask.dependsOn(quarkusGenerateCode); + compileJavaTask.mustRunAfter(quarkusGenerateCodeDev); + compileJavaTask.mustRunAfter(quarkusGenerateCode); JavaCompile compileTestJavaTask = (JavaCompile) tasks.getByName(JavaPlugin.COMPILE_TEST_JAVA_TASK_NAME); compileTestJavaTask.dependsOn(quarkusGenerateCodeTests); @@ -158,7 +162,12 @@ public void execute(Task test) { Task resourcesTask = tasks.getByName(JavaPlugin.PROCESS_RESOURCES_TASK_NAME); Task testClassesTask = tasks.getByName(JavaPlugin.TEST_CLASSES_TASK_NAME); Task testResourcesTask = tasks.getByName(JavaPlugin.PROCESS_TEST_RESOURCES_TASK_NAME); - quarkusDev.dependsOn(classesTask, resourcesTask, testClassesTask, testResourcesTask, quarkusGenerateCode, + + quarkusGenerateCode.dependsOn(resourcesTask); + quarkusGenerateCodeDev.dependsOn(resourcesTask); + quarkusGenerateCodeTests.dependsOn(resourcesTask); + + quarkusDev.dependsOn(classesTask, resourcesTask, testClassesTask, testResourcesTask, quarkusGenerateCodeDev, quarkusGenerateCodeTests); quarkusRemoteDev.dependsOn(classesTask, resourcesTask); quarkusTest.dependsOn(classesTask, resourcesTask, testClassesTask, testResourcesTask, quarkusGenerateCode, @@ -172,6 +181,7 @@ public void execute(Task test) { SourceSet testSourceSet = sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME); quarkusGenerateCode.setSourcesDirectories(getSourcesParents(mainSourceSet)); + quarkusGenerateCodeDev.setSourcesDirectories(getSourcesParents(mainSourceSet)); quarkusGenerateCodeTests.setSourcesDirectories(getSourcesParents(testSourceSet)); nativeTestSourceSet.setCompileClasspath( @@ -224,7 +234,8 @@ public void execute(Task test) { project.getPlugins().withId("org.jetbrains.kotlin.jvm", plugin -> { quarkusDev.shouldPropagateJavaCompilerArgs(false); - tasks.getByName("compileKotlin").dependsOn(quarkusGenerateCode); + tasks.getByName("compileKotlin").mustRunAfter(quarkusGenerateCode); + tasks.getByName("compileKotlin").mustRunAfter(quarkusGenerateCodeDev); tasks.getByName("compileTestKotlin").dependsOn(quarkusGenerateCodeTests); }); } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java index 58f67b79518df..cbe570046ec45 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusGenerateCode.java @@ -45,6 +45,7 @@ public class QuarkusGenerateCode extends QuarkusTask { private Consumer sourceRegistrar = (p) -> { }; private boolean test = false; + private boolean devMode = false; public QuarkusGenerateCode() { super("Performs Quarkus pre-build preparations, such as sources generation"); @@ -88,7 +89,8 @@ public File getGeneratedOutputDirectory() { public void prepareQuarkus() { getLogger().lifecycle("preparing quarkus application"); - final ApplicationModel appModel = extension().getApplicationModel(test ? LaunchMode.TEST : LaunchMode.NORMAL); + LaunchMode launchMode = test ? LaunchMode.TEST : devMode ? LaunchMode.DEVELOPMENT : LaunchMode.NORMAL; + final ApplicationModel appModel = extension().getApplicationModel(launchMode); final Properties realProperties = getBuildSystemProperties(appModel.getAppArtifact()); Path buildDir = getProject().getBuildDir().toPath(); @@ -124,7 +126,7 @@ public void prepareQuarkus() { Optional initAndRun = Arrays.stream(codeGenerator.getMethods()) .filter(m -> m.getName().equals(INIT_AND_RUN)) .findAny(); - if (!initAndRun.isPresent()) { + if (initAndRun.isEmpty()) { throw new GradleException("Failed to find " + INIT_AND_RUN + " method in " + CodeGenerator.class.getName()); } @@ -134,7 +136,8 @@ public void prepareQuarkus() { buildDir, sourceRegistrar, appCreationContext.getApplicationModel(), - realProperties); + realProperties, + launchMode.name()); } } catch (BootstrapException | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) { @@ -149,4 +152,8 @@ public void setSourcesDirectories(Set sourcesDirectories) { public void setTest(boolean test) { this.test = test; } + + public void setDevMode(boolean devMode) { + this.devMode = devMode; + } } diff --git a/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java index 6f5ebef76c8ac..c0dc5ed9d0081 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java @@ -150,6 +150,7 @@ public class DevMojo extends AbstractMojo { "install", "deploy"); private static final String QUARKUS_GENERATE_CODE_GOAL = "generate-code"; + private static final String QUARKUS_GENERATE_CODE_TESTS_GOAL = "generate-code-tests"; private static final String ORG_APACHE_MAVEN_PLUGINS = "org.apache.maven.plugins"; private static final String MAVEN_COMPILER_PLUGIN = "maven-compiler-plugin"; @@ -399,8 +400,8 @@ public void execute() throws MojoFailureException, MojoExecutionException { getLog().info("Changes detected to " + changed + ", restarting dev mode"); final DevModeRunner newRunner; try { - triggerCompile(false); - triggerCompile(true); + triggerCompile(false, true); + triggerCompile(true, true); newRunner = new DevModeRunner(); } catch (Exception e) { getLog().info("Could not load changed pom.xml file, changes not applied", e); @@ -478,10 +479,14 @@ private void handleAutoCompile() throws MojoExecutionException { boolean compileNeeded = true; boolean testCompileNeeded = true; boolean prepareNeeded = true; + boolean prepareTestsNeeded = true; for (String goal : session.getGoals()) { - if (goal.endsWith("quarkus:prepare")) { + if (goal.endsWith("quarkus:generate-code")) { prepareNeeded = false; } + if (goal.endsWith("quarkus:generate-code-tests")) { + prepareTestsNeeded = false; + } if (POST_COMPILE_PHASES.contains(goal)) { compileNeeded = false; @@ -498,14 +503,11 @@ private void handleAutoCompile() throws MojoExecutionException { //if the user did not compile we run it for them if (compileNeeded) { - if (prepareNeeded) { - triggerPrepare(); - } - triggerCompile(false); + triggerCompile(false, prepareNeeded); } if (testCompileNeeded) { try { - triggerCompile(true); + triggerCompile(true, prepareTestsNeeded); } catch (Throwable t) { getLog().error("Test compile failed, you will need to fix your tests before you can use continuous testing", t); } @@ -516,9 +518,10 @@ private void initToolchain() throws MojoExecutionException { executeIfConfigured(ORG_APACHE_MAVEN_PLUGINS, MAVEN_TOOLCHAINS_PLUGIN, "toolchain", Collections.emptyMap()); } - private void triggerPrepare() throws MojoExecutionException { + private void triggerPrepare(boolean test) throws MojoExecutionException { final PluginDescriptor pluginDescr = getPluginDescriptor(); - executeIfConfigured(pluginDescr.getGroupId(), pluginDescr.getArtifactId(), QUARKUS_GENERATE_CODE_GOAL, + executeIfConfigured(pluginDescr.getGroupId(), pluginDescr.getArtifactId(), + test ? QUARKUS_GENERATE_CODE_TESTS_GOAL : QUARKUS_GENERATE_CODE_GOAL, Collections.singletonMap("mode", LaunchMode.DEVELOPMENT.name())); } @@ -526,9 +529,13 @@ private PluginDescriptor getPluginDescriptor() { return (PluginDescriptor) getPluginContext().get("pluginDescriptor"); } - private void triggerCompile(boolean test) throws MojoExecutionException { + private void triggerCompile(boolean test, boolean prepareNeeded) throws MojoExecutionException { handleResources(test); + if (prepareNeeded) { + triggerPrepare(test); + } + // compile the Kotlin sources if needed executeIfConfigured(ORG_JETBRAINS_KOTLIN, KOTLIN_MAVEN_PLUGIN, test ? "test-compile" : "compile", Collections.emptyMap()); diff --git a/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java index d233f5881ed5d..7c7f5be85dcfb 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/GenerateCodeMojo.java @@ -3,7 +3,7 @@ import java.lang.reflect.Method; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Map; +import java.util.Properties; import java.util.function.Consumer; import org.apache.maven.plugin.MojoExecutionException; @@ -19,7 +19,7 @@ import io.quarkus.bootstrap.model.PathsCollection; import io.quarkus.runtime.LaunchMode; -@Mojo(name = "generate-code", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, threadSafe = true) +@Mojo(name = "generate-code", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, threadSafe = true) public class GenerateCodeMojo extends QuarkusBootstrapMojo { /** @@ -72,14 +72,14 @@ void generateCode(Path sourcesDir, final Method initAndRun = codeGenerator.getMethod("initAndRun", ClassLoader.class, PathsCollection.class, Path.class, Path.class, - Consumer.class, ApplicationModel.class, Map.class); + Consumer.class, ApplicationModel.class, Properties.class, String.class); initAndRun.invoke(null, deploymentClassLoader, PathsCollection.of(sourcesDir), generatedSourcesDir(test), buildDir().toPath(), sourceRegistrar, curatedApplication.getApplicationModel(), - mavenProject().getProperties()); + mavenProject().getProperties(), launchMode.name()); } catch (Exception any) { throw new MojoExecutionException("Quarkus code generation phase has failed", any); } finally { diff --git a/extensions/avro/deployment/src/main/java/io/quarkus/avro/deployment/AvroCodeGenProviderBase.java b/extensions/avro/deployment/src/main/java/io/quarkus/avro/deployment/AvroCodeGenProviderBase.java index 773f0f6803846..51e8ce9be48dd 100644 --- a/extensions/avro/deployment/src/main/java/io/quarkus/avro/deployment/AvroCodeGenProviderBase.java +++ b/extensions/avro/deployment/src/main/java/io/quarkus/avro/deployment/AvroCodeGenProviderBase.java @@ -7,11 +7,11 @@ import java.util.Collection; import java.util.HashSet; import java.util.Locale; -import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.apache.avro.generic.GenericData; +import org.eclipse.microprofile.config.Config; import org.jboss.logging.Logger; import io.quarkus.bootstrap.prebuild.CodeGenException; @@ -37,8 +37,7 @@ public String inputDirectory() { public boolean trigger(CodeGenContext context) throws CodeGenException { init(); boolean filesGenerated = false; - - AvroOptions options = new AvroOptions(context.properties(), inputExtension()); + AvroOptions options = new AvroOptions(context.config(), inputExtension()); Path input = context.inputDir(); Path outputDir = context.outDir(); @@ -90,7 +89,7 @@ public static class AvroOptions { public static final String[] EMPTY = new String[0]; - private final Map properties; + private final Config config; /** * A list of files or directories that should be compiled first thus making them @@ -142,8 +141,8 @@ public static class AvroOptions { */ final boolean optionalGettersForNullableFieldsOnly; - AvroOptions(Map properties, String specificPropertyKey) { - this.properties = properties; + AvroOptions(Config config, String specificPropertyKey) { + this.config = config; String imports = prop("avro.codegen." + specificPropertyKey + ".imports", ""); this.imports = "".equals(imports) ? EMPTY : imports.split(","); @@ -157,7 +156,7 @@ public static class AvroOptions { } private String prop(String propName, String defaultValue) { - return properties.getOrDefault(propName, defaultValue); + return config.getOptionalValue(propName, String.class).orElse(defaultValue); } private boolean getBooleanProperty(String propName, boolean defaultValue) { diff --git a/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcCodeGen.java b/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcCodeGen.java index 4501a69d09398..43819b9216cba 100644 --- a/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcCodeGen.java +++ b/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcCodeGen.java @@ -17,7 +17,6 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -25,6 +24,7 @@ import java.util.stream.Stream; import org.codehaus.plexus.util.io.RawInputStreamFacade; +import org.eclipse.microprofile.config.Config; import org.jboss.logging.Logger; import io.quarkus.bootstrap.model.ApplicationModel; @@ -70,7 +70,8 @@ public String inputDirectory() { @Override public boolean trigger(CodeGenContext context) throws CodeGenException { - if (TRUE.toString().equalsIgnoreCase(System.getProperties().getProperty("grpc.codegen.skip", "false"))) { + if (TRUE.toString().equalsIgnoreCase(System.getProperties().getProperty("grpc.codegen.skip", "false")) + || context.config().getOptionalValue("quarkus.grpc.codegen.skip", Boolean.class).orElse(false)) { log.info("Skipping " + this.getClass() + " invocation on user's request"); return false; } @@ -125,10 +126,10 @@ public boolean trigger(CodeGenContext context) throws CodeGenException { } private Collection gatherImports(Path workDir, CodeGenContext context) throws CodeGenException { - Map properties = context.properties(); + Config properties = context.config(); - String scanForImports = properties.getOrDefault("quarkus.generate-code.grpc.scan-for-imports", - "com.google.protobuf:protobuf-java"); + String scanForImports = properties.getOptionalValue("quarkus.generate-code.grpc.scan-for-imports", String.class) + .orElse("com.google.protobuf:protobuf-java"); if ("none".equals(scanForImports.toLowerCase(Locale.getDefault()))) { return Collections.emptyList(); diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/it/CodeGenIT.java b/integration-tests/maven/src/test/java/io/quarkus/maven/it/CodeGenIT.java new file mode 100644 index 0000000000000..238403ad583cc --- /dev/null +++ b/integration-tests/maven/src/test/java/io/quarkus/maven/it/CodeGenIT.java @@ -0,0 +1,43 @@ +package io.quarkus.maven.it; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import org.apache.maven.shared.invoker.MavenInvocationException; +import org.junit.jupiter.api.Test; + +import io.quarkus.maven.it.verifier.MavenProcessInvocationResult; +import io.quarkus.maven.it.verifier.RunningInvoker; +import io.quarkus.test.devmode.util.DevModeTestUtils; + +/** + *

+ * NOTE to anyone diagnosing failures in this test, to run a single method use: + *

+ * mvn install -Dit.test=CodeGenIT#methodName + */ +@DisableForNative +public class CodeGenIT extends RunAndCheckMojoTestBase { + + @Test + public void shouldCompileAndRunWithCodegenEnabled() throws MavenInvocationException, FileNotFoundException { + testDir = initProject("projects/proto-gen"); + run(true); + assertThat(DevModeTestUtils.getHttpResponse("/hello")).isEqualTo("Hello, World!"); + } + + @Test + public void shouldFailToCompileWithCodegenDisabled() throws MavenInvocationException, IOException, InterruptedException { + testDir = initProject("projects/proto-gen", "projects/proto-gen-failing"); + final File applicationProps = new File(testDir, "src/main/resources/application.properties"); + filter(applicationProps, Collections.singletonMap("quarkus.grpc.codegen.skip=false", "quarkus.grpc.codegen.skip=true")); + running = new RunningInvoker(testDir, false); + MavenProcessInvocationResult compile = running.execute(List.of("compile"), Collections.emptyMap()); + assertThat(compile.getProcess().waitFor()).isNotZero(); + } +} diff --git a/integration-tests/maven/src/test/resources/projects/proto-gen/pom.xml b/integration-tests/maven/src/test/resources/projects/proto-gen/pom.xml new file mode 100644 index 0000000000000..6e4c16cf83600 --- /dev/null +++ b/integration-tests/maven/src/test/resources/projects/proto-gen/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + org.acme + acme + 1.0-SNAPSHOT + + io.quarkus + quarkus-bom + @project.version@ + @project.version@ + 11 + UTF-8 + 11 + + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + + io.quarkus + quarkus-resteasy-reactive + + + io.quarkus + quarkus-grpc + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + + + + io.quarkus + quarkus-maven-plugin + ${quarkus-plugin.version} + + + + generate-code + generate-code-tests + build + + + + + + + + + native + + native + + + + diff --git a/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/java/org/acme/HelloResource.java b/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/java/org/acme/HelloResource.java new file mode 100644 index 0000000000000..a17698bd7f374 --- /dev/null +++ b/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/java/org/acme/HelloResource.java @@ -0,0 +1,15 @@ +package org.acme; + +import com.example.SimpleOuterClass.Msg; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +@Path("/hello") +public class HelloResource { + + @GET + public String hello() { + return "Hello, World!"; + } +} diff --git a/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/proto/simple.proto b/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/proto/simple.proto new file mode 100644 index 0000000000000..3c053dcd7621c --- /dev/null +++ b/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/proto/simple.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +option java_package = "com.example"; + +service Simple { + rpc go(Msg) returns (Msg); +} + +message Msg { + string text = 1; +} \ No newline at end of file diff --git a/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/resources/application.properties b/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/resources/application.properties new file mode 100644 index 0000000000000..169fdb145feac --- /dev/null +++ b/integration-tests/maven/src/test/resources/projects/proto-gen/src/main/resources/application.properties @@ -0,0 +1 @@ +quarkus.grpc.codegen.skip=false