3 #use warnings; # corelist and find throw tons of warnings
6 use SL::InstallationCheck;
10 my (%uselines, %modules, %supplied, %requires);
12 # since the information which classes belong to a cpan distribution is not
13 # easily obtained, I'll just hard code the bigger ones we use here. the same
14 # hash will be filled later with information gathered from the source files.
17 'DateTime::Duration' => 1,
18 'DateTime::Infinite' => 1,
20 'Rose::DB::Object' => {
21 'Rose::DB::Object::ConventionManager' => 1,
22 'Rose::DB::Object::Manager' => 1,
23 'Rose::DB::Object::Metadata' => 1,
24 'Rose::DB::Object::Helpers' => 1,
25 'Rose::DB::Object::Util' => 1,
28 'Rose::Object::MakeMethods::Generic' => 1,
31 'Template::Constants' => 1,
32 'Template::Exception' => 1,
33 'Template::Iterator' => 1,
34 'Template::Plugin' => 1,
35 'Template::Plugin::Filter' => 1,
36 'Template::Plugin::HTML' => 1,
37 'Template::Stash' => 1,
40 'namespace::clean' => 1,
43 'Email::MIME::Creator' => 1,
47 'TAP::Parser::Aggregator' => 1,
50 'Archive::Zip::Member' => 1,
55 'files-with-match|l' => \ my $l,
59 return unless /(\.p[lm]|console)$/;
61 # remember modules shipped with kivitendo
62 $supplied{modulize($File::Find::name)}++
63 if $File::Find::dir =~ m#modules/#;
65 open my $fh, '<', $_ or warn "can't open $_: $!";
70 next if /Support::Files/; # our own test support module
71 next if /use (warnings|strict|vars|lib|constant|utf8)/;
73 my ($useline) = m/^use\s+(.*?)$/;
75 next if $useline =~ /^[\d._]+;/; # skip version requirements
78 $uselines{$useline} ||= [];
79 push @{ $uselines{$useline} }, $File::Find::name;
83 for my $useline (keys %uselines) {
84 $useline =~ s/#.*//; # kill comments
86 # modules can be loaded implicitly with use base qw(Module) or use parent
87 # 'Module'. catch these:
88 my ($module, $args) = $useline =~ /
93 )? # optional parent block
98 # some comments looks very much like use lines
99 # try to get rid of them
100 next if $useline =~ /^it like a normal Perl node/; # YAML::Dump comment
101 next if $useline =~ /^most and offer that in a small/; # YAML
103 my $version = Module::CoreList->first_release($module);
104 $modules{$module} = { status => $supplied{$module} ? 'included'
105 : $version ? sprintf '%2.6f', $version
106 : is_required($module) ? 'required'
107 : is_optional($module) ? 'optional'
108 : is_developer($module) ? 'developer'
110 files => $uselines{$useline},
113 # build requirement tree
114 for my $file (@{ $uselines{$useline} }) {
115 next if $file =~ /\.pl$/;
116 my $orig_module = modulize($file);
117 $requires{$orig_module} ||= {};
118 $requires{$orig_module}{$module}++;
122 # have all documented modules mentioned here
123 $modules{$_->{name}} ||= { status => 'required' } for @SL::InstallationCheck::required_modules;
124 $modules{$_->{name}} ||= { status => 'optional' } for @SL::InstallationCheck::optional_modules;
125 $modules{$_->{name}} ||= { status => 'developer' } for @SL::InstallationCheck::developer_modules;
127 # build transitive closure for documented dependancies
131 for my $src_module (keys %requires) {
132 for my $dst_module (keys %{ $requires{$src_module} }) {
133 if ( $modules{$src_module}
134 && $modules{$dst_module}
135 && $modules{$src_module}->{status} =~ /^(required|devel|optional)/
136 && $modules{$dst_module}->{status} eq '!missing') {
137 $modules{$dst_module}->{status} = "required"; # . ", via $src_module";
145 print sprintf "%8s : %s", color_text($modules{$_}->{status}), $_;
147 print " $_" for @{ $modules{$_}->{files} || [] };
150 $modules{$a}->{status} cmp $modules{$b}->{status}
155 for (my ($name) = @_) {
166 grep { $_->{name} eq $module } @SL::InstallationCheck::required_modules;
171 grep { $_->{name} eq $module } @SL::InstallationCheck::optional_modules;
176 grep { $_->{name} eq $module } @SL::InstallationCheck::developer_modules;
181 return color(get_color($text)) . $text . color('reset');
186 return 'yellow' if /^5./ && $_ > 5.008;
187 return 'green' if /^5./;
188 return 'green' if /^included/;
189 return 'red' if /^!missing/;
204 # perl scipts/find-use.pl
205 !missing : Perl::Tags
206 !missing : Template::Constants
211 This util is useful for package builders to identify all the CPAN dependencies
212 we have. It requires Module::CoreList (which is core since 5.9) to determine if
213 a module is distributed with perl or not. The output will be one of the
220 If a version string is displayed, the module is core since this version.
221 Everything up to 5.8 is alright. 5.10 (aka 5.010) is acceptable, but should be
222 documented. Please do not use 5.12 core modules without adding an explicit
227 This module is included in C<modules/*>. Don't worry about it.
231 This module is documented in C<SL:InstallationCheck> to be necessary, or is a
232 dependancy of one of these. Everything alright.
236 These modules are neither core, nor included, nor required. This is ok for
237 developer tools, but should never occur for modules the actual program uses.
243 http://www.ledgersmb.org/ - The LedgerSMB team
244 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
248 Distributed under the terms of the GNU General Public License v2.