Skip to content

Commit

Permalink
Include removed dependencies in the ApplicationModel with
Browse files Browse the repository at this point in the history
DependencyFlags.REMOVED
  • Loading branch information
aloubyansky committed Nov 3, 2023
1 parent 31afcb2 commit aa5a0bd
Show file tree
Hide file tree
Showing 16 changed files with 769 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package io.quarkus.deployment.runnerjar;

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

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

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 ExcludedArtifactsTest extends BootstrapFromOriginalJarTestBase {

@Override
protected TsArtifact composeApplication() {

final TsArtifact extADep = TsArtifact.jar("ext-a-dep");
// excluded in the extension descriptor addToExpectedLib(extADep);

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

final TsArtifact depE = TsArtifact.jar("org.banned", "dep-e", "1");
depC.addDependency(depE);
final TsArtifact depG = TsArtifact.jar("dep-g");
depE.addDependency(depG);
addToExpectedLib(depG);

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

final TsQuarkusExt extA = new TsQuarkusExt("ext-a");
addToExpectedLib(extA.getRuntime());
extA.getRuntime().addDependency(extADep);
extA.getDeployment().addDependency(extADeploymentDep);

extA.getDescriptor().set("excluded-artifacts",
extADep.getKey().toString() + ",org.banned*");

final TsArtifact depB = TsArtifact.jar("dep-b");
addToExpectedLib(depB);

final TsArtifact depD = TsArtifact.jar("org.banned.too", "dep-d", "1");
depB.addDependency(depD);

final TsArtifact depF = TsArtifact.jar("org.banned", "dep-f", "1");
depB.addDependency(depF);

return TsArtifact.jar("app")
.addManagedDependency(platformDescriptor())
.addManagedDependency(platformProperties())
.addDependency(extA)
.addDependency(new TsDependency(depB));
}

@Override
protected void assertAppModel(ApplicationModel model) throws Exception {
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));
assertEquals(expected, getDeploymentOnlyDeps(model));

expected = new HashSet<>();
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-a", "1"),
DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP, DependencyFlags.RUNTIME_EXTENSION_ARTIFACT,
DependencyFlags.DIRECT, DependencyFlags.TOP_LEVEL_RUNTIME_EXTENSION_ARTIFACT));
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "dep-c", "1"),
DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP));
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "dep-b", "1"),
DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP, DependencyFlags.DIRECT));
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "dep-g", "1"),
DependencyFlags.RUNTIME_CP, DependencyFlags.DEPLOYMENT_CP));
assertEquals(expected, getDependenciesWithFlag(model, DependencyFlags.RUNTIME_CP));

expected = new HashSet<>();
expected.add(new ArtifactDependency(ArtifactCoords.jar("io.quarkus.bootstrap.test", "ext-a-dep", "1"),
DependencyFlags.REMOVED));
expected.add(new ArtifactDependency(ArtifactCoords.jar("org.banned", "dep-e", "1"), DependencyFlags.REMOVED));
expected.add(new ArtifactDependency(ArtifactCoords.jar("org.banned.too", "dep-d", "1"), DependencyFlags.REMOVED));
expected.add(new ArtifactDependency(ArtifactCoords.jar("org.banned", "dep-f", "1"), DependencyFlags.REMOVED));
assertEquals(expected, getDependenciesWithFlag(model, DependencyFlags.REMOVED));
}
}
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 @@ -9,10 +9,10 @@
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 +22,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,31 +34,34 @@ 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");

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));
}
Expand Down
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 @@ -4,7 +4,6 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import io.quarkus.bootstrap.workspace.WorkspaceModule;
import io.quarkus.bootstrap.workspace.WorkspaceModuleId;
Expand All @@ -26,20 +25,27 @@ 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.
*
* @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
*
* @return runtime dependencies of an application
*/
default Collection<ResolvedDependency> getRuntimeDependencies() {
return getDependencies().stream().filter(Dependency::isRuntimeCp).collect(Collectors.toList());
}
Collection<ResolvedDependency> getRuntimeDependencies();

/**
* Quarkus platforms (BOMs) found in the configuration of an application
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

import io.quarkus.bootstrap.workspace.WorkspaceModule;
import io.quarkus.bootstrap.workspace.WorkspaceModuleId;
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.maven.dependency.ArtifactCoordsPattern;
import io.quarkus.maven.dependency.ArtifactKey;
import io.quarkus.maven.dependency.DependencyFlags;
import io.quarkus.maven.dependency.GACT;
Expand All @@ -36,14 +38,22 @@ public class ApplicationModelBuilder {
final Map<ArtifactKey, ResolvedDependencyBuilder> dependencies = new LinkedHashMap<>();
final Set<ArtifactKey> parentFirstArtifacts = new HashSet<>();
final Set<ArtifactKey> runnerParentFirstArtifacts = new HashSet<>();
final Set<ArtifactKey> excludedArtifacts = new HashSet<>();
final List<ArtifactCoordsPattern> excludedArtifacts = new ArrayList<>();
final Map<ArtifactKey, Set<String>> excludedResources = new HashMap<>(0);
final Set<ArtifactKey> lesserPriorityArtifacts = new HashSet<>();
final Set<ArtifactKey> reloadableWorkspaceModules = new HashSet<>();
final List<ExtensionCapabilities> extensionCapabilities = new ArrayList<>();
PlatformImports platformImports;
final Map<WorkspaceModuleId, WorkspaceModule.Mutable> projectModules = new HashMap<>();

public ApplicationModelBuilder() {
// we never include the ide launcher in the final app model
excludedArtifacts.add(ArtifactCoordsPattern.builder()
.setGroupId("io.quarkus")
.setArtifactId("quarkus-ide-launcher")
.build());
}

public ApplicationModelBuilder setAppArtifact(ResolvedDependency appArtifact) {
this.appArtifact = appArtifact;
return this;
Expand Down Expand Up @@ -97,13 +107,20 @@ public ApplicationModelBuilder addRunnerParentFirstArtifacts(List<ArtifactKey> d
return this;
}

public ApplicationModelBuilder addExcludedArtifact(ArtifactKey deps) {
this.excludedArtifacts.add(deps);
public ApplicationModelBuilder addExcludedArtifact(ArtifactKey key) {
this.excludedArtifacts.add(ArtifactCoordsPattern.builder()
.setGroupId(key.getGroupId())
.setArtifactId(key.getArtifactId())
.setClassifier(key.getClassifier())
.setType(key.getType())
.build());
return this;
}

public ApplicationModelBuilder addExcludedArtifacts(List<ArtifactKey> deps) {
this.excludedArtifacts.addAll(deps);
public ApplicationModelBuilder addExcludedArtifacts(List<ArtifactKey> keys) {
for (var key : keys) {
addExcludedArtifact(key);
}
return this;
}

Expand Down Expand Up @@ -166,7 +183,7 @@ public void handleExtensionProperties(Properties props, String extension) {
break;
case EXCLUDED_ARTIFACTS:
for (String artifact : value.split(",")) {
excludedArtifacts.add(new GACT(artifact.split(":")));
excludedArtifacts.add(ArtifactCoordsPattern.of(artifact));
log.debugf("Extension %s is excluding %s", extension, artifact);
}
break;
Expand Down Expand Up @@ -211,37 +228,43 @@ public void handleExtensionProperties(Properties props, String extension) {
}
}

private boolean isExcluded(ResolvedDependencyBuilder d) {
return excludedArtifacts.contains(d.getKey())
// we never include the ide launcher in the final app model
|| (d.getArtifactId().equals("quarkus-ide-launcher") && d.getGroupId().equals("io.quarkus"));
private boolean isExcluded(ArtifactCoords coords) {
for (var pattern : excludedArtifacts) {
if (pattern.matches(coords)) {
return true;
}
}
return false;
}

List<ResolvedDependency> buildDependencies() {
for (ArtifactKey key : parentFirstArtifacts) {
final ResolvedDependencyBuilder d = dependencies.get(key);
if (d != null) {
if (d != null && !d.isFlagSet(DependencyFlags.REMOVED)) {
d.setFlags(DependencyFlags.CLASSLOADER_PARENT_FIRST);
}
}
for (ArtifactKey key : runnerParentFirstArtifacts) {
final ResolvedDependencyBuilder d = dependencies.get(key);
if (d != null) {
if (d != null && !d.isFlagSet(DependencyFlags.REMOVED)) {
d.setFlags(DependencyFlags.CLASSLOADER_RUNNER_PARENT_FIRST);
}
}
for (ArtifactKey key : lesserPriorityArtifacts) {
final ResolvedDependencyBuilder d = dependencies.get(key);
if (d != null) {
if (d != null && !d.isFlagSet(DependencyFlags.REMOVED)) {
d.setFlags(DependencyFlags.CLASSLOADER_LESSER_PRIORITY);
}
}

final List<ResolvedDependency> result = new ArrayList<>(dependencies.size());
for (ResolvedDependencyBuilder db : this.dependencies.values()) {
if (!isExcluded(db)) {
result.add(db.build());
if (isExcluded(db.getArtifactCoords())) {
db.setFlags(DependencyFlags.REMOVED);
db.clearFlag(DependencyFlags.DEPLOYMENT_CP);
db.clearFlag(DependencyFlags.RUNTIME_CP);
}
result.add(db.build());
}
return result;
}
Expand Down
Loading

0 comments on commit aa5a0bd

Please sign in to comment.