-
Notifications
You must be signed in to change notification settings - Fork 0
/
install_cpan_modules_required.pl
executable file
·225 lines (210 loc) · 7.39 KB
/
install_cpan_modules_required.pl
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
#!/usr/bin/env perl
##
# Module installer for projects.
# Run this script from any Project directory containing perl modules or scripts.
##
use warnings; use strict;
###
# Prerequisites for this script itself. Run first:
# cpan Term::ReadKey;
# cpan Term::ANSIColor;
## no critic (ProhibitStringyEval)
use Term::ReadKey;
use Term::ANSIColor qw(:constants);
use constant PERL_FILES_GLOB => "*local/*.pl local/*.pm system/modules/*.pm htdocs/cgi-bin/*.cgi htdocs/cgi-bin/system/modules/*.pm tests/*.pm tests/*.pl .pl *.pm *.cgi";
my $project = `pwd`."/".$0; $project =~ s/\/.*.pl$//g; $project =~ s/\s$//g;
my @user_glob;
our $PERL_VERSION = $^V->{'original'}; my $ERR = 0; my $key;
print WHITE "\n *** Project Perl Module Installer coded by ",BRIGHT_RED, "https://github.com/wbudic", WHITE,"***", qq(
\nRunning scan on project path:$project
\nYou have Perl on $^O [$^X] version: $PERL_VERSION\n
);
print BLUE "<<@<\@INC<\n# Your default module package paths:\n", YELLOW;
local $. = 0; foreach(@INC){
print $.++.".: $_\n";
}
print BLUE ">>\n", RESET;
if($> > 0){
print "You are NOT installing system wide, which is required for webservers CGI.\nAre you sure about this?\n";
print "Tip -> If you are getting web page errors of some modules missing, try runing this utility as sudo.\n";
}else{
print "You are INSTALLING modules SYSTEM WIDE, are you sure about this?\n"
}
if(@ARGV==0){
print qq(\nThis program will try to figure out now all the modules
required for this project, and install them if missing.
This can take some time.
);
print RED "Do you want to proceed (press either the 'Y'es or 'N'o key)?", RESET;
do{
ReadMode('cbreak');
$key = ReadKey(0); print "\n";
ReadMode('normal');
exit 1 if(uc $key eq 'N');
$key = "[ENTER]" if $key =~ /\n/;
print "You have pressed the '$key' key, that is nice, but why?\nOnly the CTRL+C/Y/N keys do something normal." if uc $key ne 'Y';
}while(uc $key ne 'Y');
}
else{
foreach(@ARGV){
if(-d $_){
$_ =~ s/\s$//g;
print "\nGlobing for perl files in $project/$_";
my @located = glob("$_/*.pl $_/*.pm");
print " ... found ".@located." files.";
push @user_glob, @located;
}else{
warn "Argument: $_ is not a local directory."
}
}
}
my @locals=();
print "\nGlobing for perl modules in project $project";
my @perl_files = glob(PERL_FILES_GLOB);
print " ... found ".@perl_files." files.\n";
push @perl_files, @user_glob;
my %modules; my %localPackages;
foreach my $file(@perl_files){
next if $0 =~ /$file$/;
if($file =~ /(\w*)\.pm$/){
$localPackages{$1}=$file;
}
print "\nExamining:$file\n";
my $res = `perl -ne '/\\s*(^use\\s([a-zA-Z:]*))\\W/ and print "\$2;"' $file`;
my @list = split(/;+/,$res);
foreach(@list){
if($_=~ /^\w\d\.\d+.*/){
print "\tA specified 'use $_' found in ->$file\n";
if($PERL_VERSION ne $_){
$_ =~s/^v//g;
my @fv = split(/\./, $_);
$PERL_VERSION =~s/^v//g;
my @pv = split(/\./, $PERL_VERSION);
push @fv, 0 if @fv < 3;
for my$i(0..$#fv){
if( $pv[$i] < $fv[$i] ){
$ERR++; print "\n\t\033[31mERROR -> Perl required version has been found not matching.\033[0m\n";
last
}
}
}
}
}
foreach(@list){
$_ =~ s/^\s*|\s*use\s*//g;
$_ =~ s/[\'\"].*[\'\"]$//g;
next if !$_ or $_ =~ /^[a-z]|\d*\.\d*$|^\W/;
$_ =~ s/\(\)|\(.*\)|qw\(.*\)//g;
$modules{$_}=$file if $_;
print "$_\n";
}
if($file=~/\.pm$/){# it is presumed local package module.
$locals[@locals] = `perl -ne '/\\s*(^package\\s(\\w+))/ and print "\$2" and exit' $file`;
}
}
print WHITE "\nList of Modules required for thie project:\n";
my @missing=();
foreach my $mod (sort keys %modules){
my $missing;
eval "use $mod";
if ($@){
$missing[@missing] = $mod;
print MAGENTA "\t$mod \t in ", $modules{$mod}," is suspicious?\n";
}else{
print BLUE "\t$mod\n"
}
}foreach(@missing){
if(exists $localPackages{$_}){
delete $modules{$_}
}else{
print BRIGHT_RED $_, MAGENTA, " is missing!\n"
}
}
my %skip_candidates;
my $missing_count = @missing;
if($missing_count>0){
foreach my $candidate(@missing){
foreach(@locals){
if($_ eq $candidate && not exists $skip_candidates{$_}){
$missing_count--;
$skip_candidates{$_} = 1;
print GREEN, "Found the missing $candidate module in locals.\n"
}
}
}
}
my $perls = `whereis perl`;
print GREEN, "Following is all of ",$perls;
print YELLOW, "Reminder -> Make sure you switched to the right brew release.\n" if $perls =~ /perlbrew/;
print RESET, "Number of local modules:",scalar(@locals),"\n";
print RESET, "Number of external modules:",scalar(keys %modules),"\n";
print RESET, "Number of cpan modules about to be tried to install:",$missing_count,"\n";
print GREEN, qq(
Do you still want to continue to compile/test/install or check further modules?
Only the first run is the depest and can take a long time, i.e. if you have to install over 5 modules.
At other times this will only check further your current status.
Now (press either the 'Y'es or 'N'o key) please?), RESET;
do{
ReadMode('cbreak');
$key = ReadKey(0); print "\n";
ReadMode('normal');
exit 1 if(uc $key eq 'N');
$key = "[ENTER]" if $key =~ /\n/;
print "You have pressed the '$key' key, that is nice, but why?\nOnly the CTRL+C/Y/N keys do something normal.\n" if uc $key ne 'Y';
}while(uc $key ne 'Y');
my ($mcnt,$mins) = (0,0);
my @kangaroos = sort keys %skip_candidates;
##
# Some modules if found to be forcefeed. can be hardcoded here my friends, why not?
# You got plenty of space on your disc, these days, don't you?
##
foreach (('lib::relative,',
'Syntax::Keyword::Try',
'DBD::SQLite',
'DBD::Pg',
'LWP::Simple',
'LWP::Protocol::https',
'XML::LibXML::SAX'
)){
$modules{$_}=1; print "Forcefeed: $_\n"
}
MODULES_LOOP:
foreach my $mod (sort keys %modules){
foreach(@kangaroos){
if($_ eq $mod){
next MODULES_LOOP
}
}
$mcnt++;
## no critic (ProhibitStringyEval)
eval "use $mod";
if ($@) {
system(qq(perl -MCPAN -e 'install $mod'));
if ($? == -1) {
print "failed to install: $mod\n";
}else{
my $v = eval "\$$mod\::VERSION";
$v = $v ? "(v$v)" : "";
print "Installed module $mod $v!\n";
$mins++
}
}else{
$mod =~ s/\s*$//;
my $v = eval "\$$mod\::VERSION";
$v = $v ? "(v$v)" : "";
print "Skipping module $mod $v, already installed!\n";
}
}
print "\nProject $project\nRequires $mcnt modules.\nInstalled New: $mins\n";
print "WARNING! - This project requires in ($ERR) parts code that might not be compatible yet with your installed/running version of perl (v$PERL_VERSION).\n"
if $ERR;
=begin copyright
Programed by : Will Budic
EContactHash : 990MWWLWM8C2MI8K (https://github.com/wbudic/EContactHash.md)
Source : https://github.com/wbudic/PerlCNF.git
Documentation : Specifications_For_CNF_ReadMe.md
This source file is copied and usually placed in a local directory, outside of its repository project.
So it could not be the actual or current version, can vary or has been modiefied for what ever purpose in another project.
Please leave source of origin in this file for future references.
Open Source Code License -> https://github.com/wbudic/PerlCNF/blob/master/ISC_License.md
=cut copyright