File Coverage

blib/lib/LCFG/Build/Tool.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package LCFG::Build::Tool; # -*-cperl-*-
2 1     1   1625 use strict;
  1         3  
  1         41  
3 1     1   5 use warnings;
  1         2  
  1         49  
4              
5             # $Id: Tool.pm.in 23959 2013-10-11 12:53:58Z squinney@INF.ED.AC.UK $
6             # $Source: /var/cvs/dice/LCFG-Build-Tools/lib/LCFG/Build/Tool.pm.in,v $
7             # $Revision: 23959 $
8             # $HeadURL: https://svn.lcfg.org/svn/source/tags/LCFG-Build-Tools/LCFG_Build_Tools_0_4_0/lib/LCFG/Build/Tool.pm.in $
9             # $Date: 2013-10-11 13:53:58 +0100 (Fri, 11 Oct 2013) $
10              
11             our $VERSION = '0.4.0';
12              
13 1     1   1089 use File::HomeDir;
  1         7344  
  1         65  
14 1     1   8 use File::Spec;
  1         2  
  1         17  
15 1     1   435 use LCFG::Build::PkgSpec;
  0            
  0            
16             use UNIVERSAL::require;
17              
18             my $VCS_STUB = 'LCFG::Build::VCS::';
19              
20             use Moose;
21              
22             extends 'MooseX::App::Cmd::Command';
23              
24             has 'dryrun' => (
25             is => 'rw',
26             isa => 'Bool',
27             default => 0,
28             documentation => 'Simulate operation',
29             );
30              
31             has 'quiet' => (
32             traits => ['Getopt'],
33             is => 'rw',
34             isa => 'Bool',
35             default => 0,
36             cmd_aliases => 'q',
37             documentation => 'Less output to the screen',
38             );
39              
40             has 'dir' => (
41             is => 'rw',
42             isa => 'Str',
43             required => 1,
44             default => q{.},
45             documentation => 'Project working directory',
46             );
47              
48             has 'resultsdir' => (
49             is => 'rw',
50             isa => 'Str',
51             lazy => 1,
52             default => sub { File::Spec->catdir( File::HomeDir->my_home(),
53             'lcfgbuild' ) },
54             documentation => 'Base directory for storing results',
55             );
56              
57             has '_spec' => (
58             accessor => 'spec',
59             isa => 'LCFG::Build::PkgSpec',
60             lazy => 1,
61             builder => '_load_pkgspec',
62             );
63              
64             has '_vcs' => (
65             accessor => 'vcs',
66             does => 'LCFG::Build::VCS',
67             lazy => 1,
68             builder => '_load_vcs_module',
69             );
70              
71             __PACKAGE__->meta->make_immutable;
72              
73             # A simple loader method for the required LCFG version control module.
74             # Where necessary this can be overloaded by implementing classes to
75             # handle more complex cases.
76              
77             sub _load_vcs_module {
78             my ($self) = @_;
79              
80             my $spec = $self->spec;
81              
82             my $vcstype;
83             if ( defined $spec->vcs && defined $spec->get_vcsinfo('type') ) {
84             $vcstype = $spec->get_vcsinfo('type');
85             }
86             else {
87             warn "No version-control information in the LCFG metafile for this project.\n";
88              
89             # Attempt to detect the version-control system, otherwise fall
90             # back to the "None" module. This is not very extensible but I
91             # have not yet come up with a simple method to provide support
92             # for any/all version-control systems.
93              
94             my @modules = ( 'SVN', 'CVS' );
95              
96              
97             for my $module (@modules) {
98             my $vcs = $VCS_STUB . $module;
99             if ( $vcs->require && $vcs->auto_detect($self->dir) ) {
100             $vcstype = $module;
101             last;
102             }
103             }
104              
105             if ( !$vcstype ) {
106             $vcstype = 'None';
107             }
108              
109             warn "Auto-detected that the $vcstype module should be used.\n";
110             }
111              
112             my $vcsmodule = $VCS_STUB . $vcstype;
113              
114             $vcsmodule->require or die $@;
115              
116             my $vcs = $vcsmodule->new(
117             quiet => $self->quiet,
118             dryrun => $self->dryrun,
119             module => $spec->fullname,
120             workdir => $self->dir,
121             );
122              
123             return $vcs;
124             }
125              
126             # A simple loader method for the LCFG package specification metadata.
127             # Where necessary this can be overloaded by implementing classes to
128             # handle more complex cases, e.g. where the module was not already
129             # checked out of the revision control system.
130              
131             sub _load_pkgspec {
132             my ($self) = @_;
133              
134             # Find and load the package specification.
135              
136             my $metafile = File::Spec->catfile( $self->dir, 'lcfg.yml' );
137              
138             my $spec = LCFG::Build::PkgSpec->new_from_metafile($metafile);
139              
140             return $spec;
141             }
142              
143             sub fail {
144             my ( $self, $message ) = @_;
145              
146             die $message . "\n";
147             }
148              
149             sub log {
150             my ( $self, $message ) = @_;
151              
152             if ( !$self->quiet ) {
153             print {*STDERR} 'LCFG: ' . $message . "\n";
154             }
155              
156             return;
157             }
158              
159             no Moose;
160             1;
161             __END__
162              
163             =head1 NAME
164              
165             LCFG::Build::Tool - LCFG software packaging tool
166              
167             =head1 VERSION
168              
169             This documentation refers to LCFG::Build::Tool version 0.4.0
170              
171             =head1 SYNOPSIS
172              
173             This is an interface and cannot be instantiated directly.
174              
175             =head1 DESCRIPTION
176              
177             This module provides software release tools for the LCFG build
178             suite.
179              
180             This class is an interface which must be implemented by any LCFG build
181             tool. It has a set of attributes which are relevant to all
182             implementing classes. Any class implementing this interface must
183             provide a run() method.
184              
185             More information on the LCFG build tools is available from the website
186             http://www.lcfg.org/doc/buildtools/
187              
188             =head1 ATTRIBUTES
189              
190             The following attributes are modifiable via the command-line (i.e. via
191             @ARGV) as well as the normal way when the Tool object is
192             created. Unless stated the options take strings as arguments and can
193             be used like C<--foo=bar>. Boolean options can be expressed as either
194             C<--foo> or C<--no-foo> to signify true and false values.
195              
196             =over
197              
198             =item dryrun
199              
200             A boolean value which indicates whether actions which permanently
201             alter the contents of files should be carried out. The default value
202             is false (0). When running in dry-run mode various you will typically
203             get extra output to the screen showing what would have been done.
204              
205             =item quiet
206              
207             A boolean value which indicates whether the actions should attempt to
208             be quieter. The default value is false (0).
209              
210             =item dir
211              
212             The path of the project directory which contains the software for
213             which you want to create a release. If this is not specified then a
214             default value of the current directory (.) will be used. This
215             directory must already contain the LCFG build metadata file (lcfg.yml)
216             for the software.
217              
218             =item resultsdir
219              
220             When a project is packaged for release the generated products (the
221             gzipped source tar file, various build metadata files and possibly
222             binary RPMS, etc) are stored into a directory named after the
223             combination of the full name of the project and the version
224             number. For example, a project named 'foo' with version '1.2.3' would
225             have an output directory of 'foo-1.2.3'. You should note that if the
226             C<base> attribute is specified in the metadata file (this is the case
227             for LCFG components) then that is also used. If the previous example
228             was an LCFG component it would have a directory named
229             'lcfg-foo-1.2.3'.
230              
231             This attribute controls the parent directory into which that generated
232             directory will be placed. The default on a Unix system is
233             C<$HOME/lcfgbuild/> which will be created if it does not already
234             exist.
235              
236             =back
237              
238             The following methods are not modifiable by the command-line, they are
239             however directly modifiable via the Tool object if
240             necessary. Typically you will only need to query these attributes,
241             they are automatically created when you need them using values for
242             some of the other command-line attributes.
243              
244             =over
245              
246             =item spec
247              
248             This is a reference to the current project metadata object, see
249             L<LCFG::Build::PkgSpec> for full details.
250              
251             =item vcs
252              
253             This is a reference to the current version-control object, see
254             L<LCFG::Build::VCS> and associated helper modules for full details.
255              
256             =back
257              
258             =head1 SUBROUTINES/METHODS
259              
260             =over
261              
262             =item run
263              
264             Any class implementing this interface B<MUST> have a run() method.
265              
266             =item fail($message)
267              
268             Immediately fails (i.e. dies) and displays the message.
269              
270             =item log($message)
271              
272             Logs the message to the screen if the C<quiet> attribute has not been
273             specified. A message string is prefixed with 'LCFG: ' to help visually
274             separate it from other output.
275              
276             =back
277              
278             =head1 DEPENDENCIES
279              
280             This module is L<Moose> powered and uses L<MooseX::App::Cmd> to handle
281             command-line options.
282              
283             The following modules from the LCFG build tools suite are also
284             required: L<LCFG::Build::PkgSpec>, L<LCFG::Build::VCS> and VCS helper
285             module for your preferred version-control system.
286              
287             =head1 SEE ALSO
288              
289             L<LCFG::Build::Tools>, L<LCFG::Build::Skeleton>, lcfg-reltool(1)
290              
291             =head1 PLATFORMS
292              
293             This is the list of platforms on which we have tested this
294             software. We expect this software to work on any Unix-like platform
295             which is supported by Perl.
296              
297             Fedora12, Fedora13, ScientificLinux5, ScientificLinux6, MacOSX7
298              
299             =head1 BUGS AND LIMITATIONS
300              
301             There are no known bugs in this application. Please report any
302             problems to bugs@lcfg.org, feedback and patches are also always very
303             welcome.
304              
305             =head1 AUTHOR
306              
307             Stephen Quinney <squinney@inf.ed.ac.uk>
308              
309             =head1 LICENSE AND COPYRIGHT
310              
311             Copyright (C) 2008-2013 University of Edinburgh. All rights reserved.
312              
313             This library is free software; you can redistribute it and/or modify
314             it under the terms of the GPL, version 2 or later.
315              
316             =cut