File Coverage

blib/lib/Software/License/Custom.pm
Criterion Covered Total %
statement 50 54 92.5
branch 11 18 61.1
condition 1 2 50.0
subroutine 16 17 94.1
pod 12 12 100.0
total 90 103 87.3


line stmt bran cond sub pod time code
1 9     9   70969 use strict;
  9         33  
  9         274  
2 9     9   47 use warnings;
  9         23  
  9         417  
3             package Software::License::Custom;
4             # ABSTRACT: custom license handler
5             $Software::License::Custom::VERSION = '0.104004';
6 9     9   504 use parent 'Software::License';
  9         307  
  9         43  
7              
8 9     9   536 use Carp;
  9         36  
  9         553  
9 9     9   51 use Text::Template;
  9         37  
  9         6282  
10              
11             #pod =head1 DESCRIPTION
12             #pod
13             #pod This module extends L to give the possibility of specifying
14             #pod all aspects related to a software license in a custom file. This allows for
15             #pod setting custom dates, notices, etc. while still preserving compatibility with
16             #pod all places where L is used, e.g. L.
17             #pod
18             #pod In this way, you should be able to customise some aspects of the licensing
19             #pod messages that would otherwise be difficult to tinker, e.g. adding a note
20             #pod in the notice, setting multiple years for the copyright notice or set multiple
21             #pod authors and/or copyright holders.
22             #pod
23             #pod The license details should be put inside a file that contains different
24             #pod sections. Each section has the following format:
25             #pod
26             #pod =begin :list
27             #pod
28             #pod = header line
29             #pod
30             #pod This is a line that begins and ends with two underscores C<__>. The string
31             #pod between the begin and the end of the line is first depured of any non-word
32             #pod character, then used as the name of the section;
33             #pod
34             #pod = body
35             #pod
36             #pod a L (possibly a plain text file) where items to be
37             #pod expanded are enclosed between double braces
38             #pod
39             #pod =end :list
40             #pod
41             #pod Each section is terminated by the header of the following section or by
42             #pod the end of the file. Example:
43             #pod
44             #pod __[ NAME ]__
45             #pod The Foo-Bar License
46             #pod __URL__
47             #pod http://www.example.com/foo-bar.txt
48             #pod __[ META_NAME ]__
49             #pod foo_bar_meta
50             #pod __{ META2_NAME }__
51             #pod foo_bar_meta2
52             #pod __{ SPDX_EXPRESSION }__
53             #pod foo_bar_spdx_expression
54             #pod __[ NOTICE ]__
55             #pod Copyright (C) 2000-2002 by P.R. Evious
56             #pod Copyright (C) {{$self->year}} by {{$self->holder}}.
57             #pod
58             #pod This is free software, licensed under {{$self->name}}.
59             #pod
60             #pod __[ LICENSE ]__
61             #pod The Foo-Bar License
62             #pod
63             #pod Well... this is only some sample text. Verily... only sample text!!!
64             #pod
65             #pod Yes, spanning more lines and more paragraphs.
66             #pod
67             #pod The different formats for specifying the section name in the example
68             #pod above are only examples, you're invited to use a consistent approach.
69             #pod
70             #pod =method new
71             #pod
72             #pod my $slc = Software::License::Custom->new({filename => 'LEGAL'});
73             #pod
74             #pod Create a new object. Arguments are passed through an anonymous hash, the
75             #pod following keys are allowed:
76             #pod
77             #pod filename - the file where the custom software license details are stored
78             #pod
79             #pod =cut
80              
81             sub new {
82 1     1 1 100 my ($class, $arg) = @_;
83              
84 1         14 my $filename = delete $arg->{filename};
85              
86 1         10 my $self = $class->SUPER::new($arg);
87              
88 1 50       6 $self->load_sections_from($filename) if defined $filename;
89              
90 1         4 return $self;
91             }
92              
93             #pod =method load_sections_from
94             #pod
95             #pod $slc->load_sections_from('MY-LEGAL-ASPECTS');
96             #pod
97             #pod Loads the different sections of the license from the provided filename.
98             #pod
99             #pod Returns the input object.
100             #pod
101             #pod =cut
102              
103             sub load_sections_from {
104 1     1 1 5 my ($self, $filename) = @_;
105              
106             # Sections are kept inside a hash
107 1         8 $self->{'Software::License::Custom'}{section_for} = \my %section_for;
108              
109 1         2 my $current_section = '';
110 1 50       45 open my $fh, '<', $filename or croak "open('$filename'): $!";
111              
112 1         37 while (<$fh>) {
113 20 100       65 if (my ($section) = m{\A __ (.*) __ \n\z}mxs) {
114 6         34 ($current_section = $section) =~ s/\W+//gmxs;
115             }
116             else {
117 14         46 $section_for{$current_section} .= $_;
118             }
119             }
120 1         11 close $fh;
121              
122             # strip last newline from all items
123 1         31 s{\n\z}{}mxs for values %section_for;
124              
125 1         5 return $self;
126             }
127              
128             #pod =method section_data
129             #pod
130             #pod my $notice_template_reference = $slc->section_data('NOTICE');
131             #pod
132             #pod Returns a reference to a textual template that can be fed to
133             #pod L (it could be simple text), according to what is
134             #pod currently loaded in the object.
135             #pod
136             #pod =cut
137              
138             sub section_data {
139 31     31 1 68 my ($self, $name) = @_;
140 31   50     283 my $section_for = $self->{'Software::License::Custom'}{section_for} ||= {};
141 10 50       23 return unless exists $section_for->{$name};
142 10 50       21 return unless defined $section_for->{$name};
143 10         34 return \$section_for->{$name};
144             }
145              
146             #pod =head1 MORE METHODS
147             #pod
148             #pod The following methods, found in all software license classes, look up and
149             #pod render the template with the capitalized form of their name. In other words,
150             #pod the C method looks in the C template.
151             #pod
152             #pod For now, the C and C methods return C if called
153             #pod on the class. This may become fatal in the future.
154             #pod
155             #pod =for :list
156             #pod * name
157             #pod * url
158             #pod * meta_name
159             #pod * meta2_name
160             #pod * license
161             #pod * notice
162             #pod * fulltext
163             #pod * version
164             #pod
165             #pod =cut
166              
167 24     24 1 860 sub name { shift->_fill_in('NAME') }
168 1     1 1 1174 sub url { shift->_fill_in('URL') }
169              
170             sub meta_name {
171 44     44 1 1084 my $self = shift;
172 44 100       202 return 'custom' unless ref $self;
173 1         4 return $self->_fill_in('META_NAME')
174             }
175              
176             sub meta2_name {
177 43     43 1 1009 my $self = shift;
178 43 100       131 return 'custom' unless ref $self;
179 1         4 $self->_fill_in('META2_NAME')
180             }
181              
182             sub spdx_expression {
183 21     21 1 36 my $self = shift;
184 21 50       86 return undef unless ref $self;
185 0         0 return $self->_fill_in('SPDX_EXPRESSION')
186             }
187              
188 2     2 1 1597 sub license { shift->_fill_in('LICENSE') }
189 2     2 1 971 sub notice { shift->_fill_in('NOTICE') }
190              
191             sub fulltext {
192 1     1 1 1018 my ($self) = @_;
193 1         4 return join "\n", $self->notice, $self->license;
194             }
195              
196             sub version {
197 0     0 1   my ($self) = @_;
198 0 0         return unless $self->section_data('VERSION');
199 0           return $self->_fill_in('VERSION')
200             }
201              
202             1;
203              
204             __END__