#!/usr/bin/perl
my
$apps
= [
];
$EUID
== 0 or croak
"You will have better luck if you run me as root.\n"
;
my
@failed
;
foreach
(
@$apps
) {
my
$name
=
$_
->{app} or croak
'missing app name'
;
install_app(
$name
,
$_
->{info} );
};
foreach
( get_perl_modules() ) {
my
$module
=
$_
->{module} or croak
'missing module name'
;
my
$info
=
$_
->{info};
my
$version
=
$info
->{version} ||
''
;
print
"checking for $module $version\n"
;
eval
"use $module $version"
;
next
if
!
$EVAL_ERROR
;
next
if
$info
->{ships_with} &&
$info
->{ships_with} eq
'perl'
;
install_module(
$module
,
$info
,
$version
);
eval
"use $module $version"
;
if
(
$EVAL_ERROR
) {
push
@failed
,
$module
;
}
}
if
(
scalar
@failed
> 0 ) {
print
"The following modules failed installation:\n"
;
print
join
(
"\n"
,
@failed
);
print
"\n"
;
}
exit
;
sub
get_perl_modules {
if
( -f
'dist.ini'
) {
return
get_perl_modules_from_ini();
};
if
( -f
'Makefile.PL'
) {
return
get_perl_modules_from_Makefile_PL();
};
croak
"unable to find module list. Run this script in the dist dir\n"
;
};
sub
get_perl_modules_from_Makefile_PL {
my
$fh
= new IO::File
'Makefile.PL'
,
'r'
or croak
"unable to read Makefile.PL\n"
;
my
$in
= 0;
my
@modules
;
while
(
my
$line
= <
$fh
> ) {
if
(
$line
=~ /PREREQ_PM/ ) {
$in
++;
next
;
};
next
if
!
$in
;
last
if
$line
=~ /}/;
next
if
$line
!~ /=/;
my
(
$mod
,
$ver
) =
split
/\s*=\s*/,
$line
;
$mod
=~ s/[\s'"\
next
if
!
$mod
;
push
@modules
, name_overrides(
$mod
);
}
$fh
->
close
;
return
@modules
;
};
sub
get_perl_modules_from_ini {
my
$fh
= new IO::File (
'dist.ini'
,
'r'
)
or croak
"unable to read dist.ini\n"
;
my
$in
= 0;
my
@modules
;
while
(
my
$line
= <
$fh
> ) {
if
(
'[Prereqs]'
eq
substr
(
$line
,0,9) ) {
$in
++;
next
;
};
next
if
!
$in
;
last
if
'['
eq
substr
(
$line
,0,1);
my
(
$mod
,
$ver
) =
split
/\s*=\s*/,
$line
;
$mod
=~ s/\s*//g;
$mod
=~ s/^;//g;
next
if
!
$mod
|| !
defined
$ver
;
push
@modules
, name_overrides(
$mod
);
}
$fh
->
close
;
return
@modules
;
};
sub
install_app {
my
(
$app
,
$info
) =
@_
;
return
install_app_darwin(
$app
,
$info
)
if
lc
(
$OSNAME
) eq
'darwin'
;
return
install_app_freebsd(
$app
,
$info
)
if
lc
(
$OSNAME
) eq
'freebsd'
;
return
install_app_linux(
$app
,
$info
)
if
lc
(
$OSNAME
) eq
'linux'
;
return
;
};
sub
install_app_darwin {
my
(
$app
,
$info
) =
@_
;
my
$port
=
$info
->{dport} ||
$info
->{port} ||
$app
;
if
( ! -x
'/opt/local/bin/port'
) {
print
"MacPorts is not installed! Consider installing it.\n"
;
return
;
}
system
"/opt/local/bin/port install $port"
and carp
"install failed for Darwin port $port"
;
return
;
}
sub
install_app_freebsd {
my
(
$app
,
$info
) =
@_
;
print
" from ports..."
;
my
$name
=
$info
->{port} ||
$app
;
return
if
is_freebsd_port_installed(
$name
,
$app
);
print
"installing $app"
;
my
$category
=
$info
->{category} ||
'*'
;
my
(
$portdir
) =
glob
"/usr/ports/$category/$name"
;
if
(
$portdir
&& -d
$portdir
&&
chdir
$portdir
) {
print
" from ports ($portdir)\n"
;
system
"make install clean"
and carp
"'make install clean' failed for port $app\n"
;
};
return
;
};
sub
install_app_linux {
my
(
$app
,
$info
) =
@_
;
if
( -x
'/usr/bin/yum'
) {
my
$rpm
=
$info
->{yum} ||
$app
;
return
system
"/usr/bin/yum -y install $rpm"
;
}
if
( -x
'/usr/bin/apt-get'
) {
my
$package
=
$info
->{apt} ||
$app
;
return
system
"/usr/bin/apt-get -y install $package"
;
}
carp
"no Linux package manager detected\n"
;
return
;
};
sub
install_module {
my
(
$module
,
$info
,
$version
) =
@_
;
return
install_module_darwin(
$module
,
$info
,
$version
)
if
lc
(
$OSNAME
) eq
'darwin'
;
return
install_module_freebsd(
$module
,
$info
,
$version
)
if
lc
(
$OSNAME
) eq
'freebsd'
;
return
install_module_linux(
$module
,
$info
,
$version
)
if
lc
(
$OSNAME
) eq
'linux'
;
eval
"require $module"
;
return
1
if
!
$EVAL_ERROR
;
return
install_module_cpan(
$module
,
$version
);
};
sub
install_module_cpan {
my
(
$module
,
$version
) =
@_
;
print
" from CPAN..."
;
sleep
1;
local
$ENV
{FTP_PASSIVE} = 1;
$CPAN::Config
= get_cpan_config();
if
(
$module
eq
'Provision::Unix'
&&
$version
) {
$module
=~ s/\:\:/\-/g;
$module
=
"M/MS/MSIMERSON/$module-$version.tar.gz"
;
}
return
CPAN::Shell->install(
$module
);
}
sub
install_module_darwin {
my
(
$module
,
$info
,
$version
) =
@_
;
my
$dport
=
'/opt/local/bin/port'
;
if
( ! -x
$dport
) {
print
"MacPorts is not installed! Consider installing it.\n"
;
return
;
}
my
$port
=
"p5-$module"
;
$port
=~ s/::/-/g;
system
"$dport install $port"
and carp
"install failed for Darwin port $module"
;
return
;
}
sub
install_module_freebsd {
my
(
$module
,
$info
,
$version
) =
@_
;
my
$name
=
$info
->{port} ||
$module
;
my
$portname
=
"p5-$name"
;
$portname
=~ s/::/-/g;
print
" from ports...$portname..."
;
return
if
is_freebsd_port_installed(
$portname
,
$module
);
print
"installing $module ..."
;
my
$category
=
$info
->{category} ||
'*'
;
my
(
$portdir
) =
glob
"/usr/ports/$category/$portname"
;
if
( !
$portdir
|| ! -d
$portdir
) {
print
"oops, no match at /usr/ports/$category/$portname\n"
;
return
;
};
if
( !
chdir
$portdir
) {
print
"unable to cd to /usr/ports/$category/$portname\n"
;
};
print
" from ports ($portdir)\n"
;
system
"make install clean"
and carp
"'make install clean' failed for port $module\n"
;
return
;
}
sub
install_module_linux {
my
(
$module
,
$info
,
$version
) =
@_
;
my
$package
;
if
( -x
'/usr/bin/yum'
) {
return
install_module_linux_yum(
$module
,
$info
);
}
elsif
( -x
'/usr/bin/apt-get'
) {
return
install_module_linux_apt(
$module
,
$info
);
}
carp
"no Linux package manager detected\n"
;
return
;
};
sub
install_module_linux_yum {
my
(
$module
,
$info
) =
@_
;
my
$package
;
if
(
$info
->{yum} ) {
$package
=
$info
->{yum};
}
else
{
$package
=
"perl-$module"
;
$package
=~ s/::/-/g;
};
return
system
"/usr/bin/yum -y install $package"
;
};
sub
install_module_linux_apt {
my
(
$module
,
$info
) =
@_
;
my
$package
;
if
(
$info
->{apt} ) {
$package
=
$info
->{apt};
}
else
{
$package
=
'lib'
.
$module
.
'-perl'
;
$package
=~ s/::/-/g;
};
return
system
"/usr/bin/apt-get -y install $package"
;
};
sub
is_freebsd_port_installed {
my
(
$portname
,
$display_name
) =
@_
;
$display_name
||=
$portname
;
if
(
grep
{/
$portname
/x} `/usr/sbin/pkg_info` ) {
return
print
"$display_name is installed.\n"
;
}
if
( `/usr/sbin/pkg info -x
$portname
` ) {
return
print
"$display_name is installed.\n"
;
}
return
0;
};
sub
get_cpan_config {
my
$ftp
= `which ftp`;
chomp
$ftp
;
my
$gzip
= `which gzip`;
chomp
$gzip
;
my
$unzip
= `which unzip`;
chomp
$unzip
;
my
$tar
= `which tar`;
chomp
$tar
;
my
$make
= `which make`;
chomp
$make
;
my
$wget
= `which wget`;
chomp
$wget
;
return
{
'build_cache'
=>
q[10]
,
'build_dir'
=>
qq[$ENV{HOME}/.cpan/build]
,
'cache_metadata'
=>
q[1]
,
'cpan_home'
=>
qq[$ENV{HOME}/.cpan]
,
'ftp'
=>
$ftp
,
'ftp_proxy'
=>
q[]
,
'getcwd'
=>
q[cwd]
,
'gpg'
=>
q[]
,
'gzip'
=>
$gzip
,
'histfile'
=>
qq[$ENV{HOME}/.cpan/histfile]
,
'histsize'
=>
q[100]
,
'http_proxy'
=>
q[]
,
'inactivity_timeout'
=>
q[5]
,
'index_expire'
=>
q[1]
,
'inhibit_startup_message'
=>
q[1]
,
'keep_source_where'
=>
qq[$ENV{HOME}/.cpan/sources]
,
'lynx'
=>
q[]
,
'make'
=>
$make
,
'make_arg'
=>
q[]
,
'make_install_arg'
=>
q[]
,
'makepl_arg'
=>
q[]
,
'ncftp'
=>
q[]
,
'ncftpget'
=>
q[]
,
'no_proxy'
=>
q[]
,
'pager'
=>
q[less]
,
'prerequisites_policy'
=>
q[follow]
,
'scan_cache'
=>
q[atstart]
,
'shell'
=>
q[/bin/csh]
,
'tar'
=>
$tar
,
'term_is_latin'
=>
q[1]
,
'unzip'
=>
$unzip
,
'wget'
=>
$wget
, };
}
sub
name_overrides {
my
$mod
=
shift
;
my
@modules
= (
{
module
=>
'LWP::UserAgent'
,
info
=> {
cat
=>
'www'
,
port
=>
'p5-libwww'
,
dport
=>
'p5-libwww-perl'
}, },
{
module
=>
'Mail::Send'
,
info
=> {
port
=>
'Mail::Tools'
, } },
);
my
(
$match
) =
grep
{
$_
->{module} eq
$mod
}
@modules
;
return
$match
if
$match
;
return
{
module
=>
$mod
,
info
=> { } };
};