[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/se3-unattended/var/se3/unattended/install/linuxaux/opt/perl/lib/5.10.0/CPANPLUS/ -> Selfupdate.pm (source)

   1  package CPANPLUS::Selfupdate;
   2  
   3  use strict;
   4  use Params::Check               qw[check];
   5  use IPC::Cmd                    qw[can_run];
   6  use CPANPLUS::Error             qw[error msg];
   7  use Locale::Maketext::Simple    Class => 'CPANPLUS', Style => 'gettext';
   8  
   9  use CPANPLUS::Internals::Constants;
  10  
  11  $Params::Check::VERBOSE = 1;
  12  
  13  =head1 NAME
  14  
  15  CPANPLUS::Selfupdate
  16  
  17  =head1 SYNOPSIS
  18  
  19      $su     = $cb->selfupdate_object;
  20      
  21      @feats  = $su->list_features;
  22      @feats  = $su->list_enabled_features;
  23      
  24      @mods   = map { $su->modules_for_feature( $_ ) } @feats;
  25      @mods   = $su->list_core_dependencies;
  26      @mods   = $su->list_core_modules;
  27      
  28      for ( @mods ) {
  29          print $_->name " should be version " . $_->version_required;
  30          print "Installed version is not uptodate!" 
  31              unless $_->is_installed_version_sufficient;
  32      }
  33      
  34      $ok     = $su->selfupdate( update => 'all', latest => 0 );
  35  
  36  =cut
  37  
  38  ### a config has describing our deps etc
  39  {
  40  
  41      my $Modules = {
  42          dependencies => {
  43              'File::Fetch'               => '0.13_04', # win32 & VMS file://
  44              'File::Spec'                => '0.82',
  45              'IPC::Cmd'                  => '0.36', # 5.6.2 compat: 2-arg open
  46              'Locale::Maketext::Simple'  => '0.01',
  47              'Log::Message'              => '0.01',
  48              'Module::Load'              => '0.10',
  49              'Module::Load::Conditional' => '0.18', # Better parsing: #23995,
  50                                                     # uses version.pm for <=>
  51              'version'                   => '0.73', # needed for M::L::C
  52                                                     # addresses #24630 and 
  53                                                     # #24675
  54                                                     # Address ~0 overflow issue
  55              'Params::Check'             => '0.22',
  56              'Package::Constants'        => '0.01',
  57              'Term::UI'                  => '0.18', # option parsing
  58              'Test::Harness'             => '2.62', # due to bug #19505
  59                                                     # only 2.58 and 2.60 are bad
  60              'Test::More'                => '0.47', # to run our tests
  61              'Archive::Extract'          => '0.16', # ./Dir bug fix
  62              'Archive::Tar'              => '1.23',
  63              'IO::Zlib'                  => '1.04', # needed for Archive::Tar
  64              'Object::Accessor'          => '0.32', # overloaded stringification
  65              'Module::CoreList'          => '2.09',
  66              'Module::Pluggable'         => '2.4',
  67              'Module::Loaded'            => '0.01',
  68          },
  69      
  70          features => {
  71              # config_key_name => [
  72              #     sub { } to list module key/value pairs
  73              #     sub { } to check if feature is enabled
  74              # ]
  75              prefer_makefile => [
  76                  sub {
  77                      my $cb = shift;
  78                      $cb->configure_object->get_conf('prefer_makefile') 
  79                          ? { }
  80                          : { 'CPANPLUS::Dist::Build' => '0.04'  };
  81                  },
  82                  sub { return 1 },   # always enabled
  83              ],            
  84              cpantest        => [
  85                  {
  86                      'YAML::Tiny'     => '0.0',
  87                      'Test::Reporter' => '1.34',
  88                  },
  89                  sub { 
  90                      my $cb = shift;
  91                      return $cb->configure_object->get_conf('cpantest');
  92                  },
  93              ],                
  94              dist_type => [
  95                  sub { 
  96                      my $cb      = shift;
  97                      my $dist    = $cb->configure_object->get_conf('dist_type');
  98                      return { $dist => '0.0' } if $dist;
  99                      return;
 100                  },            
 101                  sub { 
 102                      my $cb = shift;
 103                      return $cb->configure_object->get_conf('dist_type');
 104                  },
 105              ],
 106  
 107              md5 => [
 108                  {
 109                      'Digest::MD5'   => '0.0',
 110                  },            
 111                  sub { 
 112                      my $cb = shift;
 113                      return $cb->configure_object->get_conf('md5');
 114                  },
 115              ],
 116              shell => [
 117                  sub { 
 118                      my $cb      = shift;
 119                      my $dist    = $cb->configure_object->get_conf('shell');
 120                      
 121                      ### we bundle these shells, so don't bother having a dep
 122                      ### on them... If we don't do this, CPAN.pm actually detects
 123                      ### a recursive dependency and breaks (see #26077).
 124                      ### This is not an issue for CPANPLUS itself, it handles
 125                      ### it smartly.
 126                      return if $dist eq SHELL_DEFAULT or $dist eq SHELL_CLASSIC;
 127                      return { $dist => '0.0' } if $dist;
 128                      return;
 129                  },            
 130                  sub { return 1 },
 131              ],                
 132              signature => [
 133                  sub {
 134                      my $cb      = shift;
 135                      return {
 136                          'Module::Signature' => '0.06',
 137                      } if can_run('gpg');
 138                      ### leave this out -- Crypt::OpenPGP is fairly
 139                      ### painful to install, and broken on some platforms
 140                      ### so we'll just always fall back to gpg. It may
 141                      ### issue a warning or 2, but that's about it.
 142                      ### this change due to this ticket: #26914
 143                      # and $cb->configure_object->get_conf('prefer_bin');
 144  
 145                      return { 
 146                          'Crypt::OpenPGP'    => '0.0', 
 147                          'Module::Signature' => '0.06',
 148                      };
 149                  },            
 150                  sub {
 151                      my $cb = shift;
 152                      return $cb->configure_object->get_conf('signature');
 153                  },
 154              ],
 155              storable => [
 156                  { 'Storable' => '0.0' },         
 157                  sub { 
 158                      my $cb = shift;
 159                      return $cb->configure_object->get_conf('storable');
 160                  },
 161              ],
 162          },
 163          core => {
 164              'CPANPLUS' => '0.0',
 165          },
 166      };
 167  
 168      sub _get_config { return $Modules }
 169  }
 170  
 171  =head1 METHODS
 172  
 173  =head2 $self = CPANPLUS::Selfupdate->new( $backend_object );
 174  
 175  Sets up a new selfupdate object. Called automatically when
 176  a new backend object is created.
 177  
 178  =cut
 179  
 180  sub new {
 181      my $class = shift;
 182      my $cb    = shift or return;
 183      return bless sub { $cb }, $class;
 184  }    
 185  
 186  
 187  {   ### cache to find the relevant modules
 188      my $cache = {
 189          core 
 190              => sub { my $self = shift;
 191                       core => [ $self->list_core_modules ]   },
 192   
 193          dependencies        
 194              => sub { my $self = shift;
 195                       dependencies => [ $self->list_core_dependencies ] },
 196  
 197          enabled_features    
 198              => sub { my $self = shift;
 199                       map { $_ => [ $self->modules_for_feature( $_ ) ] }
 200                          $self->list_enabled_features 
 201                     },
 202          features
 203              => sub { my $self = shift;
 204                       map { $_ => [ $self->modules_for_feature( $_ ) ] }
 205                          $self->list_features   
 206                     },
 207              ### make sure to do 'core' first, in case
 208              ### we are out of date ourselves
 209          all => [ qw|core dependencies enabled_features| ],
 210      };
 211      
 212      
 213  =head2 @cat = $self->list_categories
 214  
 215  Returns a list of categories that the C<selfupdate> method accepts.
 216  
 217  See C<selfupdate> for details.
 218  
 219  =cut
 220  
 221      sub list_categories { return sort keys %$cache }
 222  
 223  =head2 %list = $self->list_modules_to_update( update => "core|dependencies|enabled_features|features|all", [latest => BOOL] )
 224      
 225  List which modules C<selfupdate> would upgrade. You can update either 
 226  the core (CPANPLUS itself), the core dependencies, all features you have
 227  currently turned on, or all features available, or everything.
 228  
 229  The C<latest> option determines whether it should update to the latest
 230  version on CPAN, or if the minimal required version for CPANPLUS is
 231  good enough.
 232      
 233  Returns a hash of feature names and lists of module objects to be
 234  upgraded based on the category you provided. For example:
 235  
 236      %list = $self->list_modules_to_update( update => 'core' );
 237      
 238  Would return:
 239  
 240      ( core => [ $module_object_for_cpanplus ] );
 241      
 242  =cut    
 243      
 244      sub list_modules_to_update {
 245          my $self = shift;
 246          my $cb   = $self->();
 247          my $conf = $cb->configure_object;
 248          my %hash = @_;
 249          
 250          my($type, $latest);
 251          my $tmpl = {
 252              update => { required => 1, store => \$type,
 253                           allow   => [ keys %$cache ], },
 254              latest => { default  => 0, store => \$latest, allow => BOOLEANS },                     
 255          };    
 256      
 257          {   local $Params::Check::ALLOW_UNKNOWN = 1;
 258              check( $tmpl, \%hash ) or return;
 259          }
 260      
 261          my $ref     = $cache->{$type};
 262  
 263          ### a list of ( feature1 => \@mods, feature2 => \@mods, etc )        
 264          my %list    = UNIVERSAL::isa( $ref, 'ARRAY' )
 265                              ? map { $cache->{$_}->( $self ) } @$ref
 266                              : $ref->( $self );
 267  
 268          ### filter based on whether we need the latest ones or not
 269          for my $aref ( values %list ) {              
 270                $aref = [ $latest 
 271                          ? grep { !$_->is_uptodate } @$aref
 272                          : grep { !$_->is_installed_version_sufficient } @$aref
 273                        ];
 274          }
 275          
 276          return %list;
 277      }
 278      
 279  =head2 $bool = $self->selfupdate( update => "core|dependencies|enabled_features|features|all", [latest => BOOL, force => BOOL] )
 280  
 281  Selfupdate CPANPLUS. You can update either the core (CPANPLUS itself),
 282  the core dependencies, all features you have currently turned on, or
 283  all features available, or everything.
 284  
 285  The C<latest> option determines whether it should update to the latest
 286  version on CPAN, or if the minimal required version for CPANPLUS is
 287  good enough.
 288  
 289  Returns true on success, false on error.
 290  
 291  =cut
 292  
 293      sub selfupdate {
 294          my $self = shift;
 295          my $cb   = $self->();
 296          my $conf = $cb->configure_object;
 297          my %hash = @_;
 298      
 299          my $force;
 300          my $tmpl = {
 301              force  => { default => $conf->get_conf('force'), store => \$force },
 302          };    
 303      
 304          {   local $Params::Check::ALLOW_UNKNOWN = 1;
 305              check( $tmpl, \%hash ) or return;
 306          }
 307      
 308          my %list = $self->list_modules_to_update( %hash ) or return;
 309  
 310          ### just the modules please
 311          my @mods = map { @$_ } values %list;
 312          
 313          my $flag;
 314          for my $mod ( @mods ) {
 315              unless( $mod->install( force => $force ) ) {
 316                  $flag++;
 317                  error(loc("Failed to update module '%1'", $mod->name));
 318              }
 319          }
 320          
 321          return if $flag;
 322          return 1;
 323      }    
 324  
 325  }
 326  
 327  =head2 @features = $self->list_features
 328  
 329  Returns a list of features that are supported by CPANPLUS.
 330  
 331  =cut
 332  
 333  sub list_features {
 334      my $self = shift;
 335      return keys %{ $self->_get_config->{'features'} };
 336  }
 337  
 338  =head2 @features = $self->list_enabled_features
 339  
 340  Returns a list of features that are enabled in your current
 341  CPANPLUS installation.
 342  
 343  =cut
 344  
 345  sub list_enabled_features {
 346      my $self = shift;
 347      my $cb   = $self->();
 348      
 349      my @enabled;
 350      for my $feat ( $self->list_features ) {
 351          my $ref = $self->_get_config->{'features'}->{$feat}->[1];
 352          push @enabled, $feat if $ref->($cb);
 353      }
 354      
 355      return @enabled;
 356  }
 357  
 358  =head2 @mods = $self->modules_for_feature( FEATURE [,AS_HASH] )
 359  
 360  Returns a list of C<CPANPLUS::Selfupdate::Module> objects which 
 361  represent the modules required to support this feature.
 362  
 363  For a list of features, call the C<list_features> method.
 364  
 365  If the C<AS_HASH> argument is provided, no module objects are
 366  returned, but a hashref where the keys are names of the modules,
 367  and values are their minimum versions.
 368  
 369  =cut
 370  
 371  sub modules_for_feature {
 372      my $self    = shift;
 373      my $feature = shift or return;
 374      my $as_hash = shift || 0;
 375      my $cb      = $self->();
 376      
 377      unless( exists $self->_get_config->{'features'}->{$feature} ) {
 378          error(loc("Unknown feature '%1'", $feature));
 379          return;
 380      }
 381      
 382      my $ref = $self->_get_config->{'features'}->{$feature}->[0];
 383      
 384      ### it's either a list of modules/versions or a subroutine that
 385      ### returns a list of modules/versions
 386      my $href = UNIVERSAL::isa( $ref, 'HASH' ) ? $ref : $ref->( $cb );
 387      
 388      return unless $href;    # nothing needed for the feature?
 389  
 390      return $href if $as_hash;
 391      return $self->_hashref_to_module( $href );
 392  }
 393  
 394  
 395  =head2 @mods = $self->list_core_dependencies( [AS_HASH] )
 396  
 397  Returns a list of C<CPANPLUS::Selfupdate::Module> objects which 
 398  represent the modules that comprise the core dependencies of CPANPLUS.
 399  
 400  If the C<AS_HASH> argument is provided, no module objects are
 401  returned, but a hashref where the keys are names of the modules,
 402  and values are their minimum versions.
 403  
 404  =cut
 405  
 406  sub list_core_dependencies {
 407      my $self    = shift;
 408      my $as_hash = shift || 0;
 409      my $cb      = $self->();
 410      my $href    = $self->_get_config->{'dependencies'};
 411  
 412      return $href if $as_hash;
 413      return $self->_hashref_to_module( $href );
 414  }
 415  
 416  =head2 @mods = $self->list_core_modules( [AS_HASH] )
 417  
 418  Returns a list of C<CPANPLUS::Selfupdate::Module> objects which 
 419  represent the modules that comprise the core of CPANPLUS.
 420  
 421  If the C<AS_HASH> argument is provided, no module objects are
 422  returned, but a hashref where the keys are names of the modules,
 423  and values are their minimum versions.
 424  
 425  =cut
 426  
 427  sub list_core_modules {
 428      my $self    = shift;
 429      my $as_hash = shift || 0;
 430      my $cb      = $self->();
 431      my $href    = $self->_get_config->{'core'};
 432  
 433      return $href if $as_hash;
 434      return $self->_hashref_to_module( $href );
 435  }
 436  
 437  sub _hashref_to_module {
 438      my $self = shift;
 439      my $cb   = $self->();
 440      my $href = shift or return;
 441      
 442      return map { 
 443              CPANPLUS::Selfupdate::Module->new(
 444                  $cb->module_tree($_) => $href->{$_}
 445              )
 446          } keys %$href;
 447  }        
 448      
 449  
 450  =head1 CPANPLUS::Selfupdate::Module
 451  
 452  C<CPANPLUS::Selfupdate::Module> extends C<CPANPLUS::Module> objects
 453  by providing accessors to aid in selfupdating CPANPLUS.
 454  
 455  These objects are returned by all methods of C<CPANPLUS::Selfupdate>
 456  that return module objects.
 457  
 458  =cut
 459  
 460  {   package CPANPLUS::Selfupdate::Module;
 461      use base 'CPANPLUS::Module';
 462      
 463      ### stores module name -> cpanplus required version
 464      ### XXX only can deal with 1 pair!
 465      my %Cache = ();
 466      my $Acc   = 'version_required';
 467      
 468      sub new {
 469          my $class = shift;
 470          my $mod   = shift or return;
 471          my $ver   = shift;          return unless defined $ver;
 472          
 473          my $obj   = $mod->clone;    # clone the module object
 474          bless $obj, $class;         # rebless it to our class
 475          
 476          $obj->$Acc( $ver );
 477          
 478          return $obj;
 479      }
 480  
 481  =head2 $version = $mod->version_required
 482  
 483  Returns the version of this module required for CPANPLUS.
 484  
 485  =cut
 486      
 487      sub version_required {
 488          my $self = shift;
 489          $Cache{ $self->name } = shift() if @_;
 490          return $Cache{ $self->name };
 491      }        
 492  
 493  =head2 $bool = $mod->is_installed_version_sufficient
 494  
 495  Returns true if the installed version of this module is sufficient
 496  for CPANPLUS, or false if it is not.
 497  
 498  =cut
 499  
 500      
 501      sub is_installed_version_sufficient {
 502          my $self = shift;
 503          return $self->is_uptodate( version => $self->$Acc );
 504      }
 505  
 506  }    
 507  
 508  1;
 509  
 510  =pod
 511  
 512  =head1 BUG REPORTS
 513  
 514  Please report bugs or other issues to E<lt>bug-cpanplus@rt.cpan.org<gt>.
 515  
 516  =head1 AUTHOR
 517  
 518  This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
 519  
 520  =head1 COPYRIGHT
 521  
 522  The CPAN++ interface (of which this module is a part of) is copyright (c) 
 523  2001 - 2007, Jos Boumans E<lt>kane@cpan.orgE<gt>. All rights reserved.
 524  
 525  This library is free software; you may redistribute and/or modify it 
 526  under the same terms as Perl itself.
 527  
 528  =cut
 529  
 530  # Local variables:
 531  # c-indentation-style: bsd
 532  # c-basic-offset: 4
 533  # indent-tabs-mode: nil
 534  # End:
 535  # vim: expandtab shiftwidth=4:


Generated: Tue Mar 17 22:47:18 2015 Cross-referenced by PHPXref 0.7.1