6 unshift(@INC, $FindBin::Bin . '/../modules/override'); # Use our own versions of various modules (e.g. YAML).
7 push (@INC, $FindBin::Bin . '/..'); # '.' will be removed from @INC soon.
8 push (@INC, $FindBin::Bin . '/../modules/fallback'); # Only use our own versions of modules if there's no system version.
12 #use warnings; # corelist and find throw tons of warnings
15 use SL::InstallationCheck;
19 my (%uselines, %modules, %supplied, %requires);
21 # since the information which classes belong to a cpan distribution is not
22 # easily obtained, I'll just hard code the bigger ones we use here. the same
23 # hash will be filled later with information gathered from the source files.
26 'DateTime::Duration' => 1,
27 'DateTime::Infinite' => 1,
29 'Rose::DB::Object' => {
30 'Rose::DB::Object::ConventionManager' => 1,
31 'Rose::DB::Object::Manager' => 1,
32 'Rose::DB::Object::Metadata' => 1,
33 'Rose::DB::Object::Helpers' => 1,
34 'Rose::DB::Object::Util' => 1,
35 'Rose::DB::Object::Constants' => 1,
38 'Rose::Object::MakeMethods::Generic' => 1,
41 'Template::Constants' => 1,
42 'Template::Exception' => 1,
43 'Template::Iterator' => 1,
44 'Template::Plugin' => 1,
45 'Template::Plugin::Filter' => 1,
46 'Template::Plugin::HTML' => 1,
47 'Template::Stash' => 1,
50 'namespace::clean' => 1,
53 'Email::MIME::Creator' => 1,
57 'TAP::Parser::Aggregator' => 1,
60 'Archive::Zip::Member' => 1,
63 'HTML::Entities' => 1,
69 'File::MimeInfo::Magic' => 1,
74 'files-with-match|l' => \ my $l,
77 chmod($FindBin::Bin . '/..');
80 return unless /(\.p[lm]|console)$/;
82 # remember modules shipped with kivitendo
83 $supplied{modulize($File::Find::name)}++
84 if $File::Find::dir =~ m#modules/#;
86 open my $fh, '<', $_ or warn "can't open $_: $!";
91 next if /Support::Files/; # our own test support module
92 next if /use (warnings|strict|vars|lib|constant|utf8)/;
93 next if /^use (with|the)/;
95 my ($useline) = m/^use\s+(.*?)$/;
97 next if $useline =~ /^[\d._]+;/; # skip version requirements
100 $uselines{$useline} ||= [];
101 push @{ $uselines{$useline} }, $File::Find::name;
105 for my $useline (keys %uselines) {
106 $useline =~ s/#.*//; # kill comments
108 # modules can be loaded implicitly with use base qw(Module) or use parent
109 # 'Module'. catch these:
110 my ($module, $args) = $useline =~ /
115 )? # optional parent block
116 ([\w:]+) # the module
120 # some comments looks very much like use lines
121 # try to get rid of them
122 next if $useline =~ /^it like a normal Perl node/; # YAML::Dump comment
123 next if $useline =~ /^most and offer that in a small/; # YAML
125 my $version = Module::CoreList->first_release($module);
126 $modules{$module} = { status => $supplied{$module} ? 'included'
127 : $version ? sprintf '%2.6f', $version
128 : is_required($module) ? 'required'
129 : is_optional($module) ? 'optional'
130 : is_developer($module) ? 'developer'
132 files => $uselines{$useline},
135 # build requirement tree
136 for my $file (@{ $uselines{$useline} }) {
137 next if $file =~ /\.pl$/;
138 my $orig_module = modulize($file);
139 $requires{$orig_module} ||= {};
140 $requires{$orig_module}{$module}++;
144 # have all documented modules mentioned here
145 $modules{$_->{name}} ||= { status => 'required' } for @SL::InstallationCheck::required_modules;
146 $modules{$_->{name}} ||= { status => 'optional' } for @SL::InstallationCheck::optional_modules;
147 $modules{$_->{name}} ||= { status => 'developer' } for @SL::InstallationCheck::developer_modules;
149 # build transitive closure for documented dependancies
153 for my $src_module (keys %requires) {
154 for my $dst_module (keys %{ $requires{$src_module} }) {
155 if ( $modules{$src_module}
156 && $modules{$dst_module}
157 && $modules{$src_module}->{status} =~ /^(required|devel|optional)/
158 && $modules{$dst_module}->{status} eq '!missing') {
159 $modules{$dst_module}->{status} = "required"; # . ", via $src_module";
167 print sprintf "%8s : %s", color_text($modules{$_}->{status}), $_;
169 print " $_" for @{ $modules{$_}->{files} || [] };
172 $modules{$a}->{status} cmp $modules{$b}->{status}
177 for (my ($name) = @_) {
188 grep { $_->{name} eq $module } @SL::InstallationCheck::required_modules;
193 grep { $_->{name} eq $module } @SL::InstallationCheck::optional_modules;
198 grep { $_->{name} eq $module } @SL::InstallationCheck::developer_modules;
203 return color(get_color($text)) . $text . color('reset');
208 return 'yellow' if /^5./ && $_ > 5.008;
209 return 'green' if /^5./;
210 return 'green' if /^included/;
211 return 'red' if /^!missing/;
226 # perl scipts/find-use.pl
227 !missing : Template::Constants
232 This util is useful for package builders to identify all the CPAN dependencies
233 we have. It requires Module::CoreList (which is core since 5.9) to determine if
234 a module is distributed with perl or not. The output will be one of the
241 If a version string is displayed, the module is core since this version.
242 Everything up to 5.8 is alright. 5.10 (aka 5.010) is acceptable, but should be
243 documented. Please do not use 5.12 core modules without adding an explicit
248 This module is included in C<modules/*>. Don't worry about it.
252 This module is documented in C<SL:InstallationCheck> to be necessary, or is a
253 dependancy of one of these. Everything alright.
257 These modules are neither core, nor included, nor required. This is ok for
258 developer tools, but should never occur for modules the actual program uses.
264 http://www.ledgersmb.org/ - The LedgerSMB team
265 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
269 Distributed under the terms of the GNU General Public License v2.