File Coverage

blib/lib/SBOM/CycloneDX/Lite.pm
Criterion Covered Total %
statement 19 48 39.5
branch 0 6 0.0
condition 0 3 0.0
subroutine 6 27 22.2
pod 21 21 100.0
total 46 105 43.8


line stmt bran cond sub pod time code
1             package SBOM::CycloneDX::Lite;
2              
3 1     1   4990 use 5.010001;
  1         4  
4 1     1   5 use strict;
  1         1  
  1         34  
5 1     1   4 use warnings;
  1         1  
  1         43  
6 1     1   4 use utf8;
  1         1  
  1         13  
7              
8 1     1   22 use Exporter ();
  1         2  
  1         915  
9              
10             require SBOM::CycloneDX;
11             require SBOM::CycloneDX::Component;
12             require SBOM::CycloneDX::ExternalReference;
13             require SBOM::CycloneDX::Hash;
14             require SBOM::CycloneDX::License;
15             require SBOM::CycloneDX::OrganizationalContact;
16             require SBOM::CycloneDX::OrganizationalEntity;
17             require SBOM::CycloneDX::Property;
18              
19              
20             our @EXPORT_OK = qw(
21             bom
22             component
23             contact
24             external_reference
25             hash
26             license
27             organization
28             property
29              
30             application_component
31             container_component
32             cryptographic_asset_component
33             data_component
34             device_component
35             device_driver_component
36             file_component
37             firmware_component
38             framework_component
39             library_component
40             machine_learning_model_component
41             operating_system_component
42             platform_component
43             );
44              
45             our %EXPORT_TAGS = (all => \@EXPORT_OK);
46              
47             my $LATEST_SPEC_VERSION = (
48             sort {
49             my ($am, $an, $ap) = split /\./, $a, 3;
50             my ($bm, $bn, $bp) = split /\./, $b, 3;
51             $ap //= 0;
52             $bp //= 0;
53             $am <=> $bm || $an <=> $bn || $ap <=> $bp
54             } keys %SBOM::CycloneDX::JSON_SCHEMA
55             )[-1];
56              
57             my $DEFAULT_SPEC_VERSION = $LATEST_SPEC_VERSION;
58              
59             my %_caller_version = ();
60              
61             sub import {
62              
63 1     1   9 my $class = shift;
64 1         4 my $caller = caller;
65              
66 1         3 foreach (@_) {
67              
68 0 0       0 if ($_ =~ /^\:v(1_\d+(?:_\d+)?)$/) {
69 0         0 my $v = $1 =~ tr/_/./r;
70 0         0 $_caller_version{$caller} = $v;
71             }
72              
73 0 0       0 if ($_ eq ':latest') {
74 0         0 $DEFAULT_SPEC_VERSION = $LATEST_SPEC_VERSION;
75             }
76              
77             }
78              
79 1         2 local $Exporter::ExportLevel = 1;
80 1 0       64 Exporter::import($class, grep { $_ !~ /^:v1_/ && $_ ne ':latest' } @_);
  0            
81              
82             }
83              
84             sub bom {
85 0     0 1   my $caller = caller;
86 0   0       my $version = $_caller_version{$caller} // $DEFAULT_SPEC_VERSION;
87 0           return SBOM::CycloneDX->new(spec_version => $version, @_);
88             }
89              
90 0     0 1   sub component { SBOM::CycloneDX::Component->new(@_) }
91 0     0 1   sub contact { SBOM::CycloneDX::OrganizationalContact->new(@_) }
92 0     0 1   sub external_reference { SBOM::CycloneDX::ExternalReference->new(@_) }
93 0     0 1   sub hash { SBOM::CycloneDX::Hash->new(@_) }
94 0     0 1   sub license { SBOM::CycloneDX::License->new(@_) }
95 0     0 1   sub organization { SBOM::CycloneDX::OrganizationalEntity->new(@_) }
96 0     0 1   sub property { SBOM::CycloneDX::Property->new(@_) }
97              
98 0     0 1   sub application_component { component(type => 'application', @_) }
99 0     0 1   sub container_component { component(type => 'container', @_) }
100 0     0 1   sub cryptographic_asset_component { component(type => 'cryptographic-asset', @_) }
101 0     0 1   sub data_component { component(type => 'data', @_) }
102 0     0 1   sub device_component { component(type => 'device', @_) }
103 0     0 1   sub device_driver_component { component(type => 'device-driver', @_) }
104 0     0 1   sub file_component { component(type => 'file', @_) }
105 0     0 1   sub firmware_component { component(type => 'firmware', @_) }
106 0     0 1   sub framework_component { component(type => 'framework', @_) }
107 0     0 1   sub library_component { component(type => 'library', @_) }
108 0     0 1   sub machine_learning_model_component { component(type => 'machine-learning-model', @_) }
109 0     0 1   sub operating_system_component { component(type => 'operating-system', @_) }
110 0     0 1   sub platform_component { component(type => 'platform', @_) }
111              
112             1;
113              
114             =encoding utf-8
115              
116             =head1 NAME
117              
118             SBOM::CycloneDX::Lite - Simple accessors and helpers for SBOM::CycloneDX
119              
120             =head1 SYNOPSIS
121              
122             use SBOM::CycloneDX::Lite qw(:v1_7 :all);
123             use SBOM::CycloneDX::Util qw(cyclonedx_tool);
124              
125             my $bom = bom;
126              
127             my $root_component = application_component(
128             name => 'MyApp',
129             licenses => [license('Artistic-2.0')],
130             bom_ref => 'MyApp'
131             );
132              
133             my $metadata = $bom->metadata;
134              
135             $metadata->tools->add(cyclonedx_tool);
136              
137             $metadata->component($root_component);
138              
139             my $component1 = library_component(
140             name => 'some-component',
141             group => 'acme',
142             version => '1.33.7-beta.1',
143             licenses => [license(name => '(c) 2021 Acme inc.')],
144             bom_ref => 'myComponent@1.33.7-beta.1',
145             purl => URI::PackageURL->new(
146             type => 'generic',
147             namespace => 'acme',
148             name => 'some-component',
149             version => '1.33.7-beta.1'
150             ),
151             );
152              
153             $bom->components->add($component1);
154             $bom->add_dependency($root_component, [$component1]);
155              
156             my $component2 = library_component(
157             name => 'some-library',
158             licenses => [license('GPL-3.0-only WITH Classpath-exception-2.0')],
159             bom_ref => 'some-lib',
160             );
161              
162             $bom->components->add($component2);
163             $bom->add_dependency($root_component, [$component2]);
164              
165             my @errors = $bom->validate;
166              
167             if (@errors) {
168             say $_ for (@errors);
169             Carp::croak 'Validation error';
170             }
171              
172             say $bom->to_string;
173              
174              
175              
176             =head1 DESCRIPTION
177              
178             L is an EXPERIMENTAL lightweight layer built on top of
179             L to quickly create CycloneDX BOM files.
180              
181             It focuses on the most commonly used BOM fields and provides a simple,
182             low-boilerplate interface. It accepts friendly input and normalizes it into
183             canonical CycloneDX structures.
184              
185             =head2 EXPORTED TAGS
186              
187             =over
188              
189             =item C<:latest>
190              
191             Select the latest CycloneDX schema version supported by L
192             distribution.
193              
194             =item C<:v1_7>
195              
196             Select the CycloneDX v1.7 schema version.
197              
198             =item C<:v1_6>
199              
200             Select the CycloneDX v1.6 schema version.
201              
202             =item C<:v1_5>
203              
204             Select the CycloneDX v1.5 schema version.
205              
206             =item C<:v1_4>
207              
208             Select the CycloneDX v1.4 schema version.
209              
210             =item C<:v1_3>
211              
212             Select the CycloneDX v1.3 schema version.
213              
214             =item C<:v1_2>
215              
216             Select the CycloneDX v1.2 schema version.
217              
218             =item C<:all>
219              
220             Export all functions.
221              
222             =back
223              
224             =head2 EXPORTED FUNCTIONS
225              
226             =head3 B
227              
228             Return a L object.
229              
230             =head3 B
231              
232             Return a L object.
233              
234             Component aliases:
235              
236             =over
237              
238             =item B
239              
240             =item B
241              
242             =item B
243              
244             =item B
245              
246             =item B
247              
248             =item B
249              
250             =item B
251              
252             =item B
253              
254             =item B
255              
256             =item B
257              
258             =item B
259              
260             =item B
261              
262             =item B
263              
264             =back
265              
266             =head3 B
267              
268             Return a L object.
269              
270             =head3 B
271              
272             Return a L object.
273              
274             =head3 B
275              
276             Return a L object.
277              
278             =head3 B
279              
280             Return a L object.
281              
282             =head3 B
283              
284             Return a L object.
285              
286             =head3 B
287              
288             Return a L object.
289              
290              
291             =head1 SUPPORT
292              
293             =head2 Bugs / Feature Requests
294              
295             Please report any bugs or feature requests through the issue tracker
296             at L.
297             You will be notified automatically of any progress on your issue.
298              
299             =head2 Source Code
300              
301             This is open source software. The code repository is available for
302             public review and contribution under the terms of the license.
303              
304             L
305              
306             git clone https://github.com/giterlizzi/perl-SBOM-CycloneDX.git
307              
308              
309             =head1 AUTHOR
310              
311             =over 4
312              
313             =item * Giuseppe Di Terlizzi
314              
315             =back
316              
317              
318             =head1 LICENSE AND COPYRIGHT
319              
320             This software is copyright (c) 2025-2026 by Giuseppe Di Terlizzi.
321              
322             This is free software; you can redistribute it and/or modify it under
323             the same terms as the Perl 5 programming language system itself.
324              
325             =cut