source: ProjectBuilder/devel/pb-modules/lib/ProjectBuilder/Base.pm@ 482

Last change on this file since 482 was 482, checked in by Bruno Cornec, 16 years ago

Improves again pb_system for feedback of printed msgs

File size: 8.9 KB
Line 
1#!/usr/bin/perl -w
2#
3# Base subroutines brought by the the Project-Builder project
4# which can be easily used by whatever perl project
5#
6# Copyright B. Cornec 2007-2008
7# Provided under the GPL v2
8#
9# $Id$
10#
11
12package ProjectBuilder::Base;
13
14use strict;
15use lib qw (lib);
16use File::Path;
17use File::Temp qw(tempdir);
18use Data::Dumper;
19use Time::localtime qw(localtime);
20use Pod::Usage;
21use English;
22
23# Inherit from the "Exporter" module which handles exporting functions.
24
25use Exporter;
26
27# Export, by default, all the functions into the namespace of
28# any code which uses this module.
29
30our $debug = 0; # Global debug level
31our $LOG = \*STDOUT; # File descriptor of the log file
32our $synmsg = "Error"; # Global error message
33
34our @ISA = qw(Exporter);
35our @EXPORT = qw(pb_mkdir_p pb_system pb_rm_rf pb_get_date pb_log pb_log_init pb_get_uri pb_get_content pb_display_file pb_syntax_init pb_syntax pb_temp_init $debug $LOG);
36
37=pod
38
39=head1 NAME
40
41ProjectBuilder::Base, part of the project-builder.org - module dealing with generic functions suitable for perl project development
42
43=head1 DESCRIPTION
44
45This modules provides generic functions suitable for perl project development
46
47=head1 SYNOPSIS
48
49 use ProjectBuilder::Base;
50
51 #
52 # Create a directory and its parents
53 #
54 pb_mkdir_p("/tmp/foo/bar");
55
56 #
57 # Remove recursively a directory and its children
58 #
59 pb_rm_rf("/tmp/foo");
60
61 #
62 # Encapsulate the system call for better output and return value test
63 #
64 pb_system("ls -l", "Printing directory content");
65
66 #
67 # Analysis a URI and return its components in a table
68 #
69 my ($scheme, $account, $host, $port, $path) = pb_get_uri("svn+ssh://ac@my.server.org/path/to/dir");
70
71 #
72 # Gives the current date in a table
73 #
74 @date = pb_get_date();
75
76 #
77 # Manages logs of the program
78 #
79 pb_log_init(2,\*STDOUT);
80 pb_log(1,"Message to print\n");
81
82 #
83 # Manages content of a file
84 #
85 pb_display_file("/etc/passwd");
86 my $cnt = pb_get_content("/etc/passwd");
87
88=head1 USAGE
89
90=over 4
91
92=item B<pb_mkdir_p>
93
94Internal mkdir -p function. Forces mode to 755. Supports multiple parameters.
95
96Based on File::Path mkpath.
97
98=cut
99
100sub pb_mkdir_p {
101my @dir = @_;
102my $ret = mkpath(@dir, 0, 0755);
103return($ret);
104}
105
106=item B<pb_rm_rf>
107
108Internal rm -rf function. Supports multiple parameters.
109
110Based on File::Path rmtree.
111
112=cut
113
114sub pb_rm_rf {
115my @dir = @_;
116my $ret = rmtree(@dir, 0, 0);
117return($ret);
118}
119
120=item B<pb_system>
121
122Encapsulate the "system" call for better output and return value test
123Needs a $ENV{'PBTMP'} variable which is created by calling the pb_mktemp_init function
124Needs pb_log support, so pb_log_init should have benn called before.
125
126The first parameter is the shell command to call.
127The second parameter is the message to print on screen. If none is given, then the command is printed.
128The third parameter print the result of the command after correct execution if value is verbose. If value is noredir, it avoids redirecting outputs (e.g. for vi).
129This function returns the result the return value of the system command.
130
131If no error reported, it prints OK on the screen, just after the message. Else it prints the errors generated.
132
133=cut
134
135sub pb_system {
136
137my $cmd=shift;
138my $cmt=shift || $cmd;
139my $verbose=shift || undef;
140my $redir = "";
141
142pb_log(0,"$cmt... ");
143pb_log(1,"Executing $cmd\n");
144unlink("$ENV{'PBTMP'}/system.log") if (-f "$ENV{'PBTMP'}/system.log");
145$redir = "2>> $ENV{'PBTMP'}/system.log 1>> $ENV{'PBTMP'}/system.log" if ((! defined $verbose) || ($verbose ne "noredir"));
146system("$cmd $redir");
147my $res = $?;
148if ($res == -1) {
149 pb_log(0,"failed to execute ($cmd): $!\n");
150 pb_display_file("$ENV{'PBTMP'}/system.log") if (-f "$ENV{'PBTMP'}/system.log");
151} elsif ($res & 127) {
152 pb_log(0, "child ($cmd) died with signal ".($? & 127).", ".($? & 128) ? 'with' : 'without'." coredump\n");
153 pb_display_file("$ENV{'PBTMP'}/system.log") if (-f "$ENV{'PBTMP'}/system.log");
154} elsif ($res == 0) {
155 pb_log(0,"OK\n");
156 pb_display_file("$ENV{'PBTMP'}/system.log") if ((defined $verbose) && (-f "$ENV{'PBTMP'}/system.log"));
157} else {
158 pb_log(0, "child ($cmd) exited with value ".($? >> 8)."\n");
159 pb_display_file("$ENV{'PBTMP'}/system.log") if (-f "$ENV{'PBTMP'}/system.log");
160}
161return($res);
162}
163
164=item B<pb_get_uri>
165
166This function returns a list of 6 parameters indicating the protocol, account, password, server, port, and path contained in the URI passed in parameter.
167
168A URI has the format protocol://[ac@]host[:port][path[?query][#fragment]].
169
170Cf man URI.
171
172=cut
173
174sub pb_get_uri {
175
176my $uri = shift || undef;
177
178pb_log(2,"DEBUG: uri:$uri\n");
179my ($scheme, $authority, $path, $query, $fragment) =
180 $uri =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?| if (defined $uri);
181my ($account,$host,$port) = $authority =~ m|(?:([^\@]+)\@)?([^:]+)(:(?:[0-9]+))?| if (defined $authority);
182
183$scheme = "" if (not defined $scheme);
184$authority = "" if (not defined $authority);
185$path = "" if (not defined $path);
186$account = "" if (not defined $account);
187$host = "" if (not defined $host);
188$port = "" if (not defined $port);
189
190pb_log(2,"DEBUG: scheme:$scheme ac:$account host:$host port:$port path:$path\n");
191return($scheme, $account, $host, $port, $path);
192}
193
194=item B<pb_get_date>
195
196This function returns a list of 9 parameters indicating the seconds, minutes, hours, day, month, year, day in the week, day in the year, and daylight saving time flag of the current time.
197
198Cf: man ctime and description of the struct tm.
199
200=cut
201
202sub pb_get_date {
203
204return(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
205}
206
207=item B<pb_log_init>
208
209This function initializes the global variables used by the pb_log function.
210
211The first parameter is the debug level which will be considered during the run of the program?
212The second parameter is a pointer on a file descriptor used to print the log info.
213
214As an example, if you set the debug level to 2 in that function, every call to pb_log which contains a value less or equal than 2 will be printed. Calls with a value greater than 2 won't be printed.
215
216The call to B<pb_log_init> is typically done after getting a parameter on the CLI indicating the level of verbosity expected.
217
218=cut
219
220sub pb_log_init {
221
222$debug = shift || 0;
223$LOG = shift || \*STDOUT;
224pb_log(1,"Debug value: $debug\n");
225
226}
227
228=item B<pb_log>
229
230This function logs the messages passed as the second parameter if the value passed as first parameter is lesser or equal than the value passed to the B<pb_log_init> function.
231
232Here is a usage example:
233
234 pb_log_init(2,\*STDERR);
235 pb_log(1,"Hello World 1\n");
236 pb_log(2,"Hello World 2\n");
237 pb_log(3,"Hello World 3\n");
238
239 will print:
240
241 Hello World 1
242 Hello World 2
243
244=cut
245
246sub pb_log {
247
248my $dlevel = shift;
249my $msg = shift;
250
251print $LOG "$msg" if ($dlevel <= $debug);
252}
253
254=item B<pb_display_file>
255
256This function print the content of the file passed in parameter.
257
258This is a cat equivalent function.
259
260=cut
261
262sub pb_display_file {
263
264my $file=shift;
265
266return if (not -f $file);
267printf "%s\n",pb_get_content($file);
268}
269
270=item B<pb_get_content>
271
272This function returns the content of the file passed in parameter.
273
274=cut
275
276sub pb_get_content {
277
278my $file=shift;
279
280my $bkp = $/;
281undef $/;
282open(R,$file) || die "Unable to open $file: $!";
283my $content=<R>;
284close(R);
285chomp($content);
286$/ = $bkp;
287return($content);
288}
289
290=item B<pb_syntax_init>
291
292This function initializes the global variable used by the pb_syntax function.
293
294The parameter is the message string which will be printed when calling pb_syntax
295
296=cut
297
298sub pb_syntax_init {
299
300$synmsg = shift || "Error";
301}
302
303=item B<pb_syntax>
304
305This function prints the syntax expected by the application, based on pod2usage, and exits.
306The first parameter is the return value of the exit.
307The second parameter is the verbosity as expected by pod2usage.
308
309Cf: man Pod::Usage
310
311=cut
312
313sub pb_syntax {
314
315my $exit_status = shift || -1;
316my $verbose_level = shift || 0;
317
318my $filehandle = \*STDERR;
319
320$filehandle = \*STDOUT if ($exit_status == 0);
321
322pod2usage( { -message => $synmsg,
323 -exitval => $exit_status ,
324 -verbose => $verbose_level,
325 -output => $filehandle } );
326}
327
328=item B<pb_temp_init>
329
330This function initializes the environemnt variable PBTMP to a random value. This directory can be safely used during the whole program, it will be removed at the end automatically.
331
332=cut
333
334sub pb_temp_init {
335
336if (not defined $ENV{'TMPDIR'}) {
337 $ENV{'TMPDIR'}="/tmp";
338}
339$ENV{'PBTMP'} = tempdir( "pb.XXXXXXXXXX", DIR => $ENV{'TMPDIR'}, CLEANUP => 1 );
340}
341
342=back
343
344=head1 WEB SITES
345
346The main Web site of the project is available at L<http://www.project-builder.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.project-builder.org/>.
347
348=head1 USER MAILING LIST
349
350None exists for the moment.
351
352=head1 AUTHORS
353
354The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
355
356=head1 COPYRIGHT
357
358Project-Builder.org is distributed under the GPL v2.0 license
359described in the file C<COPYING> included with the distribution.
360
361=cut
362
3631;
Note: See TracBrowser for help on using the repository browser.