/lib-abs/lib/lib/abs.pm

http://perl-ex.googlecode.com/ · Perl · 161 lines · 106 code · 40 blank · 15 comment · 14 complexity · 8f205a2e78616534b460f026e3dac3d6 MD5 · raw file

  1. #
  2. # Copyright (c) 200[789] Mons Anderson <mons@cpan.org>. All rights reserved
  3. # This program is free software; you can redistribute it and/or
  4. # modify it under the same terms as Perl itself.
  5. package lib::abs;
  6. =head1 NAME
  7. lib::abs - The same as C<lib>, but makes relative path absolute.
  8. =cut
  9. our $VERSION = '0.91';
  10. =head1 VERSION
  11. Version 0.91
  12. =head1 SYNOPSIS
  13. Simple use like C<use lib ...>:
  14. use lib::abs qw(./mylibs1 ../mylibs2);
  15. use lib::abs 'mylibs';
  16. Extended syntax (glob)
  17. use lib::abs 'modules/*/lib';
  18. There are also may be used helper function from lib::abs (see example/ex4):
  19. use lib::abs;
  20. # ...
  21. my $path = lib::abs::path('../path/relative/to/me'); # returns absolute path
  22. =head1 DESCRIPTION
  23. The main reason of this library is transformate relative paths to absolute at the C<BEGIN> stage, and push transformed to C<@INC>.
  24. Relative path basis is not the current working directory, but the location of file, where the statement is (caller file).
  25. When using common C<lib>, relative paths stays relative to curernt working directory,
  26. # For ex:
  27. # script: /opt/scripts/my.pl
  28. use lib::abs '../lib';
  29. # We run `/opt/scripts/my.pl` having cwd /home/mons
  30. # The @INC will contain '/opt/lib';
  31. # We run `./my.pl` having cwd /opt
  32. # The @INC will contain '/opt/lib';
  33. # We run `../my.pl` having cwd /opt/lib
  34. # The @INC will contain '/opt/lib';
  35. Also this module is useful when writing tests, when you want to load strictly the module from ../lib, respecting the test file.
  36. # t/00-test.t
  37. use lib::abs '../lib';
  38. Also this is useful, when you running under C<mod_perl>, use something like C<Apache::StatINC>, and your application may change working directory.
  39. So in case of chdir C<StatINC> fails to reload module if the @INC contain relative paths.
  40. =head1 BUGS
  41. None known
  42. =head1 COPYRIGHT & LICENSE
  43. Copyright 2007-2009 Mons Anderson.
  44. This program is free software; you can redistribute it and/or modify it
  45. under the same terms as Perl itself.
  46. =head1 AUTHOR
  47. Mons Anderson, <mons@cpan.org>
  48. =cut
  49. use 5.006;
  50. use strict;
  51. use warnings;
  52. use lib ();
  53. use Cwd 3.12 qw(abs_path);
  54. $lib::abs::sep = {
  55. ( map { $_ => qr{[^\\/]+$}o } qw(mswin32 netware symbian dos) ),
  56. ( map { $_ => qr{[^:]+:?$}o } qw(macos) ),
  57. }->{lc$^O} || qr{[^/]+$}o;
  58. BEGIN { *DEBUG = sub () { 0 } unless defined &DEBUG } # use constants is heavy
  59. sub _carp { require Carp; goto &Carp::carp }
  60. sub _croak { require Carp; goto &Carp::croak }
  61. sub _debug ($@) { printf STDERR shift()." at @{[ (caller)[1,2] ]}\n",@_ }
  62. sub mkapath($) {
  63. my $depth = shift;
  64. # Prepare absolute base bath
  65. my ($pkg,$file) = (caller($depth))[0,1];
  66. _debug "file = $file " if DEBUG > 1;
  67. $file =~ s/${lib::abs::sep}//s;
  68. $file = '.' unless length $file;
  69. _debug "base path = $file" if DEBUG > 1;
  70. my $f = abs_path($file) . '/';
  71. _debug "source dir = $f " if DEBUG > 1;
  72. $f;
  73. }
  74. sub path {
  75. local $_ = shift;
  76. s{^\./+}{};
  77. local $!;
  78. my $abs = mkapath(1) . $_;
  79. my $ret = abs_path( $abs ) or _carp("Bad path specification: `$_' => `$abs'" . ($! ? " ($!)" : ''));
  80. _debug "$_ => $ret" if DEBUG > 1;
  81. $ret;
  82. }
  83. sub transform {
  84. my $prefix;
  85. map {
  86. ref || m{^/} ? $_ : do {
  87. my $lib = $_;
  88. s{^\./+}{};
  89. local $!;
  90. my $abs = ( $prefix ||= mkapath(2) ) . $_;
  91. if (index($abs,'*') != -1 or index($abs,'?') !=-1) {
  92. _debug "transforming $abs using glob" if DEBUG > 1;
  93. map {
  94. abs_path( $_ )
  95. or _croak("Bad path specification: `$lib' => `$_'" . ($! ? " ($!)" : ''))
  96. } glob $abs;
  97. } else {
  98. $_ = abs_path( $abs ) or _croak("Bad path specification: `$lib' => `$abs'" . ($! ? " ($!)" : ''));
  99. _debug "$lib => $_" if DEBUG > 1;
  100. ($_);
  101. }
  102. }
  103. } @_;
  104. }
  105. sub import {
  106. shift;
  107. return unless @_;
  108. @_ = ( lib => transform @_ = @_ );
  109. _debug "use @_\n" if DEBUG > 0;
  110. goto &lib::import;
  111. return;
  112. }
  113. sub unimport {
  114. shift;
  115. return unless @_;
  116. @_ = ( lib => transform @_ = @_ );
  117. _debug "no @_\n" if DEBUG > 0;
  118. goto &lib::unimport;
  119. return;
  120. }
  121. 1;