use strict;
use Spoon::Base '-Base';
const class_id => 'installer';
const extract_to => '.';
sub compress_from {
$self->extract_to;
}
sub extract_files {
my @files = $self->get_packed_files;
while (@files) {
my ($file_name, $file_contents) = splice(@files, 0, 2);
my $file_path = join '/', $self->extract_to, $file_name;
$self->set_file_content($file_path, $file_contents);
}
}
sub set_file_content {
my $path = shift;
my $content = shift;
$content = $self->base64_decode($content)
if $path =~ /\.(gif|jpg|png)$/;
$content = $self->fix_hashbang($content)
if $path =~ /\.(pl|cgi)$/;
io($path)->assert->print($content);
}
sub fix_hashbang {
require Config;
my $content = shift;
$content =~ s/^#!.*\n/$Config::Config{startperl} -w\n/;
return $content;
}
sub get_packed_files {
my @files = split /^__(.+)__\n/m, $self->data;
shift @files;
return @files;
}
sub data {
my $package = ref($self);
local $/;
my $data = eval "package $package; <DATA>";
die $@ if $@;
die "No DATA section found for $package."
unless $data;
return $data;
}
sub compress_files {
require File::Spec;
my $source_dir = shift;
my $new_pack = '';
my @files = $self->get_packed_files;
my $first_file = $files[0]
or return;
my $directory = $self->compress_from;
while (@files) {
my ($file_name, $file_contents) = splice(@files, 0, 2);
my $source_path =
File::Spec->canonpath("$source_dir/$directory/$file_name");
die "$file_name does not exist as $source_path"
unless -f $source_path;
my $content = $self->get_file_content($source_path);
$new_pack .= "__${file_name}__\n$content";
}
my $module = ref($self) . '.pm';
$module =~ s/::/\//g;
my $module_path = $INC{$module} or die;
my $module_text = io($module_path)->scalar;
my ($module_code) = split /^__\Q$first_file\E__\n/m, $module_text;
($module_code . $new_pack) > io($module_path);
}
sub get_file_content {
my $path = shift;
my $content = io($path)->scalar;
$content = $self->base64_encode($content)
if $path =~ /\.(gif|jpg|png)$/;
$content = $self->unfix_hashbang($content)
if $path =~ /\.(pl|cgi)$/;
$content .= "\n"
unless $content =~ /\n\z/;
return $content;
}
sub unfix_hashbang {
my $content = shift;
$content =~ s/^#!.*\n/#!\/usr\/bin\/perl\n/;
return $content;
}
sub compress_lib {
die "Must be run from the module source code directory\n"
unless -d "lib";
my $source_dir = shift
or die "No source directory specified\n";
die "Invalid source directory '$source_dir'\n"
unless -d $source_dir;
map {
my $class_name = $_;
my $class_id = $class_name->class_id;
$self->hub->config->add_config(
+{ "${class_id}_class" => $class_name }
);
warn "Compressing $class_name\n";
$self->hub->load_class($class_id)->compress_files($source_dir);
}
grep {
my $name = $_;
eval "require $name";
UNIVERSAL::isa($name, 'Spoon::Installer')
and $name !~ /::(Installer|Theme)$/; #XXX
} map {
my $name = $_->name;
$name =~ s/^lib\/(.*)\.pm$/$1/;
$name =~ s/\//::/g;
$name;
} io('lib')->All_Files;
}
1;
__END__
=head1 NAME
Spoon::Installer - Spoon Installer Class
=head1 SYNOPSIS
=head1 DESCRIPTION
=head1 AUTHOR
Brian Ingerson <INGY@cpan.org>
=head1 COPYRIGHT
Copyright (c) 2004. Brian Ingerson. All rights reserved.
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=cut