-
Notifications
You must be signed in to change notification settings - Fork 1
/
install_prereqs
executable file
·310 lines (231 loc) · 8.75 KB
/
install_prereqs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
#!/usr/bin/perl -I./
# install prerequisites from CPAN without configuring CPAN
=for Copyright
.
Copyright (c) 2007-2008 Bruce Ravel (bravel AT bnl DOT gov).
All rights reserved.
.
This file is free software; you can redistribute it and/or
modify it under the same terms as Perl itself. See The Perl
Artistic License.
.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
=cut
use strict;
use warnings;
use CPAN;
use Cwd qw(cwd);
use Getopt::Long;
use File::Copy;
use File::Spec;
use Pod::Text;
BEGIN {
## overload any existing CPAN configuration with one "guaranteed" to work
unshift @INC, "./";
$ENV{__INSTALLING_BRPERL} = cwd();
unshift @INC, "./CPAN";
require MyConfig;
}
my $bundir = File::Spec->catfile(cwd, "Bundle/");
opendir(my $BUNDLE, $bundir) or die "could not open directory $bundir for reading";
my @files = grep {/pm$/} readdir $BUNDLE;
closedir $BUNDLE;
my $this_package = q{};
foreach my $f (@files) {
($this_package = $1), last if ($f =~ m{(\w*)Bundle\.pm});
};
my ($noforce, $help, $quickhelp, $system, $query, $copy, $proxy, $bundle) =
(0, 0, 0, 0, 0, 0, q{}, "Bundle::".$this_package."Bundle");
GetOptions("noforce" => \$noforce, "n" => \$noforce,
"bundle=s" => \$bundle,
"proxy=s" => \$proxy, # q[192.168.1.140:3128] at BNL
"system" => \$system, "s" => \$system,
"query" => \$query, "q" => \$query,
"help" => \$help, "h" => \$quickhelp,
"c" => \$copy,
);
## small chores then exit
copyem(), exit if $copy;
quickhelp(), exit if $quickhelp;
Pod::Text -> new(sentence => 0, width => 78) -> parse_from_file($0), exit if $help;
## remove the overloaded CPAN configuration and import the normal one
if ($system) {
shift @INC;
require CPAN::Config;
import CPAN::Config;
};
banner("CPAN working directory:" . $CPAN::Config->{cpan_home});
# print join($/, @INC), $/;
# exit;
## specify a proxy server
if ($proxy) {
$CPAN::Config->{http_proxy} = $proxy;
$CPAN::Config->{ftp_proxy} = $proxy;
};
my @modlist = bundle_list($bundle);
foreach my $mod (@modlist) {
my @mm = CPAN::Shell->expand("Module", "/\^$mod\$/");
if (not defined($mm[0])) {
banner("Cannot determine version number for $mod: forcing install");
CPAN::Shell->force("install", $mod) if (not $query);
} elsif (not defined($mm[0]->inst_version)) {
banner("$mod not installed: forcing install");
CPAN::Shell->force("install", $mod) if (not $query);
} elsif ($mm[0]->inst_version eq 'undef') {
banner("Cannot determine version number for $mod: forcing install");
CPAN::Shell->force("install", $mod) if (not $query);
} elsif ($mm[0]->inst_version lt $mm[0]->cpan_version) {
if ($noforce) {
banner(sprintf("Upgrade required for %s from %s to %s: installing",
$mod, $mm[0]->inst_version, $mm[0]->cpan_version));
CPAN::Shell->install($mod) if (not $query);
} else {
banner(sprintf("Upgrade required for %s from %s to %s: forcing install",
$mod, $mm[0]->inst_version, $mm[0]->cpan_version));
CPAN::Shell->force("install", $mod) if (not $query);
};
} else {
banner(sprintf("Module %s is up to date at version %s", $mod, $mm[0]->inst_version));
};
};
# if ($force) {
# CPAN::Shell->force("install", $bundle);
# } else {
# CPAN::Shell->upgrade($bundle);
# };
sub bundle_list {
my $thisbundle = $_[0] || $bundle;
$thisbundle =~ s{::}{/};
($thisbundle .= '.pm') if ($thisbundle !~ m{\.pm\z});
banner("Reading $thisbundle");
## snarf modules from the CONTENTS section
my ($flag, @modlist) = (0, ());
open(my $BUN, $thisbundle) or die "could not find $thisbundle\n";
while (<$BUN>) {
$flag = 1, next if (m{=head1\s+CONTENTS});
$flag = 0, next if (m{=head1});
next if not $flag;
next if (m{^\s*$});
chomp;
push @modlist, $_;
};
close $BUN;
return @modlist;
};
sub vnum {
my ($v) = @_;
my @parts = split(/\./, $v);
$parts[2] ||= 0;
return sprintf("%d.%3.3d%3.3d", @parts);
};
sub banner {
my ($string) = @_;
my $l = length($string) + 2;
my $sep = "+" . "=" x $l . "+" . $/;
print $/,
$sep,
"| $string |$/",
$sep;
};
sub quickhelp {
print "
install_prereqs : use CPAN to download and install all of the prerequisites for the
$this_package package
--noforce, -n do not force installation when \"make test\" fails
--proxy=<URL:PORT> specify a proxy server and port (for instance, at Brookhaven,
the proxy is \"192.168.1.140:3128\")
--system, -s use your system-wide CPAN configuration
--query, -q query about which modules need to be updated
--bundle=<bundle> specify a prerequisite Bundle (default = Bundle/${this_package}Bundle.pm)
-h short help message
--help long help message
"
};
sub copyem {
print "!!! HEY !!! This is for maintenance on Bruce's computers. Do you really need to be here?\n";
foreach my $place (qw(horae demeter aug libperlxray)) {
next if (cwd =~ m{$place});
print " copying to $place ... ";
my $ok = copy($0, "../$place/install_prereqs");
($ok) ? print "ok\n" : print "failed\n";
};
};
=head1 NAME
install_prereqs - install prerequisites from CPAN without configuring CPAN
=head1 SYNOPSIS
This script automates the installation of the prerequisites for Bruce
Ravel's XAS-related software efforts, including:
=over 4
=item I<Horae>
Athena, Artemis, and Hephaestus
=item I<Demeter>
Perl tools for writing Ifeffit-based programs
=item I<libperlxray>
The Xray::Absorption, Xray::Scattering, Chemistry::Formula, and Ifeffit modules
=item I<The Athena User's Guide>
Use the L<Template Toolkit|http://template-toolkit.org/> to generate documentation as html, PDF, and
pod.
=back
=head1 USAGE
This script almost certainly needs to be run as root or using sudo, as
in
sudo install_prereqs
See below for descriptions of the command line options.
=head1 DESCRIPTION
Configuring CPAN is a hassle for the experienced and flumoxing for
everyone else. Nonetheless, using CPAN to install prerequisites is
desirable. It is the best way to guarantee that the user ends up with
the latest and greatest versions of the Perl modules that the various
software packages depend upon.
To address this, each of Bruce's packages ships with this script along
with a Bundle file defining the list of required modules and a CPAN
configuration file which uses the current working directory to build
the files and C<http://www.perl.com/CPAN/> as the download source.
These are found in the F<Bundle/> and F<CPAN/> folders.
For those who have already configured CPAN in the normal, the use of
the configuration file that comes with this script can be overridden
by the C<--system> flag. Most people should be happy with the CPAN
configuration that comes with the package.
This script attempts to avoid installing modules that are up to date.
It's not always successful in determining versioning, so it errs on
the side of installing.
For those behind a proxy, the proxy can be specified from the command
line. For instance, those at Brookhaven National Laboratory will want
to use C<--proxy=192.168.1.140:3128> at the command line.
=head1 COMMAND LINE OPTIONS
=over 4
=item C<--noforce>, C<-n>
Do not force the installation of any modules. That is, do not install
modules when the "make test" stage fails. The default is to force
installation even in the event of test failures.
=item C<--proxy=URL:PORT>
Specify a proxy server and port. For instance, at Brookhaven, the
proxy is "192.168.1.130:3128".
=item C<--query>, C<-q>
Query about which modules will be updated, reporting to the screen
what would be done, but do not actually install anything.
=item C<--system>, C<-s>
Use your system-wide CPAN configuration. This is appropriate for
someone who has already configured CPAN for his computer, presumably
using a fast, geographically close CPAN mirror and other local
configurations.
=item C<--bundle=/path/to/BundleFile.pm>
Specify a prerequisite Bundle other than the default which ships with
the package.
=item C<--help>
Write this POD to STDOUT.
=item C<-h>
Show a quick summary of command line options.
=back
=head1 COPYRIGHT
Copyright (c) 2007-2008 Bruce Ravel (bravel AT bnl DOT gov).
All rights reserved.
This file is free software; you can redistribute it and/or
modify it under the same terms as Perl itself. See The Perl
Artistic License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
=cut