-
Notifications
You must be signed in to change notification settings - Fork 193
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add p2-aware model converter for CycloneDX SBOM generation
- Loading branch information
Showing
6 changed files
with
255 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
eclipse.preferences.version=1 | ||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 | ||
org.eclipse.jdt.core.compiler.compliance=17 | ||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled | ||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning | ||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore | ||
org.eclipse.jdt.core.compiler.release=disabled | ||
org.eclipse.jdt.core.compiler.source=17 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>org.eclipse.tycho.extras</groupId> | ||
<artifactId>tycho-extras</artifactId> | ||
<version>5.0.0-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>tycho-sbom</artifactId> | ||
<name>Tycho SBOM model extension</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.eclipse.tycho</groupId> | ||
<artifactId>tycho-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.tycho</groupId> | ||
<artifactId>tycho-api</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.tycho</groupId> | ||
<artifactId>p2-maven-plugin</artifactId> | ||
<version>${project.version}</version> | ||
<type>maven-plugin</type> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.eclipse.tycho</groupId> | ||
<artifactId>tycho-versions-plugin</artifactId> | ||
<version>${project.version}</version> | ||
<type>maven-plugin</type> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.apache.maven</groupId> | ||
<artifactId>maven-plugin-api</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.codehaus.plexus</groupId> | ||
<artifactId>plexus-component-annotations</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.cyclonedx</groupId> | ||
<artifactId>cyclonedx-maven-plugin</artifactId> | ||
<version>2.7.10</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
127 changes: 127 additions & 0 deletions
127
tycho-extras/tycho-sbom/src/main/java/org/eclipse/tycho/sbom/P2ModelConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 Patrick Ziegler and others. | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License 2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Patrick Ziegler - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.tycho.sbom; | ||
|
||
import java.net.URLEncoder; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Set; | ||
|
||
import org.apache.maven.RepositoryUtils; | ||
import org.apache.maven.artifact.Artifact; | ||
import org.codehaus.plexus.component.annotations.Component; | ||
import org.cyclonedx.maven.DefaultModelConverter; | ||
import org.cyclonedx.maven.ModelConverter; | ||
import org.eclipse.equinox.p2.metadata.IArtifactKey; | ||
import org.eclipse.tycho.ArtifactKey; | ||
import org.eclipse.tycho.ArtifactType; | ||
import org.eclipse.tycho.DefaultArtifactKey; | ||
import org.eclipse.tycho.core.resolver.target.ArtifactTypeHelper; | ||
import org.eclipse.tycho.versions.engine.Versions; | ||
|
||
/** | ||
* Custom implementation of the CycloneDX model converter with support for both | ||
* Maven and p2 artifacts. The generated PURL is usually of the form: | ||
* | ||
* <pre> | ||
* pkg:/p2/<id>@<version>?classifier=<classifier>&location=<download-url> | ||
* </pre> | ||
* | ||
* This converter can be used with the {@code cyclonedx-maven-plugin} by adding | ||
* it as a dependency as follows: | ||
* | ||
* <pre> | ||
* <plugin> | ||
* <groupId>org.cyclonedx</groupId> | ||
* <artifactId>cyclonedx-maven-plugin</artifactId> | ||
* <dependencies> | ||
* <dependency> | ||
* <groupId>org.eclipse.tycho.extras</groupId> | ||
* <artifactId>tycho-sbom</artifactId> | ||
* </dependency> | ||
* </dependencies> | ||
* </plugin> | ||
* </pre> | ||
*/ | ||
@Component(role = ModelConverter.class, hint = "p2") | ||
public class P2ModelConverter extends DefaultModelConverter { | ||
private static final Set<String> SUPPORTED_TYPES = Set.of(ArtifactType.TYPE_BUNDLE_FRAGMENT, | ||
ArtifactType.TYPE_ECLIPSE_PLUGIN, ArtifactType.TYPE_ECLIPSE_FEATURE); | ||
|
||
@Override | ||
public String generatePackageUrl(Artifact artifact) { | ||
if (SUPPORTED_TYPES.contains(artifact.getType())) { | ||
return generateP2PackageUrl(artifact, true, true); | ||
} | ||
return super.generatePackageUrl(artifact); | ||
} | ||
|
||
@Override | ||
public String generatePackageUrl(org.eclipse.aether.artifact.Artifact artifact) { | ||
return generatePackageUrl(RepositoryUtils.toArtifact(artifact)); | ||
} | ||
|
||
@Override | ||
public String generateVersionlessPackageUrl(Artifact artifact) { | ||
if (SUPPORTED_TYPES.contains(artifact.getType())) { | ||
return generateP2PackageUrl(artifact, false, true); | ||
} | ||
return super.generateVersionlessPackageUrl(artifact); | ||
} | ||
|
||
@Override | ||
public String generateVersionlessPackageUrl(org.eclipse.aether.artifact.Artifact artifact) { | ||
return generateVersionlessPackageUrl(RepositoryUtils.toArtifact(artifact)); | ||
} | ||
|
||
@Override | ||
public String generateClassifierlessPackageUrl(org.eclipse.aether.artifact.Artifact artifact) { | ||
Artifact mavenArtifact = RepositoryUtils.toArtifact(artifact); | ||
if (SUPPORTED_TYPES.contains(mavenArtifact.getType())) { | ||
return generateP2PackageUrl(mavenArtifact, true, false); | ||
} | ||
return super.generateClassifierlessPackageUrl(artifact); | ||
} | ||
|
||
private String generateP2PackageUrl(Artifact artifact, boolean withVersion, boolean withClassifier) { | ||
// TODO Resolve "artifact" and use e.g. TychoProjectManager w/ proper qualifier | ||
ArtifactKey artifactKey = new DefaultArtifactKey(artifact.getType(), artifact.getArtifactId(), | ||
Versions.toCanonicalVersion(artifact.getVersion())); | ||
IArtifactKey p2artifactKey = ArtifactTypeHelper.toP2ArtifactKey(artifactKey); | ||
// TODO Try to find p2 location | ||
String location = "unknown"; | ||
if (artifact.getFile() != null) { | ||
location = artifact.getFile().toURI().toString(); | ||
} | ||
if (artifact.getDownloadUrl() != null) { | ||
location = artifact.getDownloadUrl(); | ||
} | ||
String encodedLocation = URLEncoder.encode(location, StandardCharsets.UTF_8); | ||
// | ||
StringBuilder builder = new StringBuilder(); | ||
builder.append("pkg:p2/"); | ||
builder.append(p2artifactKey.getId()); | ||
if (withVersion) { | ||
builder.append('@'); | ||
builder.append(p2artifactKey.getVersion()); | ||
} | ||
builder.append('?'); | ||
if (withClassifier) { | ||
builder.append("classifier="); | ||
builder.append(p2artifactKey.getClassifier()); | ||
builder.append('&'); | ||
} | ||
builder.append("location="); | ||
builder.append(encodedLocation); | ||
return builder.toString(); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
tycho-extras/tycho-sbom/src/main/resources/META-INF/plexus/components.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<component-set> | ||
<components> | ||
<component> | ||
<role>org.cyclonedx.maven.ModelConverter</role> | ||
<hint>p2</hint> | ||
<implementation>org.eclipse.tycho.sbom.P2ModelConverter</implementation> | ||
</component> | ||
</components> | ||
</component-set> |
55 changes: 55 additions & 0 deletions
55
tycho-extras/tycho-sbom/src/test/java/org/eclipse/tycho/sbom/P2ModelConverterTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2023 Patrick Ziegler and others. | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License 2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Patrick Ziegler - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.tycho.sbom; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
import java.net.URLEncoder; | ||
import java.nio.charset.StandardCharsets; | ||
|
||
import org.apache.maven.artifact.Artifact; | ||
import org.apache.maven.artifact.DefaultArtifact; | ||
import org.cyclonedx.maven.ModelConverter; | ||
import org.eclipse.tycho.ArtifactType; | ||
import org.eclipse.tycho.p2maven.repository.EclipsePluginArtifactHandler; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
public class P2ModelConverterTest { | ||
private Artifact artifact; | ||
private ModelConverter modelConverter; | ||
|
||
@Before | ||
public void setUp() { | ||
artifact = new DefaultArtifact("p2.eclipse.plugin", "org.eclipse.platform", "4.30.0.v20231201-0110", "compile", | ||
ArtifactType.TYPE_ECLIPSE_PLUGIN, null, new EclipsePluginArtifactHandler()); | ||
artifact.setDownloadUrl( | ||
"https://download.eclipse.org/releases/2023-12/202312061001/plugins/org.eclipse.platform_4.30.0.v20231201-0110.jar"); | ||
modelConverter = new P2ModelConverter(); | ||
} | ||
|
||
@Test | ||
public void testGeneratePackageUrl() { | ||
String purl = modelConverter.generatePackageUrl(artifact); | ||
String location = URLEncoder.encode(artifact.getDownloadUrl(), StandardCharsets.UTF_8); | ||
assertEquals(purl, | ||
"pkg:p2/[email protected]?classifier=osgi.bundle&location=" + location); | ||
} | ||
|
||
@Test | ||
public void testGeneratePackageUrlWithoutVersion() { | ||
String purl = modelConverter.generateVersionlessPackageUrl(artifact); | ||
String location = URLEncoder.encode(artifact.getDownloadUrl(), StandardCharsets.UTF_8); | ||
assertEquals(purl, "pkg:p2/org.eclipse.platform?classifier=osgi.bundle&location=" + location); | ||
} | ||
} |