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,
65 'files-with-match|l' => \ my $l,
68 chmod($FindBin::Bin . '/..');
71 return unless /(\.p[lm]|console)$/;
73 # remember modules shipped with kivitendo
74 $supplied{modulize($File::Find::name)}++
75 if $File::Find::dir =~ m#modules/#;
77 open my $fh, '<', $_ or warn "can't open $_: $!";
82 next if /Support::Files/; # our own test support module
83 next if /use (warnings|strict|vars|lib|constant|utf8)/;
84 next if /^use (with|the)/;
86 my ($useline) = m/^use\s+(.*?)$/;
88 next if $useline =~ /^[\d._]+;/; # skip version requirements
91 $uselines{$useline} ||= [];
92 push @{ $uselines{$useline} }, $File::Find::name;
96 for my $useline (keys %uselines) {
97 $useline =~ s/#.*//; # kill comments
99 # modules can be loaded implicitly with use base qw(Module) or use parent
100 # 'Module'. catch these:
101 my ($module, $args) = $useline =~ /
106 )? # optional parent block
107 ([\w:]+) # the module
111 # some comments looks very much like use lines
112 # try to get rid of them
113 next if $useline =~ /^it like a normal Perl node/; # YAML::Dump comment
114 next if $useline =~ /^most and offer that in a small/; # YAML
116 my $version = Module::CoreList->first_release($module);
117 $modules{$module} = { status => $supplied{$module} ? 'included'
118 : $version ? sprintf '%2.6f', $version
119 : is_required($module) ? 'required'
120 : is_optional($module) ? 'optional'
121 : is_developer($module) ? 'developer'
123 files => $uselines{$useline},
126 # build requirement tree
127 for my $file (@{ $uselines{$useline} }) {
128 next if $file =~ /\.pl$/;
129 my $orig_module = modulize($file);
130 $requires{$orig_module} ||= {};
131 $requires{$orig_module}{$module}++;
135 # have all documented modules mentioned here
136 $modules{$_->{name}} ||= { status => 'required' } for @SL::InstallationCheck::required_modules;
137 $modules{$_->{name}} ||= { status => 'optional' } for @SL::InstallationCheck::optional_modules;
138 $modules{$_->{name}} ||= { status => 'developer' } for @SL::InstallationCheck::developer_modules;
140 # build transitive closure for documented dependancies
144 for my $src_module (keys %requires) {
145 for my $dst_module (keys %{ $requires{$src_module} }) {
146 if ( $modules{$src_module}
147 && $modules{$dst_module}
148 && $modules{$src_module}->{status} =~ /^(required|devel|optional)/
149 && $modules{$dst_module}->{status} eq '!missing') {
150 $modules{$dst_module}->{status} = "required"; # . ", via $src_module";
158 print sprintf "%8s : %s", color_text($modules{$_}->{status}), $_;
160 print " $_" for @{ $modules{$_}->{files} || [] };
163 $modules{$a}->{status} cmp $modules{$b}->{status}
168 for (my ($name) = @_) {
179 grep { $_->{name} eq $module } @SL::InstallationCheck::required_modules;
184 grep { $_->{name} eq $module } @SL::InstallationCheck::optional_modules;
189 grep { $_->{name} eq $module } @SL::InstallationCheck::developer_modules;
194 return color(get_color($text)) . $text . color('reset');
199 return 'yellow' if /^5./ && $_ > 5.008;
200 return 'green' if /^5./;
201 return 'green' if /^included/;
202 return 'red' if /^!missing/;
217 # perl scipts/find-use.pl
218 !missing : Perl::Tags
219 !missing : Template::Constants
224 This util is useful for package builders to identify all the CPAN dependencies
225 we have. It requires Module::CoreList (which is core since 5.9) to determine if
226 a module is distributed with perl or not. The output will be one of the
233 If a version string is displayed, the module is core since this version.
234 Everything up to 5.8 is alright. 5.10 (aka 5.010) is acceptable, but should be
235 documented. Please do not use 5.12 core modules without adding an explicit
240 This module is included in C<modules/*>. Don't worry about it.
244 This module is documented in C<SL:InstallationCheck> to be necessary, or is a
245 dependancy of one of these. Everything alright.
249 These modules are neither core, nor included, nor required. This is ok for
250 developer tools, but should never occur for modules the actual program uses.
256 http://www.ledgersmb.org/ - The LedgerSMB team
257 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
261 Distributed under the terms of the GNU General Public License v2.