/maintenance/dependencies.pl

http://github.com/bioperl/bioperl-live · Perl · 291 lines · 216 code · 50 blank · 25 comment · 29 complexity · 0e51764e495ba35f8509feae5811c20c MD5 · raw file

  1. # $Id: dependencies.pl 10084 2006-07-04 22:23:29Z cjfields $
  2. #
  3. #!/usr/bin/perl
  4. use strict;
  5. use warnings;
  6. use File::Find;
  7. use Perl6::Form;
  8. use Getopt::Long;
  9. use Module::CoreList;
  10. use CPANPLUS::Backend;
  11. my $dep_header = <<HEADER;
  12. BioPerl Dependencies
  13. NOTE : This file was auto-generated by the helper script
  14. maintenance/dependencies.pl. Do not edit directly!
  15. The following packages are used by BioPerl. While not all are required for
  16. BioPerl to operate properly, some functionality will be missing without them.
  17. You can easily choose to install all of these during the normal installation
  18. process. Note that the PPM version of the BioPerl packages always tries to
  19. install all dependencies.
  20. The DBD::mysql, DB_File and XML::Parser modules require other applications or
  21. databases: MySQL, Berkeley DB, and expat respectively.
  22. NB: This list of packages is not authoritative. See the 'requires',
  23. 'build_requires' and 'recommends' sections of Build.PL instead.
  24. HEADER
  25. #
  26. # command line options
  27. #
  28. my ($verbose, $dir, $depfile, $help, $version, $skipbio) = (0, undef, "../DEPENDENCIES.NEW", undef, "5.006001", 0);
  29. GetOptions(
  30. 'v|verbose' => \$verbose,
  31. 'dir:s' => \$dir,
  32. 'depfile:s' => \$depfile,
  33. 'p|perl:s' => \$version,
  34. 's|skipbio' => \$skipbio,
  35. 'h|help|?' => sub{ exec('perldoc',$0); exit(0) }
  36. );
  37. # Directories to check
  38. my @dirs = qw(../Bio/ );
  39. #
  40. # run
  41. #
  42. my %dependencies;
  43. my %bp_packages;
  44. my %core = %{$Module::CoreList::version{$version}};
  45. # pragmas and BioPerl modules not in core (not required)
  46. my %SKIP = map {$_ => 1} qw(base
  47. vars
  48. warnings
  49. strict
  50. constant
  51. overload
  52. Bio::Tools::Run::Ensembl
  53. Bio::Ext::HMM
  54. );
  55. if ($dir) {
  56. find {wanted => \&parse_core, no_chdir => 1}, $dir;
  57. } else {
  58. find {wanted => \&parse_core, no_chdir => 1}, @dirs;
  59. }
  60. #
  61. # process results
  62. #
  63. for my $k (keys %dependencies) {
  64. if (exists $bp_packages{$k} || exists $core{$k}) {
  65. delete $dependencies{$k};
  66. }
  67. }
  68. my $b = CPANPLUS::Backend->new();
  69. # sort by distribution into a hash, keep track of modules
  70. my %distrib;
  71. for my $key (sort keys %dependencies) {
  72. MODULE:
  73. for my $m ($b->module_tree($key)) {
  74. if (!$m) {
  75. warn "$key not found, skipping";
  76. next MODULE;
  77. }
  78. push @{$distrib{$m->package_name}}, [$m, @{$dependencies{$m->module}}]
  79. }
  80. }
  81. open my $dfile, '>', $depfile or die "Could not write dependency file '$depfile': $!\n";
  82. print $dfile $dep_header;
  83. for my $d (sort keys %distrib) {
  84. my $min_ver = 0;
  85. for my $moddata (@{$distrib{$d}}) {
  86. my ($mod, @bp) = @$moddata;
  87. for my $bp (@bp) {
  88. $min_ver = $bp->{ver} if $bp->{ver} > $min_ver;
  89. }
  90. }
  91. print $dfile
  92. form
  93. {bullet => "* "},
  94. " ============================================================================== ",
  95. "| Distribution | Module used - Description | Min. ver. |",
  96. "|---------------------------+--------------------------------------+-----------|",
  97. "| {<<<<<<<<<<<<<<<<<<<<<<<} | * {[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[} | {|||||||} |",
  98. $d,
  99. [
  100. map {
  101. $_->[0]->module.' - '.$_->[1]
  102. } map {
  103. [$_->[0], $_->[0]->description || 'NA']
  104. } @{$distrib{$d}}
  105. ],
  106. $min_ver eq 0 ? 'None' : $min_ver,
  107. "|==============================================================================|",
  108. "| Used by: |",
  109. "|------------------------------------------------------------------------------|",
  110. "| * {[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[} |",
  111. [
  112. map {
  113. my $md = $_->[0]->module;
  114. map {join(' - ',( $_->{file}.' - '. $md ))} @{$_}[1..$#{$_}] # obfuscated ain't it!!!
  115. } @{$distrib{$d}}
  116. ],
  117. " ============================================================================== ";
  118. }
  119. close $dfile;
  120. exit;
  121. #
  122. ##
  123. ### end main
  124. ##
  125. #
  126. #
  127. # this is where the action is
  128. #
  129. sub parse_core {
  130. my $file = $_;
  131. return unless $file =~ /\.PLS$/ || $file =~ /\.p[ml]$/ ;
  132. return unless -e $file;
  133. open my $F, '<', $file or die "Could not read file '$file': $!\n";
  134. my $pod = '';
  135. MODULE_LOOP:
  136. while (my $line = <$F>) {
  137. # skip POD, starting comments
  138. next if $line =~ /^\s*\#/xms;
  139. if ($line =~ /^=(\w+)/) {
  140. $pod = $1;
  141. }
  142. if ($pod) {
  143. if ($pod eq 'cut') {
  144. $pod = '';
  145. } else {
  146. next MODULE_LOOP;
  147. }
  148. }
  149. # strip off end comments
  150. $line =~ s/\#[^\n]+//;
  151. if ($line =~ /^\bpackage\s+(\S+)\s*;/) {
  152. $bp_packages{$1}++;
  153. } elsif ($line =~ /(?:['"])?\b(use|require)\s+([A-Za-z0-9:_\.\(\)]+)\s*([^;'"]+)?(?:['"])?\s*;/) {
  154. my ($use, $mod, $ver) = ($1, $2, $3);
  155. if ($mod eq 'one') {
  156. print "$File::Find::name: $. $line";
  157. }
  158. if (exists $SKIP{$mod}) {
  159. next MODULE_LOOP;
  160. }
  161. if ($ver && $ver !~ /^v?[\d\.]+$/) {
  162. next MODULE_LOOP;
  163. }
  164. my $nm = $File::Find::name;
  165. $nm =~ s{.*(Bio.*)\.pm}{$1};
  166. $nm =~ s{[\\\/]}{::}g;
  167. if (!exists $dependencies{$mod} ||
  168. !(grep {$_->{file} eq $nm} @{$dependencies{$mod}})) {
  169. push @{ $dependencies{$mod} }, {
  170. ver => $ver || 0,
  171. file => $nm};
  172. }
  173. }
  174. }
  175. close $F;
  176. }
  177. __END__
  178. =head1 NAME
  179. dependencies.pl - check modules and scripts for dependencies not in core
  180. =head1 SYNOPSIS
  181. B<dependencies.pl> [B<--dir> path ] [B<-v|--verbose>] [B<--depfile> file]
  182. [B<-?|-h|--help>] [B<-p|--perl> version]
  183. =head1 DESCRIPTION
  184. Recursively parses directory tree given (defaults to '../Bio') and checks files
  185. for possible dependencies and versions (use/require statements). Checks that
  186. modules aren't part of perl core (--version, defaults to 5.006001). Module
  187. information is returned using CPANPLUS and data is output to a table using
  188. Perl6::Form (yes I managed to get perl6 in here somehow).
  189. Requires:
  190. File::Find - core
  191. Getopt::Long - core
  192. CPANPLUS::Backend
  193. Perl6::Form
  194. Module::CoreList
  195. =head1 OPTIONS
  196. =over 3
  197. =item B<--dir> path
  198. Overides the default directories to check by one directory 'path' and
  199. all its subdirectories.
  200. =item B<--depfile> file
  201. The name of the output file for the dependencies table. Default is
  202. '../DEPENDENCIES.NEW'
  203. =item B<-v | --verbose>
  204. Show the progress through files during the checking. Not used currently.
  205. =item B<-p | --perl> version
  206. Perl version (in long form, i.e. 5.010, 5.006001). Used to weed out the
  207. core modules that should be already present (ActiveState, we're staring at
  208. you sternly).
  209. =item B<-s | --skipbio>
  210. Skips BioPerl-related modules in DEPENDENCIES.
  211. We may add something in the future to allow other forms.
  212. =item B<-? | -h | --help>
  213. This help text.
  214. =back
  215. =head1 FEEDBACK
  216. =head2 Mailing Lists
  217. User feedback is an integral part of the evolution of this and other
  218. Bioperl modules. Send your comments and suggestions preferably to
  219. the Bioperl mailing list. Your participation is much appreciated.
  220. bioperl-l@bioperl.org - General discussion
  221. http://bioperl.org/wiki/Mailing_lists - About the mailing lists
  222. =head2 Reporting Bugs
  223. Report bugs to the Bioperl bug tracking system to help us keep track
  224. of the bugs and their resolution. Bug reports can be submitted via the
  225. web:
  226. https://github.com/bioperl/bioperl-live/issues
  227. =head1 AUTHOR - Chris Fields
  228. Email cjfields-at-bioperl-dot-org
  229. =cut