File Coverage

blib/lib/String/License/Naming/Custom.pm
Criterion Covered Total %
statement 35 35 100.0
branch n/a
condition n/a
subroutine 12 12 100.0
pod n/a
total 47 47 100.0


line stmt bran cond sub pod time code
1 11     11   1096625 use v5.20;
  11         67  
2 11     11   75 use utf8;
  11         21  
  11         104  
3 11     11   2582 use warnings;
  11         24  
  11         705  
4 11     11   65 use feature qw(signatures);
  11         24  
  11         1674  
5 11     11   64 no warnings qw(experimental::signatures);
  11         21  
  11         526  
6              
7 11     11   573 use Feature::Compat::Class 0.07;
  11         523  
  11         74  
8              
9             =head1 NAME
10              
11             String::License::Naming - names of licenses and license naming schemes
12              
13             =head1 VERSION
14              
15             Version v0.0.11
16              
17             =head1 SYNOPSIS
18              
19             use String::License::Naming::Custom;
20              
21             my $obj = String::License::Naming::Custom->new( schemes => [qw(spdx internal)] );
22              
23             my $schemes = [ $obj->list_schemes ]; # => is_deeply [ 'spdx', 'internal' ]
24              
25             my $license = [ grep { /^(Expat|Perl)$/ } $obj->list_licenses ]; # => is_deeply ['Perl']
26              
27             # use and prefer Debian-specific identifiers
28             $schemes = [ $obj->add_scheme('debian') ]; # => is_deeply [ 'debian', 'spdx', 'internal' ]
29              
30             $license = [ grep { /^(Expat|Perl)$/ } $obj->list_licenses ]; # => is_deeply [ 'Expat', 'Perl' ]
31              
32             =head1 DESCRIPTION
33              
34             L enumerates supported licenses
35             matching an ordered set of naming schemes,
36             or enumerates the names of supported license naming schemes.
37              
38             Some licenses are known by different names.
39             E.g. the license "MIT" according to SPDX
40             is named "Expat" in Debian.
41              
42             Some licenses are not always represented.
43             E.g. "Perl" is a (discouraged) license in Debian
44             while it is a relationship of several licenses with SPDX
45             (and that expression is recommended in Debian as well).
46              
47             By default,
48             licenses are matched using naming schemes C<[ 'spdx', 'internal' ]>,
49             which lists all supported licenses,
50             preferrably by their SPDX name
51             or as fallback by an internal name.
52              
53             =cut
54              
55             package String::License::Naming::Custom v0.0.11;
56              
57 11     11   1208 use Carp qw(croak);
  11         24  
  11         837  
58 11     11   65 use Log::Any ();
  11         27  
  11         261  
59 11     11   53 use List::Util qw(uniq);
  11         19  
  11         823  
60 11     11   64 use Regexp::Pattern::License 3.4.0;
  11         178  
  11         266  
61              
62 11     11   5144 use namespace::clean;
  11         209485  
  11         85  
63              
64 11     11   8545 class String::License::Naming::Custom : isa(String::License::Naming);
  11         40  
  11         10109  
65              
66             field $log;
67              
68             =head1 CONSTRUCTOR
69              
70             =over
71              
72             =item new
73              
74             my $names = String::License::Naming->new;
75              
76             my $spdx_names = String::License::Naming->new( schemes => ['spdx'] );
77              
78             Constructs and returns a String::License::Naming object.
79              
80             Takes an optional array as named argument B.
81             both ordering by which name licenses should be presented,
82             and limiting which licenses to cover.
83              
84             When omitted,
85             the default schemes array C<[ 'spdx', 'internal' ]> is used,
86             which includes all supported licenses,
87             and they are presented by their SPDX name when defined
88             or otherwise by a semi-stable internal name.
89              
90             When passing an empty array reference,
91             all supported licenses are included,
92             presented by a semi-stable internal potentially multi-word description.
93              
94             =back
95              
96             =cut
97              
98             field $schemes : param = undef;
99              
100             # TODO: maybe support seeding explicit keys
101             field $keys;
102              
103             ADJUST {
104             $log = Log::Any->get_logger;
105              
106             if ( defined $schemes ) {
107              
108             croak $log->fatal('parameter "schemes" must be an array reference')
109             unless ref $schemes eq 'ARRAY';
110              
111             # TODO: die unless each arrayref entry is a string and supported
112              
113             my @uniq_schemes = uniq @$schemes;
114             if ( join( ' ', @$schemes ) ne join( ' ', @uniq_schemes ) ) {
115             $log->warn("duplicate scheme(s) omitted");
116             @$schemes = \@uniq_schemes;
117             }
118             }
119             else {
120             $schemes = [];
121             }
122              
123             $keys = [
124             String::License::Naming::resolve_shortnames( $keys, $schemes, 1 ) ];
125             }
126              
127             =head1 FUNCTIONS
128              
129             =over
130              
131             =item add_scheme
132              
133             Takes a string representing a license naming scheme to use,
134             favored over existing schemes in use.
135              
136             Returns array of schemes in use after addition.
137              
138             =cut
139              
140             method add_scheme ($new_scheme)
141             {
142             if ( grep { $_ eq $new_scheme } @$schemes ) {
143             $log->warn("already included scheme $new_scheme not added");
144             return @$schemes;
145             }
146              
147             # TODO: validate new entry is string and supported, or die
148             unshift @$schemes, $new_scheme;
149              
150             return @$schemes;
151             }
152              
153             =item list_schemes
154              
155             Returns a list of license naming schemes in use.
156              
157             =cut
158              
159             method list_schemes ()
160             {
161             return @$schemes;
162             }
163              
164             =item list_available_schemes
165              
166             Returns a list of all license naming schemes available.
167              
168             =cut
169              
170             method list_available_schemes ()
171             {
172             my ( $_prop, $_any, @result );
173              
174             $_prop = '(?:[a-z][a-z0-9_]*)';
175             $_any = '[a-z0-9_.()]';
176              
177             @result = uniq sort
178             map {/^(?:name|caption)\.alt\.org\.($_prop)$_any*/}
179             map { keys %{ $Regexp::Pattern::License::RE{$_} } }
180             grep {/^[a-z]/} keys %Regexp::Pattern::License::RE;
181              
182             return @result;
183             }
184              
185             =item list_licenses
186              
187             Returns a list of licensing patterns covered by this object instance,
188             each labeled by shortname according to current set of schemes.
189              
190             =cut
191              
192             method list_licenses ()
193             {
194             return String::License::Naming::resolve_shortnames( $keys, $schemes );
195             }
196              
197             =back
198              
199             =encoding UTF-8
200              
201             =head1 AUTHOR
202              
203             Jonas Smedegaard C<< >>
204              
205             =head1 COPYRIGHT AND LICENSE
206              
207             Copyright © 2023 Jonas Smedegaard
208              
209             This program is free software:
210             you can redistribute it and/or modify it
211             under the terms of the GNU Affero General Public License
212             as published by the Free Software Foundation,
213             either version 3, or (at your option) any later version.
214              
215             This program is distributed in the hope that it will be useful,
216             but WITHOUT ANY WARRANTY;
217             without even the implied warranty
218             of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
219             See the GNU Affero General Public License for more details.
220              
221             You should have received a copy
222             of the GNU Affero General Public License along with this program.
223             If not, see .
224              
225             =cut
226              
227             1;