File Coverage

lib/Devel/PerlySense/Config/Project.pm
Criterion Covered Total %
statement 77 77 100.0
branch 11 14 78.5
condition n/a
subroutine 19 19 100.0
pod 4 4 100.0
total 111 114 97.3


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Devel::PerlySense::Config::Project - A Project's configuration
4              
5             =head1 SYNOPSIS
6              
7              
8              
9              
10             =head1 DESCRIPTION
11              
12             Configuration can be Project level, stored in .../.PerlySense/project.cfg
13              
14             =cut
15              
16              
17              
18              
19              
20 63     63   21502 use strict;
  63         82  
  63         1579  
21 63     63   227 use warnings;
  63         106  
  63         1379  
22 63     63   622 use utf8;
  63         94  
  63         291  
23              
24             package Devel::PerlySense::Config::Project;
25              
26              
27              
28              
29              
30 63     63   2391 use Spiffy -Base;
  63         4785  
  63         267  
31 63     63   92243  
  63     63   85  
  63         1430  
  63         218  
  63         67  
  63         1363  
32 63     63   224 use Data::Dumper;
  63         68  
  63         5036  
33 63     63   248 use Carp;
  63         86  
  63         4009  
34              
35 63     63   273 use File::Basename;
  63         78  
  63         4032  
36 63     63   245 use File::Path;
  63         90  
  63         2920  
37 63     63   230 use Path::Class;
  63         88  
  63         2827  
38 63     63   37714 use YAML::Tiny ();
  63         362291  
  63         1394  
39 63     63   23469 use HTTP::Date qw/ time2iso /;
  63         349754  
  63         3692  
40              
41 63     63   700 use Devel::PerlySense::Util;
  63         79  
  63         46949  
42              
43              
44              
45              
46              
47             =head1 PROPERTIES
48              
49             =head2 nameFileConfig
50              
51             The config file name relative to the root dir.
52              
53             Default: ./PerlySenseProject/project.cfg
54              
55             =cut
56             field "nameFileConfig" => ".PerlySenseProject/project.yml";
57              
58              
59              
60              
61              
62              
63             =head2 textConfigDefault
64              
65             The default contents of the config file
66              
67             =cut
68             field "textConfigDefault" => q{#PerlySense Project Config
69              
70             #What's this all about? See: http://search.cpan.org/dist/Devel-PerlySense/
71              
72             project:
73              
74             #The human readable name of the Project
75             moniker: 'The Project Without a Name'
76              
77             #Extra @INC directories, relative to the project root
78             #These come before the default inc directories "." and "lib"
79             inc_dir: []
80              
81              
82             #Bookmarks are regexes that may match against a single line.
83             #
84             #The "rex" is either a qr regex declaration, or an array ref of
85             #regexes (any of them could match to make a bookmark for the line).
86             #
87             #The line, or $1 if captured, is displayed.
88             bookmark:
89             -
90             moniker: Todo
91             rex:
92             - "qr/\# \s* TODO \s* : \s* (.+?) \s*$/x"
93              
94              
95             external:
96             editor:
97              
98             #Emacs specific configuration
99             emacs:
100              
101             #To enable flymake in Emacs, configure this in your .emacs file
102             #(setq perly-sense-load-flymake t)
103             #
104             #For more details, settings and colors, see:
105             #http://search.cpan.org/dist/Devel-PerlySense/lib/Devel/PerlySense.pm#Emacs_installation
106             #
107             flymake:
108              
109             #During a flymake compilation, perly_sense can run:
110              
111             #Check Syntax (perl -c)
112             #
113             #!!!NOTE!!!
114             # Running perl -c on random Perl code will execute
115             # the BEGIN blocks! Any funny business in them and you're toast!
116             #!!!NOTE!!!
117             syntax: 0
118              
119             #Perl Critic
120             #PerlySense will point Critic to a .perlcritic file in this (the .PerlySense)
121             #directory. A default config file with fairly lenient rules is
122             #provided.
123             critic: 0
124              
125              
126             #Run File Configuration.
127             #"C-o C-r" to run "command" and "C-u C-o C-r" to run alternate_command
128             #
129             #These are evaluated in order to find a way to run a file. First
130             #match is used.
131             run_file:
132             -
133             command: "prove --nocolor -v ${INC} \"${SOURCE_FILE}\""
134             alternate_command: ""
135             moniker: Test
136             rex: \.t$
137             run_from: source_root_directory
138             -
139             command: "perl -c ${INC} \"${SOURCE_FILE}\" 2>&1| perl -ne \"/Subroutine \\w+ redefined at/ or print\""
140             alternate_command: ""
141             moniker: Module
142             rex: \.pm$
143             run_from: source_root_directory
144             -
145             command: "perl ${INC} \"${SOURCE_FILE}\""
146             alternate_command: ""
147             moniker: Script
148             rex: \.pl$
149             run_from: file_directory
150              
151             #This is a catch-all for all other types of files
152             -
153             command: "perl ${INC} \"${SOURCE_FILE}\""
154             alternate_command: ""
155             moniker: 'Script (no .pl)'
156             rex: .
157             run_from: file_directory
158              
159              
160              
161             #Run File in Debugger Configuration.
162             #"C-o r d" to debug "command" and "C-u C-o r d" to debug alternate_command
163             #
164             #These are evaluated in order to find a way to debug a file. First
165             #match is used.
166             debug_file:
167             -
168             command: "perl -d ${INC} \"${SOURCE_FILE}\""
169             alternate_command: ""
170             moniker: Test
171             rex: \.t$
172             debug_from: source_root_directory
173             -
174             command: "perl -d ${INC} \"${SOURCE_FILE}\""
175             alternate_command: ""
176             moniker: Script
177             rex: \.pl$
178             debug_from: file_directory
179              
180             -
181             command: "perl -d ${INC} \"${SOURCE_FILE}\""
182             alternate_command: ""
183             moniker: Module
184             rex: \.pm$
185             debug_from: source_root_directory
186              
187             #This is a catch-all for all other types of files
188             -
189             command: "perl -d ${INC} \"${SOURCE_FILE}\""
190             alternate_command: ""
191             moniker: 'Script (no .pl)'
192             rex: .
193             debug_from: file_directory
194              
195              
196              
197              
198             #EOF
199             };
200              
201              
202              
203              
204              
205             =head2 nameFileCritic
206              
207             The Perl::Critic config file name relative to the root dir.
208              
209             Default: ./PerlySenseProject/.perlcritic
210              
211             =cut
212             field "nameFileCritic" => ".PerlySenseProject/.perlcritic";
213              
214              
215              
216              
217              
218              
219             =head2 textCriticDefault
220              
221             The default contents of the Perl::Critic config file
222              
223             =cut
224             field "textCriticDefault" => q{#Default Perl Critic config file
225             #
226             #To enable Perl::Critic highlighting in your source code,
227             #edit .PerlysenseProject/project.yml and set flymake/critic: 1
228             #
229             #Make sure you read the documentation for Perl::Critic, and especially
230             #the config docs.
231             #http://search.cpan.org/dist/Perl-Critic/lib/Perl/Critic.pm#CONFIGURATION
232             #http://search.cpan.org/dist/Perl-Critic/lib/Perl/Critic/Config.pm
233             #
234             #You can obviously replace this file with your own Perl::Critic config
235             #file, or a symlink to it.
236             #
237              
238             severity = 5
239              
240             theme = bugs + maintenance + security + complexity
241              
242              
243              
244             #This one must be disabled, since flymake will create temp files which
245             #by definition never match the specified package name
246             [-Modules::RequireFilenameMatchesPackage]
247              
248              
249              
250             [-Subroutines::ProhibitSubroutinePrototypes]
251             [-Subroutines::ProhibitExplicitReturnUndef]
252              
253              
254              
255             #END
256             };
257              
258              
259              
260              
261              
262             =head2 dirRoot
263              
264             The root directory of the loaded config, or undef if no config is
265             loaded yet.
266              
267             Default: undef
268              
269             =cut
270             field "dirRoot" => undef;
271              
272              
273              
274              
275              
276             =head2 rhConfig
277              
278             The hash ref with the currently loaded config.
279              
280             Default: { }
281              
282             =cut
283             field "rhConfig" => { };
284              
285              
286              
287              
288              
289             =head2 new()
290              
291             Create new object.
292              
293             =cut
294             sub new(@) {
295 116     116 1 218 my $pkg = shift;
296              
297 116         751 my $self = $pkg->SUPER::new(@_);
298              
299 116 100       7195 $self->dirRoot and $self->loadConfig(dirRoot => $self->dirRoot);
300              
301 116         1731 return($self);
302             }
303              
304              
305              
306              
307              
308             =head1 METHODS
309              
310             =head2 loadConfig(dirRoot => DIR)
311              
312             Load the file for $dirRoot and set dirDoor and rhConfig.
313              
314             Return 1 if the file could be loaded, else die, e.g. if the file
315             contains syntax errors.
316              
317             =cut
318 57     57 1 2023 sub loadConfig {
319 57         247 my ($dirRoot) = Devel::PerlySense::Util::aNamedArg(["dirRoot"], @_);
320              
321 57         1556 my $fileConfig = file($dirRoot, $self->nameFileConfig);
322 57 100       5252 my $sourceConfig = slurp($fileConfig) or
323             die("Could not open config file ($fileConfig)\n");
324 56         157 my ($rhConfig) = eval { YAML::Tiny::Load($sourceConfig) };
  56         271  
325 56 100       130518 $rhConfig or die("Could not read .PerlySense Project config file ($fileConfig): " . $YAML::Tiny::errstr . "\n");
326              
327 55         1715 $self->dirRoot($dirRoot);
328 55         1722 $self->rhConfig($rhConfig);
329              
330 55         811 return 1;
331             }
332              
333              
334              
335              
336              
337             =head2 createFileConfigDefault(dirRoot => DIR)
338              
339             Create a config file under $dirRoot with the default config and load
340             it. Create directories as needed.
341              
342             If there is an existing config file, rename it first to end with the
343             current time.
344              
345             Return 1, or die on errors.
346              
347             =cut
348              
349 5     5   767 sub _createFileDefault {
350 5         16 my ($fileConfig, $text) = Devel::PerlySense::Util::aNamedArg(["file", "text"], @_);
351              
352 5         55 my $dirConfig = dirname($fileConfig);
353 5         743 mkpath($dirConfig);
354 5 50       29 -d $dirConfig or die("Could not create config directory ($dirConfig)\n");
355              
356 5 100       18 if(-e $fileConfig) {
357 3         142 my $textTime = time2iso( time() );
358 3         69 $textTime =~ s/\W+/_/g;
359 3         9 my $fileConfigBackup = $fileConfig . "." . $textTime;
360              
361 3 50       107 rename($fileConfig, $fileConfigBackup)
362             or die("Could not rename ($fileConfig) -> ($fileConfigBackup)\n");
363             }
364              
365 5 50       670 spew($fileConfig, $text) or
366             die("Could not create config file ($fileConfig)\n");
367              
368 5         9 return 1;
369             }
370              
371 3     3 1 8 sub createFileConfigDefault {
372 3         20 my ($dirRoot) = Devel::PerlySense::Util::aNamedArg(["dirRoot"], @_);
373              
374 3         117 $self->_createFileDefault(
375             file => file($dirRoot, $self->nameFileConfig),
376             text => $self->textConfigDefault,
377             );
378              
379 3         18 $self->loadConfig(dirRoot => $dirRoot);
380              
381 3         18 return 1;
382             }
383              
384              
385              
386              
387              
388             =head2 createFileCriticDefault(dirRoot => DIR)
389              
390             Create a Perl::Critic config file under $dirRoot with the default
391             config. Create directories as needed.
392              
393             If there is an existing config file, rename it first to end with the
394             current time.
395              
396             Return 1, or die on errors.
397              
398             =cut
399 2     2 1 4 sub createFileCriticDefault {
400 2         10 my ($dirRoot) = Devel::PerlySense::Util::aNamedArg(["dirRoot"], @_);
401              
402 2         59 $self->_createFileDefault(
403             file => file($dirRoot, $self->nameFileCritic),
404             text => $self->textCriticDefault,
405             );
406              
407 2         16 return 1;
408             }
409              
410              
411              
412              
413              
414             1;
415              
416              
417              
418              
419              
420             __END__
421              
422             =encoding utf8
423              
424             =head1 AUTHOR
425              
426             Johan Lindström, C<< <johanl[ÄT]DarSerMan.com> >>
427              
428             =head1 BUGS
429              
430             Please report any bugs or feature requests to
431             C<bug-devel-perlysense@rt.cpan.org>, or through the web interface at
432             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel-PerlySense>.
433             I will be notified, and then you'll automatically be notified of progress on
434             your bug as I make changes.
435              
436             =head1 ACKNOWLEDGEMENTS
437              
438             =head1 COPYRIGHT & LICENSE
439              
440             Copyright 2005 Johan Lindström, All Rights Reserved.
441              
442             This program is free software; you can redistribute it and/or modify it
443             under the same terms as Perl itself.
444              
445             =cut