X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCatalyst%2FUtils.pm;h=9e389e36d39bb88cba1e512ca4da0170aedf041d;hb=264bac8c94a84d7dbac9912946d1a639fa37d1cd;hp=ed40b02beb2890f8c5228732248018688df9d5c9;hpb=d9183506af8ce9cd1339fceb19d941f293efb17b;p=catagits%2FCatalyst-Runtime.git diff --git a/lib/Catalyst/Utils.pm b/lib/Catalyst/Utils.pm index ed40b02..9e389e3 100644 --- a/lib/Catalyst/Utils.pm +++ b/lib/Catalyst/Utils.pm @@ -148,30 +148,51 @@ Returns home directory for given class. =cut sub home { - my $name = shift; - $name =~ s/\:\:/\//g; - my $home = 0; - if ( my $path = $INC{"$name.pm"} ) { - $home = file($path)->absolute->dir; - $name =~ /(\w+)$/; - my $append = $1; - my $subdir = dir($home)->subdir($append); - for ( split '/', $name ) { $home = dir($home)->parent } - if ( $home =~ /blib$/ ) { $home = dir($home)->parent } - elsif (!-f file( $home, 'Makefile.PL' ) - && !-f file( $home, 'Build.PL' ) ) + my $class = shift; + + # make an $INC{ $key } style string from the class name + (my $file = "$class.pm") =~ s{::}{/}g; + + if ( my $inc_entry = $INC{$file} ) { { - $home = $subdir; + # look for an uninstalled Catalyst app + + # find the @INC entry in which $file was found + (my $path = $inc_entry) =~ s/$file$//; + my $home = dir($path)->absolute->cleanup; + + # pop off /lib and /blib if they're there + $home = $home->parent while $home =~ /b?lib$/; + + # only return the dir if it has a Makefile.PL or Build.PL + if (-f $home->file("Makefile.PL") or -f $home->file("Build.PL")) { + + # clean up relative path: + # MyApp/script/.. -> MyApp + + my ($lastdir) = $home->dir_list( -1, 1 ); + if ( $lastdir eq '..' ) { + $home = dir($home)->parent->parent; + } + + return $home->stringify; + } } - # clean up relative path: - # MyApp/script/.. -> MyApp - my ($lastdir) = $home->dir_list( -1, 1 ); - if ( $lastdir eq '..' ) { - $home = dir($home)->parent->parent; + { + # look for an installed Catalyst app + + # trim the .pm off the thing ( Foo/Bar.pm -> Foo/Bar/ ) + ( my $path = $inc_entry) =~ s/\.pm$//; + my $home = dir($path)->absolute->cleanup; + + # return if if it's a valid directory + return $home->stringify if -d $home; } } - return $home; + + # we found nothing + return 0; } =head2 prefix($class, $name); @@ -219,8 +240,10 @@ Loads the class unless it already has been loaded. sub ensure_class_loaded { my $class = shift; + my $opts = shift; - return if Class::Inspector->loaded( $class ); # if a symbol entry exists we don't load again + return if !$opts->{ ignore_loaded } + && Class::Inspector->loaded( $class ); # if a symbol entry exists we don't load again # this hack is so we don't overwrite $@ if the load did not generate an error my $error; @@ -229,7 +252,40 @@ sub ensure_class_loaded { eval "require $class"; $error = $@; } + die $error if $error; + die "require $class was successful but the package is not defined" + unless Class::Inspector->loaded($class); + + return 1; +} + +=head2 merge_hashes($hashref, $hashref) + +Base code to recursively merge two hashes together with right-hand precedence. + +=cut + +sub merge_hashes { + my ( $lefthash, $righthash ) = @_; + + return $lefthash unless defined $righthash; + + my %merged = %$lefthash; + for my $key ( keys %$righthash ) { + my $right_ref = ( ref $righthash->{ $key } || '' ) eq 'HASH'; + my $left_ref = ( ( exists $lefthash->{ $key } && ref $lefthash->{ $key } ) || '' ) eq 'HASH'; + if( $right_ref and $left_ref ) { + $merged{ $key } = merge_hashes( + $lefthash->{ $key }, $righthash->{ $key } + ); + } + else { + $merged{ $key } = $righthash->{ $key }; + } + } + + return \%merged; }