Skip to content

Commit

Permalink
fix: remove dummy root component from sbom for python/pip (#64)
Browse files Browse the repository at this point in the history
## Description

Remove dummy root component from sbom for python/pip, as in python you
don't have a root component, just a list of required packages/modules in
requirements.txt

For the purpose, Added new sbom generic feature, to remove from sbom the
root component :

from components list.
from dependencies list.
and from metadata
currently it will be used only by Python/pip.

related to:
RHEcosystemAppEng/exhort-javascript-api#58

Signed-off-by: Zvi Grinberg <zgrinber@redhat.com>
  • Loading branch information
zvigrinberg authored Oct 5, 2023
1 parent f2eb77b commit ceaabb8
Show file tree
Hide file tree
Showing 9 changed files with 22 additions and 180 deletions.
4 changes: 3 additions & 1 deletion src/main/java/com/redhat/exhort/impl/ExhortApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ public String getEndpoint() {
}

public static final void main(String[] args) throws IOException, InterruptedException, ExecutionException {
// System.setProperty("EXHORT_DEV_MOD","true");
AnalysisReport analysisReport = new ExhortApi()
.componentAnalysis("/home/zgrinber/git/exhort-java-api/src/test/resources/tst_manifests/maven/pom_deps_with_no_ignore_common_paths/pom.xml").get();

.stackAnalysis("/home/zgrinber/git/exhort-java-api/src/test/resources/tst_manifests/pip/pip_requirements_txt_no_ignore/requirements.txt").get();
System.out.println(new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(analysisReport));
// AnalysisReport analysisReport = new ExhortApi()
// byte[] analysisReport = new ExhortApi().
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public Content provideStack(Path manifestPath) throws IOException {
});
byte[] requirementsFile = Files.readAllBytes(manifestPath);
handleIgnoredDependencies(new String(requirementsFile), sbom);
// In python' pip requirements.txt, there is no real root element, then need to remove dummy root element that was created for creating the sbom.
sbom.removeRootComponent();
return new Content(sbom.getAsJsonString().getBytes(StandardCharsets.UTF_8), Api.CYCLONEDX_MEDIA_TYPE);
}

Expand Down Expand Up @@ -119,6 +121,8 @@ public Content provideComponent(byte[] manifestContent) throws IOException {
Files.delete(manifestPath);
Files.delete(tempRepository);
handleIgnoredDependencies(new String(manifestContent), sbom);
// In python' pip requirements.txt, there is no real root element, then need to remove dummy root element that was created for creating the sbom.
sbom.removeRootComponent();
return new Content(sbom.getAsJsonString().getBytes(StandardCharsets.UTF_8), Api.CYCLONEDX_MEDIA_TYPE);

}
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/com/redhat/exhort/sbom/CycloneDXSbom.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.stream.Collectors;

import com.github.packageurl.MalformedPackageURLException;
import com.redhat.exhort.tools.Ecosystem;
import org.cyclonedx.BomGeneratorFactory;
import org.cyclonedx.CycloneDxSchema.Version;
import org.cyclonedx.model.Bom;
Expand Down Expand Up @@ -286,4 +285,12 @@ public boolean checkIfPackageInsideDependsOnList(PackageURL component, String na
return result;
}

@Override
public void removeRootComponent()
{
bom.getComponents().removeIf( (component) -> component.getBomRef().equals(this.root.getCoordinates()));
bom.getDependencies().removeIf( (dependency) -> dependency.getRef().equals(this.root.getCoordinates()));
bom.getMetadata().setComponent(null);
}

}
5 changes: 3 additions & 2 deletions src/main/java/com/redhat/exhort/sbom/Sbom.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package com.redhat.exhort.sbom;

import java.util.Collection;
import java.util.function.Predicate;
import com.github.packageurl.PackageURL;

public interface Sbom {
Expand All @@ -30,7 +29,9 @@ public interface Sbom {

public boolean checkIfPackageInsideDependsOnList(PackageURL component, String name);

public enum BelongingCondition
void removeRootComponent();

public enum BelongingCondition
{
NAME("name"),
PURL("purl");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,6 @@ void Test_The_ProvideComponent_Path_Should_Throw_Exception() {
}

private String dropIgnored(String s) {
return s.replaceAll("\\s+","").replaceAll("\"timestamp\":\"[a-zA-Z0-9\\-\\:]+\",", "");
return s.replaceAll("\\s+","").replaceAll("\"timestamp\":\"[a-zA-Z0-9\\-\\:]+\"", "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,9 @@
"specVersion" : "1.4",
"version" : 1,
"metadata" : {
"timestamp" : "2023-09-28T12:40:41Z",
"component" : {
"name" : "root",
"purl" : "pkg:pypi/root",
"type" : "application",
"bom-ref" : "pkg:pypi/root"
}
"timestamp" : "2023-09-28T12:40:41Z"
},
"components" : [
{
"name" : "root",
"purl" : "pkg:pypi/root",
"type" : "application",
"bom-ref" : "pkg:pypi/root"
},
{
"name" : "anyio",
"version" : "3.6.2",
Expand Down Expand Up @@ -195,36 +183,6 @@
}
],
"dependencies" : [
{
"ref" : "pkg:pypi/root",
"dependsOn" : [
"pkg:pypi/anyio@3.6.2",
"pkg:pypi/asgiref@3.4.1",
"pkg:pypi/beautifulsoup4@4.12.2",
"pkg:pypi/certifi@2023.7.22",
"pkg:pypi/chardet@4.0.0",
"pkg:pypi/contextlib2@21.6.0",
"pkg:pypi/fastapi@0.75.1",
"pkg:pypi/flask@2.0.3",
"pkg:pypi/h11@0.13.0",
"pkg:pypi/idna@2.10",
"pkg:pypi/immutables@0.19",
"pkg:pypi/importlib-metadata@4.8.3",
"pkg:pypi/itsdangerous@2.0.1",
"pkg:pypi/jinja2@3.0.3",
"pkg:pypi/markupsafe@2.0.1",
"pkg:pypi/requests@2.25.1",
"pkg:pypi/six@1.16.0",
"pkg:pypi/sniffio@1.2.0",
"pkg:pypi/soupsieve@2.3.2.post1",
"pkg:pypi/starlette@0.17.1",
"pkg:pypi/typing-extensions@4.1.1",
"pkg:pypi/urllib3@1.26.16",
"pkg:pypi/uvicorn@0.17.0",
"pkg:pypi/werkzeug@2.0.3",
"pkg:pypi/zipp@3.6.0"
]
},
{
"ref" : "pkg:pypi/anyio@3.6.2",
"dependsOn" : [ ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,9 @@
"specVersion" : "1.4",
"version" : 1,
"metadata" : {
"timestamp" : "2023-09-28T12:40:47Z",
"component" : {
"name" : "root",
"purl" : "pkg:pypi/root",
"type" : "application",
"bom-ref" : "pkg:pypi/root"
}
"timestamp" : "2023-09-28T12:40:47Z"
},
"components" : [
{
"name" : "root",
"purl" : "pkg:pypi/root",
"type" : "application",
"bom-ref" : "pkg:pypi/root"
},
{
"name" : "anyio",
"version" : "3.6.2",
Expand Down Expand Up @@ -195,36 +183,6 @@
}
],
"dependencies" : [
{
"ref" : "pkg:pypi/root",
"dependsOn" : [
"pkg:pypi/anyio@3.6.2",
"pkg:pypi/asgiref@3.4.1",
"pkg:pypi/beautifulsoup4@4.12.2",
"pkg:pypi/certifi@2023.7.22",
"pkg:pypi/chardet@4.0.0",
"pkg:pypi/contextlib2@21.6.0",
"pkg:pypi/fastapi@0.75.1",
"pkg:pypi/flask@2.0.3",
"pkg:pypi/h11@0.13.0",
"pkg:pypi/idna@2.10",
"pkg:pypi/immutables@0.19",
"pkg:pypi/importlib-metadata@4.8.3",
"pkg:pypi/itsdangerous@2.0.1",
"pkg:pypi/jinja2@3.0.3",
"pkg:pypi/markupsafe@2.0.1",
"pkg:pypi/requests@2.25.1",
"pkg:pypi/six@1.16.0",
"pkg:pypi/sniffio@1.2.0",
"pkg:pypi/soupsieve@2.3.2.post1",
"pkg:pypi/starlette@0.17.1",
"pkg:pypi/typing-extensions@4.1.1",
"pkg:pypi/urllib3@1.26.16",
"pkg:pypi/uvicorn@0.17.0",
"pkg:pypi/werkzeug@2.0.3",
"pkg:pypi/zipp@3.6.0"
]
},
{
"ref" : "pkg:pypi/anyio@3.6.2",
"dependsOn" : [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,8 @@
"specVersion" : "1.4",
"version" : 1,
"metadata" : {
"component" : {
"name" : "root",
"purl" : "pkg:pypi/root",
"type" : "application",
"bom-ref" : "pkg:pypi/root"
}
},
"components" : [
{
"name" : "root",
"purl" : "pkg:pypi/root",
"type" : "application",
"bom-ref" : "pkg:pypi/root"
},
{
"name" : "anyio",
"version" : "3.6.2",
Expand Down Expand Up @@ -208,38 +196,6 @@
}
],
"dependencies" : [
{
"ref" : "pkg:pypi/root",
"dependsOn" : [
"pkg:pypi/anyio@3.6.2",
"pkg:pypi/asgiref@3.4.1",
"pkg:pypi/beautifulsoup4@4.12.2",
"pkg:pypi/certifi@2023.7.22",
"pkg:pypi/chardet@4.0.0",
"pkg:pypi/click@8.0.4",
"pkg:pypi/contextlib2@21.6.0",
"pkg:pypi/fastapi@0.75.1",
"pkg:pypi/flask@2.0.3",
"pkg:pypi/h11@0.13.0",
"pkg:pypi/idna@2.10",
"pkg:pypi/immutables@0.19",
"pkg:pypi/importlib-metadata@4.8.3",
"pkg:pypi/itsdangerous@2.0.1",
"pkg:pypi/jinja2@3.0.3",
"pkg:pypi/markupsafe@2.0.1",
"pkg:pypi/pydantic@1.9.2",
"pkg:pypi/requests@2.25.1",
"pkg:pypi/six@1.16.0",
"pkg:pypi/sniffio@1.2.0",
"pkg:pypi/soupsieve@2.3.2.post1",
"pkg:pypi/starlette@0.17.1",
"pkg:pypi/typing-extensions@4.1.1",
"pkg:pypi/urllib3@1.26.16",
"pkg:pypi/uvicorn@0.17.0",
"pkg:pypi/werkzeug@2.0.3",
"pkg:pypi/zipp@3.6.0"
]
},
{
"ref" : "pkg:pypi/anyio@3.6.2",
"dependsOn" : [ ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,9 @@
"specVersion" : "1.4",
"version" : 1,
"metadata" : {
"timestamp" : "2023-09-28T12:40:44Z",
"component" : {
"name" : "root",
"purl" : "pkg:pypi/root",
"type" : "application",
"bom-ref" : "pkg:pypi/root"
}
"timestamp" : "2023-09-28T12:40:44Z"
},
"components" : [
{
"name" : "root",
"purl" : "pkg:pypi/root",
"type" : "application",
"bom-ref" : "pkg:pypi/root"
},
{
"name" : "anyio",
"version" : "3.6.2",
Expand Down Expand Up @@ -209,38 +197,6 @@
}
],
"dependencies" : [
{
"ref" : "pkg:pypi/root",
"dependsOn" : [
"pkg:pypi/anyio@3.6.2",
"pkg:pypi/asgiref@3.4.1",
"pkg:pypi/beautifulsoup4@4.12.2",
"pkg:pypi/certifi@2023.7.22",
"pkg:pypi/chardet@4.0.0",
"pkg:pypi/click@8.0.4",
"pkg:pypi/contextlib2@21.6.0",
"pkg:pypi/fastapi@0.75.1",
"pkg:pypi/flask@2.0.3",
"pkg:pypi/h11@0.13.0",
"pkg:pypi/idna@2.10",
"pkg:pypi/immutables@0.19",
"pkg:pypi/importlib-metadata@4.8.3",
"pkg:pypi/itsdangerous@2.0.1",
"pkg:pypi/jinja2@3.0.3",
"pkg:pypi/markupsafe@2.0.1",
"pkg:pypi/pydantic@1.9.2",
"pkg:pypi/requests@2.25.1",
"pkg:pypi/six@1.16.0",
"pkg:pypi/sniffio@1.2.0",
"pkg:pypi/soupsieve@2.3.2.post1",
"pkg:pypi/starlette@0.17.1",
"pkg:pypi/typing-extensions@4.1.1",
"pkg:pypi/urllib3@1.26.16",
"pkg:pypi/uvicorn@0.17.0",
"pkg:pypi/werkzeug@2.0.3",
"pkg:pypi/zipp@3.6.0"
]
},
{
"ref" : "pkg:pypi/anyio@3.6.2",
"dependsOn" : [
Expand Down

0 comments on commit ceaabb8

Please sign in to comment.