pp.c:pp_pow() -- quit when you're done
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / Installed.pm
CommitLineData
354f3b56 1package ExtUtils::Installed;
17f410f9 2
57b1a898 3use 5.00503;
354f3b56 4use strict;
5use Carp qw();
6use ExtUtils::Packlist;
7use ExtUtils::MakeMaker;
8use Config;
9use File::Find;
10use File::Basename;
5de3f0da 11use File::Spec;
f6d6199c 12require VMS::Filespec if $^O eq 'VMS';
13
57b1a898 14use vars qw($VERSION);
15$VERSION = '0.05';
007a26ab 16
17my $DOSISH = ($^O =~ /^(MSWin\d\d|os2|dos|mint)$/);
18
f6d6199c 19sub _is_prefix {
20 my ($self, $path, $prefix) = @_;
21 return unless defined $prefix && defined $path;
22
23 if( $^O eq 'VMS' ) {
24 $prefix = VMS::Filespec::unixify($prefix);
25 $path = VMS::Filespec::unixify($path);
26 }
27 return 1 if substr($path, 0, length($prefix)) eq $prefix;
28
29 if ($DOSISH) {
30 $path =~ s|\\|/|g;
31 $prefix =~ s|\\|/|g;
32 return 1 if $path =~ m{^\Q$prefix\E}i;
33 }
34 return(0);
007a26ab 35}
354f3b56 36
f6d6199c 37sub _is_doc {
38 my ($self, $path) = @_;
39 my $man1dir = $Config{man1direxp};
40 my $man3dir = $Config{man3direxp};
41 return(($man1dir && $self->_is_prefix($path, $man1dir))
42 ||
43 ($man3dir && $self->_is_prefix($path, $man3dir))
44 ? 1 : 0)
34dcf69d 45}
46
f6d6199c 47sub _is_type {
48 my ($self, $path, $type) = @_;
49 return 1 if $type eq "all";
50
51 return($self->_is_doc($path)) if $type eq "doc";
52
53 if ($type eq "prog") {
54 return($self->_is_prefix($path, $Config{prefix} || $Config{prefixexp})
55 &&
56 !($self->_is_doc($path))
57 ? 1 : 0);
58 }
59 return(0);
354f3b56 60}
61
f6d6199c 62sub _is_under {
63 my ($self, $path, @under) = @_;
64 $under[0] = "" if (! @under);
65 foreach my $dir (@under) {
66 return(1) if ($self->_is_prefix($path, $dir));
67 }
354f3b56 68
f6d6199c 69 return(0);
354f3b56 70}
71
f6d6199c 72sub new {
73 my ($class) = @_;
74 $class = ref($class) || $class;
75 my $self = {};
76
77 my $archlib = $Config{archlibexp};
78 my $sitearch = $Config{sitearchexp};
79
80 # File::Find does not know how to deal with VMS filepaths.
81 if( $^O eq 'VMS' ) {
82 $archlib = VMS::Filespec::unixify($archlib);
83 $sitearch = VMS::Filespec::unixify($sitearch);
84 }
85
86 if ($DOSISH) {
87 $archlib =~ s|\\|/|g;
88 $sitearch =~ s|\\|/|g;
89 }
90
91 # Read the core packlist
92 $self->{Perl}{packlist} =
93 ExtUtils::Packlist->new( File::Spec->catfile($archlib, '.packlist') );
94 $self->{Perl}{version} = $Config{version};
95
96 # Read the module packlists
97 my $sub = sub {
98 # Only process module .packlists
99 return if ($_) ne ".packlist" || $File::Find::dir eq $archlib;
100
101 # Hack of the leading bits of the paths & convert to a module name
102 my $module = $File::Find::name;
103
104 $module =~ s!\Q$archlib\E/?auto/(.*)/.packlist!$1!s or
105 $module =~ s!\Q$sitearch\E/?auto/(.*)/.packlist!$1!s;
106 my $modfile = "$module.pm";
107 $module =~ s!/!::!g;
108
109 # Find the top-level module file in @INC
110 $self->{$module}{version} = '';
111 foreach my $dir (@INC) {
112 my $p = File::Spec->catfile($dir, $modfile);
113 if (-f $p) {
114 require ExtUtils::MM;
115 $self->{$module}{version} = MM->parse_version($p);
116 last;
117 }
118 }
119
120 # Read the .packlist
121 $self->{$module}{packlist} =
122 ExtUtils::Packlist->new($File::Find::name);
123 };
124
125 my(@dirs) = grep { -e } ($archlib, $sitearch);
126 find($sub, @dirs) if @dirs;
127
128 return(bless($self, $class));
354f3b56 129}
130
f6d6199c 131sub modules {
132 my ($self) = @_;
133 return sort keys %$self;
354f3b56 134}
135
f6d6199c 136sub files {
137 my ($self, $module, $type, @under) = @_;
138
139 # Validate arguments
140 Carp::croak("$module is not installed") if (! exists($self->{$module}));
141 $type = "all" if (! defined($type));
142 Carp::croak('type must be "all", "prog" or "doc"')
143 if ($type ne "all" && $type ne "prog" && $type ne "doc");
144
145 my (@files);
146 foreach my $file (keys(%{$self->{$module}{packlist}})) {
147 push(@files, $file)
148 if ($self->_is_type($file, $type) &&
149 $self->_is_under($file, @under));
150 }
151 return(@files);
354f3b56 152}
153
f6d6199c 154sub directories {
155 my ($self, $module, $type, @under) = @_;
156 my (%dirs);
157 foreach my $file ($self->files($module, $type, @under)) {
158 $dirs{dirname($file)}++;
159 }
160 return sort keys %dirs;
354f3b56 161}
162
f6d6199c 163sub directory_tree {
164 my ($self, $module, $type, @under) = @_;
165 my (%dirs);
166 foreach my $dir ($self->directories($module, $type, @under)) {
167 $dirs{$dir}++;
168 my ($last) = ("");
169 while ($last ne $dir) {
170 $last = $dir;
171 $dir = dirname($dir);
172 last if !$self->_is_under($dir, @under);
173 $dirs{$dir}++;
174 }
175 }
176 return(sort(keys(%dirs)));
354f3b56 177}
178
f6d6199c 179sub validate {
180 my ($self, $module, $remove) = @_;
181 Carp::croak("$module is not installed") if (! exists($self->{$module}));
182 return($self->{$module}{packlist}->validate($remove));
354f3b56 183}
184
f6d6199c 185sub packlist {
186 my ($self, $module) = @_;
187 Carp::croak("$module is not installed") if (! exists($self->{$module}));
188 return($self->{$module}{packlist});
354f3b56 189}
190
f6d6199c 191sub version {
192 my ($self, $module) = @_;
193 Carp::croak("$module is not installed") if (! exists($self->{$module}));
194 return($self->{$module}{version});
354f3b56 195}
196
f6d6199c 197
354f3b56 1981;
199
200__END__
201
202=head1 NAME
203
204ExtUtils::Installed - Inventory management of installed modules
205
206=head1 SYNOPSIS
207
208 use ExtUtils::Installed;
209 my ($inst) = ExtUtils::Installed->new();
210 my (@modules) = $inst->modules();
211 my (@missing) = $inst->validate("DBI");
212 my $all_files = $inst->files("DBI");
213 my $files_below_usr_local = $inst->files("DBI", "all", "/usr/local");
214 my $all_dirs = $inst->directories("DBI");
215 my $dirs_below_usr_local = $inst->directory_tree("DBI", "prog");
216 my $packlist = $inst->packlist("DBI");
217
218=head1 DESCRIPTION
219
220ExtUtils::Installed provides a standard way to find out what core and module
221files have been installed. It uses the information stored in .packlist files
222created during installation to provide this information. In addition it
223provides facilities to classify the installed files and to extract directory
224information from the .packlist files.
225
226=head1 USAGE
227
228The new() function searches for all the installed .packlists on the system, and
229stores their contents. The .packlists can be queried with the functions
230described below.
231
232=head1 FUNCTIONS
233
bbc7dcd2 234=over 4
354f3b56 235
236=item new()
237
238This takes no parameters, and searches for all the installed .packlists on the
239system. The packlists are read using the ExtUtils::packlist module.
240
241=item modules()
242
243This returns a list of the names of all the installed modules. The perl 'core'
244is given the special name 'Perl'.
245
246=item files()
247
248This takes one mandatory parameter, the name of a module. It returns a list of
249all the filenames from the package. To obtain a list of core perl files, use
250the module name 'Perl'. Additional parameters are allowed. The first is one
34dcf69d 251of the strings "prog", "doc" or "all", to select either just program files,
354f3b56 252just manual files or all files. The remaining parameters are a list of
253directories. The filenames returned will be restricted to those under the
254specified directories.
255
256=item directories()
257
258This takes one mandatory parameter, the name of a module. It returns a list of
259all the directories from the package. Additional parameters are allowed. The
34dcf69d 260first is one of the strings "prog", "doc" or "all", to select either just
354f3b56 261program directories, just manual directories or all directories. The remaining
262parameters are a list of directories. The directories returned will be
263restricted to those under the specified directories. This method returns only
264the leaf directories that contain files from the specified module.
265
266=item directory_tree()
267
34dcf69d 268This is identical in operation to directories(), except that it includes all the
354f3b56 269intermediate directories back up to the specified directories.
270
271=item validate()
272
273This takes one mandatory parameter, the name of a module. It checks that all
274the files listed in the modules .packlist actually exist, and returns a list of
275any missing files. If an optional second argument which evaluates to true is
276given any missing files will be removed from the .packlist
277
278=item packlist()
279
280This returns the ExtUtils::Packlist object for the specified module.
281
282=item version()
283
284This returns the version number for the specified module.
285
286=back
287
ddf41153 288=head1 EXAMPLE
289
290See the example in L<ExtUtils::Packlist>.
291
354f3b56 292=head1 AUTHOR
293
294Alan Burlison <Alan.Burlison@uk.sun.com>
295
296=cut