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