package Dynamic::Loader; use strict; require Exporter; use Carp qw/confess/; use Env::Path; use File::Basename; require Data::Dumper if defined ($ENV{DEBUG}); our ($VERSION, $BINPATH, @ISA, @EXPORT); $VERSION = '1.02'; =head1 NAME Dynamic::Loader - call a script without to know where is his location. =head1 VERSION Version 0.99 =head1 SYNOPSIS The Dynamic::Loader manage the dynamic location of scripts and bundles. Scripts and bundles are packaged in there own directory. The bundles and scripts locations are discribed on a named configuration file. The prefix configuration directory can be specified by the $JAVAPERL environnement. The default directory is $HOME/.perljava/conf, but you can specify a custom prefix with the $JAVAPERL/conf variable. A configuration is <name>.conf with this format: prefix=<absolute path> bin=<relative binary dir> lib=<relative library dir> =head1 DEFAULT SCRIPT AND PARAMS When C<Dynamic::Loader> is used, you can specify the script name and his options command: perl -S fromjar.pl scriptname.pl --a=... --b=... =cut @ISA = qw(Exporter); @EXPORT=qw($SCRIPTPATH $PATH $PERL5LIB &listScripts &getExecPrefix); our ( $SCRIPTPATH, $PATH, $PERL5LIB, ); sub import { my $class=shift; #@_ contains what could be passed on -MLoader=...; iv ever init(); $class->export_to_level(1, $class, @_) ; } =head3 init() setup libs and bin directories #fix lib and script path according to what's given =cut sub init{ my $perlJavaHome; $perlJavaHome=$ENV{PERLLOADERHOME} || $ENV{JAVAPERL}; $perlJavaHome="$ENV{HOME}/.perljava" unless defined $perlJavaHome; #$ENV{PATH}=''; $PATH = Env::Path->PATH; $SCRIPTPATH = Env::Path->SCRIPTPATH; $PERL5LIB = Env::Path->PERL5LIB; #TODO change that from ENV my @modules; my %conffiles; if($ENV{PERLLOADERMODULES}){ @modules=split /:/, $ENV{PERLLOADERMODULES}; }else{ foreach (<$perlJavaHome/conf/*.conf>){ open (CONFIGFILE, $_) or next; my %entry=(); while (my $l = <CONFIGFILE>) { if ($l =~ /^([^=]+)=(.*)/) { my ($key, $val) = ($1, $2); if ($key eq "prefix"){ $conffiles{$val}=\%entry; push @modules, $val ; }else{ $entry{$key}=$val; } } } close CONFIGFILE; } } require Data::Dumper if defined ($ENV{DEBUG}); printf Data::Dumper::Dumper(\%conffiles)."\n" if defined ($ENV{DEBUG}); foreach my $pjar (@modules) { eval "use lib \"$pjar/$conffiles{$pjar}->{lib}\""; } #we wish to put the path from the given directory, but in the correct order, and in front of all other. foreach my $pjar (reverse @modules) { my $bin="$pjar/$conffiles{$pjar}->{bin}"; $SCRIPTPATH->Prepend($bin) unless $SCRIPTPATH->Contains($bin); $PATH->Prepend($bin) unless $PATH->Contains($bin); my $lib="$pjar/$conffiles{$pjar}->{lib}"; $PERL5LIB->Prepend($lib) unless $PERL5LIB->Contains($lib); } } =head3 Dynamic::Loader::listScripts([patt]) Return a list of commands following a pattern listScripts(), listScripts("*.pl"), listScripts("phe*") The commands returned here are returned with a relative path to the package they belong to =cut sub listScripts{ require File::Find::Rule; my $patt=shift || '*'; my @tmp; foreach my $p($SCRIPTPATH->List){ foreach ( File::Find::Rule->file() ->name( $patt ) ->in( $p )){ next if /\/\.svn\//; s/^$p([\/\\])?//; push @tmp, $_; } } return @tmp; } =head3 Dynamic::Loader::getScript(relative_path) Return the complete path to the given scripts. Contrary to listScripts(), this command must return exactly one script and will die if not; =cut sub getScript{ my $relPath=shift or confess "no relative path given"; my @tmp; foreach ($SCRIPTPATH->List){ my $full="$_/$relPath"; push @tmp, $full if -f $full; } confess "no script found for [$relPath]" unless @tmp; confess "multiple scripts found (@tmp) for [$relPath]" if @tmp>1; return $tmp[0]; } =head3 Dynamic::Loader::getLibs(relative_path) Return the complete path to the given scripts + the complete perl prefix with perl5libs. =cut sub getLongScript{ my $relPath=shift or confess "no relative path given"; my $path=getScript($relPath); my $p5l="perl "; foreach ($PERL5LIB->List){ $p5l.="-I$_ "; } return $p5l.$path; } =head3 Dynamic::Loader::getExecPrefix() return an array to prepend to execution (perl, includes etc...) =cut sub getExecPrefix{ return ($^X); } =head3 Dynamic::Loader::whence([pat]) return a list of commands with the full path corresponding to a pattern. Think of ls completion in bash =cut sub whence{ return $SCRIPTPATH->Whence($_[0] or "*"); } =head1 AUTHOR Olivier Evalet, C<< <olivier.evalet at genebio.com> >> Alexandre Masselo C<< <alex at genebio.com> >> =head1 BUGS Please report any bugs or feature requests to C<bug-dynamic-loader at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Dynamic-Loader>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. =head1 SUPPORT You can find documentation for this module with the perldoc command. perldoc Dynamic::Loader You can also look for information at: =over 4 =item * RT: CPAN's request tracker L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Dynamic-Loader> =item * AnnoCPAN: Annotated CPAN documentation L<http://annocpan.org/dist/Dynamic-Loader> =item * CPAN Ratings L<http://cpanratings.perl.org/d/Dynamic-Loader> =item * Search CPAN L<http://search.cpan.org/dist/Dynamic-Loader> =back =head1 ACKNOWLEDGEMENTS =head1 COPYRIGHT & LICENSE Copyright 2008 Olivier Evalet, Alexandre Masselot all rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; # End of Dynamic::Loader