1 package ExtUtils::Installed;
6 use ExtUtils::Packlist;
7 use ExtUtils::MakeMaker;
13 my $Is_VMS = $^O eq 'VMS';
14 my $DOSISH = ($^O =~ /^(MSWin\d\d|os2|dos|mint)$/);
16 require VMS::Filespec if $Is_VMS;
18 use vars qw($VERSION);
22 my ($self, $path, $prefix) = @_;
23 return unless defined $prefix && defined $path;
26 $prefix = VMS::Filespec::unixify($prefix);
27 $path = VMS::Filespec::unixify($path);
29 $prefix =~ m!/+! && $prefix =~ s!/+!/!g;
30 $path =~ m!/+! && $path =~ s!/+!/!g;
32 return 1 if substr($path, 0, length($prefix)) eq $prefix;
37 return 1 if $path =~ m{^\Q$prefix\E}i;
43 my ($self, $path) = @_;
44 my $man1dir = $Config{man1direxp};
45 my $man3dir = $Config{man3direxp};
46 return(($man1dir && $self->_is_prefix($path, $man1dir))
48 ($man3dir && $self->_is_prefix($path, $man3dir))
53 my ($self, $path, $type) = @_;
54 return 1 if $type eq "all";
56 return($self->_is_doc($path)) if $type eq "doc";
58 if ($type eq "prog") {
59 return($self->_is_prefix($path, $Config{prefix} || $Config{prefixexp})
61 !($self->_is_doc($path))
68 my ($self, $path, @under) = @_;
69 $under[0] = "" if (! @under);
70 foreach my $dir (@under) {
71 return(1) if ($self->_is_prefix($path, $dir));
79 $class = ref($class) || $class;
82 my $archlib = $Config{archlibexp};
83 my $sitearch = $Config{sitearchexp};
85 # File::Find does not know how to deal with VMS filepaths.
87 $archlib = VMS::Filespec::unixify($archlib);
88 $sitearch = VMS::Filespec::unixify($sitearch);
93 $sitearch =~ s|\\|/|g;
96 # Read the core packlist
97 $self->{Perl}{packlist} =
98 ExtUtils::Packlist->new( File::Spec->catfile($archlib, '.packlist') );
99 $self->{Perl}{version} = $Config{version};
101 # Read the module packlists
103 # Only process module .packlists
104 return if $_ ne ".packlist" || $File::Find::dir eq $archlib;
106 # Hack of the leading bits of the paths & convert to a module name
107 my $module = $File::Find::name;
109 $module =~ s!\Q$archlib\E/?auto/(.*)/.packlist!$1!s or
110 $module =~ s!\Q$sitearch\E/?auto/(.*)/.packlist!$1!s;
111 my $modfile = "$module.pm";
114 # Find the top-level module file in @INC
115 $self->{$module}{version} = '';
116 foreach my $dir (@INC) {
117 my $p = File::Spec->catfile($dir, $modfile);
119 $module = _module_name($p, $module) if $Is_VMS;
121 require ExtUtils::MM;
122 $self->{$module}{version} = MM->parse_version($p);
128 $self->{$module}{packlist} =
129 ExtUtils::Packlist->new($File::Find::name);
132 my(@dirs) = grep { -e } ($archlib, $sitearch);
133 find($sub, @dirs) if @dirs;
135 return(bless($self, $class));
138 # VMS's non-case preserving file-system means the package name can't
139 # be reconstructed from the filename.
141 my($file, $orig_module) = @_;
144 if (open PACKFH, $file) {
146 if (/package\s+(\S+)\s*;/) {
148 # Make a sanity check, that lower case $module
149 # is identical to lowercase $pack before
151 if (lc($pack) eq lc($orig_module)) {
160 print STDERR "Couldn't figure out the package name for $file\n"
171 # Bug/feature of sort in scalar context requires this.
172 return wantarray ? sort keys %$self : keys %$self;
176 my ($self, $module, $type, @under) = @_;
179 Carp::croak("$module is not installed") if (! exists($self->{$module}));
180 $type = "all" if (! defined($type));
181 Carp::croak('type must be "all", "prog" or "doc"')
182 if ($type ne "all" && $type ne "prog" && $type ne "doc");
185 foreach my $file (keys(%{$self->{$module}{packlist}})) {
187 if ($self->_is_type($file, $type) &&
188 $self->_is_under($file, @under));
194 my ($self, $module, $type, @under) = @_;
196 foreach my $file ($self->files($module, $type, @under)) {
197 $dirs{dirname($file)}++;
199 return sort keys %dirs;
203 my ($self, $module, $type, @under) = @_;
205 foreach my $dir ($self->directories($module, $type, @under)) {
208 while ($last ne $dir) {
210 $dir = dirname($dir);
211 last if !$self->_is_under($dir, @under);
215 return(sort(keys(%dirs)));
219 my ($self, $module, $remove) = @_;
220 Carp::croak("$module is not installed") if (! exists($self->{$module}));
221 return($self->{$module}{packlist}->validate($remove));
225 my ($self, $module) = @_;
226 Carp::croak("$module is not installed") if (! exists($self->{$module}));
227 return($self->{$module}{packlist});
231 my ($self, $module) = @_;
232 Carp::croak("$module is not installed") if (! exists($self->{$module}));
233 return($self->{$module}{version});
243 ExtUtils::Installed - Inventory management of installed modules
247 use ExtUtils::Installed;
248 my ($inst) = ExtUtils::Installed->new();
249 my (@modules) = $inst->modules();
250 my (@missing) = $inst->validate("DBI");
251 my $all_files = $inst->files("DBI");
252 my $files_below_usr_local = $inst->files("DBI", "all", "/usr/local");
253 my $all_dirs = $inst->directories("DBI");
254 my $dirs_below_usr_local = $inst->directory_tree("DBI", "prog");
255 my $packlist = $inst->packlist("DBI");
259 ExtUtils::Installed provides a standard way to find out what core and module
260 files have been installed. It uses the information stored in .packlist files
261 created during installation to provide this information. In addition it
262 provides facilities to classify the installed files and to extract directory
263 information from the .packlist files.
267 The new() function searches for all the installed .packlists on the system, and
268 stores their contents. The .packlists can be queried with the functions
277 This takes no parameters, and searches for all the installed .packlists on the
278 system. The packlists are read using the ExtUtils::packlist module.
282 This returns a list of the names of all the installed modules. The perl 'core'
283 is given the special name 'Perl'.
287 This takes one mandatory parameter, the name of a module. It returns a list of
288 all the filenames from the package. To obtain a list of core perl files, use
289 the module name 'Perl'. Additional parameters are allowed. The first is one
290 of the strings "prog", "doc" or "all", to select either just program files,
291 just manual files or all files. The remaining parameters are a list of
292 directories. The filenames returned will be restricted to those under the
293 specified directories.
297 This takes one mandatory parameter, the name of a module. It returns a list of
298 all the directories from the package. Additional parameters are allowed. The
299 first is one of the strings "prog", "doc" or "all", to select either just
300 program directories, just manual directories or all directories. The remaining
301 parameters are a list of directories. The directories returned will be
302 restricted to those under the specified directories. This method returns only
303 the leaf directories that contain files from the specified module.
305 =item directory_tree()
307 This is identical in operation to directories(), except that it includes all the
308 intermediate directories back up to the specified directories.
312 This takes one mandatory parameter, the name of a module. It checks that all
313 the files listed in the modules .packlist actually exist, and returns a list of
314 any missing files. If an optional second argument which evaluates to true is
315 given any missing files will be removed from the .packlist
319 This returns the ExtUtils::Packlist object for the specified module.
323 This returns the version number for the specified module.
329 See the example in L<ExtUtils::Packlist>.
333 Alan Burlison <Alan.Burlison@uk.sun.com>