Skip to content

Commit

Permalink
Detect and manifest relocated extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
aloubyansky committed Apr 17, 2024
1 parent 0984276 commit d298f80
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -774,8 +774,7 @@ private DependencyNode collectDependencies(ArtifactCoords coords, List<Dependenc
}

try {
final Artifact a = toAetherArtifact(coords);
var descr = resolver.resolveDescriptor(a);
var descr = resolver.resolveDescriptor(toAetherArtifact(coords));
final Map<ArtifactKey, Dependency> map = new LinkedHashMap<>();
for (var d : managedDeps) {
var art = d.getArtifact();
Expand Down Expand Up @@ -810,11 +809,12 @@ private DependencyNode collectDependencies(ArtifactCoords coords, List<Dependenc
resolver.newResolutionRepositories(descr.getRepositories()));

root = resolver.getSystem().collectDependencies(resolver.getSession(),
MavenArtifactResolver.newCollectRequest(a, directDeps, constraints, List.of(), aggregatedRepos))
MavenArtifactResolver.newCollectRequest(descr.getArtifact(), directDeps, constraints, List.of(),
aggregatedRepos))
.getRoot();
// if the dependencies are not found, make sure the artifact actually exists
if (root.getChildren().isEmpty()) {
resolver.resolve(a);
resolver.resolve(descr.getArtifact());
}
} catch (Exception e) {
if (config.isWarnOnResolutionErrors()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,12 @@
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.aether.util.artifact.JavaScopes;

@Mojo(name = "generate-platform-project", defaultPhase = LifecyclePhase.INITIALIZE, requiresDependencyCollection = ResolutionScope.NONE)
public class GeneratePlatformProjectMojo extends AbstractMojo {
Expand Down Expand Up @@ -399,6 +404,7 @@ private void generateDominoCliConfig() throws MojoExecutionException {
excludePatterns = ArtifactCoordsPattern.toPatterns(dominoConfig.getExcludePatterns());
}

Set<ArtifactKey> selectedKeys = Set.of();
if (sbomConfig != null && sbomConfig.isSupportedExtensionsOnly()) {
List<Path> metadataOverrides = new ArrayList<>();
for (String s : member.config().getMetadataOverrideFiles()) {
Expand All @@ -416,7 +422,7 @@ private void generateDominoCliConfig() 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");
}
final Set<ArtifactKey> selectedKeys = new HashSet<>(metadataOverrides.size());
selectedKeys = new HashSet<>(metadataOverrides.size());
final List<ExtensionCatalog> overrides = new ArrayList<>(metadataOverrides.size());
for (Path p : metadataOverrides) {
try {
Expand All @@ -434,54 +440,13 @@ private void generateDominoCliConfig() throws MojoExecutionException {
key.getClassifier(), key.getType()));
}
}
for (ProjectRelease r : member.getAlignedDecomposedBom().releases()) {
for (ProjectDependency d : r.dependencies()) {
var a = d.artifact();
if (selectedKeys.contains(d.key())
&& isExtensionCandidate(a, member.config().getExtensionGroupIds(), excludePatterns)) {
dominoConfig.addProjectArtifacts(ArtifactCoords.of(a.getGroupId(), a.getArtifactId(),
a.getClassifier(), a.getExtension(), a.getVersion()));
dominoConfig
.addProjectArtifacts(ArtifactCoords.of(a.getGroupId(), a.getArtifactId() + "-deployment",
a.getClassifier(), a.getExtension(), a.getVersion()));
}
}
}
} else {
for (ProjectRelease r : member.getAlignedDecomposedBom().releases()) {
for (ProjectDependency d : r.dependencies()) {
var a = d.artifact();
if (!isExtensionCandidate(a, member.getExtensionGroupIds(), excludePatterns)) {
continue;
}
if (a.getFile() == null) {
try {
a = getNonWorkspaceResolver().resolve(a).getArtifact();
} catch (BootstrapMavenException e) {
throw new RuntimeException("Failed to resolve " + a, e);
}
}
var resolvedArtifact = a;
PathTree.ofArchive(a.getFile().toPath()).accept(BootstrapConstants.DESCRIPTOR_PATH, visit -> {
if (visit != null) {
var props = new Properties();
try (BufferedReader reader = Files.newBufferedReader(visit.getPath())) {
props.load(reader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
dominoConfig.addProjectArtifacts(ArtifactCoords.of(resolvedArtifact.getGroupId(),
resolvedArtifact.getArtifactId(), resolvedArtifact.getClassifier(),
resolvedArtifact.getExtension(), resolvedArtifact.getVersion()));
var deploymentArtifact = props.getProperty(BootstrapConstants.PROP_DEPLOYMENT_ARTIFACT);
if (deploymentArtifact == null) {
getLog().warn("Failed to identify the deployment artifact for " + resolvedArtifact + " in "
+ visit.getUrl());
} else {
dominoConfig.addProjectArtifacts(ArtifactCoords.fromString(deploymentArtifact));
}
}
});
}
for (ProjectRelease r : member.getAlignedDecomposedBom().releases()) {
for (ProjectDependency d : r.dependencies()) {
var a = d.artifact();
if ((selectedKeys.isEmpty() || selectedKeys.contains(d.key()))
&& isExtensionCandidate(a, member.config().getExtensionGroupIds(), excludePatterns)) {
manifestExtensionArtifacts(a, dominoConfig);
}
}
}
Expand All @@ -495,6 +460,60 @@ && isExtensionCandidate(a, member.config().getExtensionGroupIds(), excludePatter
}
}

private void manifestExtensionArtifacts(Artifact a, ProjectDependencyConfig.Mutable dominoConfig) {
final Artifact resolved;
final boolean relocated;
if (a.getFile() == null) {
var resolver = getNonWorkspaceResolver();
// this trick is done to capture relocations, i.e. when {@code a} was relocated to another artifact
var request = new DependencyRequest()
.setCollectRequest(new CollectRequest()
.setRootArtifact(a)
.setDependencies(List.of(new org.eclipse.aether.graph.Dependency(a, JavaScopes.COMPILE, false,
List.of(new org.eclipse.aether.graph.Exclusion("*", "*", "*", "*")))))
.setRepositories(resolver.getRepositories()));
List<DependencyNode> resolvedDeps;
try {
resolvedDeps = resolver.getSystem().resolveDependencies(resolver.getSession(), request).getRoot().getChildren();
} catch (DependencyResolutionException e) {
throw new RuntimeException("Failed to resolve " + a, e);
}
if (resolvedDeps.size() != 1) {
throw new IllegalStateException("Expected a single dependency but got " + resolvedDeps);
}
var node = resolvedDeps.get(0);
resolved = node.getArtifact();
relocated = !node.getRelocations().isEmpty();
} else {
resolved = a;
relocated = false;
}
PathTree.ofArchive(resolved.getFile().toPath()).accept(BootstrapConstants.DESCRIPTOR_PATH, visit -> {
if (visit != null) {
var props = new Properties();
try (BufferedReader reader = Files.newBufferedReader(visit.getPath())) {
props.load(reader);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
if (relocated) {
dominoConfig.addProjectArtifacts(ArtifactCoords.of(a.getGroupId(),
a.getArtifactId(), a.getClassifier(), a.getExtension(), a.getVersion()));
}
dominoConfig.addProjectArtifacts(ArtifactCoords.of(resolved.getGroupId(),
resolved.getArtifactId(), resolved.getClassifier(),
resolved.getExtension(), resolved.getVersion()));
var deploymentArtifact = props.getProperty(BootstrapConstants.PROP_DEPLOYMENT_ARTIFACT);
if (deploymentArtifact == null) {
getLog().warn("Failed to identify the deployment artifact for " + resolved + " in "
+ visit.getUrl());
} else {
dominoConfig.addProjectArtifacts(ArtifactCoords.fromString(deploymentArtifact));
}
}
});
}

private static boolean isExtensionCandidate(Artifact a, Collection<String> extensionGroupIds,
Collection<ArtifactCoordsPattern> excludePatterns) {
if (!a.getExtension().equals(ArtifactCoords.TYPE_JAR)
Expand Down

0 comments on commit d298f80

Please sign in to comment.