1 #line 1 "/Users/ingy/src/ingy/Spiffy/inc/Module/Install.pm - /Users/ingy/local/lib/perl5/site_perl/5.8.6/Module/Install.pm"
2 package Module::Install;
8 # Don't forget to update Module::Install::Admin too!
12 # inc::Module::Install must be loaded first
13 unless ( $INC{join('/', inc => split(/::/, __PACKAGE__)).'.pm'} ) {
15 Please invoke ${\__PACKAGE__} with:
17 use inc::${\__PACKAGE__};
31 *inc::Module::Install::VERSION = *VERSION;
32 @inc::Module::Install::ISA = 'Module::Install';
36 my $caller = $self->_caller;
38 my $sym = "$caller\::AUTOLOAD";
42 if ( my $code = $sym->{$pwd} ) {
43 # delegate back to parent dirs
44 goto &$code unless $cwd eq $pwd;
46 $$sym =~ /([^:]+)$/ or die "Cannot autoload $caller - $sym";
47 unshift @_, ($self, $1);
48 goto &{$self->can('call')} unless uc($1) eq $1;
54 my $self = $class->new(@_);
56 unless ( -f $self->{file} ) {
57 require "$self->{path}/$self->{dispatch}.pm";
58 File::Path::mkpath("$self->{prefix}/$self->{author}");
60 "$self->{name}::$self->{dispatch}"->new(_top => $self);
62 @_ = ($class, _self => $self);
63 goto &{"$self->{name}::import"};
66 *{$self->_caller . "::AUTOLOAD"} = $self->autoload;
69 # Unregister loader and worker packages so subdirs can use them again
70 delete $INC{"$self->{file}"};
71 delete $INC{"$self->{path}.pm"};
77 unless ( $self->{extentions} ) {
78 $self->load_extensions(
79 "$self->{prefix}/$self->{path}", $self
83 my @exts = @{$self->{extensions}};
85 my $admin = $self->{admin};
86 @exts = $admin->load_all_extensions;
90 foreach my $obj ( @exts ) {
91 while (my ($method, $glob) = each %{ref($obj) . '::'}) {
92 next unless defined *{$glob}{CODE};
93 next if $method =~ /^_/;
94 next if $method eq uc($method);
95 $seen_method{$method}++;
99 my $caller = $self->_caller;
100 foreach my $name (sort keys %seen_method) {
101 *{"${caller}::$name"} = sub {
102 ${"${caller}::AUTOLOAD"} = "${caller}::$name";
103 goto &{"${caller}::AUTOLOAD"};
109 my ($class, %args) = @_;
111 # ignore the prefix on extension modules built from top level.
112 my $base_path = Cwd::abs_path($FindBin::Bin);
113 unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
114 delete $args{prefix};
117 return $args{_self} if $args{_self};
119 $args{dispatch} ||= 'Admin';
120 $args{prefix} ||= 'inc';
121 $args{author} ||= '.author';
122 $args{bundle} ||= 'inc/BUNDLES';
123 $args{base} ||= $base_path;
125 $class =~ s/^\Q$args{prefix}\E:://;
126 $args{name} ||= $class;
127 $args{version} ||= $class->VERSION;
129 unless ($args{path}) {
130 $args{path} = $args{name};
131 $args{path} =~ s!::!/!g;
133 $args{file} ||= "$args{base}/$args{prefix}/$args{path}.pm";
135 bless(\%args, $class);
141 my $obj = $self->load($method) or return;
144 goto &{$obj->can($method)};
148 my ($self, $method) = @_;
150 $self->load_extensions(
151 "$self->{prefix}/$self->{path}", $self
152 ) unless $self->{extensions};
154 foreach my $obj (@{$self->{extensions}}) {
155 return $obj if $obj->can($method);
158 my $admin = $self->{admin} or die <<"END_DIE";
159 The '$method' method does not exist in the '$self->{prefix}' path!
160 Please remove the '$self->{prefix}' directory and run $0 again to load it.
163 my $obj = $admin->load($method, 1);
164 push @{$self->{extensions}}, $obj;
169 sub load_extensions {
170 my ($self, $path, $top_obj) = @_;
172 unshift @INC, $self->{prefix}
173 unless grep { $_ eq $self->{prefix} } @INC;
175 local @INC = ($path, @INC);
176 foreach my $rv ($self->find_extensions($path)) {
177 my ($file, $pkg) = @{$rv};
178 next if $self->{pathnames}{$pkg};
181 my $new = eval { require $file; $pkg->can('new') };
186 $self->{pathnames}{$pkg} = delete $INC{$file};
187 push @{$self->{extensions}}, &{$new}($pkg, _top => $top_obj );
190 $self->{extensions} ||= [];
193 sub find_extensions {
194 my ($self, $path) = @_;
197 File::Find::find( sub {
198 my $file = $File::Find::name;
199 return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
200 return if $1 eq $self->{dispatch};
202 $file = "$self->{path}/$1.pm";
203 my $pkg = "$self->{name}::$1"; $pkg =~ s!/!::!g;
204 push @found, [ $file, $pkg ];
205 }, $path ) if -d $path;
212 my $caller = caller($depth);
214 while ($caller eq __PACKAGE__) {
216 $caller = caller($depth);