Skip to content

Commit

Permalink
Merge pull request #26692 from aloubyansky/ws-module-hierarchy
Browse files Browse the repository at this point in the history
Bootstrap option to enable workspace module parent hierarchy initialization
  • Loading branch information
aloubyansky authored Jul 13, 2022
2 parents cda8d94 + 8c04013 commit 9638383
Show file tree
Hide file tree
Showing 22 changed files with 307 additions and 153 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ protected boolean createWorkspace() {
return false;
}

protected boolean workspaceModuleParentHierarchy() {
return false;
}

protected void addWorkspaceModule(TsArtifact a) {
if (wsModules.isEmpty()) {
wsModules = new ArrayList<>();
Expand Down Expand Up @@ -76,14 +80,20 @@ protected QuarkusBootstrap.Builder initBootstrapBuilder() throws Exception {
System.setProperty("basedir", ws.toAbsolutePath().toString());
final Model appPom = appJar.getPomModel();

final List<Dependency> moduleDeps = appPom.getDependencies().stream()
final List<Dependency> bomModules = (appPom.getDependencyManagement() == null ? List.<Dependency> of()
: appPom.getDependencyManagement().getDependencies()).stream()
.filter(d -> "import".equals(d.getScope())
&& d.getGroupId().equals(appPom.getGroupId()))
.collect(Collectors.toList());

final List<Dependency> depModules = appPom.getDependencies().stream()
.filter(d -> d.getGroupId().equals(appPom.getGroupId()) &&
(d.getType().isEmpty() || ArtifactCoords.TYPE_JAR.equals(d.getType())))
.collect(Collectors.toList());

final Path appModule;
final Path appPomXml;
if (moduleDeps.isEmpty() || appPom.getParent() != null) {
if (depModules.isEmpty() && bomModules.isEmpty() || appPom.getParent() != null) {
appModule = ws;
appPomXml = ws.resolve("pom.xml");
ModelUtils.persistModel(appPomXml, appPom);
Expand All @@ -100,16 +110,30 @@ protected QuarkusBootstrap.Builder initBootstrapBuilder() throws Exception {
parent.setArtifactId(parentPom.getArtifactId());
parent.setVersion(parentPom.getVersion());

// BOM modules
for (Dependency bomModule : bomModules) {
parentPom.getModules().add(bomModule.getArtifactId());
final String moduleVersion = bomModule.getVersion();
Model modulePom = ModelUtils.readModel(resolver
.resolve(ArtifactCoords.pom(bomModule.getGroupId(), bomModule.getArtifactId(), moduleVersion))
.getResolvedPaths().getSinglePath());
modulePom.setParent(parent);
final Path moduleDir = IoUtils.mkdirs(ws.resolve(modulePom.getArtifactId()));
ModelUtils.persistModel(moduleDir.resolve("pom.xml"), modulePom);
}

// APP module
parentPom.getModules().add(appPom.getArtifactId());
appModule = ws.resolve(appPom.getArtifactId());
Files.createDirectories(appModule);
appPom.setParent(parent);
appPomXml = appModule.resolve("pom.xml");
ModelUtils.persistModel(appPomXml, appPom);

// dependency modules
final Map<ArtifactKey, String> managedVersions = new HashMap<>();
collectManagedDeps(appPom, managedVersions);
for (Dependency moduleDep : moduleDeps) {
for (Dependency moduleDep : depModules) {
parentPom.getModules().add(moduleDep.getArtifactId());
final String moduleVersion = moduleDep.getVersion() == null
? managedVersions.get(ArtifactKey.of(moduleDep.getGroupId(), moduleDep.getArtifactId(),
Expand Down Expand Up @@ -196,6 +220,7 @@ protected QuarkusBootstrap.Builder initBootstrapBuilder() throws Exception {

final LocalProject appProject = new BootstrapMavenContext(BootstrapMavenContext.config()
.setWorkspaceDiscovery(true)
.setWorkspaceModuleParentHierarchy(workspaceModuleParentHierarchy())
.setRootProjectDir(ws)
.setCurrentProject(appPomXml.toString()))
.getCurrentProject();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package io.quarkus.deployment.runnerjar;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Set;
import java.util.stream.Collectors;

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.bootstrap.workspace.WorkspaceModule;
import io.quarkus.bootstrap.workspace.WorkspaceModuleId;

public class DependencyVersionOverridesManagedVersionTest extends BootstrapFromOriginalJarTestBase {

Expand All @@ -11,6 +19,13 @@ protected boolean createWorkspace() {
return true;
}

@Override
protected boolean workspaceModuleParentHierarchy() {
// this is to simply make sure the workspace modules available
// through ApplicationModel.getWorkspaceModules() include parent POMs and BOMs
return true;
}

@Override
protected TsArtifact composeApplication() {

Expand All @@ -22,7 +37,7 @@ protected TsArtifact composeApplication() {
final TsArtifact extB_100_rt = extB_100.getRuntime();
addToExpectedLib(extB_100_rt);

final TsArtifact bom = new TsArtifact("test.quarkus", "test-bom", null, "pom", "1.0.0");
final TsArtifact bom = TsArtifact.pom("test-bom");
bom.addManagedDependency(platformDescriptor());
bom.addManagedDependency(platformProperties());
bom.addManagedDependency(new TsDependency(extA_100.getRuntime()));
Expand All @@ -43,4 +58,15 @@ protected TsArtifact composeApplication() {

return appJar;
}

@Override
protected void assertAppModel(ApplicationModel model) {
assertThat(model.getWorkspaceModules().stream().map(WorkspaceModule::getId).collect(Collectors.toSet()))
.isEqualTo(Set.of(
WorkspaceModuleId.of(TsArtifact.DEFAULT_GROUP_ID, "app-parent", TsArtifact.DEFAULT_VERSION),
WorkspaceModuleId.of(TsArtifact.DEFAULT_GROUP_ID, "test-bom", TsArtifact.DEFAULT_VERSION),
WorkspaceModuleId.of(TsArtifact.DEFAULT_GROUP_ID, "app", TsArtifact.DEFAULT_VERSION),
WorkspaceModuleId.of(TsArtifact.DEFAULT_GROUP_ID, "ext-a", "1.0.1"),
WorkspaceModuleId.of(TsArtifact.DEFAULT_GROUP_ID, "ext-b", "1.0.0")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.maven.cli.transfer.QuietMavenTransferListener;
Expand Down Expand Up @@ -49,20 +48,11 @@ public void doExecute(QuarkusProject quarkusProject, MessageWriter log) throws M
throw new MojoExecutionException("This goal requires a Quarkus extension registry client to be enabled");
}

// to support profiles
final String emb = System.getProperty("quarkus.bootstrap.effective-model-builder");
System.setProperty("quarkus.bootstrap.effective-model-builder", "true");

final Collection<Path> createdDirs = ensureResolvable(new DefaultArtifact(project.getGroupId(),
project.getArtifactId(), ArtifactCoords.TYPE_POM, project.getVersion()));
try {
processProjectState(quarkusProject);
} finally {
if (emb == null) {
System.clearProperty("quarkus.bootstrap.effective-model-builder");
} else {
System.setProperty("quarkus.bootstrap.effective-model-builder", emb);
}
for (Path p : createdDirs) {
IoUtils.recursiveDelete(p);
}
Expand All @@ -84,7 +74,7 @@ protected ApplicationModel resolveApplicationModel() throws MojoExecutionExcepti
private Collection<Path> ensureResolvable(Artifact a) throws MojoExecutionException {
final DependencyNode root;
try {
root = artifactResolver().collectDependencies(a, Collections.emptyList()).getRoot();
root = artifactResolver().collectDependencies(a, List.of()).getRoot();
} catch (Exception e) {
throw new MojoExecutionException("Failed to collect dependencies of " + a, e);
}
Expand Down Expand Up @@ -155,6 +145,10 @@ protected MavenArtifactResolver initArtifactResolver() throws MojoExecutionExcep
.setRemoteRepositories(repos)
// To support multi-module projects that haven't been installed
.setPreferPomsFromWorkspace(true)
// to support profiles
.setEffectiveModelBuilder(true)
// to initialize WorkspaceModule parents and BOM modules
.setWorkspaceModuleParentHierarchy(true)
.build();
} catch (BootstrapMavenException e) {
throw new MojoExecutionException("Failed to initialize Maven artifact resolver", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,31 @@ default WorkspaceModule getApplicationModule() {
}

default Collection<WorkspaceModule> getWorkspaceModules() {
final Map<WorkspaceModuleId, WorkspaceModule> modules = new HashMap<>();
final Map<WorkspaceModuleId, WorkspaceModule> result = new HashMap<>();
collectModules(getAppArtifact().getWorkspaceModule(), result);
for (ResolvedDependency d : getDependencies()) {
final WorkspaceModule module = d.getWorkspaceModule();
if (module != null) {
modules.putIfAbsent(module.getId(), module);
collectModules(d.getWorkspaceModule(), result);
}
return result.values();
}

private static void collectModules(WorkspaceModule module, Map<WorkspaceModuleId, WorkspaceModule> collected) {
if (module == null) {
return;
}
collected.putIfAbsent(module.getId(), module);

WorkspaceModule parent = module.getParent();
if (parent != null) {
collectModules(parent, collected);
}

for (Dependency d : module.getDirectDependencyConstraints()) {
if (!Dependency.SCOPE_IMPORT.equals(d.getScope())
|| !(d instanceof ResolvedDependency)) {
continue;
}
collectModules(((ResolvedDependency) d).getWorkspaceModule(), collected);
}
return modules.values();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ public Builder setAdditionalTestClasspathElements(Collection<String> elements) {
return this;
}

@Override
public Builder setParent(WorkspaceModule parent) {
DefaultWorkspaceModule.this.parent = parent;
return this;
}

@Override
public WorkspaceModule build() {
final DefaultWorkspaceModule module = DefaultWorkspaceModule.this;
Expand Down Expand Up @@ -176,6 +182,11 @@ public Collection<String> getTestClasspathDependencyExclusions() {
public Collection<String> getAdditionalTestClasspathElements() {
return DefaultWorkspaceModule.this.additionalTestClasspathElements;
}

@Override
public WorkspaceModule getParent() {
return parent;
}
}

private WorkspaceModuleId id;
Expand All @@ -187,6 +198,7 @@ public Collection<String> getAdditionalTestClasspathElements() {
private List<Dependency> directDeps;
private Collection<String> testClasspathDependencyExclusions = List.of();
private Collection<String> additionalTestClasspathElements = List.of();
private WorkspaceModule parent;

private DefaultWorkspaceModule() {
}
Expand Down Expand Up @@ -270,6 +282,11 @@ public Collection<String> getAdditionalTestClasspathElements() {
return additionalTestClasspathElements;
}

@Override
public WorkspaceModule getParent() {
return parent;
}

@Override
public Mutable mutable() {
return new DefaultWorkspaceModule(this).new Builder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ default PathTree getContentTree(String classifier) {

Collection<String> getAdditionalTestClasspathElements();

WorkspaceModule getParent();

Mutable mutable();

interface Mutable extends WorkspaceModule {
Expand All @@ -85,6 +87,8 @@ interface Mutable extends WorkspaceModule {

Mutable setAdditionalTestClasspathElements(Collection<String> elements);

Mutable setParent(WorkspaceModule parent);

WorkspaceModule build();

default Mutable mutable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public static Dependency of(String groupId, String artifactId, String version) {

public ArtifactDependency(String groupId, String artifactId, String classifier, String type, String version) {
super(groupId, artifactId, classifier, type, version);
this.scope = "compile";
this.scope = SCOPE_COMPILE;
flags = 0;
}

Expand All @@ -29,7 +29,7 @@ public ArtifactDependency(String groupId, String artifactId, String classifier,
}

public ArtifactDependency(ArtifactCoords coords, int... flags) {
this(coords, "compile", flags);
this(coords, SCOPE_COMPILE, flags);
}

public ArtifactDependency(ArtifactCoords coords, String scope, int... flags) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

public interface Dependency extends ArtifactCoords {

String SCOPE_COMPILE = "compile";
String SCOPE_IMPORT = "import";

public static Dependency of(String groupId, String artifactId) {
return new ArtifactDependency(groupId, artifactId, null, ArtifactCoords.TYPE_JAR, null);
}
Expand All @@ -11,7 +14,7 @@ public static Dependency of(String groupId, String artifactId, String version) {
}

public static Dependency pomImport(String groupId, String artifactId, String version) {
return new ArtifactDependency(groupId, artifactId, null, ArtifactCoords.TYPE_POM, version, "import", false);
return new ArtifactDependency(groupId, artifactId, null, ArtifactCoords.TYPE_POM, version, SCOPE_IMPORT, false);
}

String getScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.maven.dependency.ArtifactDependency;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.maven.dependency.GACTV;
import io.quarkus.maven.dependency.ResolvedArtifactDependency;
import io.quarkus.maven.dependency.ResolvedDependency;
import io.quarkus.maven.dependency.ResolvedDependencyBuilder;
Expand Down Expand Up @@ -100,7 +99,7 @@ public static Closeable main(String... args) {
.setMode(QuarkusBootstrap.Mode.DEV)
.setTargetDirectory(targetClasses)
.setAppArtifact(appArtifact)
.setManagingProject(new GACTV("io.quarkus", "quarkus-bom", "", "pom", getQuarkusVersion()))
.setManagingProject(ArtifactCoords.pom("io.quarkus", "quarkus-bom", getQuarkusVersion()))
.setForcedDependencies(deps.entrySet().stream().map(s -> {
String[] parts = s.getKey().split(":");
Dependency artifact;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ public static TsArtifact jar(String artifactId, String version) {
return new TsArtifact(DEFAULT_GROUP_ID, artifactId, EMPTY, TYPE_JAR, version);
}

public static TsArtifact pom(String artifactId) {
return new TsArtifact(DEFAULT_GROUP_ID, artifactId, EMPTY, TYPE_POM, DEFAULT_VERSION);
}

public static TsArtifact pom(String artifactId, String version) {
return new TsArtifact(DEFAULT_GROUP_ID, artifactId, EMPTY, TYPE_POM, version);
}

public static TsArtifact pom(String groupId, String artifactId, String version) {
return new TsArtifact(groupId, artifactId, EMPTY, TYPE_POM, version);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.VersionRangeResult;
import org.eclipse.aether.util.artifact.JavaScopes;
import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor;
import org.eclipse.aether.version.Version;

Expand Down Expand Up @@ -202,7 +203,7 @@ public ApplicationModel resolveModel(WorkspaceModule module)

final Map<ArtifactKey, Dependency> managedMap = new HashMap<>();
for (io.quarkus.maven.dependency.Dependency d : module.getDirectDependencyConstraints()) {
if (d.getScope().equals("import")) {
if (io.quarkus.maven.dependency.Dependency.SCOPE_IMPORT.equals(d.getScope())) {
mvn.resolveDescriptor(toAetherArtifact(d)).getManagedDependencies()
.forEach(dep -> managedMap.putIfAbsent(getKey(dep.getArtifact()), dep));
} else {
Expand Down Expand Up @@ -289,9 +290,9 @@ private Set<String> getExcludedScopes() {
return Set.of();
}
if (devmode) {
return Set.of("test");
return Set.of(JavaScopes.TEST);
}
return Set.of("provided", "test");
return Set.of(JavaScopes.PROVIDED, JavaScopes.TEST);
}

private ApplicationModel buildAppModel(ResolvedDependency appArtifact, CollectRequest collectRtDepsRequest,
Expand Down Expand Up @@ -335,7 +336,8 @@ private io.quarkus.maven.dependency.ResolvedDependency resolve(ArtifactCoords ap
}

final WorkspaceModule resolvedModule = mvn.getProjectModuleResolver() == null ? null
: mvn.getProjectModuleResolver().getProjectModule(appArtifact.getGroupId(), appArtifact.getArtifactId());
: mvn.getProjectModuleResolver().getProjectModule(appArtifact.getGroupId(), appArtifact.getArtifactId(),
appArtifact.getVersion());
if (resolvedArtifact != null && resolvedModule == null) {
return resolvedArtifact;
}
Expand Down Expand Up @@ -523,5 +525,4 @@ private ArtifactDescriptorResult resolveDescriptor(Artifact artifact, List<Remot
throw new BootstrapMavenException("Failed to read descriptor of " + artifact, e);
}
}

}
Loading

0 comments on commit 9638383

Please sign in to comment.