File Coverage

blib/lib/Slackware/Slackget.pm
Criterion Covered Total %
statement 9 142 6.3
branch 0 38 0.0
condition 0 18 0.0
subroutine 3 17 17.6
pod n/a
total 12 215 5.5


line stmt bran cond sub pod time code
1             package Slackware::Slackget;
2              
3 1     1   58049 use warnings;
  1         4  
  1         31  
4 1     1   7 use strict;
  1         5  
  1         218  
5              
6             require Slackware::Slackget::Base ;
7             require Slackware::Slackget::Network::Auth ;
8             require Slackware::Slackget::Config ;
9             require Slackware::Slackget::PkgTools ;
10 1     1   620 use Slackware::Slackget::File;
  1         2  
  1         2767  
11              
12             =head1 NAME
13              
14             Slackware::Slackget - Main library for slack-get package manager 1.X
15              
16             =head1 VERSION
17              
18             Version 0.17
19              
20             =cut
21              
22             our $VERSION = '0.17';
23              
24             =head1 SYNOPSIS
25              
26             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.
27              
28             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).
29              
30             This module is still beta development version and I release it on CPAN only for coder which want to see the new architecture. For more informations, have a look on subclasses.
31              
32             use Slackware::Slackget;
33              
34             my $sgo = Slackware::Slackget->new(
35             -config => '/etc/slack-get/config.xml',
36             -name => 'slack-getd',
37             -version => '1.0.1228'
38             );
39              
40             =cut
41              
42             =head1 CONSTRUCTOR
43              
44             The constructor ( new() ), is used to instanciate all needed class for a slack-get instance.
45              
46             =head2 new
47              
48             You have to pass the followings arguments to the constructor :
49              
50             -config => the name of the configuration file.
51             -name => ignored : for backward compatibility
52             -version => ignored : for backward compatibility
53              
54             -name and -version arguments are passed to the constructor of the Slackware::Slackget::Log object.
55              
56             =cut
57              
58             sub new {
59 0     0     my $class = 'Slackware::Slackget' ;
60 0           my $self = {} ;
61 0 0         if(scalar(@_)%2 != 0)
62             {
63 0           $class = shift(@_) ;
64             }
65 0           my %args = @_ ;
66 0 0 0       die "FATAL: You must pass a configuration file as -config parameter.\n" if(!defined($args{'-config'}) || ! -e $args{'-config'}) ;
67 0 0         $self->{'config'} = new Slackware::Slackget::Config ( $args{'-config'} ) or die "FATAL: error during configuration file parsing\n$!\n" ;
68 0           $self->{'base'} = new Slackware::Slackget::Base ( $self->{'config'} );
69 0           $self->{'pkgtools'} = new Slackware::Slackget::PkgTools ( $self->{'config'} );
70 0           $self->{'auth'} = Slackware::Slackget::Network::Auth->new( $self->{'config'} );
71 0           $self->{'slackware_version'}=undef;
72 0           bless($self,$class) ;
73 0           return $self;
74             }
75              
76             =head2 slackware_version
77              
78             Return the host's Slackware version as written in the /etc/slackware-version file.
79              
80             if ( $sgo->slackware_version >= 12.0.0 ){
81             print "Slackware distribution is ok, let's continue.\n";
82             }
83              
84             =cut
85              
86             sub slackware_version {
87 0     0     my $self = shift;
88 0 0         unless( defined($self->{'slackware_version'}) ){
89 0           my $file = Slackware::Slackget::File->new('/etc/slackware-version');
90 0           my $line = $file->get_line(0);
91 0           chomp $line;
92 0 0         if( $line =~ /^Slackware\s*([\d\.]+)$/ ){
93 0           $self->{'slackware_version'}=$1;
94             }
95             }
96 0           return $self->{'slackware_version'};
97             }
98              
99             =head1 FUNCTIONS
100              
101             =head2 load_plugins
102              
103             Search for all plugins in the followings directories : /lib/Slackware/Slackget/Plugin/, /lib/Slackware/Slackget/Plugin/, /lib/Slackware/Slackget/Plugin/.
104              
105             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 :
106              
107             1) scan for plug-in
108              
109             2) try to "require" all the finded modules.
110              
111             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 :
112              
113             # Slackware::Slackget::Plugin::MyPlugin is the name of the plug-in
114             # $self is the reference to the current Slackware::Slackget object.
115            
116             my $plugin = Slackware::Slackget::Plugin::MyPlugin->new( $self ) ;
117              
118             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.
119              
120             IN ALL CASE, PLUG-INS ARE NOT ALLOWED TO MODIFY THE Slackware::Slackget OBJECT !
121              
122             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.
123              
124             4) dispatch plug-ins' instance by supported HOOK.
125              
126             Parameters :
127              
128             1) An ARRAY reference on supported Hooks.
129              
130             2) the type of plug-in you want to load.
131              
132             Ex:
133              
134             $sgo->load_plugins( ['HOOK_COMMAND_LINE_OPTIONS','HOOK_COMMAND_LINE_HELP','HOOK_START_DAEMON','HOOK_RESTART_DAEMON','HOOK_STOP_DAEMON'], 'daemon');
135              
136             =cut
137              
138             sub load_plugins {
139 0     0     my $self = shift;
140 0           my $HOOKS = shift;
141 0           my $plugin_type = shift; # TODO: impl�enter la s��tion des types de plug-in
142 0           my $extra_ref = shift;
143             # print "[SG10] needed type : $plugin_type\n";
144             #NOTE : searching for install plug-in
145 0           $self->log()->Log(2,"searching for plug-in\n") ;
146 0           my %tmp_pg;
147 0           foreach my $dir (@INC)
148             {
149 0 0 0       if( -e "$dir/Slackware/Slackget/Plugin" && -d "$dir/Slackware/Slackget/Plugin")
150             {
151 0           foreach my $name (`ls -1 $dir/Slackware/Slackget/Plugin/*.pm`)
152             {
153 0           chomp $name ;
154 0           $name =~ s/.+\/([^\/]+)\.pm$/$1/;
155 0           $self->log()->Log(2,"found plug-in: $name\n") ;
156 0           print "[SG10] found plug-in: $name in $dir/Slackware/Slackget/Plugin/\n" ;
157             # push @plugins_name, $name;
158 0           $tmp_pg{$name} = 1;
159             }
160             }
161             }
162             #NOTE : loading plug-in
163 0           $self->log()->Log(2,"loading plug-in\n") ;
164 0           my @loaded_plugins;
165             # foreach my $plg (@plugins_name)
166 0           foreach my $plg (keys(%tmp_pg))
167             {
168 0           my $ret = eval qq{require Slackware::Slackget::Plugin::$plg} ;
169 0 0         unless($ret)
170             {
171 0 0         if($@)
    0          
172             {
173 0           warn "Fatal Error while parsing plugin $plg : $@\n";
174 0           $self->log()->Log(1,"Fatal Error while parsing plugin $plg (this is a programming error) : $@\n") ;
175             }
176             elsif($!)
177             {
178 0           warn "Fatal Error while loading plugin $plg : $!\n";
179 0           $self->log()->Log(1,"Fatal Error while parsing plugin $plg : $!\n") ;
180             }
181             }
182             else
183             {
184 0           my $package = "Slackware::Slackget::Plugin::$plg";
185             # print "[SG10] \$package:$package\n";
186 0           my $type = '$'.$package.'::PLUGIN_TYPE';
187             # print "[SG10] \$type:$type\n";
188 0           my $pg_type = eval qq{ $type };
189 0 0 0       if(defined($pg_type) && ($pg_type eq $plugin_type or $pg_type eq 'ALL'))
      0        
190             {
191 0           print "[SG10] loaded success for plug-in $plg\n" ;
192 0           $self->log()->Log(3,"loaded success for plug-in $plg\n") ;
193 0           push @loaded_plugins, $plg;
194 0           $self->{'plugin'}->{'types'}->{$ret} = $pg_type ;
195             }
196             }
197             }
198             #NOTE : creating new instances
199 0           $self->log()->Log(2,"creating new plug-in instance\n") ;
200 0           my @plugins;
201 0           foreach my $plugin (@loaded_plugins)
202             {
203 0           my $package = "Slackware::Slackget::Plugin::$plugin";
204 0           my $ret;
205 0 0         if($plugin_type=~ /gui/i)
206             {
207             # TODO: tester le code de chargement d'un plug-in graphique, la ligne suivante n'a pas encore ��test�
208 0           print "[DEBUG Slackware::Slackget.pm::load_plugins()] loading package \"$package\" call is \"use $package; $package( $extra_ref ) ;\" }\"\n";
209 0           $ret = eval "use $package; $package( $extra_ref ) ;" ;
210             }
211             else
212             {
213 0           $ret = eval{ $package->new($self) ; } ;
  0            
214             }
215            
216 0 0 0       if($@ or !$ret)
217             {
218 0           $self->{'plugin'}->{'types'}->{$ret} = undef;
219 0           delete $self->{'plugin'}->{'types'}->{$ret} ;
220 0           warn "Fatal Error while creating new instance of plugin $package: $@\n";
221 0           $self->log()->Log(1,"Fatal Error while creating new instance of plugin $package: $@\n") ;
222             }
223             else
224             {
225            
226             # print "[SG10] $plugin instanciates\n" ;
227 0           $self->log()->Log(3,"$plugin instanciates\n") ;
228             # if($plugin_type=~ /gui/i)
229             # {
230             # $ret->show();
231             # }
232 0           print "[DEBUG Slackware::Slackget.pm::load_plugins()] print pushing reference \"$ret\" on the plugin stack\n";
233 0           push @plugins, $ret;
234             }
235             }
236 0           %tmp_pg = ();
237 0           @loaded_plugins = ();
238 0           $self->register_plugins(\@plugins,$HOOKS);
239             }
240              
241             =head2 register_plugins
242              
243             Register all plug-ins by supported calls.
244              
245             Take a plug-in array reference and a hooks array reference in arguments.
246              
247             $sgo->register_plugins(\@plugins, \@HOOKS) ;
248              
249             Please read the code of the load_plugins() method to see how to set the object internal state.
250              
251             =cut
252              
253             sub register_plugins
254             {
255 0     0     my ($self,$plugins,$HOOKS) = @_ ;
256 0           $self->{'plugin'}->{'raw_table'} = $plugins ;
257 0           $self->{'plugin'}->{'sorted'} = {} ;
258             # NOTE: dispatching plug-ins by hooks.
259 0           $self->log()->Log(2,"dispatching plug-in by supported HOOKS\n") ;
260 0           foreach my $hook (@{ $HOOKS })
  0            
261             {
262 0           my $hk = lc($hook) ;
263             # print "[DEBUG Slackware::Slackget.pm::register_plugins()] examining if plug-in support hook $hk\n";
264 0           $self->{'plugin'}->{'sorted'}->{$hook} = [] ;
265 0           foreach my $plugin (@{ $plugins })
  0            
266             {
267 0 0         if($self->{'plugin'}->{'types'}->{$plugin}=~ /gui/i)
268             {
269            
270 0           eval{ $plugin->$hk('test') ;};
  0            
271 0 0         if($@)
272             {
273 0           print "[SG10] plug-in $plugin do not support hook $hook\n" ;
274             # warn "$@\n";
275             }
276             else
277             {
278 0           print "[SG10] registered plug-in $plugin for hook $hook\n" ;
279 0           $self->log()->Log(3,"registered plug-in $plugin for hook $hook\n") ;
280 0           push @{ $self->{'plugin'}->{'sorted'}->{$hook} },$plugin ;
  0            
281             }
282             }
283             else
284             {
285 0 0         if($plugin->can($hk))
286             {
287 0           print "[SG10] registered plug-in $plugin for hook $hook\n" ;
288 0           $self->log()->Log(3,"registered plug-in $plugin for hook $hook\n") ;
289 0           push @{ $self->{'plugin'}->{'sorted'}->{$hook} },$plugin ;
  0            
290             }
291             }
292             }
293             }
294             }
295              
296             =head2 call_plugins
297              
298             Main method for calling back differents plug-in. This method is quite easy to use : just call it with a hook name in parameter.
299              
300             call_plugins() will iterate on all plug-ins wich implements the given HOOK.
301              
302             $sgo->call_plugins( 'HOOK_START_DAEMON' ) ;
303              
304             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.
305              
306             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.
307              
308             So all call will be eval-ed and juste a little log message will be done on error.
309              
310             =cut
311              
312             sub call_plugins
313             {
314 0     0     my $self = shift;
315 0           my $HOOK = shift ;
316 0           my @returned;
317 0           foreach my $pg ( @{ $self->{'plugin'}->{'sorted'}->{$HOOK} })
  0            
318             {
319 0           my $callback = lc($HOOK);
320 0           push @returned, eval{ $pg->$callback(@_) ;} ;
  0            
321 0 0         if($@)
322             {
323 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");
324             }
325             }
326 0           return @returned ;
327             }
328              
329             =head1 ACCESSORS
330              
331             =head2 base
332              
333             Return the Slackware::Slackget::Base object of the current instance of the Slackware::Slackget object.
334              
335             $sgo->base()->compil_package_directory('/var/log/packages/');
336              
337             =cut
338              
339             sub base
340             {
341 0     0     my $self = shift;
342 0           return $self->{'base'} ;
343             }
344              
345             =head2 pkgtools
346              
347             Return the Slackware::Slackget::PkgTools object of the current instance of the Slackware::Slackget object.
348              
349             $sgo->pkgtools()->install( $package_list ) ;
350              
351             =cut
352              
353             sub pkgtools
354             {
355 0     0     my $self = shift;
356 0           return $self->{'pkgtools'} ;
357             }
358              
359             =head2 removepkg()
360              
361             Alias for :
362              
363             $sgo->pkgtools()->remove();
364              
365             =cut
366              
367             sub removepkg {
368 0     0     my ($self,@params) = @_;
369 0           return $self->{'pkgtools'}->remove(@params) ;
370             }
371              
372             =head2 installpkg()
373              
374             Alias for :
375              
376             $sgo->pkgtools()->install();
377              
378             =cut
379              
380             sub installpkg {
381 0     0     my ($self,@params) = @_;
382 0           return $self->{'pkgtools'}->install(@params) ;
383             }
384              
385             =head2 upgradepkg()
386              
387             Alias for :
388              
389             $sgo->pkgtools()->upgrade();
390              
391             =cut
392              
393             sub upgradepkg {
394 0     0     my ($self,@params) = @_;
395 0           print "Slackware::slackget::upgradepkg: pass \@params to pkgtools->upgrade(@params).\n";
396 0           return $self->{'pkgtools'}->upgrade(@params) ;
397             }
398              
399             =head2 config
400              
401             Return the Slackware::Slackget::Config object of the current instance of the Slackware::Slackget object.
402              
403             print $sgo->config()->{common}->{'file-encoding'} ;
404              
405             =cut
406              
407             sub config
408             {
409 0     0     my $self = shift;
410 0           my $cfg_name = shift;
411 0 0         if($cfg_name)
412             {
413 0 0 0       return undef if(!defined($cfg_name) || ! -e $cfg_name) ;
414 0 0         $self->{'config'} = new Slackware::Slackget::Config ( $cfg_name ) or die "FATAL: error during configuration file parsing\n$!\n" ;
415 0           return 1;
416             }
417             else
418             {
419 0           return $self->{'config'} ;
420             }
421             }
422              
423             =head2 get_config_token
424              
425             A wrapper method to get a configuration key. This method call the Slackware::Slackget::Config->get_token() method.
426              
427             SO YOU HAVE TO COMPLY WITH THIS SYNTAX !
428              
429             print "Official media is: ",$sgo->get_config_token('/daemon/official-media'),"\n";
430              
431             =cut
432              
433             sub get_config_token {
434 0     0     my ($self, $query) = @_;
435 0           return $self->{'config'}->get_token($query);
436             }
437              
438             =head2 set_config_token
439              
440             A wrapper method to set a configuration key. This method call the Slackware::Slackget::Config->set_token() method.
441              
442             SO YOU HAVE TO COMPLY WITH THIS SYNTAX !
443              
444             $sgo->set_config_token('/daemon/official-media','slackware-12.0');
445              
446             =cut
447              
448             sub set_config_token {
449 0     0     my ($self, $query,$value) = @_;
450 0           return $self->{'config'}->set_token($query,$value);
451             }
452              
453             =head2 auth
454              
455             Return the Slackware::Slackget::Network::Auth object of the current instance of the Slackware::Slackget object.
456              
457             $sgo->auth()->can_connect($client) or die "Client not allowed to connect here\n";
458              
459             =cut
460              
461             sub auth
462             {
463 0     0     my $self = shift;
464 0           return $self->{'auth'} ;
465             }
466              
467             =head1 AUTHOR
468              
469             DUPUIS Arnaud, C<< >>
470              
471             =head1 BUGS
472              
473             Please report any bugs or feature requests to
474             C, or through the web interface at
475             L.
476             I will be notified, and then you'll automatically be notified of progress on
477             your bug as I make changes.
478              
479             =head1 SUPPORT
480              
481             You can find documentation for this module with the perldoc command.
482              
483             perldoc Slackware::Slackget
484              
485              
486             You can also look for information at:
487              
488             =over 4
489              
490             =item * Infinity Perl website
491              
492             L
493              
494             =item * slack-get specific website
495              
496             L
497              
498             =item * RT: CPAN's request tracker
499              
500             L
501              
502             =item * AnnoCPAN: Annotated CPAN documentation
503              
504             L
505              
506             =item * CPAN Ratings
507              
508             L
509              
510             =item * Search CPAN
511              
512             L
513              
514             =back
515              
516             =head1 ACKNOWLEDGEMENTS
517              
518             Thanks to Bertrand Dupuis (yes my brother) for his contribution to the documentation.
519              
520             =head1 COPYRIGHT & LICENSE
521              
522             Copyright 2005 DUPUIS Arnaud, All Rights Reserved.
523              
524             This program is free software; you can redistribute it and/or modify it
525             under the same terms as Perl itself.
526              
527             =cut
528              
529             1; # End of Slackware::Slackget