File Coverage

blib/lib/Slackware/Slackget.pm
Criterion Covered Total %
statement 6 119 5.0
branch 0 34 0.0
condition 0 18 0.0
subroutine 2 10 20.0
pod 8 8 100.0
total 16 189 8.4


line stmt bran cond sub pod time code
1             package Slackware::Slackget;
2              
3 2     2   62484 use warnings;
  2         4  
  2         64  
4 2     2   8 use strict;
  2         1  
  2         2682  
5              
6             require Slackware::Slackget::Base ;
7             require Slackware::Slackget::Network::Auth ;
8             require Slackware::Slackget::Config ;
9             require Slackware::Slackget::PkgTools ;
10              
11             =head1 NAME
12              
13             Slackware::Slackget - The main slack-get 1.0 library
14              
15             =head1 VERSION
16              
17             Version 0.15_99
18              
19             =cut
20              
21             our $VERSION = '0.15_99';
22              
23             =head1 SYNOPSIS
24              
25             slack-get (http://slackget.infinityperl.org and now http://www.infinityperl.org/category/slack-get) is an apt-get like tool for Slackware Linux. This bundle is the core library of this program.
26              
27             The name Slackware::Slackget means slack-get 1.0 because this module is complely new and is for the 1.0 release. It is entierely object oriented, and require some other modules (like XML::Simple, Net::Ftp and LWP::Simple).
28              
29             This module is still pre-in alpha development phase and I release it on CPAN only for coder which want to see the new architecture. For more informations, have a look on subclasses.
30              
31             use Slackware::Slackget;
32              
33             my $sgo = Slackware::Slackget->new(
34             -config => '/etc/slack-get/config.xml',
35             -name => 'slack-getd',
36             -version => '1.0.1228'
37             );
38              
39             =cut
40              
41             =head1 CONSTRUCTOR
42              
43             The constructor (new()), is used to instanciate all needed class for a slack-get instance.
44              
45             =head2 new
46              
47             You have to pass the followings arguments to the constructor :
48              
49             -config => the name of the configuration file.
50             -name => ignored : for backward compatibility
51             -version => ignored : for backward compatibility
52              
53             -name and -version arguments are passed to the constructor of the Slackware::Slackget::Log object.
54              
55             =cut
56              
57             sub new {
58 0     0 1   my $class = 'Slackware::Slackget' ;
59 0           my $self = {} ;
60 0 0         if(scalar(@_)%2 != 0)
61             {
62 0           $class = shift(@_) ;
63             }
64 0           my %args = @_ ;
65 0 0 0       die "FATAL: You must pass a configuration file as -config parameter.\n" if(!defined($args{'-config'}) || ! -e $args{'-config'}) ;
66 0 0         $self->{'config'} = new Slackware::Slackget::Config ( $args{'-config'} ) or die "FATAL: error during configuration file parsing\n$!\n" ;
67 0           $self->{'base'} = new Slackware::Slackget::Base ( $self->{'config'} );
68 0           $self->{'pkgtools'} = new Slackware::Slackget::PkgTools ( $self->{'config'} );
69 0           $self->{'auth'} = Slackware::Slackget::Network::Auth->new( $self->{'config'} );
70 0           bless($self,$class) ;
71 0           return $self;
72             }
73              
74             =head1 FUNCTIONS
75              
76             =head2 load_plugins
77              
78             Search for all plugins in the followings directories : <all @INC directories>/lib/Slackware/Slackget/Plugin/, <INSTALLDIR>/lib/Slackware/Slackget/Plugin/, <HOME DIRECTORY>/lib/Slackware/Slackget/Plugin/.
79              
80             When you call this method, she scan in thoses directory and try to load all files ending by .pm. The loading is in 4 times :
81              
82             1) scan for plug-in
83              
84             2) try to "require" all the finded modules.
85              
86             3) Try to instanciate all modules successfully "require"-ed. To do that, this method call the new() method of the plug-in and passed the current Slackware::Slackget object reference. The internal code is like that :
87              
88             # Slackware::Slackget::Plugin::MyPlugin is the name of the plug-in
89             # $self is the reference to the current Slackware::Slackget object.
90            
91             my $plugin = Slackware::Slackget::Plugin::MyPlugin->new( $self ) ;
92              
93             The plug-in can internally store this reference, and by the way acces to the instance of this objects : Slackware::Slackget, Slackware::Slackget::Base, Slackware::Slackget::Config, Slackware::Slackget::Network::Auth and Slackware::Slackget::PkgTools.
94              
95             IN ALL CASE, PLUG-INS ARE NOT ALLOWED TO MODIFY THE Slackware::Slackget OBJECT !
96              
97             For performance consideration we don't want to clone all accesible objects, so all plug-in developper will have to respect this rule : you never modify object accessible from this object ! At the very least if you have a good idea send me an e-mail to discuss it.
98              
99             4) dispatch plug-ins' instance by supported HOOK.
100              
101             Parameters :
102              
103             1) An ARRAY reference on supported Hooks.
104              
105             2) the type of plug-in you want to load.
106              
107             Ex:
108              
109             $sgo->load_plugins( ['HOOK_COMMAND_LINE_OPTIONS','HOOK_COMMAND_LINE_HELP','HOOK_START_DAEMON','HOOK_RESTART_DAEMON','HOOK_STOP_DAEMON'], 'daemon');
110              
111             =cut
112              
113             sub load_plugins {
114 0     0 1   my $self = shift;
115 0           my $HOOKS = shift;
116 0           my $plugin_type = shift; # TODO: impl�enter la s��tion des types de plug-in
117 0           my $extra_ref = shift;
118             # print "[SG10] needed type : $plugin_type\n";
119             #NOTE : searching for install plug-in
120 0           $self->log()->Log(2,"searching for plug-in\n") ;
121 0           my %tmp_pg;
122 0           foreach my $dir (@INC)
123             {
124 0 0 0       if( -e "$dir/Slackware/Slackget/Plugin" && -d "$dir/Slackware/Slackget/Plugin")
125             {
126 0           foreach my $name (`ls -1 $dir/Slackware/Slackget/Plugin/*.pm`)
127             {
128 0           chomp $name ;
129 0           $name =~ s/.+\/([^\/]+)\.pm$/$1/;
130 0           $self->log()->Log(2,"found plug-in: $name\n") ;
131 0           print "[SG10] found plug-in: $name in $dir/Slackware/Slackget/Plugin/\n" ;
132             # push @plugins_name, $name;
133 0           $tmp_pg{$name} = 1;
134             }
135             }
136             }
137             #NOTE : loading plug-in
138 0           $self->log()->Log(2,"loading plug-in\n") ;
139 0           my @loaded_plugins;
140             # foreach my $plg (@plugins_name)
141 0           foreach my $plg (keys(%tmp_pg))
142             {
143 0           my $ret = eval qq{require Slackware::Slackget::Plugin::$plg} ;
144 0 0         unless($ret)
145             {
146 0 0         if($@)
    0          
147             {
148 0           warn "Fatal Error while parsing plugin $plg : $@\n";
149 0           $self->log()->Log(1,"Fatal Error while parsing plugin $plg (this is a programming error) : $@\n") ;
150             }
151             elsif($!)
152             {
153 0           warn "Fatal Error while loading plugin $plg : $!\n";
154 0           $self->log()->Log(1,"Fatal Error while parsing plugin $plg : $!\n") ;
155             }
156             }
157             else
158             {
159 0           my $package = "Slackware::Slackget::Plugin::$plg";
160             # print "[SG10] \$package:$package\n";
161 0           my $type = '$'.$package.'::PLUGIN_TYPE';
162             # print "[SG10] \$type:$type\n";
163 0           my $pg_type = eval qq{ $type };
164 0 0 0       if(defined($pg_type) && ($pg_type eq $plugin_type or $pg_type eq 'ALL'))
      0        
165             {
166 0           print "[SG10] loaded success for plug-in $plg\n" ;
167 0           $self->log()->Log(3,"loaded success for plug-in $plg\n") ;
168 0           push @loaded_plugins, $plg;
169 0           $self->{'plugin'}->{'types'}->{$ret} = $pg_type ;
170             }
171             }
172             }
173             #NOTE : creating new instances
174 0           $self->log()->Log(2,"creating new plug-in instance\n") ;
175 0           my @plugins;
176 0           foreach my $plugin (@loaded_plugins)
177             {
178 0           my $package = "Slackware::Slackget::Plugin::$plugin";
179 0           my $ret;
180 0 0         if($plugin_type=~ /gui/i)
181             {
182             # TODO: tester le code de chargement d'un plug-in graphique, la ligne suivante n'a pas encore ��test�
183 0           print "[DEBUG Slackware::Slackget.pm::load_plugins()] loading package \"$package\" call is \"use $package; $package( $extra_ref ) ;\" }\"\n";
184 0           $ret = eval "use $package; $package( $extra_ref ) ;" ;
185             }
186             else
187             {
188 0           $ret = eval{ $package->new($self) ; } ;
  0            
189             }
190            
191 0 0 0       if($@ or !$ret)
192             {
193 0           $self->{'plugin'}->{'types'}->{$ret} = undef;
194 0           delete $self->{'plugin'}->{'types'}->{$ret} ;
195 0           warn "Fatal Error while creating new instance of plugin $package: $@\n";
196 0           $self->log()->Log(1,"Fatal Error while creating new instance of plugin $package: $@\n") ;
197             }
198             else
199             {
200            
201             # print "[SG10] $plugin instanciates\n" ;
202 0           $self->log()->Log(3,"$plugin instanciates\n") ;
203             # if($plugin_type=~ /gui/i)
204             # {
205             # $ret->show();
206             # }
207 0           print "[DEBUG Slackware::Slackget.pm::load_plugins()] print pushing reference \"$ret\" on the plugin stack\n";
208 0           push @plugins, $ret;
209             }
210             }
211 0           %tmp_pg = ();
212 0           @loaded_plugins = ();
213 0           $self->register_plugins(\@plugins,$HOOKS);
214             }
215              
216             =head2 register_plugins
217              
218             Register all plug-ins by supported calls.
219              
220             Take a plug-in array reference and a hooks array reference in arguments.
221              
222             $sgo->register_plugins(\@plugins, \@HOOKS) ;
223              
224             Please read the code of the load_plugins() method to see how to set the object internal state.
225              
226             =cut
227              
228             sub register_plugins
229             {
230 0     0 1   my ($self,$plugins,$HOOKS) = @_ ;
231 0           $self->{'plugin'}->{'raw_table'} = $plugins ;
232 0           $self->{'plugin'}->{'sorted'} = {} ;
233             # NOTE: dispatching plug-ins by hooks.
234 0           $self->log()->Log(2,"dispatching plug-in by supported HOOKS\n") ;
235 0           foreach my $hook (@{ $HOOKS })
  0            
236             {
237 0           my $hk = lc($hook) ;
238             # print "[DEBUG Slackware::Slackget.pm::register_plugins()] examining if plug-in support hook $hk\n";
239 0           $self->{'plugin'}->{'sorted'}->{$hook} = [] ;
240 0           foreach my $plugin (@{ $plugins })
  0            
241             {
242 0 0         if($self->{'plugin'}->{'types'}->{$plugin}=~ /gui/i)
243             {
244            
245 0           eval{ $plugin->$hk('test') ;};
  0            
246 0 0         if($@)
247             {
248 0           print "[SG10] plug-in $plugin do not support hook $hook\n" ;
249             # warn "$@\n";
250             }
251             else
252             {
253 0           print "[SG10] registered plug-in $plugin for hook $hook\n" ;
254 0           $self->log()->Log(3,"registered plug-in $plugin for hook $hook\n") ;
255 0           push @{ $self->{'plugin'}->{'sorted'}->{$hook} },$plugin ;
  0            
256             }
257             }
258             else
259             {
260 0 0         if($plugin->can($hk))
261             {
262 0           print "[SG10] registered plug-in $plugin for hook $hook\n" ;
263 0           $self->log()->Log(3,"registered plug-in $plugin for hook $hook\n") ;
264 0           push @{ $self->{'plugin'}->{'sorted'}->{$hook} },$plugin ;
  0            
265             }
266             }
267             }
268             }
269             }
270              
271             =head2 call_plugins
272              
273             Main method for calling back differents plug-in. This method is quite easy to use : just call it with a hook name in parameter.
274              
275             call_plugins() will iterate on all plug-ins wich implements the given HOOK.
276              
277             $sgo->call_plugins( 'HOOK_START_DAEMON' ) ;
278              
279             Additionaly you can pass all arguments you need to pass to the callback which take care of the HOOK. All extra arguments are passed to the callback.
280              
281             Since all plug-ins have access to many objects which allow them to perform all needed operations (like logging etc), they have to care about output and user information.
282              
283             So all call will be eval-ed and juste a little log message will be done on error.
284              
285             =cut
286              
287             sub call_plugins
288             {
289 0     0 1   my $self = shift;
290 0           my $HOOK = shift ;
291 0           my @returned;
292 0           foreach my $pg ( @{ $self->{'plugin'}->{'sorted'}->{$HOOK} })
  0            
293             {
294 0           my $callback = lc($HOOK);
295 0           push @returned, eval{ $pg->$callback(@_) ;} ;
  0            
296 0 0         if($@)
297             {
298 0           $self->{'log'}->Log(1,"An error occured while attempting to call plug-in ".ref($pg)." for hook $HOOK. The error occured in method $callback. The evaluation return the following error : $@\n");
299             }
300             }
301 0           return @returned ;
302             }
303              
304             =head1 ACCESSORS
305              
306             =head2 base
307              
308             Return the Slackware::Slackget::Base object of the current instance of the Slackware::Slackget object.
309              
310             $sgo->base()->compil_package_directory('/var/log/packages/');
311              
312             =cut
313              
314             sub base
315             {
316 0     0 1   my $self = shift;
317 0           return $self->{'base'} ;
318             }
319              
320             =head2 pkgtools
321              
322             Return the Slackware::Slackget::PkgTools object of the current instance of the Slackware::Slackget object.
323              
324             $sgo->pkgtools()->install( $package_list ) ;
325              
326             =cut
327              
328             sub pkgtools
329             {
330 0     0 1   my $self = shift;
331 0           return $self->{'pkgtools'} ;
332             }
333              
334             =head2 config
335              
336             Return the Slackware::Slackget::Config object of the current instance of the Slackware::Slackget object.
337              
338             print $sgo->config()->{common}->{'file-encoding'} ;
339              
340             =cut
341              
342             sub config
343             {
344 0     0 1   my $self = shift;
345 0           my $cfg_name = shift;
346 0 0         if($cfg_name)
347             {
348 0 0 0       return undef if(!defined($cfg_name) || ! -e $cfg_name) ;
349 0 0         $self->{'config'} = new Slackware::Slackget::Config ( $cfg_name ) or die "FATAL: error during configuration file parsing\n$!\n" ;
350 0           return 1;
351             }
352             else
353             {
354 0           return $self->{'config'} ;
355             }
356             }
357              
358             =head2 auth
359              
360             Return the Slackware::Slackget::Network::Auth object of the current instance of the Slackware::Slackget object.
361              
362             $sgo->auth()->can_connect($client) or die "Client not allowed to connect here\n";
363              
364             =cut
365              
366             sub auth
367             {
368 0     0 1   my $self = shift;
369 0           return $self->{'auth'} ;
370             }
371              
372             =head1 AUTHOR
373              
374             DUPUIS Arnaud, C<< <a.dupuis@infinityperl.org> >>
375              
376             =head1 BUGS
377              
378             Please report any bugs or feature requests to
379             C<bug-Slackware-Slackget@rt.cpan.org>, or through the web interface at
380             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Slackware-Slackget>.
381             I will be notified, and then you'll automatically be notified of progress on
382             your bug as I make changes.
383              
384             =head1 SUPPORT
385              
386             You can find documentation for this module with the perldoc command.
387              
388             perldoc Slackware::Slackget
389              
390              
391             You can also look for information at:
392              
393             =over 4
394              
395             =item * Infinity Perl website
396              
397             L<http://www.infinityperl.org/category/slack-get>
398              
399             =item * slack-get specific website
400              
401             L<http://slackget.infinityperl.org>
402              
403             =item * RT: CPAN's request tracker
404              
405             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Slackware-Slackget>
406              
407             =item * AnnoCPAN: Annotated CPAN documentation
408              
409             L<http://annocpan.org/dist/Slackware-Slackget>
410              
411             =item * CPAN Ratings
412              
413             L<http://cpanratings.perl.org/d/Slackware-Slackget>
414              
415             =item * Search CPAN
416              
417             L<http://search.cpan.org/dist/Slackware-Slackget>
418              
419             =back
420              
421             =head1 ACKNOWLEDGEMENTS
422              
423             Thanks to Bertrand Dupuis (yes my brother) for his contribution to the documentation.
424              
425             =head1 COPYRIGHT & LICENSE
426              
427             Copyright 2005 DUPUIS Arnaud, All Rights Reserved.
428              
429             This program is free software; you can redistribute it and/or modify it
430             under the same terms as Perl itself.
431              
432             =cut
433              
434             1; # End of Slackware::Slackget