1
1
#!/usr/bin/env php
2
2
<?php declare (strict_types=1 );
3
- if ($ argc !== 2 ) {
3
+ if ($ argc !== 3 ) {
4
4
fwrite (
5
5
STDERR ,
6
6
sprintf (
7
- '%s /path/to/manifest.txt ' . PHP_EOL ,
7
+ '%s /path/to/manifest.txt /path/to/sbom.xml ' . PHP_EOL ,
8
8
$ argv [0 ]
9
9
)
10
10
);
16
16
$ version = version ();
17
17
18
18
manifest ($ argv [1 ], $ version , $ dependencies );
19
+ sbom ($ argv [2 ], $ version , $ dependencies );
19
20
20
21
function manifest (string $ outputFilename , string $ version , array $ dependencies ): void
21
22
{
@@ -34,6 +35,53 @@ function manifest(string $outputFilename, string $version, array $dependencies):
34
35
file_put_contents ($ outputFilename , $ buffer );
35
36
}
36
37
38
+ function sbom (string $ outputFilename , string $ version , array $ dependencies ): void
39
+ {
40
+ $ writer = new XMLWriter ;
41
+
42
+ $ writer ->openMemory ();
43
+ $ writer ->setIndent (true );
44
+ $ writer ->startDocument ();
45
+
46
+ $ writer ->startElement ('bom ' );
47
+ $ writer ->writeAttribute ('xmlns ' , 'https://cyclonedx.org/schema/bom/1.4 ' );
48
+
49
+ $ writer ->startElement ('components ' );
50
+
51
+ writeComponent (
52
+ $ writer ,
53
+ 'phpunit ' ,
54
+ 'phpunit ' ,
55
+ $ version ,
56
+ 'The PHP Unit Testing framework ' ,
57
+ ['BSD-3-Clause ' ]
58
+ );
59
+
60
+ foreach ($ dependencies as $ dependency ) {
61
+ [$ group , $ name ] = explode ('/ ' , $ dependency ['name ' ]);
62
+ $ dependencyVersion = $ dependency ['version ' ];
63
+
64
+ if (!preg_match ('/^[v= ]*(([0-9]+)( \\.([0-9]+)( \\.([0-9]+)(-([0-9]+))?(-?([a-zA-Z-+][a-zA-Z0-9. \\-:]*)?)?)?)?)$/ ' , $ dependencyVersion )) {
65
+ $ dependencyVersion .= '@ ' . $ dependency ['source ' ]['reference ' ];
66
+ }
67
+
68
+ writeComponent (
69
+ $ writer ,
70
+ $ group ,
71
+ $ name ,
72
+ $ dependencyVersion ,
73
+ $ dependency ['description ' ],
74
+ $ dependency ['license ' ]
75
+ );
76
+ }
77
+
78
+ $ writer ->endElement ();
79
+ $ writer ->endElement ();
80
+ $ writer ->endDocument ();
81
+
82
+ file_put_contents ($ outputFilename , $ writer ->outputMemory ());
83
+ }
84
+
37
85
function dependencies (): array
38
86
{
39
87
return json_decode (
@@ -57,3 +105,36 @@ function version(): string
57
105
58
106
return $ branch . '@ ' . $ hash ;
59
107
}
108
+
109
+ function writeComponent (XMLWriter $ writer , string $ group , string $ name , string $ version , string $ description , array $ licenses ): void
110
+ {
111
+ $ writer ->startElement ('component ' );
112
+ $ writer ->writeAttribute ('type ' , 'library ' );
113
+
114
+ $ writer ->writeElement ('group ' , $ group );
115
+ $ writer ->writeElement ('name ' , $ name );
116
+ $ writer ->writeElement ('version ' , $ version );
117
+ $ writer ->writeElement ('description ' , $ description );
118
+
119
+ $ writer ->startElement ('licenses ' );
120
+
121
+ foreach ($ licenses as $ license ) {
122
+ $ writer ->startElement ('license ' );
123
+ $ writer ->writeElement ('id ' , $ license );
124
+ $ writer ->endElement ();
125
+ }
126
+
127
+ $ writer ->endElement ();
128
+
129
+ $ writer ->writeElement (
130
+ 'purl ' ,
131
+ sprintf (
132
+ 'pkg:composer/%s/%s@%s ' ,
133
+ $ group ,
134
+ $ name ,
135
+ $ version
136
+ )
137
+ );
138
+
139
+ $ writer ->endElement ();
140
+ }
0 commit comments