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.
11 #use warnings; # corelist and find throw tons of warnings
14 use SL::InstallationCheck;
18 my (%uselines, %modules, %supplied, %requires);
20 # since the information which classes belong to a cpan distribution is not
21 # easily obtained, I'll just hard code the bigger ones we use here. the same
22 # hash will be filled later with information gathered from the source files.
25 'DateTime::Duration' => 1,
26 'DateTime::Infinite' => 1,
28 'Rose::DB::Object' => {
29 'Rose::DB::Object::ConventionManager' => 1,
30 'Rose::DB::Object::Manager' => 1,
31 'Rose::DB::Object::Metadata' => 1,
32 'Rose::DB::Object::Helpers' => 1,
33 'Rose::DB::Object::Util' => 1,
34 'Rose::DB::Object::Constants' => 1,
37 'Rose::Object::MakeMethods::Generic' => 1,
40 'Template::Constants' => 1,
41 'Template::Exception' => 1,
42 'Template::Iterator' => 1,
43 'Template::Plugin' => 1,
44 'Template::Plugin::Filter' => 1,
45 'Template::Plugin::HTML' => 1,
46 'Template::Stash' => 1,
49 'namespace::clean' => 1,
52 'Email::MIME::Creator' => 1,
56 'TAP::Parser::Aggregator' => 1,
59 'Archive::Zip::Member' => 1,
62 'HTML::Entities' => 1,
68 'File::MimeInfo::Magic' => 1,
73 'files-with-match|l' => \ my $l,
76 chmod($FindBin::Bin . '/..');
79 return unless /(\.p[lm]|console)$/;
81 # remember modules shipped with kivitendo
82 $supplied{modulize($File::Find::name)}++
83 if $File::Find::dir =~ m#modules/#;
85 open my $fh, '<', $_ or warn "can't open $_: $!";
90 next if /Support::Files/; # our own test support module
91 next if /use (warnings|strict|vars|lib|constant|utf8)/;
92 next if /^use (with|the)/;
94 my ($useline) = m/^use\s+(.*?)$/;
96 next if $useline =~ /^[\d._]+;/; # skip version requirements
99 $uselines{$useline} ||= [];
100 push @{ $uselines{$useline} }, $File::Find::name;
104 for my $useline (keys %uselines) {
105 $useline =~ s/#.*//; # kill comments
107 # modules can be loaded implicitly with use base qw(Module) or use parent
108 # 'Module'. catch these:
109 my ($module, $args) = $useline =~ /
114 )? # optional parent block
115 ([\w:]+) # the module
119 # some comments looks very much like use lines
120 # try to get rid of them
121 next if $useline =~ /^it like a normal Perl node/; # YAML::Dump comment
122 next if $useline =~ /^most and offer that in a small/; # YAML
124 my $version = Module::CoreList->first_release($module);
125 $modules{$module} = { status => $supplied{$module} ? 'included'
126 : $version ? sprintf '%2.6f', $version
127 : is_required($module) ? 'required'
128 : is_optional($module) ? 'optional'
129 : is_developer($module) ? 'developer'
131 files => $uselines{$useline},
134 # build requirement tree
135 for my $file (@{ $uselines{$useline} }) {
136 next if $file =~ /\.pl$/;
137 my $orig_module = modulize($file);
138 $requires{$orig_module} ||= {};
139 $requires{$orig_module}{$module}++;
143 # have all documented modules mentioned here
144 $modules{$_->{name}} ||= { status => 'required' } for @SL::InstallationCheck::required_modules;
145 $modules{$_->{name}} ||= { status => 'optional' } for @SL::InstallationCheck::optional_modules;
146 $modules{$_->{name}} ||= { status => 'developer' } for @SL::InstallationCheck::developer_modules;
148 # build transitive closure for documented dependencies
152 for my $src_module (keys %requires) {
153 for my $dst_module (keys %{ $requires{$src_module} }) {
154 if ( $modules{$src_module}
155 && $modules{$dst_module}
156 && $modules{$src_module}->{status} =~ /^(required|devel|optional)/
157 && $modules{$dst_module}->{status} eq '!missing') {
158 $modules{$dst_module}->{status} = "required"; # . ", via $src_module";
166 print sprintf "%8s : %s", color_text($modules{$_}->{status}), $_;
168 print " $_" for @{ $modules{$_}->{files} || [] };
171 $modules{$a}->{status} cmp $modules{$b}->{status}
176 for (my ($name) = @_) {
187 grep { $_->{name} eq $module } @SL::InstallationCheck::required_modules;
192 grep { $_->{name} eq $module } @SL::InstallationCheck::optional_modules;
197 grep { $_->{name} eq $module } @SL::InstallationCheck::developer_modules;
202 return color(get_color($text)) . $text . color('reset');
207 return 'yellow' if /^5./ && $_ > 5.008;
208 return 'green' if /^5./;
209 return 'green' if /^included/;
210 return 'red' if /^!missing/;
225 # perl scipts/find-use.pl
226 !missing : Template::Constants
231 This util is useful for package builders to identify all the CPAN dependencies
232 we have. It requires Module::CoreList (which is core since 5.9) to determine if
233 a module is distributed with perl or not. The output will be one of the
240 If a version string is displayed, the module is core since this version.
241 Everything up to 5.8 is alright. 5.10 (aka 5.010) is acceptable, but should be
242 documented. Please do not use 5.12 core modules without adding an explicit
247 This module is included in C<modules/*>. Don't worry about it.
251 This module is documented in C<SL:InstallationCheck> to be necessary, or is a
252 dependency of one of these. Everything alright.
256 These modules are neither core, nor included, nor required. This is ok for
257 developer tools, but should never occur for modules the actual program uses.
263 http://www.ledgersmb.org/ - The LedgerSMB team
264 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
268 Distributed under the terms of the GNU General Public License v2.