Skip to content

Commit

Permalink
Include compile-only dependencies in the ApplicationModel
Browse files Browse the repository at this point in the history
  • Loading branch information
aloubyansky committed Sep 25, 2023
1 parent 383c126 commit c4ce3ec
Show file tree
Hide file tree
Showing 12 changed files with 288 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -115,7 +114,17 @@ public Path getPath(Path workDir) throws IOException {

public static Collection<Dependency> getDeploymentOnlyDeps(ApplicationModel model) {
return model.getDependencies().stream().filter(d -> d.isDeploymentCp() && !d.isRuntimeCp())
.map(d -> new ArtifactDependency(d)).collect(Collectors.toSet());
.map(ArtifactDependency::new).collect(Collectors.toSet());
}

public static Collection<Dependency> getDependenciesWithFlag(ApplicationModel model, int flag) {
var set = new HashSet<Dependency>();
for (var d : model.getDependencies(flag)) {
if (d.isFlagSet(flag)) {
set.add(new ArtifactDependency(d));
}
}
return set;
}

@Override
Expand Down Expand Up @@ -159,7 +168,7 @@ protected void testBootstrap(QuarkusBootstrap creator) throws Exception {
}
}

List<String> missingEntries = Collections.emptyList();
List<String> missingEntries = List.of();
for (String entry : expectedLib) {
if (!actualMainLib.remove(entry)) {
if (missingEntries.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
import java.util.HashSet;
import java.util.Set;

import org.eclipse.aether.util.artifact.JavaScopes;

import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.bootstrap.resolver.TsArtifact;
import io.quarkus.bootstrap.resolver.TsDependency;
import io.quarkus.bootstrap.resolver.TsQuarkusExt;
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.maven.dependency.ArtifactDependency;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.maven.dependency.DependencyFlags;
import io.quarkus.maven.dependency.GACTV;

public class ProvidedExtensionDepsTest extends BootstrapFromOriginalJarTestBase {

Expand All @@ -22,6 +24,10 @@ protected TsArtifact composeApplication() {
final TsArtifact extADep = TsArtifact.jar("ext-a-dep");
addToExpectedLib(extADep);

final TsArtifact depC1 = TsArtifact.jar("dep-c");
addToExpectedLib(depC1);
extADep.addDependency(depC1);

final TsArtifact extAProvidedDep = TsArtifact.jar("ext-a-provided-dep");

final TsArtifact extADeploymentDep = TsArtifact.jar("ext-a-deployment-dep");
Expand All @@ -30,32 +36,56 @@ protected TsArtifact composeApplication() {
final TsQuarkusExt extA = new TsQuarkusExt("ext-a");
addToExpectedLib(extA.getRuntime());
extA.getRuntime()
.addDependency(new TsDependency(extADep))
.addDependency(extADep)
.addDependency(new TsDependency(extAProvidedDep, "provided"));
extA.getDeployment()
.addDependency(new TsDependency(extADeploymentDep))
.addDependency(extADeploymentDep)
.addDependency(new TsDependency(extAOptionalDeploymentDep, "provided"));

final TsQuarkusExt extB = new TsQuarkusExt("ext-b");
this.install(extB);

final TsArtifact someProvidedDep = TsArtifact.jar("some-provided-dep");
final TsArtifact directProvidedDep = TsArtifact.jar("direct-provided-dep");

// TODO this is when provided leaks into runtime
//final TsArtifact depC2 = TsArtifact.jar("dep-c", "2");
//addToExpectedLib(depC2); // in this case provided version will override the compile one
//directProvidedDep.addDependency(depC2);

final TsArtifact transitiveProvidedDep = TsArtifact.jar("transitive-provided-dep");
directProvidedDep.addDependency(transitiveProvidedDep);

return TsArtifact.jar("app")
.addManagedDependency(platformDescriptor())
.addManagedDependency(platformProperties())
.addDependency(extA)
.addDependency(extB, "provided")
.addDependency(new TsDependency(someProvidedDep, "provided"));
.addDependency(new TsDependency(directProvidedDep, "provided"));
}

@Override
protected void assertAppModel(ApplicationModel model) throws Exception {
final Set<Dependency> expected = new HashSet<>();
expected.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-deployment", "1"), "compile",
Set<Dependency> expected = new HashSet<>();
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-a-deployment", "1"),
DependencyFlags.DEPLOYMENT_CP));
expected.add(new ArtifactDependency(new GACTV("io.quarkus.bootstrap.test", "ext-a-deployment-dep", "1"), "compile",
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-a-deployment-dep", "1"),
DependencyFlags.DEPLOYMENT_CP));
assertEquals(expected, getDeploymentOnlyDeps(model));

expected = new HashSet<>();
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-b", "1"),
JavaScopes.PROVIDED,
DependencyFlags.RUNTIME_EXTENSION_ARTIFACT,
DependencyFlags.DIRECT,
DependencyFlags.TOP_LEVEL_RUNTIME_EXTENSION_ARTIFACT,
DependencyFlags.COMPILE_ONLY));
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "direct-provided-dep", "1"),
JavaScopes.PROVIDED,
DependencyFlags.DIRECT,
DependencyFlags.COMPILE_ONLY));
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "transitive-provided-dep", "1"),
JavaScopes.PROVIDED,
DependencyFlags.COMPILE_ONLY));
assertEquals(expected, getDependenciesWithFlag(model, DependencyFlags.COMPILE_ONLY));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package io.quarkus.deployment.runnerjar;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.aether.util.artifact.JavaScopes;

import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.bootstrap.resolver.TsArtifact;
import io.quarkus.bootstrap.resolver.TsDependency;
import io.quarkus.bootstrap.resolver.TsQuarkusExt;
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.maven.dependency.ArtifactDependency;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.maven.dependency.DependencyFlags;

public class ProvidedExtensionDepsTestModeTest extends BootstrapFromOriginalJarTestBase {

@Override
protected boolean isBootstrapForTestMode() {
return true;
}

@Override
protected TsArtifact composeApplication() {

final TsArtifact extADep = TsArtifact.jar("ext-a-dep");
addToExpectedLib(extADep);

final TsArtifact depC1 = TsArtifact.jar("dep-c");
extADep.addDependency(depC1);

final TsArtifact extAProvidedDep = TsArtifact.jar("ext-a-provided-dep");

final TsArtifact extADeploymentDep = TsArtifact.jar("ext-a-deployment-dep");
final TsArtifact extAOptionalDeploymentDep = TsArtifact.jar("ext-a-provided-deployment-dep");

final TsQuarkusExt extA = new TsQuarkusExt("ext-a");
addToExpectedLib(extA.getRuntime());
extA.getRuntime()
.addDependency(extADep)
.addDependency(new TsDependency(extAProvidedDep, "provided"));
extA.getDeployment()
.addDependency(extADeploymentDep)
.addDependency(new TsDependency(extAOptionalDeploymentDep, "provided"));

final TsQuarkusExt extB = new TsQuarkusExt("ext-b");
this.install(extB);
addToExpectedLib(extB.getRuntime()); // test mode enabled

final TsArtifact directProvidedDep = TsArtifact.jar("direct-provided-dep");
addToExpectedLib(directProvidedDep); // test mode enabled

final TsArtifact depC2 = TsArtifact.jar("dep-c", "2");
addToExpectedLib(depC2); // in this case provided version will override the compile one
directProvidedDep.addDependency(depC2);

final TsArtifact transitiveProvidedDep = TsArtifact.jar("transitive-provided-dep");
directProvidedDep.addDependency(transitiveProvidedDep);
addToExpectedLib(transitiveProvidedDep); // test mode enabled

return TsArtifact.jar("app")
.addManagedDependency(platformDescriptor())
.addManagedDependency(platformProperties())
.addDependency(new TsDependency(directProvidedDep, "provided"))
.addDependency(extA)
.addDependency(extB, "provided");
}

@Override
protected void assertAppModel(ApplicationModel model) throws Exception {

final Set<Dependency> compileOnly = new HashSet<>();
compileOnly.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-b", "1"),
JavaScopes.PROVIDED,
DependencyFlags.RUNTIME_CP,
DependencyFlags.DEPLOYMENT_CP,
DependencyFlags.RUNTIME_EXTENSION_ARTIFACT,
DependencyFlags.DIRECT,
DependencyFlags.TOP_LEVEL_RUNTIME_EXTENSION_ARTIFACT,
DependencyFlags.COMPILE_ONLY));
compileOnly.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "direct-provided-dep", "1"),
JavaScopes.PROVIDED,
DependencyFlags.RUNTIME_CP,
DependencyFlags.DEPLOYMENT_CP,
DependencyFlags.DIRECT,
DependencyFlags.COMPILE_ONLY));
compileOnly.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "transitive-provided-dep", "1"),
JavaScopes.PROVIDED,
DependencyFlags.RUNTIME_CP,
DependencyFlags.DEPLOYMENT_CP,
DependencyFlags.COMPILE_ONLY));
assertEquals(compileOnly, getDependenciesWithFlag(model, DependencyFlags.COMPILE_ONLY));

Set<Dependency> expected = new HashSet<>();
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-a-deployment", "1"),
DependencyFlags.DEPLOYMENT_CP));
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-a-deployment-dep", "1"),
DependencyFlags.DEPLOYMENT_CP));
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-b-deployment", "1"),
JavaScopes.PROVIDED,
DependencyFlags.DEPLOYMENT_CP));

assertEquals(expected, getDeploymentOnlyDeps(model));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ private void collectDependencies(ResolvedConfiguration configuration,
.setVersion(version)
.setResolvedPath(f.toPath())
.setDirect(true)
.setRuntimeCp();
.setRuntimeCp()
.setDeploymentCp();
processQuarkusDependency(artifactBuilder, modelBuilder);
modelBuilder.addDependency(artifactBuilder);
}
Expand All @@ -296,7 +297,8 @@ private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency res
final ArtifactCoords depCoords = toArtifactCoords(a);
final ResolvedDependencyBuilder depBuilder = ResolvedDependencyBuilder.newInstance()
.setCoords(depCoords)
.setRuntimeCp();
.setRuntimeCp()
.setDeploymentCp();
if (isFlagOn(flags, COLLECT_DIRECT_DEPS)) {
depBuilder.setDirect(true);
flags = clearFlag(flags, COLLECT_DIRECT_DEPS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -98,7 +97,8 @@ public void test() throws Exception {
System.setOut(defaultOut);
}

assertEquals(readInLowCase(Paths.get("").toAbsolutePath().resolve("target").resolve("test-classes")
assertEquals(readInLowCase(Path.of("").normalize().toAbsolutePath()
.resolve("target").resolve("test-classes")
.resolve(app.getArtifactFileName() + "." + mode())), readInLowCase(mojoLog));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,25 @@ public interface ApplicationModel {
ResolvedDependency getAppArtifact();

/**
* All the dependencies of an application including runtime and build time dependencies.
* Returns application dependencies that are included into the runtime and augmentation (Quarkus build time)
* classpath.
* <p>
* Note: in production bootstrap mode, {@link io.quarkus.maven.dependency.DependencyFlags#COMPILE_ONLY} dependencies
* will not be included in the result. However, they could still be queries by calling {@link #getDependencies(int)}
* passing in {@link io.quarkus.maven.dependency.DependencyFlags#COMPILE_ONLY} flag as an argument.
*
* @return application runtime and build time dependencies
*/
Collection<ResolvedDependency> getDependencies();

/**
* Returns application dependencies with the requested flags set.
*
* @param flags dependency flags that must be set for a dependency to be included in the result
* @return application dependencies that have requested flags set
*/
Iterable<ResolvedDependency> getDependencies(int flags);

/**
* Runtime dependencies of an application
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package io.quarkus.bootstrap.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -39,7 +42,50 @@ public ResolvedDependency getAppArtifact() {

@Override
public Collection<ResolvedDependency> getDependencies() {
return dependencies;
var result = new ArrayList<ResolvedDependency>(dependencies.size());
for (var d : getDependencies(DependencyFlags.DEPLOYMENT_CP)) {
result.add(d);
}
return result;
}

@Override
public Iterable<ResolvedDependency> getDependencies(int flags) {
return () -> new Iterator<>() {

final Iterator<ResolvedDependency> i = dependencies.iterator();
ResolvedDependency next;

{
moveOn();
}

@Override
public boolean hasNext() {
return next != null;
}

@Override
public ResolvedDependency next() {
if (next == null) {
throw new NoSuchElementException();
}
var current = next;
moveOn();
return current;
}

private void moveOn() {
next = null;
while (i.hasNext()) {
var d = i.next();
if ((d.getFlags() & flags) == flags) {
next = d;
break;
}
}
}
};
}

@Override
Expand Down
Loading

0 comments on commit c4ce3ec

Please sign in to comment.