Skip to content
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 @@ -14,9 +14,11 @@
import io.quarkus.domino.manifest.SbomGenerator;
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.paths.PathTree;
import io.quarkus.paths.PathVisit;
import io.quarkus.registry.catalog.Extension;
import io.quarkus.registry.catalog.ExtensionCatalog;
import io.quarkus.registry.util.PlatformArtifacts;
import io.quarkus.util.GlobUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
Expand All @@ -30,6 +32,7 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
Expand All @@ -52,6 +55,23 @@
@Mojo(name = "dependencies-to-build", threadSafe = true, requiresProject = false)
public class DependenciesToBuildMojo extends AbstractMojo {

/**
* Compiles glob patters to {@link Pattern}.
*
* @param patterns glob patterns
* @return compiled patterns
*/
private static List<Pattern> compilePatterns(List<String> patterns) {
if (patterns == null || patterns.isEmpty()) {
return List.of();
}
final List<Pattern> compiled = new ArrayList<>(patterns.size());
for (var pattern : patterns) {
compiled.add(Pattern.compile(GlobUtil.toRegexPattern(pattern)));
}
return compiled;
}

@Parameter(required = false, defaultValue = "${project.file}")
File projectFile;

Expand Down Expand Up @@ -206,8 +226,13 @@ public class DependenciesToBuildMojo extends AbstractMojo {
@Parameter(required = false, property = "flatManifest")
boolean flatManifest;

@Parameter(required = false, property = "redhatSupported")
boolean redhatSupported;
/**
* Extension metadata key glob patterns used when determining whether an extension should be selected for a rebuild
* from source. The default value is {@code *-support}.
*/
@Parameter(property = "supportPatterns", defaultValue = "*-support")
List<String> supportPatterns;
private List<Pattern> compiledSupportPatterns;

/**
* Whether to calculate hashes for manifested components
Expand Down Expand Up @@ -403,12 +428,38 @@ private void collectManagedByTargetBom(DependencyNode node,
}
}

private List<Pattern> getCompiledSupportPatters() {
if (compiledSupportPatterns == null) {
var result = new ArrayList<Pattern>(supportPatterns.size());
for (var pattern : supportPatterns) {
result.add(Pattern.compile(pattern));
}
compiledSupportPatterns = result;
}
return compiledSupportPatterns;
}

private static boolean isMatchesSupportPattern(Extension extension, List<Pattern> patterns) {
for (var key : extension.getMetadata().keySet()) {
for (var pattern : patterns) {
if (pattern.matcher(key).matches()) {
return true;
}
}
}
return false;
}

private boolean isSelected(Extension ext) {
var patterns = getCompiledSupportPatters();
return patterns.isEmpty() || isMatchesSupportPattern(ext, patterns);
}

private Collection<ArtifactCoords> getExtensionArtifacts(ExtensionCatalog catalog) throws MojoExecutionException {
final List<ArtifactCoords> supported = new ArrayList<>();
for (Extension ext : catalog.getExtensions()) {
ArtifactCoords rtArtifact = ext.getArtifact();
if (isExcluded(rtArtifact)
|| redhatSupported && !ext.getMetadata().containsKey(("redhat-support"))) {
if (isExcluded(rtArtifact) || isSelected(ext)) {
continue;
}
supported.add(ext.getArtifact());
Expand All @@ -422,19 +473,8 @@ private Collection<ArtifactCoords> getExtensionArtifacts(ExtensionCatalog catalo
} catch (BootstrapMavenException e1) {
throw new MojoExecutionException("Failed to resolve " + rtArtifact, e1);
}
deploymentCoords = PathTree.ofDirectoryOrArchive(rtJar).apply(BootstrapConstants.DESCRIPTOR_PATH, visit -> {
if (visit == null) {
return null;
}
final Properties props = new Properties();
try (BufferedReader reader = Files.newBufferedReader(visit.getPath())) {
props.load(reader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
final String str = props.getProperty(BootstrapConstants.PROP_DEPLOYMENT_ARTIFACT);
return str == null ? null : ArtifactCoords.fromString(str);
});
deploymentCoords = PathTree.ofDirectoryOrArchive(rtJar).apply(BootstrapConstants.DESCRIPTOR_PATH,
DependenciesToBuildMojo::getDeploymentArtifactCoords);
if (deploymentCoords == null) {
throw new MojoExecutionException(
"Failed to determine the corresponding deployment artifact for " + rtArtifact.toCompactCoords());
Expand All @@ -445,6 +485,20 @@ private Collection<ArtifactCoords> getExtensionArtifacts(ExtensionCatalog catalo
return supported;
}

private static ArtifactCoords getDeploymentArtifactCoords(PathVisit visit) {
if (visit == null) {
return null;
}
final Properties props = new Properties();
try (BufferedReader reader = Files.newBufferedReader(visit.getPath())) {
props.load(reader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
final String str = props.getProperty(BootstrapConstants.PROP_DEPLOYMENT_ARTIFACT);
return str == null ? null : ArtifactCoords.fromString(str);
}

private boolean isManifestMode() {
return manifest || flatManifest;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,16 @@ public List<String> checkDependencyVersions(ExtensionCatalog catalog) {
+ " is not an instance of java.util.List but " + o.getClass().getName());
return;
}
if (!((List<?>) o).stream().filter(i -> CHECK_SUPPORT_LEVELS.contains(i)).findFirst().isPresent()) {
if (!((List<?>) o).stream().anyMatch(CHECK_SUPPORT_LEVELS::contains)) {
return;
}
var a = new DefaultArtifact(extensionCoords.getGroupId(), extensionCoords.getArtifactId(),
extensionCoords.getClassifier(), extensionCoords.getType(), extensionCoords.getVersion());
final DependencyNode root;
try {
root = repoSystem.collectDependencies(repoSession, new CollectRequest()
.setRootArtifact(new DefaultArtifact("org.acme", "acme-app", null, "jar", "1.0-SNAPSHOT"))
.setRootArtifact(new DefaultArtifact("org.acme", "acme-app",
ArtifactCoords.DEFAULT_CLASSIFIER, ArtifactCoords.TYPE_JAR, "1.0-SNAPSHOT"))
.setManagedDependencies(bomConstraints)
.addDependency(new Dependency(a, "compile"))
.setRepositories(repos)).getRoot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@
import io.quarkus.paths.PathTree;
import io.quarkus.registry.Constants;
import io.quarkus.registry.catalog.CatalogMapperHelper;
import io.quarkus.registry.catalog.Extension;
import io.quarkus.registry.catalog.ExtensionCatalog;
import io.quarkus.registry.util.PlatformArtifacts;
import io.quarkus.util.GlobUtil;
import java.io.*;
import java.net.MalformedURLException;
import java.nio.file.FileVisitResult;
Expand All @@ -77,6 +79,7 @@
import java.util.Properties;
import java.util.Set;
import java.util.StringJoiner;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
Expand Down Expand Up @@ -149,6 +152,23 @@ public class GeneratePlatformProjectMojo extends AbstractMojo {
public static final String EXCLUDE = "exclude";
public static final String INCLUDE = "include";

/**
* Compiles glob patters to {@link Pattern}.
*
* @param patterns glob patterns
* @return compiled patterns
*/
private static List<Pattern> compilePatterns(List<String> patterns) {
if (patterns == null || patterns.isEmpty()) {
return List.of();
}
final List<Pattern> compiled = new ArrayList<>(patterns.size());
for (var pattern : patterns) {
compiled.add(Pattern.compile(GlobUtil.toRegexPattern(pattern)));
}
return compiled;
}

@Component
RepositorySystem repoSystem;

Expand Down Expand Up @@ -189,6 +209,13 @@ public class GeneratePlatformProjectMojo extends AbstractMojo {
@Parameter(property = "recordUpdatedBoms")
boolean recordUpdatedBoms;

/**
* Extension metadata key glob patterns used when determining whether an extension should be selected for a rebuild
* from source. The default value is {@code *-support}.
*/
@Parameter(property = "dominoBuildExtensionSupportPatterns", defaultValue = "*-support")
List<String> dominoBuildExtensionSupportPatterns;

Artifact universalBom;
MavenArtifactResolver nonWsResolver;
MavenArtifactResolver wsAwareResolver;
Expand Down Expand Up @@ -417,6 +444,7 @@ private void generateDominoCliConfig() throws MojoExecutionException {
private void generateDominoManifestCliConfig() throws MojoExecutionException {
final Path dominoDir = deleteAndCreateDir(Path.of(DominoInfo.CONFIG_DIR_NAME).resolve("manifest"));
final SbomerGlobalConfig globalSbomerConfig = platformConfig.getSbomer();
List<Pattern> extensionSupportPatterns = null;
SbomerConfig sbomerConfig = null;
for (PlatformMember member : members.values()) {
if (!member.config().isEnabled() || member.config().isHidden()) {
Expand Down Expand Up @@ -499,12 +527,15 @@ private void generateDominoManifestCliConfig() throws MojoExecutionException {
throw new IllegalStateException("The SBOM generator for member " + member.config().getName()
+ " is configured to include only supported extensions but no support metadata override sources were provided");
}
if (extensionSupportPatterns == null) {
extensionSupportPatterns = compilePatterns(dominoBuildExtensionSupportPatterns);
}
selectedKeys = new HashSet<>(metadataOverrides.size());
for (Path p : metadataOverrides) {
try {
ExtensionCatalog c = ExtensionCatalog.fromFile(p);
for (var e : c.getExtensions()) {
if (e.getMetadata().containsKey("redhat-support")) {
if (isMatchesDominoBuildPattern(e, extensionSupportPatterns)) {
var key = e.getArtifact().getKey();
selectedKeys.add(key);
selectedKeys.add(ArtifactKey.of(key.getGroupId(), key.getArtifactId() + "-deployment",
Expand Down Expand Up @@ -541,6 +572,10 @@ && isExtensionCandidate(a, member.config().getExtensionGroupIds(), excludePatter
private void generateDominoBuildCliConfig() throws MojoExecutionException {
final Path dominoDir = deleteAndCreateDir(
Path.of(DominoInfo.CONFIG_DIR_NAME).normalize().toAbsolutePath().resolve("build"));
List<Pattern> supportPatterns = compilePatterns(dominoBuildExtensionSupportPatterns);
if (supportPatterns.isEmpty()) {
return;
}
for (PlatformMember member : members.values()) {
if (!member.config().isEnabled() || member.config().isHidden()) {
continue;
Expand Down Expand Up @@ -590,7 +625,7 @@ private void generateDominoBuildCliConfig() throws MojoExecutionException {
try {
ExtensionCatalog c = ExtensionCatalog.fromFile(p);
for (var e : c.getExtensions()) {
if (e.getMetadata().containsKey("redhat-support")) {
if (isMatchesDominoBuildPattern(e, supportPatterns)) {
var key = e.getArtifact().getKey();
selectedKeys.add(key);
selectedKeys.add(ArtifactKey.of(key.getGroupId(), key.getArtifactId() + "-deployment",
Expand Down Expand Up @@ -621,6 +656,17 @@ && isExtensionCandidate(a, member.config().getExtensionGroupIds(), excludePatter
}
}

private static boolean isMatchesDominoBuildPattern(Extension extension, List<Pattern> patterns) {
for (var key : extension.getMetadata().keySet()) {
for (var pattern : patterns) {
if (pattern.matcher(key).matches()) {
return true;
}
}
}
return false;
}

private void addExtensionArtifacts(Artifact a, ProjectDependencyConfig.Mutable dominoConfig) {
final Artifact resolved;
final boolean relocated;
Expand Down Expand Up @@ -3450,9 +3496,10 @@ private static boolean isBlank(String s) {
private static Path deleteAndCreateDir(Path dir) throws MojoExecutionException {
IoUtils.recursiveDelete(dir);
try {
return Files.createDirectories(dir);
Files.createDirectories(dir);
} catch (IOException e) {
throw new MojoExecutionException("Failed to create directory " + dir, e);
}
return dir;
}
}
Loading