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

Last change on this file since 500 was 500, checked in by Bruno Cornec, 16 years ago
  • Working patch support added to pb (tested with buffer)
  • Filtering functions now handle also pointer on hashes (such as the new pb hash)
  • Filtering functions support new macro for patch support (PBPATCHSRC and PBPATCHCMD)
  • Env.pm now generates correct templates for patch support and uses the new pb hash
  • pb_cms_export extended to support file:// URI, and also supports an undef second param (no local export available)
  • In pb, hashes now include also the arch (for better patch support)
  • pb supports local CMS based patches, as well as external references (not tested yet)
  • New pb_get_arch function provided
  • New parameters for pb_system (mayfail and quiet)
File size: 10.8 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... ") if ($verbose ne "quiet");
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 = $?;
160# Exit now if the command may fail
161if ((defined $verbose) and ($verbose eq "mayfail")) {
162 pb_log(0,"N/A\n") if ($res != 0);
163 pb_log(0,"OK\n") if ($res == 0);
164 return($res)
165 }
166if ($res == -1) {
167 pb_log(0,"failed to execute ($cmd): $!\n") if ($verbose ne "quiet");
168 pb_display_file("$ENV{'PBTMP'}/system.log") if ((-f "$ENV{'PBTMP'}/system.log") and ($verbose ne "quiet"));
169} elsif ($res & 127) {
170 pb_log(0, "child ($cmd) died with signal ".($? & 127).", ".($? & 128) ? 'with' : 'without'." coredump\n") if ($verbose ne "quiet");
171 pb_display_file("$ENV{'PBTMP'}/system.log") if ((-f "$ENV{'PBTMP'}/system.log") and ($verbose ne "quiet"));
172} elsif ($res == 0) {
173 pb_log(0,"OK\n") if ($verbose ne "quiet");
174 pb_display_file("$ENV{'PBTMP'}/system.log") if ((defined $verbose) and (-f "$ENV{'PBTMP'}/system.log") and ($verbose ne "quiet"));
175} else {
176 pb_log(0, "child ($cmd) exited with value ".($? >> 8)."\n") if ($verbose ne "quiet");
177 pb_display_file("$ENV{'PBTMP'}/system.log") if ((-f "$ENV{'PBTMP'}/system.log") and ($verbose ne "quiet"));
178}
179return($res);
180}
181
182=item B<pb_get_uri>
183
184This function returns a list of 6 parameters indicating the protocol, account, password, server, port, and path contained in the URI passed in parameter.
185
186A URI has the format protocol://[ac@]host[:port][path[?query][#fragment]].
187
188Cf man URI.
189
190=cut
191
192sub pb_get_uri {
193
194my $uri = shift || undef;
195
196pb_log(2,"DEBUG: uri:$uri\n");
197my ($scheme, $authority, $path, $query, $fragment) =
198 $uri =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?| if (defined $uri);
199my ($account,$host,$port) = $authority =~ m|(?:([^\@]+)\@)?([^:]+)(:(?:[0-9]+))?| if (defined $authority);
200
201$scheme = "" if (not defined $scheme);
202$authority = "" if (not defined $authority);
203$path = "" if (not defined $path);
204$account = "" if (not defined $account);
205$host = "" if (not defined $host);
206$port = "" if (not defined $port);
207
208pb_log(2,"DEBUG: scheme:$scheme ac:$account host:$host port:$port path:$path\n");
209return($scheme, $account, $host, $port, $path);
210}
211
212=item B<pb_get_date>
213
214This 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.
215
216Cf: man ctime and description of the struct tm.
217
218=cut
219
220sub pb_get_date {
221
222return(localtime->sec(), localtime->min(), localtime->hour(), localtime->mday(), localtime->mon(), localtime->year(), localtime->wday(), localtime->yday(), localtime->isdst());
223}
224
225=item B<pb_log_init>
226
227This function initializes the global variables used by the pb_log function.
228
229The first parameter is the debug level which will be considered during the run of the program?
230The second parameter is a pointer on a file descriptor used to print the log info.
231
232As 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.
233
234The call to B<pb_log_init> is typically done after getting a parameter on the CLI indicating the level of verbosity expected.
235
236=cut
237
238sub pb_log_init {
239
240$pbdebug = shift || 0;
241$pbLOG = shift || \*STDOUT;
242pb_log(1,"Debug value: $pbdebug\n");
243
244}
245
246=item B<pb_log>
247
248This 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.
249
250Here is a usage example:
251
252 pb_log_init(2,\*STDERR);
253 pb_log(1,"Hello World 1\n");
254 pb_log(2,"Hello World 2\n");
255 pb_log(3,"Hello World 3\n");
256
257 will print:
258
259 Hello World 1
260 Hello World 2
261
262=cut
263
264sub pb_log {
265
266my $dlevel = shift;
267my $msg = shift;
268
269print $pbLOG "$msg" if ($dlevel <= $pbdebug);
270}
271
272
273=item B<pb_display_init>
274
275This function initializes the environment used by the pb_display function.
276
277The first parameter is the type of display which will be used. Could be "text", "web", "newt",...
278The second parameter is the loacle to be used.
279
280The 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.
281
282=cut
283
284sub pb_display_init {
285
286$pbdisplaytype = shift || "text";
287$pblocale = shift || "C";
288
289setlocale(LC_ALL, $pblocale);
290pb_log(1,"Using $pbdisplaytype interface with $pblocale locale\n");
291
292if ($pbdisplaytype =~ /text/) {
293} elsif ($pbdisplaytype = /newt/) {
294} else {
295 die "display system $pbdisplaytype unsupported";
296}
297}
298
299=item B<pb_display>
300
301This function prints the messages passed as parameter using the configuration set up with the B<pb_display_init> function.
302
303Here is a usage example:
304
305 pb_display_init("text","fr_FR.UTF-8");
306 pb_display("Hello World\n");
307
308 will print:
309
310 Bonjour Monde
311
312=cut
313
314sub pb_display {
315
316my $msg = shift;
317
318if ($pbdisplaytype =~ /text/) {
319 print STDOUT gettext($msg);
320 }
321}
322
323=item B<pb_display_file>
324
325This function print the content of the file passed in parameter.
326
327This is a cat equivalent function.
328
329=cut
330
331sub pb_display_file {
332
333my $file=shift;
334
335return if (not -f $file);
336printf "%s\n",pb_get_content($file);
337}
338
339=item B<pb_get_content>
340
341This function returns the content of the file passed in parameter.
342
343=cut
344
345sub pb_get_content {
346
347my $file=shift;
348
349my $bkp = $/;
350undef $/;
351open(R,$file) || die "Unable to open $file: $!";
352my $content=<R>;
353close(R);
354chomp($content);
355$/ = $bkp;
356return($content);
357}
358
359=item B<pb_syntax_init>
360
361This function initializes the global variable used by the pb_syntax function.
362
363The parameter is the message string which will be printed when calling pb_syntax
364
365=cut
366
367sub pb_syntax_init {
368
369$pbsynmsg = shift || "Error";
370}
371
372=item B<pb_syntax>
373
374This function prints the syntax expected by the application, based on pod2usage, and exits.
375The first parameter is the return value of the exit.
376The second parameter is the verbosity as expected by pod2usage.
377
378Cf: man Pod::Usage
379
380=cut
381
382sub pb_syntax {
383
384my $exit_status = shift || -1;
385my $verbose_level = shift || 0;
386
387my $filehandle = \*STDERR;
388
389$filehandle = \*STDOUT if ($exit_status == 0);
390
391pod2usage( { -message => $pbsynmsg,
392 -exitval => $exit_status ,
393 -verbose => $verbose_level,
394 -output => $filehandle } );
395}
396
397=item B<pb_temp_init>
398
399This 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.
400
401=cut
402
403sub pb_temp_init {
404
405if (not defined $ENV{'TMPDIR'}) {
406 $ENV{'TMPDIR'}="/tmp";
407}
408$ENV{'PBTMP'} = tempdir( "pb.XXXXXXXXXX", DIR => $ENV{'TMPDIR'}, CLEANUP => 1 );
409}
410
411=back
412
413=head1 WEB SITES
414
415The 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/>.
416
417=head1 USER MAILING LIST
418
419None exists for the moment.
420
421=head1 AUTHORS
422
423The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
424
425=head1 COPYRIGHT
426
427Project-Builder.org is distributed under the GPL v2.0 license
428described in the file C<COPYING> included with the distribution.
429
430=cut
431
4321;
Note: See TracBrowser for help on using the repository browser.