Skip to content

Commit

Permalink
Allow to use forced deps managed by BOM
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvavrik authored and mjurc committed Oct 8, 2024
1 parent 10fa75f commit d9d4b84
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dependency {

String groupId() default "";

String artifactId();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.test.services.quarkus;

import static io.quarkus.test.services.quarkus.QuarkusMavenPluginBuildHelper.findJvmArtifact;
import static io.quarkus.test.services.quarkus.QuarkusMavenPluginBuildHelper.findNativeBuildExecutable;
import static io.quarkus.test.utils.FileUtils.findTargetFile;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -33,10 +34,6 @@ public class ProdQuarkusApplicationManagedResourceBuilder extends ArtifactQuarku
static final String EXE = ".exe";
static final String TARGET = "target";

private static final String JVM_RUNNER = "-runner.jar";
private static final String QUARKUS_APP = "quarkus-app";
private static final String QUARKUS_RUN = "quarkus-run.jar";

private final ServiceLoader<QuarkusApplicationManagedResourceBinding> managedResourceBindingsRegistry = ServiceLoader
.load(QuarkusApplicationManagedResourceBinding.class);

Expand Down Expand Up @@ -119,8 +116,7 @@ private Path tryToReuseOrBuildArtifact() {
// custom native executable has different name, therefore we can safely re-use it
artifactLocation = findNativeBuildExecutable(targetFolder, requiresCustomBuild(), getApplicationFolder());
} else if (!requiresCustomBuild()) {
artifactLocation = findTargetFile(targetFolder, JVM_RUNNER)
.or(() -> findTargetFile(targetFolder.resolve(QUARKUS_APP), QUARKUS_RUN));
artifactLocation = findJvmArtifact(targetFolder);
}
}

Expand All @@ -140,6 +136,9 @@ private Path buildArtifact() {
return buildArtifactUsingQuarkusBootstrap();
});
}
if (!getForcedDependencies().isEmpty()) {
return new QuarkusMavenPluginBuildHelper(this, getTargetFolderForLocalArtifacts()).jvmModeBuild();
}
return buildArtifactUsingQuarkusBootstrap();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

import org.apache.commons.lang3.StringUtils;

import io.quarkus.builder.Version;
import io.quarkus.deployment.configuration.BuildTimeConfigurationReader;
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.maven.dependency.ArtifactDependency;
Expand Down Expand Up @@ -217,13 +216,20 @@ public void initForcedDependencies(Dependency[] forcedDependencies) {
requiresCustomBuild = true;
this.forcedDependencies = Stream.of(forcedDependencies).map(d -> {
String groupId = StringUtils.defaultIfEmpty(resolveProperty(d.groupId()), QUARKUS_GROUP_ID_DEFAULT);
String version = StringUtils.defaultIfEmpty(resolveProperty(d.version()), Version.getVersion());
String version = getVersion(d);
ArtifactCoords artifactCoords = ArtifactCoords.jar(groupId, d.artifactId(), version);
return new ArtifactDependency(artifactCoords, DEPENDENCY_SCOPE_DEFAULT, DEPENDENCY_DIRECT_FLAG);
}).collect(Collectors.toList());
}
}

private static String getVersion(Dependency dependency) {
if (dependency.version() == null || dependency.version().isEmpty()) {
return null;
}
return resolveProperty(dependency.version());
}

protected void configureLogging() {
context.getOwner().withProperty("quarkus.log.console.format", "%d{HH:mm:ss,SSS} %s%e%n");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@

class QuarkusMavenPluginBuildHelper {

private static final String JVM_RUNNER = "-runner.jar";
private static final String QUARKUS_APP = "quarkus-app";
private static final String QUARKUS_RUN = "quarkus-run.jar";
private static final String CUSTOM_RUNNER_DIR = "custom-build";
private static final Set<String> FAILSAFE_BUILD_LIFECYCLE_PHASES = Set.of("verify", "install", "deploy",
"integration-test");
Expand Down Expand Up @@ -145,17 +148,41 @@ private Path prepareMavenProject(Path mavenBuildProjectRoot) {
return mavenBuildProjectRoot;
}

Path jvmModeBuild() {
return buildArtifact(Mode.JVM).orElseThrow(() -> new RuntimeException("""
Failed to build JAR artifact, the most likely reason is that Quarkus Maven plugin is missing.
Please add 'quarkus-maven-plugin' to your project.
"""));
}

Optional<Path> buildNativeExecutable() {
return buildArtifact(Mode.NATIVE);
}

private Optional<Path> buildArtifact(Mode mode) {
Objects.requireNonNull(targetFolderForLocalArtifacts);
var mavenBuildProjectRoot = prepareMavenProject(appFolder.resolve("mvn-build"));

// build artifact with Quarkus Maven Plugin
try {
new Command(getBuildNativeExecutableCmd()).onDirectory(mavenBuildProjectRoot).runAndWait();
new Command(getBuildCmd(mode)).onDirectory(mavenBuildProjectRoot).runAndWait();
} catch (IOException | InterruptedException e) {
throw new RuntimeException("Failed to build native executable: " + e.getMessage());
throw new RuntimeException("Failed to build artifact: " + e.getMessage());
}

if (mode == Mode.JVM) {
return findJvmArtifact(mavenBuildProjectRoot.resolve(TARGET)).map(Path::of);
} else {
return findNativeExecutable(mavenBuildProjectRoot);
}
}

static Optional<String> findJvmArtifact(Path targetFolder) {
return findTargetFile(targetFolder, JVM_RUNNER)
.or(() -> findTargetFile(targetFolder.resolve(QUARKUS_APP), QUARKUS_RUN));
}

private Optional<Path> findNativeExecutable(Path mavenBuildProjectRoot) {
return findTargetFile(mavenBuildProjectRoot.resolve(TARGET), nativeRunnerName())
.map(Path::of)
.flatMap(this::moveToPermanentLocation);
Expand Down Expand Up @@ -195,15 +222,20 @@ private boolean isCustomBuildRequired() {
// runtime properties provided at build time are currently available during the build time and so are custom props
// therefore we can't allow re-using of native executable with application specific properties (e.g. "withProperty")
resourceBuilder.createSnapshotOfBuildProperties();
return resourceBuilder.requiresCustomBuild() || resourceBuilder.hasAppSpecificConfigProperties();
return resourceBuilder.requiresCustomBuild() || resourceBuilder.hasAppSpecificConfigProperties()
|| !forcedDependencies.isEmpty();
}

private String[] getBuildNativeExecutableCmd() {
private String[] getBuildCmd(Mode mode) {
Stream<String> cmdStream = Stream.of(mvnCmd(), "-B", "--no-transfer-progress", "clean", "install",
"-Dquarkus.build.skip=false", "-Dnative", "-DskipTests", "-DskipITs", "-Dcheckstyle.skip",
"-Dquarkus.build.skip=false");
if (mode == Mode.NATIVE) {
cmdStream = Stream.concat(cmdStream, Stream.of("-Dnative"));
}
cmdStream = Stream.concat(cmdStream, Stream.of("-DskipTests", "-DskipITs", "-Dcheckstyle.skip",
toMvnSystemProperty(PLATFORM_VERSION.getPropertyKey(), getVersion()),
toMvnSystemProperty(PLATFORM_GROUP_ID.getPropertyKey(), PLATFORM_GROUP_ID.get()),
toMvnSystemProperty(PLUGIN_VERSION.getPropertyKey(), getPluginVersion()));
toMvnSystemProperty(PLUGIN_VERSION.getPropertyKey(), getPluginVersion())));
var cmdLineBuildArgs = getCmdLineBuildArgs();
if (!cmdLineBuildArgs.isEmpty()) {
cmdStream = Stream.concat(cmdStream, cmdLineBuildArgs.stream());
Expand Down Expand Up @@ -377,7 +409,7 @@ private void addForcedDependenciesToNewPom(Document pomDocument, Node projectEle
}
newDependency.appendChild(groupId);
// <version>
if (!forcedDependency.getVersion().isEmpty()) {
if (forcedDependency.getVersion() != null && !forcedDependency.getVersion().isEmpty()) {
Element version = pomDocument.createElement("version");
version.setTextContent(forcedDependency.getVersion());
newDependency.appendChild(version);
Expand Down Expand Up @@ -494,4 +526,9 @@ private static String nativeRunnerName() {
return NATIVE_RUNNER;
}
}

private enum Mode {
JVM,
NATIVE
}
}

0 comments on commit d9d4b84

Please sign in to comment.