Gradle plugin: include the test dependencies into the resolved application model when launching in test mode

This commit is contained in:
Alexey Loubyansky
2020-02-05 12:09:08 +01:00
parent 5f14689194
commit e83e6ab980
8 changed files with 65 additions and 49 deletions

View File

@@ -10,7 +10,6 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@@ -39,15 +38,18 @@ import io.quarkus.bootstrap.model.AppDependency;
import io.quarkus.bootstrap.model.AppModel;
import io.quarkus.bootstrap.resolver.AppModelResolver;
import io.quarkus.bootstrap.resolver.AppModelResolverException;
import io.quarkus.runtime.LaunchMode;
public class AppModelGradleResolver implements AppModelResolver {
private AppModel appModel;
private final Project project;
private final LaunchMode mode;
public AppModelGradleResolver(Project project) {
public AppModelGradleResolver(Project project, LaunchMode mode) {
this.project = project;
this.mode = mode;
}
@Override
@@ -122,40 +124,20 @@ public class AppModelGradleResolver implements AppModelResolver {
if (appModel != null && appModel.getAppArtifact().equals(appArtifact)) {
return appModel;
}
final Configuration compileCp = project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME);
final List<Dependency> extensionDeps = new ArrayList<>();
final List<AppDependency> userDeps = new ArrayList<>();
Map<AppArtifactKey, AppDependency> versionMap = new HashMap<>();
Map<ModuleIdentifier, ModuleVersionIdentifier> userModules = new HashMap<>();
for (ResolvedArtifact a : compileCp.getResolvedConfiguration().getResolvedArtifacts()) {
final File f = a.getFile();
if (!"jar".equals(a.getExtension()) && !f.isDirectory()) {
continue;
}
userModules.put(getModuleId(a), a.getModuleVersion().getId());
AppDependency dependency = toAppDependency(a);
userDeps.add(dependency);
versionMap.put(new AppArtifactKey(dependency.getArtifact().getGroupId(), dependency.getArtifact().getArtifactId(),
dependency.getArtifact().getClassifier()), dependency);
final Dependency dep;
if (f.isDirectory()) {
dep = processQuarkusDir(a, f.toPath().resolve(BootstrapConstants.META_INF), appBuilder);
} else {
try (FileSystem artifactFs = FileSystems.newFileSystem(f.toPath(), null)) {
dep = processQuarkusDir(a, artifactFs.getPath(BootstrapConstants.META_INF), appBuilder);
} catch (IOException e) {
throw new GradleException("Failed to process " + f, e);
}
}
if (dep != null) {
extensionDeps.add(dep);
}
collectDependencies(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME, appBuilder, extensionDeps, userDeps, versionMap,
userModules);
if (mode == LaunchMode.TEST) {
collectDependencies(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME, appBuilder, extensionDeps, userDeps,
versionMap, userModules);
}
List<AppDependency> deploymentDeps = new ArrayList<>();
List<AppDependency> fullDeploymentDeps = new ArrayList<>();
final List<AppDependency> deploymentDeps = new ArrayList<>();
final List<AppDependency> fullDeploymentDeps = new ArrayList<>();
if (!extensionDeps.isEmpty()) {
final Configuration deploymentConfig = project.getConfigurations()
.detachedConfiguration(extensionDeps.toArray(new Dependency[extensionDeps.size()]));
@@ -165,21 +147,15 @@ public class AppModelGradleResolver implements AppModelResolver {
if (userVersion != null) {
continue;
}
AppDependency dependency = toAppDependency(a);
deploymentDeps.add(alignVersion(dependency, versionMap));
final AppDependency dependency = toAppDependency(a);
fullDeploymentDeps.add(dependency);
if (!userDeps.contains(dependency)) {
deploymentDeps.add(alignVersion(dependency, versionMap));
}
}
}
fullDeploymentDeps.addAll(deploymentDeps);
fullDeploymentDeps.addAll(userDeps);
Iterator<AppDependency> it = deploymentDeps.iterator();
while (it.hasNext()) {
AppDependency val = it.next();
if (userDeps.contains(val)) {
it.remove();
}
}
// In the case of quarkusBuild (which is the primary user of this),
// it's not necessary to actually resolve the original application JAR
if (!appArtifact.isResolved()) {
@@ -202,6 +178,39 @@ public class AppModelGradleResolver implements AppModelResolver {
return this.appModel = appBuilder.build();
}
private void collectDependencies(String configName, AppModel.Builder appBuilder, final List<Dependency> extensionDeps,
final List<AppDependency> userDeps, Map<AppArtifactKey, AppDependency> versionMap,
Map<ModuleIdentifier, ModuleVersionIdentifier> userModules) {
final Configuration config = project.getConfigurations().getByName(configName);
for (ResolvedArtifact a : config.getResolvedConfiguration().getResolvedArtifacts()) {
final File f = a.getFile();
if (!"jar".equals(a.getExtension()) && !f.isDirectory()) {
continue;
}
userModules.put(getModuleId(a), a.getModuleVersion().getId());
AppDependency dependency = toAppDependency(a);
userDeps.add(dependency);
versionMap
.put(new AppArtifactKey(dependency.getArtifact().getGroupId(), dependency.getArtifact().getArtifactId(),
dependency.getArtifact().getClassifier()), dependency);
final Dependency dep;
if (f.isDirectory()) {
dep = processQuarkusDir(a, f.toPath().resolve(BootstrapConstants.META_INF), appBuilder);
} else {
try (FileSystem artifactFs = FileSystems.newFileSystem(f.toPath(), null)) {
dep = processQuarkusDir(a, artifactFs.getPath(BootstrapConstants.META_INF), appBuilder);
} catch (IOException e) {
throw new GradleException("Failed to process " + f, e);
}
}
if (dep != null) {
extensionDeps.add(dep);
}
}
}
private AppDependency alignVersion(AppDependency dependency, Map<AppArtifactKey, AppDependency> versionMap) {
AppArtifactKey appKey = new AppArtifactKey(dependency.getArtifact().getGroupId(),
dependency.getArtifact().getArtifactId(),

View File

@@ -10,6 +10,7 @@ import org.gradle.api.tasks.SourceSet;
import io.quarkus.bootstrap.model.AppArtifact;
import io.quarkus.bootstrap.resolver.AppModelResolver;
import io.quarkus.runtime.LaunchMode;
public class QuarkusPluginExtension {
@@ -97,8 +98,12 @@ public class QuarkusPluginExtension {
project.getVersion().toString());
}
public AppModelResolver resolveAppModel() {
return new AppModelGradleResolver(project);
public AppModelResolver getAppModelResolver() {
return getAppModelResolver(LaunchMode.NORMAL);
}
public AppModelResolver getAppModelResolver(LaunchMode mode) {
return new AppModelGradleResolver(project, mode);
}
/**

View File

@@ -54,7 +54,7 @@ public class QuarkusBuild extends QuarkusTask {
getLogger().lifecycle("building quarkus runner");
final AppArtifact appArtifact = extension().getAppArtifact();
final AppModelResolver modelResolver = extension().resolveAppModel();
final AppModelResolver modelResolver = extension().getAppModelResolver();
try {
// this needs to be done otherwise the app artifact doesn't get a proper path
modelResolver.resolveModel(appArtifact);

View File

@@ -238,7 +238,7 @@ public class QuarkusDev extends QuarkusTask {
StringBuilder classPathManifest = new StringBuilder();
final AppModel appModel;
final AppModelResolver modelResolver = extension().resolveAppModel();
final AppModelResolver modelResolver = extension().getAppModelResolver();
try {
final AppArtifact appArtifact = extension.getAppArtifact();
appArtifact.setPath(extension.outputDirectory().toPath());

View File

@@ -39,7 +39,7 @@ public class QuarkusGenerateConfig extends QuarkusTask {
getLogger().lifecycle("generating example config");
final AppArtifact appArtifact = extension().getAppArtifact();
final AppModelResolver modelResolver = extension().resolveAppModel();
final AppModelResolver modelResolver = extension().getAppModelResolver();
if (extension().resourcesDir().isEmpty()) {
throw new GradleException("No resources directory, cannot create application.properties");
}

View File

@@ -344,7 +344,7 @@ public class QuarkusNative extends QuarkusTask {
getLogger().lifecycle("building native image");
final AppArtifact appArtifact = extension().getAppArtifact();
final AppModelResolver modelResolver = extension().resolveAppModel();
final AppModelResolver modelResolver = extension().getAppModelResolver();
try {
modelResolver.resolveModel(appArtifact);
} catch (AppModelResolverException e) {

View File

@@ -42,7 +42,7 @@ public abstract class QuarkusPlatformTask extends QuarkusTask {
}
return QuarkusJsonPlatformDescriptorResolver.newInstance()
.setArtifactResolver(extension().resolveAppModel())
.setArtifactResolver(extension().getAppModelResolver())
.setMessageWriter(msgWriter)
.resolveFromBom(
getRequiredProperty(props, "quarkusPlatformGroupId"),

View File

@@ -11,6 +11,7 @@ import org.gradle.api.tasks.testing.Test;
import io.quarkus.bootstrap.BootstrapConstants;
import io.quarkus.bootstrap.model.AppModel;
import io.quarkus.gradle.QuarkusPluginExtension;
import io.quarkus.runtime.LaunchMode;
public class QuarkusTestConfig extends QuarkusTask {
@@ -22,7 +23,8 @@ public class QuarkusTestConfig extends QuarkusTask {
public void setupTest() {
final QuarkusPluginExtension quarkusExt = extension();
try {
final AppModel deploymentDeps = quarkusExt.resolveAppModel().resolveModel(quarkusExt.getAppArtifact());
final AppModel deploymentDeps = quarkusExt.getAppModelResolver(LaunchMode.TEST)
.resolveModel(quarkusExt.getAppArtifact());
final String nativeRunner = getProject().getBuildDir().toPath().resolve(quarkusExt.finalName() + "-runner")
.toAbsolutePath()
.toString();