diff --git a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java index 5d4c076161efb..b7532ae9fd96c 100644 --- a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java +++ b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/dependency/ApplicationDeploymentClasspathBuilder.java @@ -1,11 +1,6 @@ package io.quarkus.gradle.dependency; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import org.gradle.api.GradleException; @@ -37,16 +32,19 @@ public class ApplicationDeploymentClasspathBuilder { - private static String getRuntimeConfigName(LaunchMode mode, boolean base) { - final StringBuilder sb = new StringBuilder(); - sb.append("quarkus"); + private static String getLaunchModeAlias(LaunchMode mode) { if (mode == LaunchMode.DEVELOPMENT) { - sb.append("Dev"); - } else if (mode == LaunchMode.TEST) { - sb.append("Test"); - } else { - sb.append("Prod"); + return "Dev"; } + if (mode == LaunchMode.TEST) { + return "Test"; + } + return "Prod"; + } + + private static String getRuntimeConfigName(LaunchMode mode, boolean base) { + final StringBuilder sb = new StringBuilder(); + sb.append("quarkus").append(getLaunchModeAlias(mode)); if (base) { sb.append("Base"); } @@ -118,6 +116,8 @@ public static void initConfigurations(Project project) { private final String runtimeConfigurationName; private final String platformConfigurationName; private final String deploymentConfigurationName; + private final String compileOnlyConfigurationName; + /** * The platform configuration updates the PlatformImports, but since the PlatformImports don't * have a place to be stored in the project, they're stored here. The way that extensions are @@ -136,10 +136,12 @@ public ApplicationDeploymentClasspathBuilder(Project project, LaunchMode mode) { this.platformConfigurationName = ToolingUtils.toPlatformConfigurationName(this.runtimeConfigurationName); this.deploymentConfigurationName = ToolingUtils.toDeploymentConfigurationName(this.runtimeConfigurationName); this.platformImportName = project.getPath() + ":" + this.platformConfigurationName; + this.compileOnlyConfigurationName = "quarkus" + getLaunchModeAlias(mode) + "CompileOnlyConfiguration"; setUpPlatformConfiguration(); setUpRuntimeConfiguration(); setUpDeploymentConfiguration(); + setUpCompileOnlyConfiguration(); } private void setUpPlatformConfiguration() { @@ -254,6 +256,16 @@ private void setUpDeploymentConfiguration() { } } + private void setUpCompileOnlyConfiguration() { + if (!project.getConfigurations().getNames().contains(compileOnlyConfigurationName)) { + project.getConfigurations().register(compileOnlyConfigurationName, config -> { + config.extendsFrom(project.getConfigurations().getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME)); + config.shouldResolveConsistentlyWith(getDeploymentConfiguration()); + config.setCanBeConsumed(false); + }); + } + } + public Configuration getPlatformConfiguration() { return project.getConfigurations().getByName(this.platformConfigurationName); } @@ -274,6 +286,14 @@ public Configuration getDeploymentConfiguration() { return project.getConfigurations().getByName(this.deploymentConfigurationName); } + /** + * Compile-only configuration which is consistent with the deployment one + */ + public Configuration getCompileOnly() { + this.getDeploymentConfiguration().resolve(); + return project.getConfigurations().getByName(compileOnlyConfigurationName); + } + /** * Forces the platform configuration to resolve and then uses that to populate platform imports. */ diff --git a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java index 378a06566f018..453652d50941f 100644 --- a/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java +++ b/devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java @@ -124,6 +124,45 @@ public Object buildAll(String modelName, ModelParameter parameter, Project proje project, modelBuilder, appArtifact.getWorkspaceModule().mutable()); collectExtensionDependencies(project, deploymentConfig, modelBuilder); + var compileOnlyConfig = classpathBuilder.getCompileOnly(); + final List queue = new ArrayList<>( + compileOnlyConfig.getResolvedConfiguration().getFirstLevelModuleDependencies()); + project.getLogger().info("COMPILE ONLY CONFIG " + queue.size()); + for (int i = 0; i < queue.size(); ++i) { + var d = queue.get(i); + boolean skip = true; + for (var a : d.getModuleArtifacts()) { + if (!isDependency(a)) { + continue; + } + var moduleId = a.getModuleVersion().getId(); + var key = ArtifactKey.of(moduleId.getGroup(), moduleId.getName(), a.getClassifier(), a.getType()); + var appDep = modelBuilder.getDependency(key); + var sb = new StringBuilder().append("- "); + if (appDep != null && appDep.isFlagSet(DependencyFlags.COMPILE_ONLY)) { + } else { + skip = false; + if (appDep == null) { + sb.append("[not used] "); + addArtifactDependency(project, modelBuilder, a); + appDep = modelBuilder.getDependency(key); + appDep.clearFlag(DependencyFlags.DEPLOYMENT_CP); + } else { + sb.append(" "); + } + appDep.setFlags(DependencyFlags.COMPILE_ONLY); + sb.append(appDep.getArtifactCoords().toCompactCoords()); + if (!appDep.getVersion().equals(moduleId.getVersion())) { + sb.append(" VS ").append(moduleId.getVersion()); + } + project.getLogger().info(sb.toString()); + } + } + if (!skip) { + queue.addAll(d.getChildren()); + } + } + return modelBuilder.build(); } @@ -191,39 +230,44 @@ private void collectExtensionDependencies(Project project, Configuration deploym ApplicationModelBuilder modelBuilder) { final ResolvedConfiguration rc = deploymentConfiguration.getResolvedConfiguration(); for (ResolvedArtifact a : rc.getResolvedArtifacts()) { - if (a.getId().getComponentIdentifier() instanceof ProjectComponentIdentifier) { - ProjectComponentIdentifier projectComponentIdentifier = (ProjectComponentIdentifier) a.getId() - .getComponentIdentifier(); - var includedBuild = ToolingUtils.includedBuild(project, projectComponentIdentifier); - Project projectDep = null; - if (includedBuild != null) { - projectDep = ToolingUtils.includedBuildProject((IncludedBuildInternal) includedBuild, - projectComponentIdentifier); - } else { - projectDep = project.getRootProject().findProject(projectComponentIdentifier.getProjectPath()); - } - Objects.requireNonNull(projectDep, "project " + projectComponentIdentifier.getProjectPath() + " should exist"); - SourceSetContainer sourceSets = projectDep.getExtensions().getByType(SourceSetContainer.class); - - SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME); - ResolvedDependencyBuilder dep = modelBuilder.getDependency( - toAppDependenciesKey(a.getModuleVersion().getId().getGroup(), a.getName(), a.getClassifier())); - if (dep == null) { - dep = toDependency(a, mainSourceSet); - modelBuilder.addDependency(dep); - } - dep.setDeploymentCp(); - dep.clearFlag(DependencyFlags.RELOADABLE); - } else if (isDependency(a)) { - ResolvedDependencyBuilder dep = modelBuilder.getDependency( - toAppDependenciesKey(a.getModuleVersion().getId().getGroup(), a.getName(), a.getClassifier())); - if (dep == null) { - dep = toDependency(a); - modelBuilder.addDependency(dep); - } - dep.setDeploymentCp(); - dep.clearFlag(DependencyFlags.RELOADABLE); + addArtifactDependency(project, modelBuilder, a); + } + } + + private static void addArtifactDependency(Project project, ApplicationModelBuilder modelBuilder, ResolvedArtifact a) { + if (a.getId().getComponentIdentifier() instanceof ProjectComponentIdentifier) { + ProjectComponentIdentifier projectComponentIdentifier = (ProjectComponentIdentifier) a.getId() + .getComponentIdentifier(); + var includedBuild = ToolingUtils.includedBuild(project, projectComponentIdentifier); + final Project projectDep; + if (includedBuild != null) { + projectDep = ToolingUtils.includedBuildProject((IncludedBuildInternal) includedBuild, + projectComponentIdentifier); + } else { + projectDep = project.getRootProject().findProject(projectComponentIdentifier.getProjectPath()); + } + Objects.requireNonNull(projectDep, + () -> "project " + projectComponentIdentifier.getProjectPath() + " should exist"); + SourceSetContainer sourceSets = projectDep.getExtensions().getByType(SourceSetContainer.class); + + SourceSet mainSourceSet = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME); + ResolvedDependencyBuilder dep = modelBuilder.getDependency( + toAppDependenciesKey(a.getModuleVersion().getId().getGroup(), a.getName(), a.getClassifier())); + if (dep == null) { + dep = toDependency(a, mainSourceSet); + modelBuilder.addDependency(dep); + } + dep.setDeploymentCp(); + dep.clearFlag(DependencyFlags.RELOADABLE); + } else if (isDependency(a)) { + ResolvedDependencyBuilder dep = modelBuilder.getDependency( + toAppDependenciesKey(a.getModuleVersion().getId().getGroup(), a.getName(), a.getClassifier())); + if (dep == null) { + dep = toDependency(a); + modelBuilder.addDependency(dep); } + dep.setDeploymentCp(); + dep.clearFlag(DependencyFlags.RELOADABLE); } }