Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to enable workspace discovery in NORMAL mode #25933

Merged
merged 1 commit into from
Jun 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ public class BootstrapConfig {
@ConfigItem(defaultValue = "false")
boolean effectiveModelBuilder;

/**
* If set to true, workspace discovery will be enabled for all launch modes.
* Usually, workspace discovery is enabled by default only for dev and test modes.
*/
@ConfigItem(defaultValue = "false")
Boolean workspaceDiscovery;

/**
* Whether to throw an error, warn or silently ignore misaligned platform BOM imports
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,24 @@ public Object buildAll(String modelName, ModelParameter parameter, Project proje
final Configuration deploymentConfig = classpathBuilder.getDeploymentConfiguration();
final PlatformImports platformImports = classpathBuilder.getPlatformImports();

final ResolvedDependency appArtifact = getProjectArtifact(project, mode);
boolean workspaceDiscovery = LaunchMode.DEVELOPMENT.equals(mode) || LaunchMode.TEST.equals(mode)
|| Boolean.parseBoolean(System.getProperty(BootstrapConstants.QUARKUS_BOOTSTRAP_WORKSPACE_DISCOVERY));
if (!workspaceDiscovery) {
Object o = project.getProperties().get(BootstrapConstants.QUARKUS_BOOTSTRAP_WORKSPACE_DISCOVERY);
if (o != null) {
workspaceDiscovery = Boolean.parseBoolean(o.toString());
}
}

final ResolvedDependency appArtifact = getProjectArtifact(project, workspaceDiscovery);
final ApplicationModelBuilder modelBuilder = new ApplicationModelBuilder()
.setAppArtifact(appArtifact)
.addReloadableWorkspaceModule(appArtifact.getKey())
.setPlatformImports(platformImports);

final Map<ArtifactKey, ResolvedDependencyBuilder> appDependencies = new LinkedHashMap<>();
collectDependencies(classpathConfig.getResolvedConfiguration(), mode, project, appDependencies, modelBuilder,
appArtifact.getWorkspaceModule().mutable());
collectDependencies(classpathConfig.getResolvedConfiguration(), workspaceDiscovery,
project, appDependencies, modelBuilder, appArtifact.getWorkspaceModule().mutable());
collectExtensionDependencies(project, deploymentConfig, appDependencies);

for (ResolvedDependencyBuilder d : appDependencies.values()) {
Expand All @@ -115,7 +124,7 @@ public Object buildAll(String modelName, ModelParameter parameter, Project proje
return modelBuilder.build();
}

public static ResolvedDependency getProjectArtifact(Project project, LaunchMode mode) {
public static ResolvedDependency getProjectArtifact(Project project, boolean workspaceDiscovery) {
final ResolvedDependencyBuilder appArtifact = ResolvedDependencyBuilder.newInstance()
.setGroupId(project.getGroup().toString())
.setArtifactId(project.getName())
Expand All @@ -133,7 +142,7 @@ public static ResolvedDependency getProjectArtifact(Project project, LaunchMode

initProjectModule(project, mainModule, javaConvention.getSourceSets().findByName(SourceSet.MAIN_SOURCE_SET_NAME),
SourceSet.MAIN_SOURCE_SET_NAME, ArtifactSources.MAIN);
if (mode.equals(LaunchMode.TEST) || mode.equals(LaunchMode.DEVELOPMENT)) {
if (workspaceDiscovery) {
initProjectModule(project, mainModule, javaConvention.getSourceSets().findByName(SourceSet.TEST_SOURCE_SET_NAME),
SourceSet.TEST_SOURCE_SET_NAME, ArtifactSources.TEST);
}
Expand Down Expand Up @@ -185,7 +194,7 @@ private void collectExtensionDependencies(Project project, Configuration deploym
}

private void collectDependencies(ResolvedConfiguration configuration,
LaunchMode mode, Project project, Map<ArtifactKey, ResolvedDependencyBuilder> appDependencies,
boolean workspaceDiscovery, Project project, Map<ArtifactKey, ResolvedDependencyBuilder> appDependencies,
ApplicationModelBuilder modelBuilder, WorkspaceModule.Mutable wsModule) {

final Set<ResolvedArtifact> resolvedArtifacts = configuration.getResolvedArtifacts();
Expand All @@ -197,7 +206,8 @@ private void collectDependencies(ResolvedConfiguration configuration,

configuration.getFirstLevelModuleDependencies()
.forEach(d -> {
collectDependencies(d, mode, project, appDependencies, artifactFiles, new HashSet<>(), modelBuilder,
collectDependencies(d, workspaceDiscovery, project, appDependencies, artifactFiles, new HashSet<>(),
modelBuilder,
wsModule,
(byte) (COLLECT_TOP_EXTENSION_RUNTIME_NODES | COLLECT_DIRECT_DEPS | COLLECT_RELOADABLE_MODULES));
});
Expand Down Expand Up @@ -238,7 +248,8 @@ private void collectDependencies(ResolvedConfiguration configuration,
}
}

private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency resolvedDep, LaunchMode mode, Project project,
private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency resolvedDep, boolean workspaceDiscovery,
Project project,
Map<ArtifactKey, ResolvedDependencyBuilder> appDependencies, Set<File> artifactFiles,
Set<ArtifactKey> processedModules, ApplicationModelBuilder modelBuilder, WorkspaceModule.Mutable parentModule,
byte flags) {
Expand All @@ -262,8 +273,7 @@ private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency res
}

PathCollection paths = null;
if ((LaunchMode.DEVELOPMENT.equals(mode) || LaunchMode.TEST.equals(mode)) &&
a.getId().getComponentIdentifier() instanceof ProjectComponentIdentifier) {
if (workspaceDiscovery && a.getId().getComponentIdentifier() instanceof ProjectComponentIdentifier) {

final Project projectDep = project.getRootProject().findProject(
((ProjectComponentIdentifier) a.getId().getComponentIdentifier()).getProjectPath());
Expand Down Expand Up @@ -320,7 +330,8 @@ private void collectDependencies(org.gradle.api.artifacts.ResolvedDependency res
processedModules.add(new GACT(resolvedDep.getModuleGroup(), resolvedDep.getModuleName()));
for (org.gradle.api.artifacts.ResolvedDependency child : resolvedDep.getChildren()) {
if (!processedModules.contains(new GACT(child.getModuleGroup(), child.getModuleName()))) {
collectDependencies(child, mode, project, appDependencies, artifactFiles, processedModules, modelBuilder,
collectDependencies(child, workspaceDiscovery, project, appDependencies, artifactFiles, processedModules,
modelBuilder,
projectModule, flags);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import io.quarkus.bootstrap.BootstrapConstants;
import io.quarkus.bootstrap.BootstrapException;
import io.quarkus.bootstrap.app.CuratedApplication;
import io.quarkus.bootstrap.app.QuarkusBootstrap;
Expand Down Expand Up @@ -115,6 +116,14 @@ public void close() throws IOException {
}
}

private static boolean isWorkspaceDiscovery(QuarkusBootstrapMojo mojo) {
String v = System.getProperty(BootstrapConstants.QUARKUS_BOOTSTRAP_WORKSPACE_DISCOVERY);
if (v == null) {
v = mojo.mavenProject().getProperties().getProperty(BootstrapConstants.QUARKUS_BOOTSTRAP_WORKSPACE_DISCOVERY);
}
return Boolean.parseBoolean(v);
}

public class QuarkusMavenAppBootstrap implements Closeable {

private CuratedApplication prodApp;
Expand All @@ -123,9 +132,11 @@ public class QuarkusMavenAppBootstrap implements Closeable {

private MavenArtifactResolver artifactResolver(QuarkusBootstrapMojo mojo, LaunchMode mode)
throws MojoExecutionException {
isWorkspaceDiscovery(mojo);
try {
return MavenArtifactResolver.builder()
.setWorkspaceDiscovery(mode == LaunchMode.DEVELOPMENT || mode == LaunchMode.TEST)
.setWorkspaceDiscovery(
mode == LaunchMode.DEVELOPMENT || mode == LaunchMode.TEST || isWorkspaceDiscovery(mojo))
.setCurrentProject(mojo.mavenProject().getFile().toString())
.setPreferPomsFromWorkspace(mode == LaunchMode.DEVELOPMENT || mode == LaunchMode.TEST)
.setRepositorySystem(repoSystem)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ public interface BootstrapConstants {
String PLATFORM_PROPERTIES_ARTIFACT_ID_SUFFIX = "-quarkus-platform-properties";

String PLATFORM_PROPERTY_PREFIX = "platform.";

String QUARKUS_BOOTSTRAP_WORKSPACE_DISCOVERY = "quarkus.bootstrap.workspace-discovery";
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ class BuildIT extends MojoTestBase {
private RunningInvoker running;
private File testDir;

@Test
void testQuarkusBootstrapWorkspaceDiscovery() throws Exception {
testDir = initProject("projects/project-with-extension", "projects/project-with-extension-build");
running = new RunningInvoker(testDir, false);
MavenProcessInvocationResult result = running
.execute(List.of("clean", "compile", "quarkus:build", "-Dquarkus.bootstrap.workspace-discovery"), Map.of());
assertThat(result.getProcess().waitFor()).isZero();

launch(TestContext.FAST_NO_PREFIX, "/app/hello/local-modules", new File(testDir, "runner"), "",
"[org.acme:acme-common-transitive:1.0-SNAPSHOT, org.acme:acme-common:1.0-SNAPSHOT, org.acme:acme-library:1.0-SNAPSHOT, org.acme:acme-quarkus-ext-deployment:1.0-SNAPSHOT, org.acme:acme-quarkus-ext:1.0-SNAPSHOT]");
}

@Test
void testCustomTestSourceSets()
throws MavenInvocationException, IOException, InterruptedException {
Expand Down Expand Up @@ -179,6 +191,11 @@ private void launch(TestContext context, String outputPrefix, String expectedMes
}

private void launch(TestContext context, File testDir, String outputPrefix, String expectedMessage) throws IOException {
launch(context, "/hello", testDir, outputPrefix, expectedMessage);
}

private void launch(TestContext context, String path, File testDir, String outputPrefix, String expectedMessage)
throws IOException {
File output = new File(testDir, String.format("target/%s%soutput.log", context.prefix, outputPrefix));
output.createNewFile();
Process process = JarRunnerIT
Expand All @@ -187,7 +204,7 @@ private void launch(TestContext context, File testDir, String outputPrefix, Stri
Collections.emptyList())
.start();
try {
Assertions.assertEquals(expectedMessage, DevModeTestUtils.getHttpResponse("/hello"));
Assertions.assertEquals(expectedMessage, DevModeTestUtils.getHttpResponse(path));
} finally {
process.destroy();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core-deployment</artifactId>
<artifactId>quarkus-arc-deployment</artifactId>
</dependency>
<dependency>
<groupId>org.acme</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
package org.acme.quarkus.ext.deployment;

import java.util.stream.Collectors;

import javax.inject.Singleton;

import io.quarkus.arc.deployment.SyntheticBeanBuildItem;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.maven.dependency.Dependency;

import org.acme.AcmeQuarkusExtRecorder;
import org.acme.ModuleList;

class AcmeQuarkusExtProcessor {

Expand All @@ -12,4 +24,17 @@ FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}

@BuildStep
@Record(ExecutionTime.STATIC_INIT)
SyntheticBeanBuildItem syntheticBean(AcmeQuarkusExtRecorder recorder, CurateOutcomeBuildItem curateOutcome) {
var localModules = curateOutcome.getApplicationModel().getDependencies().stream()
.filter(Dependency::isWorkspaceModule)
.map(Dependency::toCompactCoords)
.sorted()
.collect(Collectors.toList());
return SyntheticBeanBuildItem.configure(ModuleList.class)
.scope(Singleton.class)
.runtimeValue(recorder.initLocalModules(localModules))
.done();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-core</artifactId>
<artifactId>quarkus-arc</artifactId>
</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.acme;

import java.util.List;

import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;

@Recorder
public class AcmeQuarkusExtRecorder {

public RuntimeValue<ModuleList> initLocalModules(List<String> localModules) {
return new RuntimeValue<>(new ModuleList(localModules));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.acme;

import java.util.List;

public class ModuleList {

private final List<String> localModules;

public ModuleList(List<String> localModules) {
this.localModules = localModules;
}

public List<String> getModules() {
return localModules;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import org.eclipse.microprofile.config.inject.ConfigProperty;


import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

@Path("/hello")
public class HelloResource {
Expand All @@ -21,6 +19,9 @@ public class HelloResource {
@ConfigProperty(name = "greeting")
String greeting;

@Inject
ModuleList moduleList;

public HelloResource(CommonBean common, LibraryBean library) {
this.common = java.util.Objects.requireNonNull(common);
this.library = java.util.Objects.requireNonNull(library);
Expand All @@ -38,4 +39,11 @@ public String hello() {
public String greeting() {
return greeting;
}

@GET
@Path("/local-modules")
@Produces(MediaType.TEXT_PLAIN)
public String localModules() {
return moduleList.getModules().toString();
}
}