more, better tests for the new implementation for tree/bootstrap -- still some things...
[bioperl-run.git] / scripts / bioperl_application_installer.PLS
blob8c1cd99cbdb4afec949d7b472996f4b66931cb89
1 #!/usr/local/bin/perl
2 # BioPerl script for Bio::Installer
4 # Cared for by Albert Vilella <avilella@ebi.ac.uk, avilella@ub.edu>
6 # based on the CPAN::FirstTime module
8 # Copyright Albert Vilella
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
14 =head1 NAME
16 bioperl_application_installer - downloads and installs runnables
18 =head1 SYNOPSIS
20 bioperl_application_installer
22 =head1 DESCRIPTION
24 This script will ask the user which programs wants to install and
25 where. It will download the packages, decompress them (if necessary)
26 and compile/install them in the specified directory.
28 =head1 AUTHOR
30 Albert Vilella, avilella-AT-ebi-DOT-ac-DOT-uk,avilella-AT-ub-DOT-edu
32 =head1 TODO
34 Check if the programs are already installed in the computer and prompt
35 it so that the user is at least aware of it.
37 Check for the available installers, instead of hard-coding
38 $INSTALLERLIST in this script.
40 =cut
42 use strict;
43 use ExtUtils::MakeMaker;
44 use Data::Dumper;
45 use Bio::Factory::ObjectFactory;
47 use vars qw($DEFAULT $CONFIG $INSTALLERLIST);
49 BEGIN {
50 $DEFAULT = 'bioperl-runnables';
51 $INSTALLERLIST = [
52 'Clustalw',
53 'EMBOSS',
54 'TCoffee',
55 'PAML',
59 my $dir = shift @ARGV || $DEFAULT;
60 init($dir);
65 ################################################################################
67 sub init {
68 my($configpm) = @_;
69 use Config;
70 local($/) = "\n";
71 local($\) = "";
72 local($|) = 1;
74 my($ans,$default);
77 # Files, directories
80 print qq[
82 This script will install the runnable programs associated with
83 bioperl-run.
85 Bioperl-run contain modules that provides a PERL interface to various
86 bioinformatics applications. This allows various applications to be
87 used with common bioperl objects.
89 If you do not want to enter a dialog now, you can answer 'no' to this
90 question.
94 my $manual_conf =
95 ExtUtils::MakeMaker::prompt("Are you ready for manual configuration?",
96 "yes");
97 my $fastread;
99 local $^W;
100 if ($manual_conf =~ /^\s*y/i) {
101 $fastread = 0;
102 *prompt = \&ExtUtils::MakeMaker::prompt;
103 } else {
104 print "Done.\n\n";
105 exit;
108 print qq{
110 The following questions are intended to help you with the
111 installation.
115 $default = File::Spec->catdir( $ENV{'HOME'}, $configpm);
116 while ($ans = prompt("Where do you want to install the runnables in your computer?",$default)) {
117 unless (File::Spec->file_name_is_absolute($ans)) {
118 require Cwd;
119 my $cwd = Cwd::cwd();
120 my $absans = File::Spec->catdir($cwd,$ans);
121 warn "The path '$ans' is not an absolute path. Please specify an absolute path\n";
122 $default = $absans;
123 next;
125 eval { File::Path::mkpath($ans); }; # dies if it can't
126 if ($@) {
127 warn "Couldn't create directory $ans.
128 Please retry.\n";
129 next;
131 if (-d $ans && -w _) {
132 print qq{
133 Directory $ans successfully created.
137 last;
138 } else {
139 warn "Couldn't find directory $ans
140 or directory is not writable. Please retry.\n";
144 print qq{
146 The script will need a few external programs to work properly.
147 Please correct me, if I guess the wrong path for a program. Don\'t
148 panic if you do not have some of them, just press ENTER for those.
152 my $old_warn = $^W;
153 local $^W if $^O eq 'MacOS';
154 my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'};
155 local $^W = $old_warn;
156 my $progname;
157 for $progname (qw/gzip tar unzip make links wget ncftpget ncftp ftp gpg/) {
158 if ($^O eq 'MacOS') {
159 $CONFIG->{$progname} = 'not_here';
160 next;
162 my $progcall = $progname;
163 # we don't need ncftp if we have ncftpget
164 next if $progname eq "ncftp" && $CONFIG->{ncftpget} gt " ";
165 my $path = $CONFIG->{$progname}
166 || $Config::Config{$progname}
167 || "";
168 if (File::Spec->file_name_is_absolute($path)) {
169 # testing existence is not good enough, some have these exe
170 # extensions
172 # warn "Warning: configured $path does not exist\n" unless -e $path;
173 # $path = "";
174 } else {
175 $path = '';
177 unless ($path) {
178 # e.g. make -> nmake
179 $progcall = $Config::Config{$progname} if $Config::Config{$progname};
182 $path ||= find_exe($progcall,[@path]);
183 warn "Warning: $progcall not found in PATH\n" unless
184 $path; # not -e $path, because find_exe already checked that
185 $ans = prompt("Where is your $progname program?",$path) || $path;
186 $CONFIG->{$progname} = $ans;
188 my $path = $CONFIG->{'pager'} ||
189 $ENV{PAGER} || find_exe("less",[@path]) ||
190 find_exe("more",[@path]) || ($^O eq 'MacOS' ? $ENV{EDITOR} : 0 )
191 || "more";
192 $ans = prompt("What is your favorite pager program?",$path);
193 $CONFIG->{'pager'} = $ans;
194 $path = $CONFIG->{'shell'};
195 if (File::Spec->file_name_is_absolute($path)) {
196 warn "Warning: configured $path does not exist\n" unless -e $path;
197 $path = "";
199 $path ||= $ENV{SHELL};
200 if ($^O eq 'MacOS') {
201 $CONFIG->{'shell'} = 'not_here';
202 } else {
203 $path =~ s,\\,/,g if $^O eq 'os2'; # Cosmetic only
204 $ans = prompt("What is your favorite shell?",$path);
205 $CONFIG->{'shell'} = $ans;
208 print qq{
210 Which programs would you like to install?
213 my @selected_programs;
214 my $prompt = "Select the programs you would like to install (by number),
215 put them on one line, separated by blanks, e.g. '1 2 4'";
217 push (@selected_programs, @$INSTALLERLIST);
218 @selected_programs = picklist (\@selected_programs, $prompt);
219 push @{$CONFIG->{selected_programs_list}}, @selected_programs;
221 print qq{
223 The selected programs will now be installed
227 # TODO: Check for the available installers, instead of hard-coding
228 # $INSTALLERLIST in this script.
229 # my @l;
230 # for my $i (@INC) {
231 # next unless (-e $i."/My/Stuff/");
232 # opendir(X,$i."/My/Stuff")|| warn "$!";
233 # push @l,readdir(X);
236 # find sub { push(@l, $File::Find::name) if -f && /\.pm$/ },
237 # map { "$_/My/Module" } @INC;
239 foreach my $program (@selected_programs) {
240 my $type = 'Bio::Installer::' . $program;
241 my $factory = new Bio::Factory::ObjectFactory(-type => $type);
242 my $instance = $factory->create_object();
243 $instance->destination_install_dir($default);
244 $instance->download();
245 $instance->install();
251 sub picklist {
252 my($items,$prompt,$default,$require_nonempty,$empty_warning)=@_;
253 $default ||= '';
255 my $pos = 0;
257 my @nums;
258 while (1) {
260 # display, at most, 15 items at a time
261 my $limit = $#{ $items } - $pos;
262 $limit = 15 if $limit > 15;
264 # show the next $limit items, get the new position
265 $pos = display_some($items, $limit, $pos);
266 $pos = 0 if $pos >= @$items;
268 my $num = prompt($prompt,$default);
270 @nums = split (' ', $num);
271 my $i = scalar @$items;
272 (warn "invalid items entered, try again\n"), next
273 if grep (/\D/ || $_ < 1 || $_ > $i, @nums);
274 if ($require_nonempty) {
275 (warn "$empty_warning\n");
277 print "\n";
279 # a blank line continues...
280 next unless @nums;
281 last;
283 for (@nums) { $_-- }
284 @{$items}[@nums];
288 sub display_some {
289 my ($items, $limit, $pos) = @_;
290 $pos ||= 0;
292 my @displayable = @$items[$pos .. ($pos + $limit)];
293 for my $item (@displayable) {
294 printf "(%d) %s\n", ++$pos, $item;
296 printf("%d more items, hit SPACE RETURN to show them\n",
297 (@$items - $pos)
299 if $pos < @$items;
300 return $pos;
304 sub find_exe {
305 my($exe,$path) = @_;
306 my($dir);
307 #warn "in find_exe exe[$exe] path[@$path]";
308 for $dir (@$path) {
309 my $abs = File::Spec->catfile($dir,$exe);
310 if (($abs = MM->maybe_command($abs))) {
311 return $abs;