Skip to content

Commit b01688f

Browse files
committed
chore: add README for sbom creation and the xlst template for html output
1 parent 4ee79aa commit b01688f

2 files changed

Lines changed: 225 additions & 0 deletions

File tree

sbom/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Software Bill of Materials (SBOM)
2+
3+
---
4+
5+
## What is an SBOM?
6+
7+
An **SBOM (Software Bill of Materials)** is a detailed inventory of all software components, libraries, and dependencies included in a project. It provides transparency into its composition.
8+
9+
10+
## Why CycloneDX?
11+
12+
[CycloneDX](https://cyclonedx.org/) is a leading open standard for SBOMs that supports rich metadata and is widely supported by tools and ecosystems. It is especially suited for modern DevSecOps workflows and integrates well with build tools.
13+
14+
15+
## How to Generate an SBOM
16+
17+
The ownCloud Android app is ready to generate it. The dependency *CycloneDX* is included in the build.gradle file, so, the SBOM file is an easy one via gradlew:
18+
19+
```
20+
./gradlew cyclonedxBom
21+
```
22+
23+
that command will generate the sbom file in json and xml formats.
24+
25+
## Preview
26+
27+
Since XML and JSON are not easily human-readable formats, the `xsltproc` tool can be used to transform the SBOM into a more user-friendly and visually readable HTML document, with a XSLT template.
28+
29+
XSLT (Extensible Stylesheet Language Transformations) is a language for transforming XML documents into other formats, such as HTML, plain text, or other XML structures. It uses a set of rules defined in an XSLT stylesheet to match and manipulate elements in the source XML, allowing the data to be presented in a more readable or usable format.
30+
31+
Now...
32+
33+
```
34+
xsltproc cyclonedx-xml-to-html.xslt bom.xml > bom.html
35+
```
36+
37+
And the `bom.html` file is ready to go.
38+
39+
40+

sbom/cyclonedx-xml-to-html.xslt

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xsl:stylesheet version="1.0"
3+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4+
xmlns:bom="http://cyclonedx.org/schema/bom/1.6"
5+
exclude-result-prefixes="bom">
6+
7+
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
8+
9+
<xsl:template match="/">
10+
<html>
11+
<head>
12+
<title>Software Bill of Materials</title>
13+
<style>
14+
body {
15+
font-family: sans-serif;
16+
margin: 20px;
17+
background-color: #f0f4fb;
18+
color: #000;
19+
}
20+
h1 {
21+
text-align: left;
22+
color: #2c3e50;
23+
font-size: 2em;
24+
margin-bottom: 0.5em;
25+
}
26+
h2 {
27+
color: #3a4f7a;
28+
border-bottom: 2px solid #ccc;
29+
padding-bottom: 5px;
30+
margin-top: 40px;
31+
margin-bottom: 15px;
32+
}
33+
table {
34+
border-collapse: collapse;
35+
background-color: #fff;
36+
color: #000;
37+
margin-top: 10px;
38+
margin-bottom: 40px;
39+
border-radius: 6px;
40+
overflow: hidden;
41+
}
42+
.metadata-table {
43+
width: auto;
44+
margin: 0;
45+
padding: 0;
46+
}
47+
th, td {
48+
padding: 10px 10px;
49+
text-align: left;
50+
border-bottom: 1px solid #ccc;
51+
}
52+
tr {
53+
line-height: 2;
54+
}
55+
th {
56+
background-color: #d0def0;
57+
font-weight: bold;
58+
color: #1b2e4b;
59+
}
60+
a {
61+
color: #003366;
62+
text-decoration: none;
63+
}
64+
a:hover {
65+
text-decoration: underline;
66+
}
67+
.footer {
68+
margin-top: 50px;
69+
font-size: 0.9em;
70+
color: #666;
71+
text-align: center;
72+
}
73+
ul {
74+
list-style: none;
75+
padding: 0;
76+
margin: 10px 0 30px 0;
77+
}
78+
li {
79+
margin-bottom: 5px;
80+
}
81+
.index a {
82+
color: #000;
83+
text-decoration: underline;
84+
}
85+
.back-to-top {
86+
display: inline-block;
87+
margin-top: 20px;
88+
font-size: 0.9em;
89+
color: #003366;
90+
text-decoration: none;
91+
}
92+
.back-to-top::before {
93+
content: "↑ ";
94+
font-weight: bold;
95+
margin-right: 4px;
96+
}
97+
.back-to-top:hover {
98+
text-decoration: underline;
99+
}
100+
</style>
101+
</head>
102+
<body>
103+
<h1>Software Bill of Materials - ownCloud Android app</h1>
104+
105+
<div class="index">
106+
<h2>Index</h2>
107+
<ul>
108+
<li><a href="#metadata">Metadata</a></li>
109+
<li><a href="#components">Components</a></li>
110+
</ul>
111+
</div>
112+
113+
<!-- Metadata Section -->
114+
<h2 id="metadata">Metadata</h2>
115+
<table class="metadata-table">
116+
<tr><th>Creation Date</th><td><xsl:call-template name="format-date"><xsl:with-param name="timestamp" select="bom:bom/bom:metadata/bom:timestamp"/></xsl:call-template></td></tr>
117+
<tr><th>Generated by</th>
118+
<td>
119+
<xsl:for-each select="bom:bom/bom:metadata/bom:tools/bom:components/bom:component">
120+
<xsl:value-of select="bom:name"/> <xsl:text> </xsl:text><xsl:value-of select="bom:version"/>
121+
</xsl:for-each>
122+
</td>
123+
</tr>
124+
</table>
125+
126+
<!-- Components Section -->
127+
<h2 id="components">Components</h2>
128+
<table style="width: 100%;">
129+
<tr>
130+
<th style="width: 10%;">Type</th>
131+
<th style="width: 12%;">Group</th>
132+
<th style="width: 20%;">Name</th>
133+
<th style="width: 12%;">Version</th>
134+
<th>style="width: 30%;">PURL</th>
135+
</tr>
136+
<xsl:for-each select="bom:bom/bom:components/bom:component">
137+
<tr>
138+
<td><xsl:value-of select="@type"/></td>
139+
<td><xsl:value-of select="bom:group"/></td>
140+
<td><xsl:value-of select="bom:name"/></td>
141+
<td><xsl:value-of select="bom:version"/></td>
142+
<td><xsl:value-of select="bom:purl"/></td>
143+
</tr>
144+
</xsl:for-each>
145+
</table>
146+
147+
<div><a class="back-to-top" href="#metadata">Back to top</a></div>
148+
149+
<div class="footer">
150+
Document generated from CycloneDX SBOM using XSLT styling.
151+
</div>
152+
</body>
153+
</html>
154+
</xsl:template>
155+
156+
<!-- Helper: Convert ISO timestamp to readable date -->
157+
<xsl:template name="format-date">
158+
<xsl:param name="timestamp"/>
159+
<xsl:variable name="year" select="substring($timestamp, 1, 4)"/>
160+
<xsl:variable name="month" select="substring($timestamp, 6, 2)"/>
161+
<xsl:variable name="day" select="substring($timestamp, 9, 2)"/>
162+
<xsl:variable name="hour" select="substring($timestamp, 12, 2)"/>
163+
<xsl:variable name="minute" select="substring($timestamp, 15, 2)"/>
164+
<xsl:variable name="monthName">
165+
<xsl:choose>
166+
<xsl:when test="$month = '01'">January</xsl:when>
167+
<xsl:when test="$month = '02'">February</xsl:when>
168+
<xsl:when test="$month = '03'">March</xsl:when>
169+
<xsl:when test="$month = '04'">April</xsl:when>
170+
<xsl:when test="$month = '05'">May</xsl:when>
171+
<xsl:when test="$month = '06'">June</xsl:when>
172+
<xsl:when test="$month = '07'">July</xsl:when>
173+
<xsl:when test="$month = '08'">August</xsl:when>
174+
<xsl:when test="$month = '09'">September</xsl:when>
175+
<xsl:when test="$month = '10'">October</xsl:when>
176+
<xsl:when test="$month = '11'">November</xsl:when>
177+
<xsl:when test="$month = '12'">December</xsl:when>
178+
<xsl:otherwise>Unknown</xsl:otherwise>
179+
</xsl:choose>
180+
</xsl:variable>
181+
<xsl:value-of select="concat($day, ' ', $monthName, ' ', $year, ', ', $hour, ':', $minute, ' UTC')"/>
182+
</xsl:template>
183+
184+
</xsl:stylesheet>
185+

0 commit comments

Comments
 (0)