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

Last change on this file since 495 was 495, checked in by Bruno Cornec, 16 years ago
  • all global variables are prefixed with pb
  • First attempt at using locale and gettext
  • use of pb_display and pb_display_init added
  • Update presentation following RMLL 2008
File size: 10.4 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;
22use locale;
23use Locale::gettext;
24use POSIX qw(setlocale);
25
26# Inherit from the "Exporter" module which handles exporting functions.
27
28use Exporter;
29
30# Export, by default, all the functions into the namespace of
31# any code which uses this module.
32
33our $pbdebug = 0; # Global debug level
34our $pbLOG = \*STDOUT; # File descriptor of the log file
35our $pbsynmsg = "Error"; # Global error message
36our $pbdisplaytype = "text";
37 # default display mode for messages
38our $pblocale = "C";
39
40our @ISA = qw(Exporter);
41our @EXPORT = qw(pb_mkdir_p pb_system pb_rm_rf pb_get_date pb_log pb_log_init pb_display pb_display_init pb_get_uri pb_get_content pb_display_file pb_syntax_init pb_syntax pb_temp_init $pbdebug $pbLOG $pbdisplaytype $pblocale);
42
43=pod
44
45=head1 NAME
46
47ProjectBuilder::Base, part of the project-builder.org - module dealing with generic functions suitable for perl project development
48
49=head1 DESCRIPTION
50
51This modules provides generic functions suitable for perl project development
52
53=head1 SYNOPSIS
54
55 use ProjectBuilder::Base;
56
57 #
58 # Create a directory and its parents
59 #
60 pb_mkdir_p("/tmp/foo/bar");
61
62 #
63 # Remove recursively a directory and its children
64 #
65 pb_rm_rf("/tmp/foo");
66
67 #
68 # Encapsulate the system call for better output and return value test
69 #
70 pb_system("ls -l", "Printing directory content");
71
72 #
73 # Analysis a URI and return its components in a table
74 #
75 my ($scheme, $account, $host, $port, $path) = pb_get_uri("svn+ssh://ac@my.server.org/path/to/dir");
76
77 #
78 # Gives the current date in a table
79 #
80 @date = pb_get_date();
81
82 #
83 # Manages logs of the program
84 #
85 pb_log_init(2,\*STDOUT);
86 pb_log(1,"Message to print\n");
87
88 #
89 # Manages prints of the program
90 #
91 pb_display_init("text","fr_FR:UTF-8");
92 pb_display("Message to print\n");
93
94 #
95 # Manages content of a file
96 #
97 pb_display_file("/etc/passwd");
98 my $cnt = pb_get_content("/etc/passwd");
99
100=head1 USAGE
101
102=over 4
103
104=item B<pb_mkdir_p>
105
106Internal mkdir -p function. Forces mode to 755. Supports multiple parameters.
107
108Based on File::Path mkpath.
109
110=cut
111
112sub pb_mkdir_p {
113my @dir = @_;
114my $ret = mkpath(@dir, 0, 0755);
115return($ret);
116}
117
118=item B<pb_rm_rf>
119
120Internal rm -rf function. Supports multiple parameters.
121
122Based on File::Path rmtree.
123
124=cut
125
126sub pb_rm_rf {
127my @dir = @_;
128my $ret = rmtree(@dir, 0, 0);
129return($ret);
130}
131
132=item B<pb_system>
133
134Encapsulate the "system" call for better output and return value test
135Needs a $ENV{'PBTMP'} variable which is created by calling the pb_mktemp_init function
136Needs pb_log support, so pb_log_init should have benn called before.
137
138The first parameter is the shell command to call.
139The second parameter is the message to print on screen. If none is given, then the command is printed.
140The 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).
141This function returns the result the return value of the system command.
142
143If no error reported, it prints OK on the screen, just after the message. Else it prints the errors generated.
144
145=cut
146
147sub pb_system {
148
149my $cmd=shift;
150my $cmt=shift || $cmd;
151my $verbose=shift || undef;
152my $redir = "";
153
154pb_log(0,"$cmt... ");
155pb_log(1,"Executing $cmd\n");
156unlink("$ENV{'PBTMP'}/system.log") if (-f "$ENV{'PBTMP'}/system.log");
157$redir = "2>> $ENV{'PBTMP'}/system.log 1>> $ENV{'PBTMP'}/system.log" if ((! defined $verbose) || ($verbose ne "noredir"));
158system("$cmd $redir");
159my $res = $?;
160if ($res == -1) {
161 pb_log(0,"failed to execute ($cmd): $!\n");
162 pb_display_file("$ENV{'PBTMP'}/system.log") if (-f "$ENV{'PBTMP'}/system.log");
163} elsif ($res & 127) {
164 pb_log(0, "child ($cmd) died with signal ".($? & 127).", ".($? & 128) ? 'with' : 'without'." coredump\n");
165 pb_display_file("$ENV{'PBTMP'}/system.log") if (-f "$ENV{'PBTMP'}/system.log");
166} elsif ($res == 0) {
167 pb_log(0,"OK\n");
168 pb_display_file("$ENV{'PBTMP'}/system.log") if ((defined $verbose) && (-f "$ENV{'PBTMP'}/system.log"));
169} else {
170 pb_log(0, "child ($cmd) exited with value ".($? >> 8)."\n");
171 pb_display_file("$ENV{'PBTMP'}/system.log") if (-f "$ENV{'PBTMP'}/system.log");
172}
173return($res);
174}
175
176=item B<pb_get_uri>
177
178This function returns a list of 6 parameters indicating the protocol, account, password, server, port, and path contained in the URI passed in parameter.
179
180A URI has the format protocol://[ac@]host[:port][path[?query][#fragment]].
181
182Cf man URI.
183
184=cut
185
186sub pb_get_uri {
187
188my $uri = shift || undef;
189
190pb_log(2,"DEBUG: uri:$uri\n");
191my ($scheme, $authority, $path, $query, $fragment) =
192 $uri =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?| if (defined $uri);
193my ($account,$host,$port) = $authority =~ m|(?:([^\@]+)\@)?([^:]+)(:(?:[0-9]+))?| if (defined $authority);
194
195$scheme = "" if (not defined $scheme);
196$authority = "" if (not defined $authority);
197$path = "" if (not defined $path);
198$account = "" if (not defined $account);
199$host = "" if (not defined $host);
200$port = "" if (not defined $port);
201
202pb_log(2,"DEBUG: scheme:$scheme ac:$account host:$host port:$port path:$path\n");
203return($scheme, $account, $host, $port, $path);
204}
205
206=item B<pb_get_date>
207
208This 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.
209
210Cf: man ctime and description of the struct tm.
211
212=cut
213
214sub pb_get_date {
215
216return(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
217}
218
219=item B<pb_log_init>
220
221This function initializes the global variables used by the pb_log function.
222
223The first parameter is the debug level which will be considered during the run of the program?
224The second parameter is a pointer on a file descriptor used to print the log info.
225
226As 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.
227
228The call to B<pb_log_init> is typically done after getting a parameter on the CLI indicating the level of verbosity expected.
229
230=cut
231
232sub pb_log_init {
233
234$pbdebug = shift || 0;
235$pbLOG = shift || \*STDOUT;
236pb_log(1,"Debug value: $pbdebug\n");
237
238}
239
240=item B<pb_log>
241
242This 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.
243
244Here is a usage example:
245
246 pb_log_init(2,\*STDERR);
247 pb_log(1,"Hello World 1\n");
248 pb_log(2,"Hello World 2\n");
249 pb_log(3,"Hello World 3\n");
250
251 will print:
252
253 Hello World 1
254 Hello World 2
255
256=cut
257
258sub pb_log {
259
260my $dlevel = shift;
261my $msg = shift;
262
263print $pbLOG "$msg" if ($dlevel <= $pbdebug);
264}
265
266
267=item B<pb_display_init>
268
269This function initializes the environment used by the pb_display function.
270
271The first parameter is the type of display which will be used. Could be "text", "web", "newt",...
272The second parameter is the loacle to be used.
273
274The call to B<pb_display_init> is typically done after getting a parameter on the CLI indicating the locale used or the type of interface to report messages to.
275
276=cut
277
278sub pb_display_init {
279
280$pbdisplaytype = shift || "text";
281$pblocale = shift || "C";
282
283setlocale(LC_ALL, $pblocale);
284pb_log(1,"Using $pbdisplaytype interface with $pblocale locale\n");
285
286if ($pbdisplaytype =~ /text/) {
287} elsif ($pbdisplaytype = /newt/) {
288} else {
289 die "display system $pbdisplaytype unsupported";
290}
291}
292
293=item B<pb_display>
294
295This function prints the messages passed as parameter using the configuration set up with the B<pb_display_init> function.
296
297Here is a usage example:
298
299 pb_display_init("text","fr_FR.UTF-8");
300 pb_display("Hello World\n");
301
302 will print:
303
304 Bonjour Monde
305
306=cut
307
308sub pb_display {
309
310my $msg = shift;
311
312if ($pbdisplaytype =~ /text/) {
313 print STDOUT gettext($msg);
314 }
315}
316
317=item B<pb_display_file>
318
319This function print the content of the file passed in parameter.
320
321This is a cat equivalent function.
322
323=cut
324
325sub pb_display_file {
326
327my $file=shift;
328
329return if (not -f $file);
330printf "%s\n",pb_get_content($file);
331}
332
333=item B<pb_get_content>
334
335This function returns the content of the file passed in parameter.
336
337=cut
338
339sub pb_get_content {
340
341my $file=shift;
342
343my $bkp = $/;
344undef $/;
345open(R,$file) || die "Unable to open $file: $!";
346my $content=<R>;
347close(R);
348chomp($content);
349$/ = $bkp;
350return($content);
351}
352
353=item B<pb_syntax_init>
354
355This function initializes the global variable used by the pb_syntax function.
356
357The parameter is the message string which will be printed when calling pb_syntax
358
359=cut
360
361sub pb_syntax_init {
362
363$pbsynmsg = shift || "Error";
364}
365
366=item B<pb_syntax>
367
368This function prints the syntax expected by the application, based on pod2usage, and exits.
369The first parameter is the return value of the exit.
370The second parameter is the verbosity as expected by pod2usage.
371
372Cf: man Pod::Usage
373
374=cut
375
376sub pb_syntax {
377
378my $exit_status = shift || -1;
379my $verbose_level = shift || 0;
380
381my $filehandle = \*STDERR;
382
383$filehandle = \*STDOUT if ($exit_status == 0);
384
385pod2usage( { -message => $pbsynmsg,
386 -exitval => $exit_status ,
387 -verbose => $verbose_level,
388 -output => $filehandle } );
389}
390
391=item B<pb_temp_init>
392
393This 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.
394
395=cut
396
397sub pb_temp_init {
398
399if (not defined $ENV{'TMPDIR'}) {
400 $ENV{'TMPDIR'}="/tmp";
401}
402$ENV{'PBTMP'} = tempdir( "pb.XXXXXXXXXX", DIR => $ENV{'TMPDIR'}, CLEANUP => 1 );
403}
404
405=back
406
407=head1 WEB SITES
408
409The 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/>.
410
411=head1 USER MAILING LIST
412
413None exists for the moment.
414
415=head1 AUTHORS
416
417The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
418
419=head1 COPYRIGHT
420
421Project-Builder.org is distributed under the GPL v2.0 license
422described in the file C<COPYING> included with the distribution.
423
424=cut
425
4261;
Note: See TracBrowser for help on using the repository browser.