[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

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

   1  package CPANPLUS::Internals::Utils;
   2  
   3  use strict;
   4  
   5  use CPANPLUS::Error;
   6  use CPANPLUS::Internals::Constants;
   7  
   8  use Cwd;
   9  use File::Copy;
  10  use Params::Check               qw[check];
  11  use Module::Load::Conditional   qw[can_load];
  12  use Locale::Maketext::Simple    Class => 'CPANPLUS', Style => 'gettext';
  13  
  14  local $Params::Check::VERBOSE = 1;
  15  
  16  =pod
  17  
  18  =head1 NAME
  19  
  20  CPANPLUS::Internals::Utils
  21  
  22  =head1 SYNOPSIS
  23  
  24      my $bool = $cb->_mkdir( dir => 'blah' );
  25      my $bool = $cb->_chdir( dir => 'blah' );
  26      my $bool = $cb->_rmdir( dir => 'blah' );
  27  
  28      my $bool = $cb->_move( from => '/some/file', to => '/other/file' );
  29      my $bool = $cb->_move( from => '/some/dir',  to => '/other/dir' );
  30  
  31      my $cont = $cb->_get_file_contents( file => '/path/to/file' );
  32  
  33  
  34      my $version = $cb->_perl_version( perl => $^X );
  35  
  36  =head1 DESCRIPTION
  37  
  38  C<CPANPLUS::Internals::Utils> holds a few convenience functions for
  39  CPANPLUS libraries.
  40  
  41  =head1 METHODS
  42  
  43  =head2 $cb->_mkdir( dir => '/some/dir' )
  44  
  45  C<_mkdir> creates a full path to a directory.
  46  
  47  Returns true on success, false on failure.
  48  
  49  =cut
  50  
  51  sub _mkdir {
  52      my $self = shift;
  53  
  54      my %hash = @_;
  55  
  56      my $tmpl = {
  57          dir     => { required => 1 },
  58      };
  59  
  60      my $args = check( $tmpl, \%hash ) or (
  61          error(loc( Params::Check->last_error ) ), return
  62      );       
  63  
  64      unless( can_load( modules => { 'File::Path' => 0.0 } ) ) {
  65          error( loc("Could not use File::Path! This module should be core!") );
  66          return;
  67      }
  68  
  69      eval { File::Path::mkpath($args->{dir}) };
  70  
  71      if($@) {
  72          chomp($@);
  73          error(loc(qq[Could not create directory '%1': %2], $args->{dir}, $@ ));
  74          return;
  75      }
  76  
  77      return 1;
  78  }
  79  
  80  =pod
  81  
  82  =head2 $cb->_chdir( dir => '/some/dir' )
  83  
  84  C<_chdir> changes directory to a dir.
  85  
  86  Returns true on success, false on failure.
  87  
  88  =cut
  89  
  90  sub _chdir {
  91      my $self = shift;
  92      my %hash = @_;
  93  
  94      my $tmpl = {
  95          dir     => { required => 1, allow => DIR_EXISTS },
  96      };
  97  
  98      my $args = check( $tmpl, \%hash ) or return;
  99  
 100      unless( chdir $args->{dir} ) {
 101          error( loc(q[Could not chdir into '%1'], $args->{dir}) );
 102          return;
 103      }
 104  
 105      return 1;
 106  }
 107  
 108  =pod
 109  
 110  =head2 $cb->_rmdir( dir => '/some/dir' );
 111  
 112  Removes a directory completely, even if it is non-empty.
 113  
 114  Returns true on success, false on failure.
 115  
 116  =cut
 117  
 118  sub _rmdir {
 119      my $self = shift;
 120      my %hash = @_;
 121  
 122      my $tmpl = {
 123          dir     => { required => 1, allow => IS_DIR },
 124      };
 125  
 126      my $args = check( $tmpl, \%hash ) or return;
 127  
 128      unless( can_load( modules => { 'File::Path' => 0.0 } ) ) {
 129          error( loc("Could not use File::Path! This module should be core!") );
 130          return;
 131      }
 132  
 133      eval { File::Path::rmtree($args->{dir}) };
 134  
 135      if($@) {
 136          chomp($@);
 137          error(loc(qq[Could not delete directory '%1': %2], $args->{dir}, $@ ));
 138          return;
 139      }
 140  
 141      return 1;
 142  }
 143  
 144  =pod
 145  
 146  =head2 $cb->_perl_version ( perl => 'some/perl/binary' );
 147  
 148  C<_perl_version> returns the version of a certain perl binary.
 149  It does this by actually running a command.
 150  
 151  Returns the perl version on success and false on failure.
 152  
 153  =cut
 154  
 155  sub _perl_version {
 156      my $self = shift;
 157      my %hash = @_;
 158  
 159      my $perl;
 160      my $tmpl = {
 161          perl    => { required => 1, store => \$perl },
 162      };
 163  
 164      check( $tmpl, \%hash ) or return;
 165      
 166      my $perl_version;
 167      ### special perl, or the one we are running under?
 168      if( $perl eq $^X ) {
 169          ### just load the config        
 170          require Config;
 171          $perl_version = $Config::Config{version};
 172          
 173      } else {
 174          my $cmd  = $perl .
 175                  ' -MConfig -eprint+Config::config_vars+version';
 176          ($perl_version) = (`$cmd` =~ /version='(.*)'/);
 177      }
 178      
 179      return $perl_version if defined $perl_version;
 180      return;
 181  }
 182  
 183  =pod
 184  
 185  =head2 $cb->_version_to_number( version => $version );
 186  
 187  Returns a proper module version, or '0.0' if none was available.
 188  
 189  =cut
 190  
 191  sub _version_to_number {
 192      my $self = shift;
 193      my %hash = @_;
 194  
 195      my $version;
 196      my $tmpl = {
 197          version => { default => '0.0', store => \$version },
 198      };
 199  
 200      check( $tmpl, \%hash ) or return;
 201  
 202      return $version if $version =~ /^\.?\d/;
 203      return '0.0';
 204  }
 205  
 206  =pod
 207  
 208  =head2 $cb->_whoami
 209  
 210  Returns the name of the subroutine you're currently in.
 211  
 212  =cut
 213  
 214  sub _whoami { my $name = (caller 1)[3]; $name =~ s/.+:://; $name }
 215  
 216  =pod
 217  
 218  =head2 _get_file_contents( file => $file );
 219  
 220  Returns the contents of a file
 221  
 222  =cut
 223  
 224  sub _get_file_contents {
 225      my $self = shift;
 226      my %hash = @_;
 227  
 228      my $file;
 229      my $tmpl = {
 230          file => { required => 1, store => \$file }
 231      };
 232  
 233      check( $tmpl, \%hash ) or return;
 234  
 235      my $fh = OPEN_FILE->($file) or return;
 236      my $contents = do { local $/; <$fh> };
 237  
 238      return $contents;
 239  }
 240  
 241  =pod $cb->_move( from => $file|$dir, to => $target );
 242  
 243  Moves a file or directory to the target.
 244  
 245  Returns true on success, false on failure.
 246  
 247  =cut
 248  
 249  sub _move {
 250      my $self = shift;
 251      my %hash = @_;
 252  
 253      my $from; my $to;
 254      my $tmpl = {
 255          file    => { required => 1, allow => [IS_FILE,IS_DIR],
 256                          store => \$from },
 257          to      => { required => 1, store => \$to }
 258      };
 259  
 260      check( $tmpl, \%hash ) or return;
 261  
 262      if( File::Copy::move( $from, $to ) ) {
 263          return 1;
 264      } else {
 265          error(loc("Failed to move '%1' to '%2': %3", $from, $to, $!));
 266          return;
 267      }
 268  }
 269  
 270  =pod $cb->_copy( from => $file|$dir, to => $target );
 271  
 272  Moves a file or directory to the target.
 273  
 274  Returns true on success, false on failure.
 275  
 276  =cut
 277  
 278  sub _copy {
 279      my $self = shift;
 280      my %hash = @_;
 281      
 282      my($from,$to);
 283      my $tmpl = {
 284          file    =>{ required => 1, allow => [IS_FILE,IS_DIR],
 285                          store => \$from },
 286          to      => { required => 1, store => \$to }
 287      };
 288  
 289      check( $tmpl, \%hash ) or return;
 290  
 291      if( File::Copy::copy( $from, $to ) ) {
 292          return 1;
 293      } else {
 294          error(loc("Failed to copy '%1' to '%2': %3", $from, $to, $!));
 295          return;
 296      }
 297  }
 298  
 299  =head2 $cb->_mode_plus_w( file => '/path/to/file' );
 300  
 301  Sets the +w bit for the file.
 302  
 303  Returns true on success, false on failure.
 304  
 305  =cut
 306  
 307  sub _mode_plus_w {
 308      my $self = shift;
 309      my %hash = @_;
 310      
 311      require File::stat;
 312      
 313      my $file;
 314      my $tmpl = {
 315          file    => { required => 1, allow => IS_FILE, store => \$file },
 316      };
 317      
 318      check( $tmpl, \%hash ) or return;
 319      
 320      ### set the mode to +w for a file and +wx for a dir
 321      my $x       = File::stat::stat( $file );
 322      my $mask    = -d $file ? 0100 : 0200;
 323      
 324      if( $x and chmod( $x->mode|$mask, $file ) ) {
 325          return 1;
 326  
 327      } else {        
 328          error(loc("Failed to '%1' '%2': '%3'", 'chmod +w', $file, $!));
 329          return;
 330      }
 331  }    
 332  
 333  =head2 $uri = $cb->_host_to_uri( scheme => SCHEME, host => HOST, path => PATH );
 334  
 335  Turns a CPANPLUS::Config style C<host> entry into an URI string.
 336  
 337  Returns the uri on success, and false on failure
 338  
 339  =cut
 340  
 341  sub _host_to_uri {
 342      my $self = shift;
 343      my %hash = @_;
 344      
 345      my($scheme, $host, $path);
 346      my $tmpl = {
 347          scheme  => { required => 1,             store => \$scheme },
 348          host    => { default  => 'localhost',   store => \$host },
 349          path    => { default  => '',            store => \$path },
 350      };       
 351  
 352      check( $tmpl, \%hash ) or return;
 353  
 354      ### it's an URI, so unixify the path.
 355      ### VMS has a special method for just that
 356      $path = ON_VMS
 357                  ? VMS::Filespec::unixify($path) 
 358                  : File::Spec::Unix->catdir( File::Spec->splitdir( $path ) );
 359  
 360      return "$scheme://" . File::Spec::Unix->catdir( $host, $path ); 
 361  }
 362  
 363  =head2 $cb->_vcmp( VERSION, VERSION );
 364  
 365  Normalizes the versions passed and does a '<=>' on them, returning the result.
 366  
 367  =cut
 368  
 369  sub _vcmp {
 370      my $self = shift;
 371      my ($x, $y) = @_;
 372      
 373      s/_//g foreach $x, $y;
 374  
 375      return $x <=> $y;
 376  }
 377  
 378  =head2 $cb->_home_dir
 379  
 380  Returns the user's homedir, or C<cwd> if it could not be found
 381  
 382  =cut
 383  
 384  sub _home_dir {
 385      my @os_home_envs = qw( APPDATA HOME USERPROFILE WINDIR SYS$LOGIN );
 386  
 387      for my $env ( @os_home_envs ) {
 388          next unless exists $ENV{ $env };
 389          next unless defined $ENV{ $env } && length $ENV{ $env };
 390          return $ENV{ $env } if -d $ENV{ $env };
 391      }
 392  
 393      return cwd();
 394  }
 395  
 396  =head2 $path = $cb->_safe_path( path => $path );
 397  
 398  Returns a path that's safe to us on Win32 and VMS. 
 399  
 400  Only cleans up the path on Win32 if the path exists.
 401  
 402  On VMS, it encodes dots to _ using C<VMS::Filespec::vmsify>
 403  
 404  =cut
 405  
 406  sub _safe_path {
 407      my $self = shift;
 408      
 409      my %hash = @_;
 410      
 411      my $path;
 412      my $tmpl = {
 413          path  => { required => 1,     store => \$path },
 414      };       
 415  
 416      check( $tmpl, \%hash ) or return;
 417      
 418      if( ON_WIN32 ) {
 419          ### only need to fix it up if there's spaces in the path   
 420          return $path unless $path =~ /\s+/;
 421          
 422          ### clean up paths if we are on win32
 423          return Win32::GetShortPathName( $path ) || $path;
 424  
 425      } elsif ( ON_VMS ) {
 426          ### XXX According to John Malmberg, there's an VMS issue:
 427          ### catdir on VMS can not currently deal with directory components
 428          ### with dots in them.  
 429          ### Fixing this is a a three step procedure, which will work for 
 430          ### VMS in its traditional ODS-2 mode, and it will also work if 
 431          ### VMS is in the ODS-5 mode that is being implemented.
 432          ### If the path is already in VMS syntax, assume that we are done.
 433   
 434          ### VMS format is a path with a trailing ']' or ':'
 435          return $path if $path =~ /\:|\]$/;
 436  
 437          ### 1. Make sure that the value to be converted, $path is 
 438          ### in UNIX directory syntax by appending a '/' to it.
 439          $path .= '/' unless $path =~ m|/$|;
 440  
 441          ### 2. Use VMS::Filespec::vmsify($path . '/') to convert the dots to
 442          ### underscores if needed.  The trailing '/' is needed as so that
 443          ### C<vmsify> knows that it should use directory translation instead of
 444          ### filename translation, as filename translation leaves one dot.
 445          $path = VMS::Filespec::vmsify( $path );
 446  
 447          ### 3. Use $path = File::Spec->splitdir( VMS::Filespec::vmsify( 
 448          ### $path . '/') to remove the directory delimiters.
 449  
 450          ### From John Malmberg:
 451          ### File::Spec->catdir will put the path back together.
 452          ### The '/' trick only works if the string is a directory name 
 453          ### with UNIX style directory delimiters or no directory delimiters.  
 454          ### It is to force vmsify to treat the input specification as UNIX.
 455          ###
 456          ### There is a VMS::Filespec::unixpath() to do the appending of the '/'
 457          ### to the specification, which will do a VMS::Filespec::vmsify() 
 458          ### if needed.
 459          ### However it is not a good idea to call vmsify() on a pathname
 460          ### returned by unixify(), and it is not a good idea to call unixify()
 461          ### on a pathname returned by vmsify().  Because of the nature of the
 462          ### conversion, not all file specifications can make the round trip.
 463          ###
 464          ### I think that directory specifications can safely make the round
 465          ### trip, but not ones containing filenames.
 466          $path = File::Spec->catdir( File::Spec->splitdir( $path ) )
 467      }
 468      
 469      return $path;
 470  }
 471  
 472  
 473  =head2 ($pkg, $version, $ext) = $cb->_split_package_string( package => PACKAGE_STRING );
 474  
 475  Splits the name of a CPAN package string up in it's package, version 
 476  and extension parts.
 477  
 478  For example, C<Foo-Bar-1.2.tar.gz> would return the following parts:
 479  
 480      Package:    Foo-Bar
 481      Version:    1.2
 482      Extension:  tar.gz
 483  
 484  =cut
 485  
 486  {   my $del_re = qr/[-_\+]/i;           # delimiter between elements
 487      my $pkg_re = qr/[a-z]               # any letters followed by 
 488                      [a-z\d]*            # any letters, numbers
 489                      (?i:\.pm)?          # followed by '.pm'--authors do this :(
 490                      (?:                 # optionally repeating:
 491                          $del_re         #   followed by a delimiter
 492                          [a-z]           #   any letters followed by 
 493                          [a-z\d]*        #   any letters, numbers                        
 494                          (?i:\.pm)?      # followed by '.pm'--authors do this :(
 495                      )*
 496                  /xi;   
 497      
 498      my $ver_re = qr/[a-z]*\d+[a-z]*     # contains a digit and possibly letters
 499                      (?:
 500                          [-._]           # followed by a delimiter
 501                          [a-z\d]+        # and more digits and or letters
 502                      )*?
 503                  /xi;
 504   
 505      my $ext_re = qr/[a-z]               # a letter, followed by
 506                      [a-z\d]*            # letters and or digits, optionally
 507                      (?:                 
 508                          \.              #   followed by a dot and letters
 509                          [a-z\d]+        #   and or digits (like .tar.bz2)
 510                      )?                  #   optionally
 511                  /xi;
 512  
 513      my $ver_ext_re = qr/
 514                          ($ver_re+)      # version, optional
 515                          (?:
 516                              \.          # a literal .
 517                              ($ext_re)   # extension,
 518                          )?              # optional, but requires version
 519                  /xi;
 520                  
 521      ### composed regex for CPAN packages
 522      my $full_re = qr/
 523                      ^
 524                      ($pkg_re+)          # package
 525                      (?: 
 526                          $del_re         # delimiter
 527                          $ver_ext_re     # version + extension
 528                      )?
 529                      $                    
 530                  /xi;
 531                  
 532      ### composed regex for perl packages
 533      my $perl    = PERL_CORE;
 534      my $perl_re = qr/
 535                      ^
 536                      ($perl)             # package name for 'perl'
 537                      (?:
 538                          $ver_ext_re     # version + extension
 539                      )?
 540                      $
 541                  /xi;       
 542  
 543  
 544  sub _split_package_string {
 545          my $self = shift;
 546          my %hash = @_;
 547          
 548          my $str;
 549          my $tmpl = { package => { required => 1, store => \$str } };
 550          check( $tmpl, \%hash ) or return;
 551          
 552          
 553          ### 2 different regexes, one for the 'perl' package, 
 554          ### one for ordinary CPAN packages.. try them both, 
 555          ### first match wins.
 556          for my $re ( $full_re, $perl_re ) {
 557              
 558              ### try the next if the match fails
 559              $str =~ $re or next;
 560  
 561              my $pkg = $1 || ''; 
 562              my $ver = $2 || '';
 563              my $ext = $3 || '';
 564  
 565              ### this regex resets the capture markers!
 566              ### strip the trailing delimiter
 567              $pkg =~ s/$del_re$//;
 568              
 569              ### strip the .pm package suffix some authors insist on adding
 570              $pkg =~ s/\.pm$//i;
 571  
 572              return ($pkg, $ver, $ext );
 573          }
 574          
 575          return;
 576      }
 577  }
 578  
 579  {   my %escapes = map {
 580          chr($_) => sprintf("%%%02X", $_)
 581      } 0 .. 255;  
 582      
 583      sub _uri_encode {
 584          my $self = shift;
 585          my %hash = @_;
 586          
 587          my $str;
 588          my $tmpl = {
 589              uri => { store => \$str, required => 1 }
 590          };
 591          
 592          check( $tmpl, \%hash ) or return;
 593  
 594          ### XXX taken straight from URI::Encode
 595          ### Default unsafe characters.  RFC 2732 ^(uric - reserved)
 596          $str =~ s|([^A-Za-z0-9\-_.!~*'()])|$escapes{$1}|g;
 597      
 598          return $str;          
 599      }
 600      
 601      
 602      sub _uri_decode {
 603          my $self = shift;
 604          my %hash = @_;
 605          
 606          my $str;
 607          my $tmpl = {
 608              uri => { store => \$str, required => 1 }
 609          };
 610          
 611          check( $tmpl, \%hash ) or return;
 612      
 613          ### XXX use unencode routine in utils?
 614          $str =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; 
 615      
 616          return $str;    
 617      }
 618  }
 619  
 620  sub _update_timestamp {
 621      my $self = shift;
 622      my %hash = @_;
 623      
 624      my $file;
 625      my $tmpl = {
 626          file => { required => 1, store => \$file, allow => FILE_EXISTS }
 627      };
 628      
 629      check( $tmpl, \%hash ) or return;
 630     
 631      ### `touch` the file, so windoze knows it's new -jmb
 632      ### works on *nix too, good fix -Kane
 633      ### make sure it is writable first, otherwise the `touch` will fail
 634  
 635      my $now = time;
 636      unless( chmod( 0644, $file) && utime ($now, $now, $file) ) {
 637          error( loc("Couldn't touch %1", $file) );
 638          return;
 639      }
 640      
 641      return 1;
 642  }
 643  
 644  
 645  1;
 646  
 647  # Local variables:
 648  # c-indentation-style: bsd
 649  # c-basic-offset: 4
 650  # indent-tabs-mode: nil
 651  # End:
 652  # vim: expandtab shiftwidth=4:


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