File Coverage

blib/lib/LCFG/Build/PkgSpec.pm
Criterion Covered Total %
statement 169 209 80.8
branch 39 44 88.6
condition 19 26 73.0
subroutine 28 36 77.7
pod 21 23 91.3
total 276 338 81.6


line stmt bran cond sub pod time code
1             package LCFG::Build::PkgSpec; # -*-perl-*-
2 10     10   967196 use strict;
  10         110  
  10         286  
3 10     10   54 use warnings;
  10         20  
  10         436  
4              
5             # $Id: PkgSpec.pm.in 35434 2019-01-18 10:43:38Z squinney@INF.ED.AC.UK $
6             # $Source: /var/cvs/dice/LCFG-Build-PkgSpec/lib/LCFG/Build/PkgSpec.pm.in,v $
7             # $Revision: 35434 $
8             # $HeadURL: https://svn.lcfg.org/svn/source/tags/LCFG-Build-PkgSpec/LCFG_Build_PkgSpec_0_2_6/lib/LCFG/Build/PkgSpec.pm.in $
9             # $Date: 2019-01-18 10:43:38 +0000 (Fri, 18 Jan 2019) $
10              
11             our $VERSION = '0.2.6';
12              
13 10     10   118 use v5.10;
  10         38  
14              
15 10     10   5078 use Data::Structure::Util ();
  10         70932  
  10         259  
16 10     10   8879 use DateTime ();
  10         5001926  
  10         468  
17 10     10   6409 use Email::Address ();
  10         68320  
  10         423  
18 10     10   5394 use Email::Valid ();
  10         998160  
  10         965  
19 10     10   189 use IO::File ();
  10         88  
  10         337  
20 10     10   127 use Scalar::Util ();
  10         63  
  10         367  
21              
22 10     10   5912 use Moose;
  10         4609749  
  10         94  
23 10     10   78711 use Moose::Util::TypeConstraints;
  10         35  
  10         104  
24              
25             # A type and coercion to allow the attribute to be set as either an
26             # ref to an array or a scalar string.
27              
28             subtype 'ArrayRefOrString' => as 'ArrayRef[Str]';
29             coerce 'ArrayRefOrString' => from 'Str' => via { [ split /\s*,\s*/, $_ ] };
30              
31             subtype 'EmailAddress'
32             => as 'Str'
33             => where { Email::Valid->address( -address => $_ ) }
34             => message { "Address ($_) for report must be a valid email address" };
35              
36             subtype 'EmailAddressList'
37             => as 'ArrayRef[EmailAddress]';
38              
39             coerce 'EmailAddressList'
40             => from 'Str'
41             => via { [ map { $_->format } Email::Address->parse($_)] };
42              
43             coerce 'EmailAddressList'
44             => from 'ArrayRef'
45             => via { [ map { $_->format } map { Email::Address->parse($_) } @{$_} ] };
46              
47             subtype 'VersionString'
48             => as 'Str'
49             => where { $_ =~ m/^\d+\.\d+\.\d+(\.dev\d*)?$/ }
50             => message { $_ = 'undef' if !defined $_; "Version string ($_) does not match the expected LCFG format." };
51              
52             subtype 'ReleaseString'
53             => as 'Str'
54             => where { $_ =~ m/^\d+/ }
55             => message { "Release string ($_) does not match the expected LCFG format." };
56              
57             has 'name' => ( is => 'rw', required => 1 );
58             has 'base' => ( is => 'rw', default => q{} );
59             has 'abstract' => ( is => 'rw' );
60              
61             has 'version' => (
62             is => 'rw',
63             required => 1,
64             isa => 'VersionString',
65             default => '0.0.0',
66             );
67              
68             has 'release' => (
69             is => 'rw',
70             isa => 'Maybe[ReleaseString]',
71             default => 1,
72             );
73              
74             has 'schema' => (
75             is => 'rw',
76             isa => 'Int',
77             default => 1,
78             );
79              
80             has 'group' => ( is => 'rw');
81             has 'vendor' => ( is => 'rw');
82             has 'license' => ( is => 'rw');
83              
84             has 'translate' => (
85             is => 'rw',
86             isa => 'ArrayRef[Str]',
87             auto_deref => 1,
88             );
89              
90             has 'date' => (
91             is => 'rw',
92             isa => 'Str',
93             default => sub { DateTime->now->strftime('%d/%m/%y %T') },
94             );
95              
96             has 'metafile' => (
97             is => 'rw',
98             isa => 'Maybe[Str]',
99             );
100              
101             # I would quite like to treat author and platforms as sets but that
102             # doesn't seem to be available at present.
103              
104             has 'author' => (
105             is => 'rw',
106             isa => 'EmailAddressList',
107             coerce => 1,
108             auto_deref => 1,
109             default => sub { [] },
110             );
111              
112             has 'platforms' => (
113             is => 'rw',
114             isa => 'ArrayRefOrString',
115             coerce => 1,
116             auto_deref => 1,
117             default => sub { [] },
118             );
119              
120             has 'build' => (
121             traits => ['Hash'],
122             is => 'rw',
123             isa => 'HashRef[Str]',
124             default => sub { {} },
125             lazy => 1,
126             handles => {
127             exists_in_buildinfo => 'exists',
128             ids_in_buildinfo => 'keys',
129             get_buildinfo => 'get',
130             set_buildinfo => 'set',
131             },
132             );
133              
134             has 'vcs' => (
135             traits => ['Hash'],
136             is => 'rw',
137             isa => 'HashRef[Str]',
138             default => sub { {} },
139             handles => {
140             exists_in_vcsinfo => 'exists',
141             ids_in_vcsinfo => 'keys',
142             get_vcsinfo => 'get',
143             set_vcsinfo => 'set',
144             },
145             );
146              
147             has 'orgident' => (
148             is => 'rw',
149             isa => 'Str',
150             default => 'org.lcfg'
151             );
152              
153 10     10   31788 no Moose;
  10         28  
  10         97  
154             __PACKAGE__->meta->make_immutable;
155              
156             sub perl_version {
157 0     0 1 0 my ($self) = @_;
158              
159 0         0 my $perl_version = $self->version;
160 0 0       0 if ( $perl_version =~ s/\.dev\d*$// ) {
161              
162             # Cannot use a non-numeric in a Perl version string. A "devel"
163             # version is signified with a suffix which is an underscore
164             # and a release number. See "perldoc version" for details.
165              
166 0         0 $perl_version = join q{.}, $self->get_major, $self->get_minor, $self->get_micro;
167 0         0 $perl_version .= q{_} . $self->release;
168             }
169              
170 0         0 return $perl_version;
171             }
172              
173             sub deb_version {
174 0     0 1 0 my ($self) = @_;
175              
176 0         0 my $deb_version = $self->version;
177              
178 0         0 $deb_version =~ s/[^a-zA-Z0-9~.+-]//;
179              
180 0         0 return $deb_version;
181             }
182              
183             sub get_major {
184 19     19 1 55 my ($self) = @_;
185              
186 19         842 my $version = $self->version;
187              
188 19         106 my $major = (split /\./, $version)[0];
189              
190 19         81 return $major;
191             }
192              
193             sub get_minor {
194 19     19 1 49 my ($self) = @_;
195              
196 19         655 my $version = $self->version;
197              
198 19         77 my $minor = (split /\./, $version)[1];
199              
200 19         103 return $minor;
201             }
202              
203             sub get_micro {
204 19     19 1 58 my ($self) = @_;
205              
206 19         566 my $version = $self->version;
207              
208 19         72 my $micro = (split /\./, $version)[2];
209              
210 19         78 return $micro;
211             }
212              
213             sub pkgident {
214 0     0 1 0 my ($self) = @_;
215              
216 0         0 my $org = $self->orgident;
217 0         0 my $name = $self->fullname;
218 0         0 my $id = join q{.}, $org, $name;
219              
220 0         0 return $id;
221             }
222              
223             sub fullname {
224 6     6 1 17 my ($self) = @_;
225              
226 6         10 my $fullname;
227 6 100 66     211 if ( defined $self->base && length $self->base > 0 ) {
228 3         78 $fullname = join q{-}, $self->base, $self->name;
229             }
230             else {
231 3         81 $fullname = $self->name;
232             }
233              
234 6         76 return $fullname;
235             }
236              
237             sub deb_name {
238 0     0 1 0 my ($self) = @_;
239              
240             # By convention debian package names are lower-case
241 0         0 my $name = lc $self->fullname;
242              
243             # underscores are not permitted, helpfully replace with dashes
244 0         0 $name =~ s/_/-/g;
245              
246             # For safety remove any other invalid characters
247 0         0 $name =~ s/[^a-z0-9-]//;
248              
249 0         0 return $name;
250             }
251              
252             sub tarname {
253 2     2 1 6 my ( $self, $comp ) = @_;
254 2   100     10 $comp ||= 'gz';
255              
256 2         6 my $packname = join q{-}, $self->fullname, $self->version;
257 2         7 my $tarname = $packname . ".tar.$comp";
258              
259 2         12 return $tarname;
260             }
261              
262             sub deb_srctarname {
263 0     0 0 0 my ( $self, $comp ) = @_;
264 0   0     0 $comp ||= 'gz';
265              
266 0         0 my $packname = join q{_}, $self->deb_name, $self->deb_version;
267 0         0 my $tarname = $packname . ".orig.tar.$comp";
268              
269 0         0 return $tarname;
270             }
271              
272             sub deb_tarname {
273 0     0 1 0 my ( $self, $comp ) = @_;
274 0   0     0 $comp ||= 'gz';
275              
276 0         0 my $packname = join q{_}, $self->deb_name, $self->deb_version;
277 0         0 my $tarname = $packname . "-1.debian.tar.$comp";
278              
279 0         0 return $tarname;
280             }
281              
282             sub deb_dscname {
283 0     0 1 0 my ($self) = @_;
284              
285 0         0 my $packname = join q{_}, $self->deb_name, $self->deb_version;
286 0         0 my $dscname = $packname . "-1.dsc";
287              
288 0         0 return $dscname;
289             }
290              
291             sub rpmspec_name {
292 0     0 1 0 my ( $self, $base ) = @_;
293              
294 0         0 return $self->fullname . '.spec';
295             }
296              
297             sub clone {
298 1     1 0 1020 my ($self) = @_;
299              
300 1         7 require Storable;
301 1         115 my $clone = Storable::dclone($self);
302              
303 1         6 return $clone;
304             }
305              
306             sub new_from_metafile {
307 6     6 1 2460 my ( $class, $file ) = @_;
308              
309 6 100 100     138 if ( !defined $file || !length $file ) {
    100          
310 2         25 die "Error: You need to specify the LCFG meta-data file name\n";
311             }
312             elsif ( !-f $file ) {
313 1         11 die "Error: Cannot find LCFG meta-data file '$file'\n";
314             }
315              
316 3         1442 require YAML::Syck;
317 3         5697 my $data;
318             {
319             # Allow true/false, yes/no for booleans
320 3         8 local $YAML::Syck::ImplicitTyping = 1;
  3         10  
321              
322 3         13 $data = YAML::Syck::LoadFile($file);
323              
324             # We unbless as previously saved metafiles are going to have a
325             # blessing. We want all input files treated with the same
326             # amount of contempt.
327              
328 3         821 Data::Structure::Util::unbless($data);
329             }
330              
331 3         184 my $self = $class->new($data);
332              
333 3         94 $self->metafile($file);
334              
335 3         28 return $self;
336             }
337              
338             sub new_from_cfgmk {
339 9     9 1 1305 my ( $proto, $file ) = @_;
340              
341 9 100 100     246 if ( !defined $file || !length $file ) {
    100          
342 2         13 die "Error: You need to specify the LCFG config file name\n";
343             }
344             elsif ( !-f $file ) {
345 1         13 die "Error: Cannot find LCFG config file '$file'\n";
346             }
347              
348 6         72 my %translator = (
349             COMP => 'name',
350             DESCR => 'abstract',
351             V => 'version',
352             R => 'release',
353             SCHEMA => 'schema',
354             GROUP => 'group',
355             AUTHOR => 'author',
356             ORGANIZATION => 'vendor',
357             DATE => 'date',
358             );
359              
360 6         14 my %spec;
361              
362 6 50       52 my $in = IO::File->new( $file, 'r' ) or die "Could not open $file: $!\n";
363              
364 6         892 while ( defined ( my $line = <$in> ) ) {
365 173         348 $line =~ s/^\s+//;
366 173         519 $line =~ s/\s+$//;
367              
368 173         380 while ( $line =~ m{^(.*?)\\$} ) {
369 0         0 my $extra = <$in>;
370 0         0 $line = $1 . $extra;
371             }
372              
373 173 100       520 if ( $line =~ m/^([^=]+)=(.+)$/ ) {
374 143         357 my ( $key, $value ) = ( $1, $2 );
375 143 100       463 if ( exists $translator{$key} ) {
    100          
    100          
376 53         281 $spec{ $translator{$key} } = $value;
377             }
378             elsif ( $key eq 'PLATFORMS' ) {
379 6         33 my @platforms = split /,\s*/, $value;
380 6         33 $spec{platforms} = [@platforms];
381             }
382             elsif ( $key eq 'NAME' ) {
383 6         11 my $compname;
384 6 50       34 if ( $value =~ m/^(.+?)-(.+?)$/ ) {
385 6         27 ( $spec{base}, $compname ) = ( $1, $2 );
386             }
387             else {
388 0         0 $compname = $value;
389             }
390              
391 6 100       27 if ( $compname ne '$(COMP)' ) {
392 1         5 $spec{name} = $compname;
393             }
394             }
395             }
396              
397             }
398              
399 6         67 $in->close;
400              
401 6         101 my $pkgspec;
402 6 100 100     53 if ( !ref $proto ) {
    100          
403 3         9 $spec{license} = 'GPLv2';
404 3   100     16 $spec{vendor} ||= 'University of Edinburgh';
405 3         14 $spec{vcs} = { logname => 'ChangeLog' };
406 3         11 $spec{build} = { gencmake => 1 };
407 3         11 $spec{translate} = [ '*.cin' ];
408 3         111 $pkgspec = $proto->new(\%spec);
409             }
410             elsif ( defined Scalar::Util::blessed($proto) && $proto->isa(__PACKAGE__) ) {
411 1         3 $pkgspec = $proto;
412 1         15 for my $key ( keys %spec ) {
413 11         340 $pkgspec->$key($spec{$key});
414             }
415             }
416             else {
417 2         29 die "Error: new_from_cfgmk method called on wrong class or object\n";
418             }
419              
420 3         33 return $pkgspec;
421             }
422              
423             sub save_metafile {
424 3     3 1 5282 my ( $self, $file ) = @_;
425              
426 3   66     80 $file ||= $self->metafile;
427              
428 3 100 66     15 if ( !defined $file || !length $file ) {
429 2         14 die "Error: You need to specify the LCFG config file name\n";
430             }
431              
432 1         6 require YAML::Syck;
433             {
434 1         3 local $YAML::Syck::SortKeys = 1;
  1         2  
435 1         2 my $dump = \%{$self};
  1         3  
436 1         3 delete $dump->{metafile};
437 1         4 YAML::Syck::DumpFile( $file, $dump );
438             }
439              
440 1         288 return;
441             }
442              
443             sub dev_version {
444 2     2 1 5 my ($self) = @_;
445              
446 2         6 $self->update_release;
447              
448 2         52 my $dev_version = 'dev' . $self->release;
449              
450 2         10 $dev_version = join q{.}, $self->get_major, $self->get_minor,
451             $self->get_micro, $dev_version;
452              
453 2         55 $self->version($dev_version);
454              
455 2         52 return $self->version;
456             }
457              
458             sub update_release {
459 6     6 1 2340 my ($self) = @_;
460              
461 6         176 my $release = $self->release;
462              
463 6 100       22 if ( !defined $release ) {
464 1         3 $release = 1;
465             }
466             else {
467 5         9 $release++;
468             }
469              
470 6         160 $self->release($release);
471              
472 6         13 return;
473             }
474              
475             sub update_date {
476 12     12 1 1000332 my ($self) = @_;
477              
478 12         118 my $now = DateTime->now->strftime('%d/%m/%y %T');
479              
480 12         7441 $self->date($now);
481              
482 12         29 return;
483             }
484              
485             sub update_major {
486 3     3 1 1000277 my ($self) = @_;
487 3         21 return $self->_update_version('major');
488             }
489              
490             sub update_minor {
491 3     3 1 1000277 my ($self) = @_;
492 3         18 return $self->_update_version('minor');
493             }
494              
495             sub update_micro {
496 4     4 1 1000262 my ($self) = @_;
497 4         44 return $self->_update_version('micro');
498             }
499              
500             sub _update_version {
501 11     11   1000396 my ( $self, $uptype ) = @_;
502              
503 11         59 my $major = $self->get_major;
504 11         61 my $minor = $self->get_minor;
505 11         51 my $micro = $self->get_micro;
506              
507 11 100       72 if ( $uptype eq 'major' ) {
    100          
    100          
508 3         11 $major++;
509 3         7 $minor = 0;
510 3         10 $micro = 0;
511             }
512             elsif ( $uptype eq 'minor' ) {
513 3         10 $minor++;
514 3         9 $micro = 0;
515             }
516             elsif ( $uptype eq 'micro' ) {
517 4         12 $micro++;
518             }
519             else {
520 1         18 die "Unknown version update-type: $uptype\n";
521             }
522              
523 10         45 my $newver = join q{.}, $major, $minor, $micro;
524              
525 10         289 my $rel = $self->release;
526 10         23 my $newrel;
527 10 100       28 if ( defined $rel ) {
528 9 50       59 if ( $rel =~ m/^\d+(.*)$/ ) {
529 9         39 $newrel = q{1} . $1;
530             }
531             else {
532 0         0 die "Release string, '$rel', does not match expected format\n";
533             }
534             }
535             else {
536 1         3 $newrel = 1;
537             }
538              
539             # Only update the attributes if everything else has succeeded
540             # (i.e. we got this far in the code).
541              
542 10         281 $self->version($newver);
543 10         266 $self->release($newrel);
544 10         46 $self->update_date();
545              
546 10         32 return;
547             }
548              
549             1;
550             __END__
551              
552             =head1 NAME
553              
554             LCFG::Build::PkgSpec - Object-oriented interface to LCFG build metadata
555              
556             =head1 VERSION
557              
558             This documentation refers to LCFG::Build::PkgSpec version 0.2.6
559              
560             =head1 SYNOPSIS
561              
562             my $spec = LCFG::Build::PkgSpec->new( name => "foo",
563             version => "0.0.1" );
564              
565             $spec->schema(2);
566              
567             $spec->save_metafile("./lcfg.yml");
568              
569             my $spec2 =
570             LCFG::Build::PkgSpec->new_from_metafile("./lcfg.yml");
571              
572             print "Package name is: " . $spec2->name . "\n";
573              
574             $spec2->update_major();
575              
576             $spec->save_metafile("./lcfg.yml");
577              
578             =head1 DESCRIPTION
579              
580             This class provides an object-oriented interface to the LCFG build
581             tools metadata file. All simple fields are available through attribute
582             accessors. Specific methods are also provided for querying and
583             modifying the more complex data types (e.g. lists and hashes).
584              
585             This class has methods for carrying out specific procedures related to
586             tagging releases with the LCFG build tools. It also has methods for
587             handling the old format LCFG build configuration files.
588              
589             More information on the LCFG build tools is available from the website
590             http://www.lcfg.org/doc/buildtools/
591              
592             =head1 ATTRIBUTES
593              
594             =over
595              
596             =item name
597              
598             This is the name of the project or LCFG component. In the case of the
599             component think of it as the "foo" part of "lcfg-foo". When an object
600             is created this field MUST be specified, there is no default value.
601              
602             =item base
603              
604             This is only really meaningful in terms of LCFG components, in which
605             case it is the "lcfg" part of "lcfg-foo" or the "dice" part of
606             "dice-foo". This is optional and the default value is an empty string.
607              
608             =item abstract
609              
610             This is a short description of the project, it is optional and there
611             is no default.
612              
613             =item version
614              
615             This is the version of the project, it is required and if not
616             specified at object creation time it will default to '0.0.0'. Due to
617             backwards compatibility reasons this version must be in 3 integer
618             parts separated with the period character. Any attempt to set it
619             otherwise will result in an error being thrown.
620              
621             =item release
622              
623             This is the release number for a project and is directly related to
624             the release field used for RPMs and Debian packages. It is optional
625             and defaults to 1. If used, the first character of the release field
626             MUST be an integer, after that you can put in whatever you like.
627              
628             =item schema
629              
630             This is only really meaningful in terms of LCFG components. It is the
631             schema number of the defaults file which specifies the details for the
632             supported resources. It is optional and will default to 1.
633              
634             =item group
635              
636             This is the software group into which this project best fits, it is
637             mainly provided for RPM specfile generation support
638             (e.g. "Development/Libraries"). It is optional and has no default
639             value.
640              
641             =item vendor
642              
643             This matches the "Vendor" field used in RPMs, it is optional and has
644             no default value.
645              
646             =item orgident
647              
648             This is an identifier for your organisation which is based on the
649             reversed form of your domain name, C<com.example> or C<org.example>
650             for example. No validation is done to check if this is the reversal of
651             a real domain name, you can use whatever you want, the default value
652             is C<org.lcfg>. This is used by the C<pkgident> method as part of the
653             process of generating MacOSX packages.
654              
655             =item license
656              
657             This is the short string used in RPMs to specify the license for the
658             project. This field is optional and there is no default value.
659              
660             =item date
661              
662             This is used to show the date and time at which the project version
663             was last altered. If not specified it will default to the current date
664             and time in the format 'DD/MM/YY HH:MM:SS'.
665              
666             =item author
667              
668             This is the name (or list of names) of the project author(s). The
669             default value is an empty list. You should note that calling this
670             accessor with no arguments returns a list not a scalar value. See
671             below for convenience methods provided for accessing and managing the
672             information contained with the list.
673              
674             =item platforms
675              
676             This is the list of supported platforms for the project. The default
677             value is an empty list. You should note that calling this accessor
678             with no arguments returns a list not a scalar value. See below for
679             convenience methods provided for accessing and managing the
680             information contained with the list.
681              
682             =item vcs
683              
684             This is a reference to a hash containing details of the version
685             control system used for the project. This is optional and defaults to
686             an empty hash. See below for convenience methods provided for
687             accessing and managing the information contained with the hash.
688              
689             =back
690              
691             =head1 SUBROUTINES/METHODS
692              
693             =over
694              
695             =item fullname
696              
697             Returns the full name of the package, if the 'base' attribute is
698             specified then this will be a combination of base and package name
699             separated with a hyphen, e.g. 'lcfg-foo'. If no base is specified then
700             this is just the package name, e.g. 'foo'.
701              
702             =item deb_name
703              
704             Returns a name for the package which is safe for use as a Debian
705             package name. Debian package names must not contain the C<_>
706             (underscore) character so those are replace with hyphens, also by
707             convention the name is lower-cased. Any invalid characters (not in the
708             set C<[a-zA-Z0-9-]>) are simply removed.
709              
710             =item deb_version
711              
712             Returns a version for the package which is safe for use with Debian
713             packages. Typically this will be identical to the standard C<version>
714             string. Debian package versions must only contain characters in the
715             set C<[a-zA-Z0-9~.+-]>, any invalid characters are simply removed
716              
717             =item deb_tarname
718              
719             Returns the name of the debian source package tarfile which would be
720             generated for this version of the package. This combines the full name
721             and the version, for example, C<lcfg-foo_1.0.1-1.debian.tar.gz>. Note
722             that the LCFG build tools will only actually generate this file when a
723             project contains a C<debian> sub-directory.
724              
725             =item deb_dscname
726              
727             Returns the name of the debian source control (dsc) file which would
728             be generated for this version of the package. This combines the full
729             name and the version, for example, C<lcfg-foo_1.0.1-1.dsc>. Note that
730             the LCFG build tools will only actually generate this file when a
731             project contains a C<debian> sub-directory.
732              
733             =item pkgident
734              
735             This returns a string formed by the concatenation of the C<orgident>
736             and C<fullname> values, joined with a period character,
737             C<com.example.lcfg-client> for example. This is used as the identifier
738             name for MacOSX packages.
739              
740             =item rpmspec_name
741              
742             This returns the name of the RPM specfile for the project. This is
743             just based on the full name with a C<.spec> suffix
744             (e.g. C<lcfg-foo.spec>).
745              
746             =item tarname
747              
748             Returns the standard LCFG name of the tarfile which would be generated
749             for this version of the package. This combines the full name and the
750             version, for example, C<lcfg-foo_1.0.1.orig.tar.gz>
751              
752             =item new_from_metafile($file)
753              
754             Create a new object which represents the LCFG build metadata stored in
755             the YAML file.
756              
757             =item save_metafile($file)
758              
759             Save the object data into the LCFG metadata file.
760              
761             =item new_from_cfgmk($file)
762              
763             Create from the old-style LCFG config.mk a new object which represents
764             the LCFG build metadata.
765              
766             =item perl_version
767              
768             This returns the package version as a string in a style which is safe
769             for use in Perl modules. If this is a development release the C<dev>
770             suffix is replaced with the value of the release. This is done because
771             Perl versions are not permitted to contain non-numeric characters.
772              
773             =item get_major
774              
775             Get just the major (first) part of the package version.
776              
777             =item get_minor
778              
779             Get just the minor (middle) part of the package version.
780              
781             =item get_micro
782              
783             Get just the micro (last) part of the package version.
784              
785             =item update_major
786              
787             Increment by one the first (largest) part of the version. This will
788             also reset the second and third parts of the version to 0 (zero) and
789             the release field to 1. For example, version 1.2.3 would become 2.0.0
790             and the release field would go from 5 to 1.
791              
792             =item update_minor
793              
794             Increment by one the second (middle) part of the version. This will
795             also reset the third part of the version to 0 (zero) and the release
796             field to 1. For example, version 1.2.3 would become 1.3.0 and the
797             release field would go from 5 to 1.
798              
799             =item update_micro
800              
801             Increment by one the third (smallest) part of the version field. This
802             will also reset the release field to 1. For example, version 1.2.3
803             would become 1.2.4 and the release field would go from 5 to 1.
804              
805             =item update_date
806              
807             Update the date attribute to the current time, this is set to the
808             format 'DD/MM/YY HH:MM::SS'. You should not normally need to call this
809             method, it is called at the end of the update_micro, update_minor and
810             update_major methods to show when the version update occurred.
811              
812             =item update_release
813              
814             This method updates the release field by incrementing the value. If it
815             was not previously defined then it will be set to one.
816              
817             =item dev_version
818              
819             This method converts the version to the development format. If it is
820             not already present an C<.dev> string is appended to the version
821             string along with the value of the release field. The release field is
822             also incremented. For example, the first dev version for C<1.2.3>
823             would be C<1.2.3.dev1> and the second would be C<1.2.3.dev2>.
824              
825             =item add_author
826              
827             A convenience method for adding new authors to the list of project
828             authors. Note that this does not prevent an author being added
829             multiple times.
830              
831             =item add_platform
832              
833             A convenience method for adding new platforms to the list of
834             supported platforms for this project. Note that this does not prevent
835             a platform being added multiple times.
836              
837             =item exists_in_vcsinfo($key)
838              
839             A convenience method to see if a particular key exists in the
840             version-control information.
841              
842             =item ids_in_vcsinfo
843              
844             A convenience method to get a list of all the keys in the
845             version-control information.
846              
847             =item get_vcsinfo($key)
848              
849             A convenience method to get the data associated with a particular key
850             in the version-control information.
851              
852             =item set_vcsinfo($key, $value)
853              
854             A convenience method to set the data associated with a particular key
855             in the version-control information.
856              
857             =item exists_in_buildinfo($key)
858              
859             A convenience method to see if a particular key exists in the
860             build information.
861              
862             =item ids_in_buildinfo
863              
864             A convenience method to get a list of all the keys in the
865             build information.
866              
867             =item get_buildinfo($key)
868              
869             A convenience method to get the data associated with a particular key
870             in the build information.
871              
872             =item set_buildinfo($key, $value)
873              
874             A convenience method to set the data associated with a particular key
875             in the build information.
876              
877             =back
878              
879             =head1 DEPENDENCIES
880              
881             This module is L<Moose> powered. It also requires
882             L<Data::Structure::Util>, L<DateTime> and if you want to parse and
883             write LCFG metadata files you will need L<YAML::Syck>.
884              
885             =head1 SEE ALSO
886              
887             lcfg-cfg2meta(1), lcfg-pkgcfg(1), LCFG::Build::Tools(3)
888              
889             =head1 PLATFORMS
890              
891             This is the list of platforms on which we have tested this
892             software. We expect this software to work on any Unix-like platform
893             which is supported by Perl.
894              
895             ScientificLinux5, ScientificLinux6
896              
897             =head1 BUGS AND LIMITATIONS
898              
899             There are no known bugs in this application. Please report any
900             problems to bugs@lcfg.org, feedback and patches are also always very
901             welcome.
902              
903             =head1 AUTHOR
904              
905             Stephen Quinney <squinney@inf.ed.ac.uk>
906              
907             =head1 LICENSE AND COPYRIGHT
908              
909             Copyright (C) 2008-2019 University of Edinburgh. All rights reserved.
910              
911             This library is free software; you can redistribute it and/or modify
912             it under the terms of the GPL, version 2 or later.
913              
914             =cut